From f0c580498f8cc4258e1695e7f0014af1abb5d941 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Sun, 5 Sep 2021 22:58:40 +0800 Subject: [PATCH 001/114] implement Linux iwlwifi generic rate control RS algorithm for iwm --- itl80211/linux/bitfield.h | 91 +- itl80211/linux/kernel.h | 1 + itl80211/linux/types.h | 4 + itl80211/openbsd/net80211/ieee80211.h | 29 +- itl80211/openbsd/net80211/ieee80211_output.c | 3 +- itl80211/openbsd/net80211/ieee80211_var.h | 1 + itlwm.xcodeproj/project.pbxproj | 28 + itlwm/hal_iwm/ItlIwm.cpp | 1 + itlwm/hal_iwm/ItlIwm.hpp | 9 +- itlwm/hal_iwm/if_iwmreg.h | 13 +- itlwm/hal_iwm/if_iwmvar.h | 17 +- itlwm/hal_iwm/mac80211.cpp | 641 ++- itlwm/hal_iwm/rs.cpp | 3685 ++++++++++++++++++ itlwm/hal_iwm/rs.h | 1509 +++++++ itlwm/hal_iwm/rx.cpp | 10 +- 15 files changed, 5878 insertions(+), 164 deletions(-) create mode 100644 itlwm/hal_iwm/rs.cpp create mode 100644 itlwm/hal_iwm/rs.h diff --git a/itl80211/linux/bitfield.h b/itl80211/linux/bitfield.h index faf0b53e8..6eafe987a 100644 --- a/itl80211/linux/bitfield.h +++ b/itl80211/linux/bitfield.h @@ -44,13 +44,100 @@ ({ \ ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); \ }) + +static inline int +find_first_zero_bit(volatile void *p, int max) +{ + int b; + volatile u_int *ptr = (volatile u_int *)p; + + for (b = 0; b < max; b += 32) { + if (ptr[b >> 5] != ~0) { + for (;;) { + if ((ptr[b >> 5] & (1 << (b & 0x1f))) == 0) + return b; + b++; + } + } + } + return max; +} + +static inline int +find_next_zero_bit(volatile void *p, int max, int b) +{ + volatile u_int *ptr = (volatile u_int *)p; + + for (; b < max; b += 32) { + if (ptr[b >> 5] != ~0) { + for (;;) { + if ((ptr[b >> 5] & (1 << (b & 0x1f))) == 0) + return b; + b++; + } + } + } + return max; +} + +static inline int +find_first_bit(volatile void *p, int max) +{ + int b; + volatile u_int *ptr = (volatile u_int *)p; + + for (b = 0; b < max; b += 32) { + if (ptr[b >> 5] != 0) { + for (;;) { + if (ptr[b >> 5] & (1 << (b & 0x1f))) + return b; + b++; + } + } + } + return max; +} + +static inline int +find_next_bit(volatile void *p, int max, int b) +{ + volatile u_int *ptr = (volatile u_int *)p; + + for (; b < max; b+= 32) { + if (ptr[b >> 5] != 0) { + for (;;) { + if (ptr[b >> 5] & (1 << (b & 0x1f))) + return b; + b++; + } + } + } + return max; +} + +static inline int +find_last_bit(volatile void *p, int max) +{ + int b; + volatile u_int *ptr = (volatile u_int *)p; + + for (b = max; b > 0; b -= 32) { + if (ptr[b >> 5] != 0) { + for (;;) { + if (ptr[b >> 5] & (1 << (b & 0x1f))) + return b; + b--; + } + } + } + return max; +} + #define for_each_set_bit(bit, addr, size) \ for ((bit) = find_first_bit((addr), (size)); \ (bit) < (size); \ (bit) = find_next_bit((addr), (size), (bit) + 1)) -#define find_first_bit(addr, size) find_next_bit((addr), (size), 0) - #define GENMASK(h, l) \ (((~(0UL)) - ((1UL) << (l)) + 1) & \ (~(0UL) >> (BITS_PER_LONG - 1 - (h)))) diff --git a/itl80211/linux/kernel.h b/itl80211/linux/kernel.h index cc63a15f0..d410944e1 100644 --- a/itl80211/linux/kernel.h +++ b/itl80211/linux/kernel.h @@ -185,6 +185,7 @@ pointer_t __mptr = (pointer_t)(ptr); \ #define time_after(a,b) \ ((long)(b) - (long)(a) < 0) +#define time_is_before_jiffies(a) time_after(ticks, a) #define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1)) diff --git a/itl80211/linux/types.h b/itl80211/linux/types.h index befe717b4..b52204d56 100644 --- a/itl80211/linux/types.h +++ b/itl80211/linux/types.h @@ -147,6 +147,10 @@ typedef UInt16 __sum16; typedef u64 dma_addr_t; +#define U8_MAX ((u8)~0U) +#define S8_MAX ((s8)(U8_MAX >> 1)) +#define S8_MIN ((s8)(-S8_MAX - 1)) + #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) #define upper_32_bits(n) ((u32)(((n) >> 16) >> 16)) diff --git a/itl80211/openbsd/net80211/ieee80211.h b/itl80211/openbsd/net80211/ieee80211.h index b9d110f53..7ad71efa3 100644 --- a/itl80211/openbsd/net80211/ieee80211.h +++ b/itl80211/openbsd/net80211/ieee80211.h @@ -356,24 +356,35 @@ ieee80211_get_qos(const struct ieee80211_frame *wh) } static __inline int -ieee80211_is_ctl(const struct ieee80211_frame *wh) +ieee80211_is_ctl(uint16_t fc) { - return (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == - IEEE80211_FC0_TYPE_CTL; + return (fc & htole16(IEEE80211_FC0_TYPE_MASK)) == + htole16(IEEE80211_FC0_TYPE_CTL); } static __inline int -ieee80211_is_data(const struct ieee80211_frame *wh) +ieee80211_is_data(uint16_t fc) { - return (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == - IEEE80211_FC0_TYPE_DATA; + return (fc & htole16(IEEE80211_FC0_TYPE_MASK)) == + htole16(IEEE80211_FC0_TYPE_DATA); } static __inline int -ieee80211_is_mgmt(const struct ieee80211_frame *wh) +ieee80211_is_mgmt(uint16_t fc) { - return (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == - IEEE80211_FC0_TYPE_MGT; + return (fc & htole16(IEEE80211_FC0_TYPE_MASK)) == + htole16(IEEE80211_FC0_TYPE_MGT); +} + +static __inline int +ieee80211_is_data_qos(uint16_t fc) +{ + /* + * mask with QOS_DATA rather than IEEE80211_FCTL_STYPE as we just need + * to check the one bit + */ + return (fc & htole16(IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_QOS)) == + htole16(IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS); } static __inline int diff --git a/itl80211/openbsd/net80211/ieee80211_output.c b/itl80211/openbsd/net80211/ieee80211_output.c index 2da63b462..429d36c10 100644 --- a/itl80211/openbsd/net80211/ieee80211_output.c +++ b/itl80211/openbsd/net80211/ieee80211_output.c @@ -637,7 +637,8 @@ ieee80211_encap(struct _ifnet *ifp, mbuf_t m, struct ieee80211_node **pni) if (ba->ba_state != IEEE80211_BA_AGREED) { hdrlen = sizeof(struct ieee80211_frame); addqos = 0; - if (ieee80211_can_use_ampdu(ic, ni)) + if ((ic->ic_caps & IEEE80211_C_TX_AMPDU_SETUP_IN_RS) == 0 && + ieee80211_can_use_ampdu(ic, ni)) ieee80211_node_trigger_addba_req(ni, tid); } else { hdrlen = sizeof(struct ieee80211_qosframe); diff --git a/itl80211/openbsd/net80211/ieee80211_var.h b/itl80211/openbsd/net80211/ieee80211_var.h index 96ad077ad..c56c5dbd4 100644 --- a/itl80211/openbsd/net80211/ieee80211_var.h +++ b/itl80211/openbsd/net80211/ieee80211_var.h @@ -659,6 +659,7 @@ struct ieee80211_ess { #define IEEE80211_C_AMSDU_IN_AMPDU 0x00020000 /* CAPABILITY: Rx AMSDU inside AMPDU */ #define IEEE80211_C_TX_AMPDU_SETUP_IN_HW 0x00040000 /* CAPABILITY: BA negotiation in HW */ #define IEEE80211_C_SUPPORTS_VHT_EXT_NSS_BW 0x00080000 /* CAPABILITY: for 160mhz */ +#define IEEE80211_C_TX_AMPDU_SETUP_IN_RS 0x00100000 /* flags for ieee80211_fix_rate() */ #define IEEE80211_F_DOSORT 0x00000001 /* sort rate list */ diff --git a/itlwm.xcodeproj/project.pbxproj b/itlwm.xcodeproj/project.pbxproj index f8aa71d60..fb638124d 100644 --- a/itlwm.xcodeproj/project.pbxproj +++ b/itlwm.xcodeproj/project.pbxproj @@ -324,6 +324,18 @@ A5FA2AE828A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; A5FA2AE928A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; A5FA2AEA28A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; + A5DD111526D93B5F00BA01EF /* rs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5DD111326D93B5F00BA01EF /* rs.cpp */; }; + A5DD111626D93B5F00BA01EF /* rs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5DD111326D93B5F00BA01EF /* rs.cpp */; }; + A5DD111726D93B5F00BA01EF /* rs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5DD111326D93B5F00BA01EF /* rs.cpp */; }; + A5DD111826D93B5F00BA01EF /* rs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5DD111326D93B5F00BA01EF /* rs.cpp */; }; + A5DD111926D93B5F00BA01EF /* rs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5DD111326D93B5F00BA01EF /* rs.cpp */; }; + A5DD111A26D93B5F00BA01EF /* rs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5DD111326D93B5F00BA01EF /* rs.cpp */; }; + A5DD111B26D93B5F00BA01EF /* rs.h in Headers */ = {isa = PBXBuildFile; fileRef = A5DD111426D93B5F00BA01EF /* rs.h */; }; + A5DD111C26D93B5F00BA01EF /* rs.h in Headers */ = {isa = PBXBuildFile; fileRef = A5DD111426D93B5F00BA01EF /* rs.h */; }; + A5DD111D26D93B5F00BA01EF /* rs.h in Headers */ = {isa = PBXBuildFile; fileRef = A5DD111426D93B5F00BA01EF /* rs.h */; }; + A5DD111E26D93B5F00BA01EF /* rs.h in Headers */ = {isa = PBXBuildFile; fileRef = A5DD111426D93B5F00BA01EF /* rs.h */; }; + A5DD111F26D93B5F00BA01EF /* rs.h in Headers */ = {isa = PBXBuildFile; fileRef = A5DD111426D93B5F00BA01EF /* rs.h */; }; + A5DD112026D93B5F00BA01EF /* rs.h in Headers */ = {isa = PBXBuildFile; fileRef = A5DD111426D93B5F00BA01EF /* rs.h */; }; F800DD9B24FBEBF000789320 /* ItlDriverController.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F800DD9A24FBEBF000789320 /* ItlDriverController.hpp */; }; F8294FE424FCBF5100239253 /* FwBinary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5076FA7F24CC71E40011B2BB /* FwBinary.cpp */; }; F837C91D2724577F00B2C499 /* coex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F837C91C2724577F00B2C499 /* coex.cpp */; }; @@ -829,6 +841,8 @@ A5213EBD27A0C3ED00D7EAB1 /* iwm-9260-46 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "iwm-9260-46"; sourceTree = ""; }; A5213EBE27A0C3ED00D7EAB1 /* iwm-8265-36 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "iwm-8265-36"; sourceTree = ""; }; A5FA2AE328A797B200847103 /* _ifq.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = _ifq.cpp; sourceTree = ""; }; + A5DD111326D93B5F00BA01EF /* rs.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = rs.cpp; sourceTree = ""; }; + A5DD111426D93B5F00BA01EF /* rs.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = rs.h; sourceTree = ""; }; F800DD9A24FBEBF000789320 /* ItlDriverController.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ItlDriverController.hpp; sourceTree = ""; }; F837C91C2724577F00B2C499 /* coex.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = coex.cpp; sourceTree = ""; }; F837C9252724732B00B2C499 /* iwlwifi-so-a0-gf-a0.pnvm */ = {isa = PBXFileReference; lastKnownFileType = file; path = "iwlwifi-so-a0-gf-a0.pnvm"; sourceTree = ""; }; @@ -1261,6 +1275,8 @@ F837C91C2724577F00B2C499 /* coex.cpp */, F8AF3A2F24F9F35B008911C1 /* ItlIwm.cpp */, F8AF3A3024F9F35B008911C1 /* ItlIwm.hpp */, + A5DD111326D93B5F00BA01EF /* rs.cpp */, + A5DD111426D93B5F00BA01EF /* rs.h */, ); path = hal_iwm; sourceTree = ""; @@ -1429,6 +1445,7 @@ 024A085423FCBC6C009FBA6C /* podd.h in Headers */, F8C2EC562408031A007A9422 /* ieee80211_node.h in Headers */, F8C2EC9524080557007A9422 /* _mbuf.h in Headers */, + A5DD111B26D93B5F00BA01EF /* rs.h in Headers */, 024A084423FCBC6C009FBA6C /* sha2.h in Headers */, 024A088C23FCBE38009FBA6C /* if_iwmvar.h in Headers */, 024A083A23FCBC6C009FBA6C /* blf.h in Headers */, @@ -1470,6 +1487,7 @@ F8F7EA4D252D834600520FD4 /* IO80211Interface.h in Headers */, F8F7EA49252D834600520FD4 /* IO80211SkywalkInterface.h in Headers */, 35CBE666251CB89700435CBC /* AirportItlwm.hpp in Headers */, + A5DD111F26D93B5F00BA01EF /* rs.h in Headers */, F8F7EA3D252D834600520FD4 /* IO80211VirtualInterface.h in Headers */, F8F7EA41252D834600520FD4 /* IO80211Controller.h in Headers */, F8C594DC25FD935B0007D19C /* ieee80211_ra.h in Headers */, @@ -1491,6 +1509,7 @@ F8F7EA4B252D834600520FD4 /* IO80211Interface.h in Headers */, F8F7EA47252D834600520FD4 /* IO80211SkywalkInterface.h in Headers */, 35CBE6D0251CB8BF00435CBC /* AirportItlwm.hpp in Headers */, + A5DD111D26D93B5F00BA01EF /* rs.h in Headers */, F8F7EA3B252D834600520FD4 /* IO80211VirtualInterface.h in Headers */, F8F7EA3F252D834600520FD4 /* IO80211Controller.h in Headers */, F8C594DA25FD935B0007D19C /* ieee80211_ra.h in Headers */, @@ -1512,6 +1531,7 @@ F8F7EA4A252D834600520FD4 /* IO80211Interface.h in Headers */, F8F7EA46252D834600520FD4 /* IO80211SkywalkInterface.h in Headers */, 35CBE73B251CB8CA00435CBC /* AirportItlwm.hpp in Headers */, + A5DD111C26D93B5F00BA01EF /* rs.h in Headers */, F8F7EA3A252D834600520FD4 /* IO80211VirtualInterface.h in Headers */, F8F7EA3E252D834600520FD4 /* IO80211Controller.h in Headers */, F8C594D925FD935B0007D19C /* ieee80211_ra.h in Headers */, @@ -1529,6 +1549,7 @@ F897ECBD266EFF93005EE8F7 /* IO80211P2PInterface.h in Headers */, F897ECBE266EFF93005EE8F7 /* IO80211WorkLoop.h in Headers */, F897ECBF266EFF93005EE8F7 /* apple80211_var.h in Headers */, + A5DD112026D93B5F00BA01EF /* rs.h in Headers */, F897ECC0266EFF93005EE8F7 /* AirportItlwmInterface.hpp in Headers */, F897ECC1266EFF93005EE8F7 /* IO80211Interface.h in Headers */, F897ECC2266EFF93005EE8F7 /* (null) in Headers */, @@ -1556,6 +1577,7 @@ F8F7EA4C252D834600520FD4 /* IO80211Interface.h in Headers */, F8F7EA48252D834600520FD4 /* IO80211SkywalkInterface.h in Headers */, F89B6BBC25021C9C000F77FF /* AirportItlwm.hpp in Headers */, + A5DD111E26D93B5F00BA01EF /* rs.h in Headers */, F8F7EA3C252D834600520FD4 /* IO80211VirtualInterface.h in Headers */, F8F7EA40252D834600520FD4 /* IO80211Controller.h in Headers */, F8C594DB25FD935B0007D19C /* ieee80211_ra.h in Headers */, @@ -1905,6 +1927,7 @@ 024A08CE23FCE67F009FBA6C /* nvm.cpp in Sources */, 024A083D23FCBC6C009FBA6C /* sha1.c in Sources */, 17FD7F10255E4AC800611406 /* ItlIwn.cpp in Sources */, + A5DD111526D93B5F00BA01EF /* rs.cpp in Sources */, 024A085923FCBC6C009FBA6C /* idgen.c in Sources */, F8C2EC522408031A007A9422 /* ieee80211_ioctl.c in Sources */, F8C594D325FD935B0007D19C /* ieee80211_ra.c in Sources */, @@ -1982,6 +2005,7 @@ 35CBE697251CB89700435CBC /* md5.c in Sources */, 35CBE698251CB89700435CBC /* arc4.c in Sources */, 35CBE699251CB89700435CBC /* blf.c in Sources */, + A5DD111926D93B5F00BA01EF /* rs.cpp in Sources */, 35CBE69A251CB89700435CBC /* poly1305.c in Sources */, 35CBE69B251CB89700435CBC /* key_wrap.c in Sources */, 35CBE69C251CB89700435CBC /* gmac.c in Sources */, @@ -2060,6 +2084,7 @@ 35CBE701251CB8BF00435CBC /* md5.c in Sources */, 35CBE702251CB8BF00435CBC /* arc4.c in Sources */, 35CBE703251CB8BF00435CBC /* blf.c in Sources */, + A5DD111726D93B5F00BA01EF /* rs.cpp in Sources */, 35CBE704251CB8BF00435CBC /* poly1305.c in Sources */, 35CBE705251CB8BF00435CBC /* key_wrap.c in Sources */, 35CBE706251CB8BF00435CBC /* gmac.c in Sources */, @@ -2138,6 +2163,7 @@ 35CBE76C251CB8CA00435CBC /* md5.c in Sources */, 35CBE76D251CB8CA00435CBC /* arc4.c in Sources */, 35CBE76E251CB8CA00435CBC /* blf.c in Sources */, + A5DD111626D93B5F00BA01EF /* rs.cpp in Sources */, 35CBE76F251CB8CA00435CBC /* poly1305.c in Sources */, 35CBE770251CB8CA00435CBC /* key_wrap.c in Sources */, 35CBE771251CB8CA00435CBC /* gmac.c in Sources */, @@ -2209,6 +2235,7 @@ F897ECEC266EFF93005EE8F7 /* cast.c in Sources */, F897ECED266EFF93005EE8F7 /* michael.c in Sources */, F897ECEE266EFF93005EE8F7 /* sha1.c in Sources */, + A5DD111A26D93B5F00BA01EF /* rs.cpp in Sources */, F897ECEF266EFF93005EE8F7 /* cmac.c in Sources */, F897ECF0266EFF93005EE8F7 /* ecb_enc.c in Sources */, F897ECF1266EFF93005EE8F7 /* chachapoly.c in Sources */, @@ -2295,6 +2322,7 @@ F89B6C16250231E4000F77FF /* md5.c in Sources */, F89B6C17250231E4000F77FF /* arc4.c in Sources */, F89B6C18250231E4000F77FF /* blf.c in Sources */, + A5DD111826D93B5F00BA01EF /* rs.cpp in Sources */, F89B6C19250231E4000F77FF /* poly1305.c in Sources */, F89B6C1A250231E4000F77FF /* key_wrap.c in Sources */, F89B6C1B250231E4000F77FF /* gmac.c in Sources */, diff --git a/itlwm/hal_iwm/ItlIwm.cpp b/itlwm/hal_iwm/ItlIwm.cpp index 49d2c729d..cbbd64070 100644 --- a/itlwm/hal_iwm/ItlIwm.cpp +++ b/itlwm/hal_iwm/ItlIwm.cpp @@ -25,6 +25,7 @@ detach(IOPCIDevice *device) for (int txq_i = 0; txq_i < nitems(sc->txq); txq_i++) iwm_free_tx_ring(sc, &sc->txq[txq_i]); + iwm_rs_free(sc); iwm_free_rx_ring(sc, &sc->rxq); iwm_dma_contig_free(&sc->ict_dma); iwm_dma_contig_free(&sc->kw_dma); diff --git a/itlwm/hal_iwm/ItlIwm.hpp b/itlwm/hal_iwm/ItlIwm.hpp index cdc2bc3d8..976cf6e4f 100644 --- a/itlwm/hal_iwm/ItlIwm.hpp +++ b/itlwm/hal_iwm/ItlIwm.hpp @@ -242,8 +242,8 @@ class ItlIwm : public ItlHalService, ItlDriverInfo, ItlDriverController { int iwm_run_init_mvm_ucode(struct iwm_softc *, int); int iwm_config_ltr(struct iwm_softc *); int iwm_rx_addbuf(struct iwm_softc *, int, int); - int iwm_get_signal_strength(struct iwm_softc *, struct iwm_rx_phy_info *); - int iwm_rxmq_get_signal_strength(struct iwm_softc *, struct iwm_rx_mpdu_desc *); + int iwm_get_signal_strength(struct iwm_softc *, struct ieee80211_rx_status *, struct iwm_rx_phy_info *); + int iwm_rxmq_get_signal_strength(struct iwm_softc *, struct ieee80211_rx_status *, uint32_t, struct iwm_rx_mpdu_desc *); void iwm_rx_rx_phy_cmd(struct iwm_softc *, struct iwm_rx_packet *, struct iwm_rx_data *); int iwm_get_noise(const struct iwm_statistics_rx_non_phy *); @@ -254,14 +254,14 @@ class ItlIwm : public ItlHalService, ItlDriverInfo, ItlDriverController { void iwm_rx_frame(struct iwm_softc *, mbuf_t, int, uint32_t, int, int, uint32_t, struct ieee80211_rxinfo *, struct mbuf_list *); void iwm_rx_tx_cmd_single(struct iwm_softc *, struct iwm_tx_resp *, - struct iwm_node *, int, int, int); + int, int); void iwm_ampdu_tx_done(struct iwm_softc *, struct iwm_cmd_header *, struct iwm_node *, struct iwm_tx_ring *, uint32_t, uint8_t, uint8_t, uint16_t, int, struct iwm_agg_tx_status *); void iwm_rx_tx_ba_notif(struct iwm_softc *, struct iwm_rx_packet *, struct iwm_rx_data *); void iwm_rx_tx_cmd(struct iwm_softc *, struct iwm_rx_packet *, struct iwm_rx_data *); - void iwm_ampdu_rate_control(struct iwm_softc *, struct ieee80211_node *, struct iwm_tx_ring *, uint16_t, uint16_t); + void iwm_ampdu_rate_control(struct iwm_softc *, struct ieee80211_node *, struct iwm_tx_ring *, uint16_t, uint16_t, struct ieee80211_tx_info *, int, uint32_t); void iwm_ht_single_rate_control(struct iwm_softc *, struct ieee80211_node *, uint8_t, uint8_t, uint8_t, int); void iwm_rx_mpdu_mq(struct iwm_softc *sc, mbuf_t m, void *pktdata, @@ -292,6 +292,7 @@ class ItlIwm : public ItlHalService, ItlDriverInfo, ItlDriverController { struct ieee80211_frame *, struct iwm_tx_cmd *); void iwm_txd_done(struct iwm_softc *, struct iwm_tx_data *); void iwm_ampdu_txq_advance(struct iwm_softc *, struct iwm_tx_ring *, int); + void iwm_tx_reclaim(struct iwm_softc *, struct ieee80211_tx_info *tx_info, int, int, int, uint32_t, bool); void iwm_clear_oactive(struct iwm_softc *, struct iwm_tx_ring *); void iwm_ra_choose(struct iwm_softc *, struct ieee80211_node *); int iwm_tx(struct iwm_softc *, mbuf_t, struct ieee80211_node *, int); diff --git a/itlwm/hal_iwm/if_iwmreg.h b/itlwm/hal_iwm/if_iwmreg.h index 170aba648..44ebf1842 100644 --- a/itlwm/hal_iwm/if_iwmreg.h +++ b/itlwm/hal_iwm/if_iwmreg.h @@ -933,6 +933,7 @@ enum iwm_msix_ivar_for_cause { #define IWM_UCODE_TLV_CAPA_BINDING_CDB_SUPPORT 39 #define IWM_UCODE_TLV_CAPA_CDB_SUPPORT 40 #define IWM_UCODE_TLV_CAPA_DYNAMIC_QUOTA 44 +#define IWM_UCODE_TLV_CAPA_COEX_SCHEMA_2 45 #define IWM_UCODE_TLV_CAPA_ULTRA_HB_CHANNELS 48 #define IWM_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE 64 #define IWM_UCODE_TLV_CAPA_SHORT_PM_TIMEOUTS 65 @@ -4719,11 +4720,11 @@ enum { * 2 - 0x3f: maximal number of frames (up to 3f == 63) * @rs_table: array of rates for each TX try, each is rate_n_flags, * meaning it is a combination of IWM_RATE_MCS_* and IWM_RATE_*_PLCP - * @bf_params: beam forming params, currently not used + * @ss_params: single stream features. declare whether STBC or BFER are allowed. */ struct iwm_lq_cmd { uint8_t sta_id; - uint8_t reserved1; + uint8_t reduced_tpc; uint16_t control; /* LINK_QUAL_GENERAL_PARAMS_API_S_VER_1 */ uint8_t flags; @@ -4737,7 +4738,7 @@ struct iwm_lq_cmd { uint8_t agg_frame_cnt_limit; uint32_t reserved2; uint32_t rs_table[IWM_LQ_MAX_RETRY_NUM]; - uint32_t bf_params; + uint32_t ss_params; }; /* LINK_QUALITY_CMD_API_S_VER_1 */ /** @@ -5137,7 +5138,8 @@ struct iwm_tx_resp { uint8_t pa_integ_res_b[3]; uint8_t pa_integ_res_c[3]; uint16_t measurement_req_id; - uint16_t reserved; + uint8_t reduced_tpc; + uint8_t reserved; uint32_t tfd_info; uint16_t seq_ctl; @@ -5145,8 +5147,7 @@ struct iwm_tx_resp { uint8_t tlc_info; uint8_t ra_tid; uint16_t frame_ctrl; - - struct iwm_agg_tx_status status; + struct iwm_agg_tx_status status[]; } __packed; /* IWM_TX_RSP_API_S_VER_3 */ /** diff --git a/itlwm/hal_iwm/if_iwmvar.h b/itlwm/hal_iwm/if_iwmvar.h index 0ae7b539a..3d48b00fa 100644 --- a/itlwm/hal_iwm/if_iwmvar.h +++ b/itlwm/hal_iwm/if_iwmvar.h @@ -124,6 +124,8 @@ #include #include +#include "rs.h" + struct iwm_rx_radiotap_header { struct ieee80211_radiotap_header wr_ihdr; uint64_t wr_tsft; @@ -285,11 +287,12 @@ struct iwm_tx_data { int txmcs; int txrate; int totlen; - int data_type; + uint16_t fc; /* A-MPDU subframes */ int ampdu_txmcs; int ampdu_nframes; + struct ieee80211_tx_info info; }; struct iwm_tx_ring { @@ -489,6 +492,12 @@ struct iwm_rxq_dup_data { struct iwm_tx_ba { struct iwm_node * wn; + uint32_t rate_n_flags; + uint8_t lq_color; + uint16_t tx_time; + uint32_t tx_count_last; + uint32_t tx_count; + unsigned long tpt_meas_start; }; struct iwm_ba_task_data { @@ -655,6 +664,7 @@ struct iwm_softc { int sc_ltr_enabled; enum iwm_nvm_type nvm_type; int support_ldpc; + uint8_t non_shared_ant; int sc_mqrx_supported; int sc_integrated; @@ -687,6 +697,11 @@ struct iwm_softc { #define sc_txtap sc_txtapu.th int sc_txtap_len; #endif + union { + struct iwl_lq_sta_rs_fw rs_fw; + struct iwl_lq_sta rs_drv; + } lq_sta; + int tx_protection; }; struct iwm_node { diff --git a/itlwm/hal_iwm/mac80211.cpp b/itlwm/hal_iwm/mac80211.cpp index a3ef0f581..461720989 100644 --- a/itlwm/hal_iwm/mac80211.cpp +++ b/itlwm/hal_iwm/mac80211.cpp @@ -123,6 +123,7 @@ #include #include #include +#include "rs.h" #ifdef IWM_DEBUG int iwm_debug = 1; @@ -727,7 +728,7 @@ iwm_set_hw_address_8000(struct iwm_softc *sc, struct iwm_nvm_data *data, * values by -256dBm: practically 0 power and a non-feasible 8 bit value. */ int ItlIwm:: -iwm_get_signal_strength(struct iwm_softc *sc, struct iwm_rx_phy_info *phy_info) +iwm_get_signal_strength(struct iwm_softc *sc, struct ieee80211_rx_status *rx_status, struct iwm_rx_phy_info *phy_info) { int energy_a, energy_b, energy_c, max_energy; uint32_t val; @@ -745,11 +746,19 @@ iwm_get_signal_strength(struct iwm_softc *sc, struct iwm_rx_phy_info *phy_info) max_energy = MAX(energy_a, energy_b); max_energy = MAX(max_energy, energy_c); + rx_status->signal = max_energy; + rx_status->chains = (le16toh(phy_info->phy_flags) & + IWM_RX_RES_PHY_FLAGS_ANTENNA) + >> IWM_RX_RES_PHY_FLAGS_ANTENNA_POS; + rx_status->chain_signal[0] = energy_a; + rx_status->chain_signal[1] = energy_b; + rx_status->chain_signal[2] = energy_c; + return max_energy; } int ItlIwm:: -iwm_rxmq_get_signal_strength(struct iwm_softc *sc, +iwm_rxmq_get_signal_strength(struct iwm_softc *sc, struct ieee80211_rx_status *rx_status, uint32_t rate_n_flags, struct iwm_rx_mpdu_desc *desc) { int energy_a, energy_b; @@ -758,7 +767,13 @@ iwm_rxmq_get_signal_strength(struct iwm_softc *sc, energy_b = desc->v1.energy_b; energy_a = energy_a ? -energy_a : -256; energy_b = energy_b ? -energy_b : -256; - return MAX(energy_a, energy_b); + rx_status->signal = MAX(energy_a, energy_b); + rx_status->chains = (rate_n_flags & RATE_MCS_ANT_AB_MSK) >> RATE_MCS_ANT_POS; + rx_status->chain_signal[0] = energy_a; + rx_status->chain_signal[1] = energy_b; + rx_status->chain_signal[2] = S8_MIN; + + return rx_status->signal; } /* @@ -989,6 +1004,76 @@ static const char *iwm_get_agg_tx_status(u16 status) return "UNKNOWN"; } +#define IEEE80211_TX_MAX_RATES 4 + +static int ieee80211_tx_get_rates(struct iwm_softc *sc, + struct ieee80211_tx_info *info, + int *retry_count) +{ + int count = -1; + int i; + int max_report_rates = 1; + + for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { + if ((info->flags & IEEE80211_TX_CTL_AMPDU) && + !(info->flags & IEEE80211_TX_STAT_AMPDU)) { + /* just the first aggr frame carry status info */ + info->status.rates[i].idx = -1; + info->status.rates[i].count = 0; + break; + } else if (info->status.rates[i].idx < 0) { + break; + } else if (i >= max_report_rates) { + /* the HW cannot have attempted that rate */ + info->status.rates[i].idx = -1; + info->status.rates[i].count = 0; + break; + } + + count += info->status.rates[i].count; + } + + if (count < 0) + count = 0; + + *retry_count = count; + return i - 1; +} + +static void __ieee80211_tx_status(struct iwm_softc *sc, + struct ieee80211_tx_info *info, + int rates_idx, int retry_count, int tid, uint16_t fc, int ssn) +{ + bool acked; + bool noack_success; + + acked = !!(info->flags & IEEE80211_TX_STAT_ACK); + noack_success = !!(info->flags & + IEEE80211_TX_STAT_NOACK_TRANSMITTED); + + if ((info->flags & IEEE80211_TX_STAT_AMPDU_NO_BACK) && + (ieee80211_is_data_qos(fc))) { + + ieee80211_tx_compressed_bar(&sc->sc_ic, sc->sc_ic.ic_bss, tid, ssn); + XYLog("%s sending bar ssn=%d tid=%d\n", __FUNCTION__, ssn, tid); + } +} + +void ieee80211_tx_status(struct iwm_softc *sc, struct ieee80211_tx_info *info, int tid, uint16_t fc, int ssn) +{ + int rates_idx, retry_count; + + if (!info) + return; + + rates_idx = ieee80211_tx_get_rates(sc, info, &retry_count); + + rs_drv_mac80211_tx_status(sc, sc->sc_ic.ic_bss, info, tid, fc, ssn); + + if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP)) + __ieee80211_tx_status(sc, info, rates_idx, retry_count, tid, fc, ssn); +} + void ItlIwm:: iwm_ampdu_txq_advance(struct iwm_softc *sc, struct iwm_tx_ring *ring, int idx) { @@ -1008,14 +1093,90 @@ iwm_ampdu_txq_advance(struct iwm_softc *sc, struct iwm_tx_ring *ring, int idx) } } +void ItlIwm:: +iwm_tx_reclaim(struct iwm_softc *sc, struct ieee80211_tx_info *tx_info, int tid, int qid, int ssn, uint32_t rate, bool is_flush) +{ + XYLog("%s ssn %d\n", __FUNCTION__, ssn); + struct iwm_tx_data *txd; + int idx = IWM_AGG_SSN_TO_TXQ_IDX(ssn); + struct iwm_tx_ring *ring = &sc->txq[qid]; + struct iwm_tx_ba *tid_data = &sc->sc_tx_ba[tid]; + int freed = 0; + bool rs_update = false; + + /* pack lq color from tid_data along the reduced txp */ + tx_info->status.status_driver_data[0] = + RS_DRV_DATA_PACK(tid_data->lq_color, + tx_info->status.status_driver_data[0]); + tx_info->status.status_driver_data[1] = (void *)(uintptr_t)rate; + while (ring->tail != idx) { + txd = &ring->data[ring->tail]; + struct ieee80211_tx_info *info = &txd->info; + if (txd->m != NULL) { + rs_update = true; + iwm_reset_sched(sc, ring->qid, ring->tail, IWM_STATION_ID); + + memset(&info->status, 0, sizeof(info->status)); + /* Packet was transmitted successfully, failures come as single + * frames because before failing a frame the firmware transmits + * it without aggregation at least once. + */ + if (!is_flush) + info->flags |= IEEE80211_TX_STAT_ACK; + + if (!is_flush) { + if (ieee80211_is_data_qos(txd->fc)) + freed++; + else + WARN_ON_ONCE(tid != IWL_MAX_TID_COUNT); + } + + /* this is the first skb we deliver in this batch */ + /* put the rate scaling data there */ + if (freed == 1) { + info->flags |= IEEE80211_TX_STAT_AMPDU; + memcpy(&info->status, &tx_info->status, + sizeof(tx_info->status)); + iwl_mvm_hwrate_to_tx_status(rate, info); + } + + ieee80211_tx_status(sc, info, tid, txd->fc, ssn); + + iwm_txd_done(sc, txd); + ring->queued--; + } + ring->tail = (ring->tail + 1) % IWM_TX_RING_COUNT; + XYLog("%s tail %d\n", __FUNCTION__, ring->tail); + } + + /* We got a BA notif with 0 acked or scd_ssn didn't progress which is + * possible (i.e. first MPDU in the aggregation wasn't acked) + * Still it's important to update RS about sent vs. acked. + */ + if (!is_flush && !rs_update) { + tx_info->band = IEEE80211_IS_CHAN_2GHZ(sc->sc_ic.ic_bss->ni_chan) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ; + iwl_mvm_hwrate_to_tx_status(rate, tx_info); + XYLog("No reclaim. Update rs directly\n"); + iwl_mvm_rs_tx_status(sc, sc->sc_ic.ic_bss, tid, tx_info, false); + } +} + void ItlIwm:: iwm_ampdu_rate_control(struct iwm_softc *sc, struct ieee80211_node *ni, - struct iwm_tx_ring *ring, uint16_t seq, uint16_t ssn) + struct iwm_tx_ring *ring, uint16_t seq, uint16_t ssn, struct ieee80211_tx_info *tx_info, int tid, uint32_t rate_n_flags) { struct ieee80211com *ic = &sc->sc_ic; struct iwm_node *wn = (struct iwm_node *)ni; int idx, end_idx; - + struct iwm_tx_ba *tid_data = &sc->sc_tx_ba[tid]; + int freed = 0; + bool rs_update = false; + + /* pack lq color from tid_data along the reduced txp */ + tx_info->status.status_driver_data[0] = + RS_DRV_DATA_PACK(tid_data->lq_color, + tx_info->status.status_driver_data[0]); + tx_info->status.status_driver_data[1] = (void *)(uintptr_t)rate_n_flags; /* * Update Tx rate statistics for A-MPDUs before firmware's BA window. */ @@ -1023,25 +1184,48 @@ iwm_ampdu_rate_control(struct iwm_softc *sc, struct ieee80211_node *ni, end_idx = IWM_AGG_SSN_TO_TXQ_IDX(ssn); while (idx != end_idx) { struct iwm_tx_data *txdata = &ring->data[idx]; + struct ieee80211_tx_info *info = &txdata->info; - if (txdata->m != NULL && txdata->ampdu_nframes > 1) { - /* - * We can assume that this subframe has been ACKed - * because ACK failures come as single frames and - * before failing an A-MPDU subframe the firmware - * sends it as a single frame at least once. + if (txdata->m != NULL) { + rs_update = true; + + memset(&info->status, 0, sizeof(info->status)); + /* Packet was transmitted successfully, failures come as single + * frames because before failing a frame the firmware transmits + * it without aggregation at least once. */ - ieee80211_ra_add_stats_ht(&wn->in_rn, ic, ni, - txdata->ampdu_txmcs, 1, 0); - - /* Report this frame only once. */ - txdata->ampdu_nframes = 0; + info->flags |= IEEE80211_TX_STAT_ACK; + + if (ieee80211_is_data_qos(txdata->fc)) + freed++; + else + WARN_ON_ONCE(tid != IWL_MAX_TID_COUNT); + + /* this is the first skb we deliver in this batch */ + /* put the rate scaling data there */ + if (freed == 1) { + info->flags |= IEEE80211_TX_STAT_AMPDU; + memcpy(&info->status, &tx_info->status, + sizeof(tx_info->status)); + iwl_mvm_hwrate_to_tx_status(rate_n_flags, info); + } + + ieee80211_tx_status(sc, info, tid, txdata->fc, ssn); } idx = (idx + 1) % IWM_TX_RING_COUNT; } - iwm_ra_choose(sc, ni); + /* We got a BA notif with 0 acked or scd_ssn didn't progress which is + * possible (i.e. first MPDU in the aggregation wasn't acked) + * Still it's important to update RS about sent vs. acked. + */ + if (!rs_update) { + tx_info->band = IEEE80211_IS_CHAN_2GHZ(sc->sc_ic.ic_bss->ni_chan) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ; + iwl_mvm_hwrate_to_tx_status(rate_n_flags, tx_info); + DPRINTFN(3, ("No reclaim. Update rs directly\n")); + iwl_mvm_rs_tx_status(sc, sc->sc_ic.ic_bss, tid, tx_info, false); + } } void ItlIwm:: @@ -1100,6 +1284,8 @@ iwm_rx_tx_ba_notif(struct iwm_softc *sc, struct iwm_rx_packet *pkt, struct iwm_r int qid; struct ieee80211_node *ni = ic->ic_bss; struct iwm_node *in = (struct iwm_node *)ni; + struct iwm_tx_ba *tid_data; + struct ieee80211_tx_info ba_info = {}; DPRINTFN(3, ("TID = %d, SeqCtl = %d, bitmap = 0x%llx, scd_flow = %d, scd_ssn = %d sent:%d, acked:%d\n", ba_notif->tid, le16_to_cpu(ba_notif->seq_ctl), @@ -1140,13 +1326,23 @@ iwm_rx_tx_ba_notif(struct iwm_softc *sc, struct iwm_rx_packet *pkt, struct iwm_r */ ssn = le16toh(ba_notif->scd_ssn); - if (SEQ_LT(ssn, ba->ba_winstart)) - return; + /* pack lq color from tid_data along the reduced txp */ + tid_data = &sc->sc_tx_ba[ba_notif->tid]; + + ba_info.flags = IEEE80211_TX_STAT_AMPDU; + ba_info.status.ampdu_ack_len = ba_notif->txed_2_done; + ba_info.status.ampdu_len = ba_notif->txed; + ba_info.status.tx_time = tid_data->tx_time; + ba_info.status.status_driver_data[0] = + (void *)(uintptr_t)ba_notif->reduced_txp; +// if (SEQ_LT(ssn, ba->ba_winstart)) +// return; + /* Skip rate control if our Tx rate is fixed. */ if (ic->ic_fixed_mcs == -1) iwm_ampdu_rate_control(sc, ni, ring, - ba->ba_winstart, ssn); + ba->ba_winstart, ssn, &ba_info, ba_notif->tid, tid_data->rate_n_flags); /* * SSN corresponds to the first (perhaps not yet transmitted) frame @@ -1190,15 +1386,15 @@ iwm_ampdu_tx_done(struct iwm_softc *sc, struct iwm_cmd_header *cmd_hdr, int i; /* - * Collect information about this A-MPDU. - */ + * Collect information about this A-MPDU. + */ for (i = 0; i < nframes; i++) { uint8_t qid = agg_status[i].qid; uint8_t idx = agg_status[i].idx; uint16_t txstatus = (le16toh(agg_status[i].status) & IWM_AGG_TX_STATE_STATUS_MSK); - if (status != IWM_TX_STATUS_SUCCESS && txdata->data_type == IEEE80211_FC0_TYPE_MGT) { + if (status != IWM_TX_STATUS_SUCCESS && ieee80211_is_mgmt(txdata->fc)) { iwm_toggle_tx_ant(sc, &sc->sc_mgmt_last_antenna_idx); } @@ -1252,7 +1448,7 @@ iwm_ampdu_tx_done(struct iwm_softc *sc, struct iwm_cmd_header *cmd_hdr, /* Report the final single-frame Tx attempt. */ iwm_ht_single_rate_control(sc, ni, rate, initial_rate, - failure_frame, txfail); + failure_frame, txfail); } if (txfail) { @@ -1270,104 +1466,208 @@ iwm_ampdu_tx_done(struct iwm_softc *sc, struct iwm_cmd_header *cmd_hdr, iwm_clear_oactive(sc, txq); } +#define IWL_MVM_TX_RES_GET_TID(_ra_tid) ((_ra_tid) & 0x0f) +#define TX_RES_INIT_RATE_INDEX_MSK 0x0f +#define TX_RES_RATE_TABLE_COLOR_POS 4 +#define TX_RES_RATE_TABLE_COLOR_MSK 0x70 +#define TX_RES_INV_RATE_INDEX_MSK 0x80 +#define TX_RES_RATE_TABLE_COL_GET(_f) (((_f) & TX_RES_RATE_TABLE_COLOR_MSK) >>\ + TX_RES_RATE_TABLE_COLOR_POS) + +static inline struct iwm_agg_tx_status * +iwl_mvm_get_agg_status(struct iwm_softc *sc, void *tx_resp) +{ + return (struct iwm_agg_tx_status *)(((struct iwm_tx_resp *)tx_resp)->status); +} + +static inline u32 iwl_mvm_get_scd_ssn(struct iwm_softc *sc, + struct iwm_tx_resp *tx_resp) +{ + return le32_to_cpup((__le32 *)iwl_mvm_get_agg_status(sc, tx_resp) + + tx_resp->frame_count) & 0xfff; +} + void ItlIwm:: iwm_rx_tx_cmd_single(struct iwm_softc *sc, struct iwm_tx_resp *tx_resp, - struct iwm_node *in, int txmcs, int txrate, int qid) + int qid, int idx) { struct ieee80211com *ic = &sc->sc_ic; + struct iwm_node *in = (struct iwm_node *)ic->ic_bss; struct ieee80211_node *ni = &in->in_ni; struct _ifnet *ifp = IC2IFP(ic); - int status = le16toh(tx_resp->status.status) & IWM_TX_STATUS_MSK; + u32 status = le16toh(iwl_mvm_get_agg_status(sc, tx_resp)->status); + u16 ssn = iwl_mvm_get_scd_ssn(sc, tx_resp); + ssn = le32toh(ssn) & 0xfff; int txfail; + int tid = IWL_MVM_TX_RES_GET_TID(tx_resp->ra_tid); + struct iwm_tx_data *txd; + struct iwm_tx_ring *ring = &sc->txq[qid]; + struct iwm_tx_ba *tid_data = &sc->sc_tx_ba[tid]; + u8 skb_freed = 0; + u8 lq_color; - KASSERT(tx_resp->frame_count == 1, ""); - - txfail = (status != IWM_TX_STATUS_SUCCESS && - status != IWM_TX_STATUS_DIRECT_DONE); - - /* - * Update rate control statistics. - * Only report frames which were actually queued with the currently - * selected Tx rate. Because Tx queues are relatively long we may - * encounter previously selected rates here during Tx bursts. - * Providing feedback based on such frames can lead to suboptimal - * Tx rate control decisions. - */ - if ((ni->ni_flags & IEEE80211_NODE_HT) == 0) { - if (txrate != ni->ni_txrate) { - if (++in->lq_rate_mismatch > 15) { - /* Try to sync firmware with the driver... */ - iwm_setrates(in, 1); - in->lq_rate_mismatch = 0; - } - } else { - in->lq_rate_mismatch = 0; - - in->in_amn.amn_txcnt++; - if (txfail) - in->in_amn.amn_retrycnt++; - if (tx_resp->failure_frame > 0) - in->in_amn.amn_retrycnt++; - } - } else if (ic->ic_fixed_mcs == -1 && ic->ic_state == IEEE80211_S_RUN && - (le32toh(tx_resp->initial_rate) & IWM_RATE_MCS_HT_MSK)) { - uint32_t fw_txmcs = le32toh(tx_resp->initial_rate) & - (IWM_RATE_HT_MCS_RATE_CODE_MSK | IWM_RATE_HT_MCS_NSS_MSK); - /* Ignore Tx reports which don't match our last LQ command. */ - if (fw_txmcs != ni->ni_txmcs) { - if (++in->lq_rate_mismatch > 15) { - /* Try to sync firmware with the driver... */ - iwm_setrates(in, 1); - in->lq_rate_mismatch = 0; - } - } else { - int mcs = fw_txmcs; - const struct ieee80211_ra_rate *rs = - ieee80211_ra_get_rateset(&in->in_rn, ic, ni, fw_txmcs); - unsigned int retries = 0, i; - int old_txmcs = ni->ni_txmcs; - int old_bw = in->in_rn.bw; - int old_nss = in->in_rn.nss; - int old_sgi = in->in_rn.sgi; - - in->lq_rate_mismatch = 0; - - for (i = 0; i < tx_resp->failure_frame; i++) { - if (mcs > rs->min_mcs) { - ieee80211_ra_add_stats_ht(&in->in_rn, - ic, ni, mcs, 1, 1); - mcs--; - } else - retries++; - } - - if (txfail && tx_resp->failure_frame == 0) { - ieee80211_ra_add_stats_ht(&in->in_rn, ic, ni, - fw_txmcs, 1, 1); - } else { - ieee80211_ra_add_stats_ht(&in->in_rn, ic, ni, - mcs, retries + 1, retries); + while (ring->tail != idx) { + txd = &ring->data[ring->tail]; + struct ieee80211_tx_info *info = &txd->info; + bool flushed = false; + if (txd->m != NULL) { + skb_freed++; + + memset(&info->status, 0, sizeof(info->status)); + + /* inform mac80211 about what happened with the frame */ + switch (status & IWM_TX_STATUS_MSK) { + case IWM_TX_STATUS_SUCCESS: + case IWM_TX_STATUS_DIRECT_DONE: + info->flags |= IEEE80211_TX_STAT_ACK; + break; + case IWM_TX_STATUS_FAIL_FIFO_FLUSHED: + case IWM_TX_STATUS_FAIL_DRAIN_FLOW: + flushed = true; + break; + case IWM_TX_STATUS_FAIL_DEST_PS: + /* the FW should have stopped the queue and not + * return this status + */ + WARN_ON(1); + info->flags |= IEEE80211_TX_STAT_TX_FILTERED; + break; + default: + break; } - - ieee80211_ra_choose(&in->in_rn, ic, ni); - + + if ((status & IWM_TX_STATUS_MSK) != IWM_TX_STATUS_SUCCESS && + ieee80211_is_mgmt(txd->fc)) + iwm_toggle_tx_ant(sc, &sc->sc_mgmt_last_antenna_idx); + + /* + * If we are freeing multiple frames, mark all the frames + * but the first one as acked, since they were acknowledged + * before + * */ + if (skb_freed > 1) + info->flags |= IEEE80211_TX_STAT_ACK; + + info->status.rates[0].count = tx_resp->failure_frame + 1; + iwl_mvm_hwrate_to_tx_status(le32_to_cpu(tx_resp->initial_rate), + info); + info->status.status_driver_data[1] = + (void *)(uintptr_t)le32_to_cpu(tx_resp->initial_rate); + + /* Single frame failure in an AMPDU queue => send BAR */ + if (info->flags & IEEE80211_TX_CTL_AMPDU && + !(info->flags & IEEE80211_TX_STAT_ACK) && + !(info->flags & IEEE80211_TX_STAT_TX_FILTERED) && !flushed) + info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; + info->flags &= ~IEEE80211_TX_CTL_AMPDU; + /* - * If RA has chosen a new TX rate we must update - * the firmware's LQ rate table. - * ni_txmcs may change again before the task runs so - * cache the chosen rate in the iwm_node structure. + * TODO: this is not accurate if we are freeing more than one + * packet. */ - if (ni->ni_txmcs != old_txmcs || in->in_rn.bw != old_bw || in->in_rn.sgi != old_sgi || in->in_rn.nss != old_nss) - iwm_setrates(in, 1); + info->status.tx_time = + le16_to_cpu(tx_resp->wireless_media_time); + BUILD_BUG_ON(ARRAY_SIZE(info->status.status_driver_data) < 1); + lq_color = TX_RES_RATE_TABLE_COL_GET(tx_resp->tlc_info); + info->status.status_driver_data[0] = + RS_DRV_DATA_PACK(lq_color, tx_resp->reduced_tpc); + + ieee80211_tx_status(sc, info, tid, txd->fc, ssn); + + iwm_reset_sched(sc, ring->qid, ring->tail, IWM_STATION_ID); + iwm_txd_done(sc, txd); + ring->queued--; } + ring->tail = (ring->tail + 1) % IWM_TX_RING_COUNT; } - - if (txfail) { - XYLog("%s %d OUTPUT_ERROR status=%d\n", __FUNCTION__, __LINE__, status); - ifp->netStat->outputErrors++; - } else { - DPRINTFN(2, ("%s %d succeed status=%d\n", __FUNCTION__, __LINE__, status)); - } + +// status = status & IWM_TX_STATUS_MSK; +// txfail = (status != IWM_TX_STATUS_SUCCESS && +// status != IWM_TX_STATUS_DIRECT_DONE); +// +// /* +// * Update rate control statistics. +// * Only report frames which were actually queued with the currently +// * selected Tx rate. Because Tx queues are relatively long we may +// * encounter previously selected rates here during Tx bursts. +// * Providing feedback based on such frames can lead to suboptimal +// * Tx rate control decisions. +// */ +// if ((ni->ni_flags & IEEE80211_NODE_HT) == 0) { +// if (ring->data[idx].txrate != ni->ni_txrate) { +// if (++in->lq_rate_mismatch > 15) { +// /* Try to sync firmware with the driver... */ +// iwm_setrates(in, 1); +// in->lq_rate_mismatch = 0; +// } +// } else { +// in->lq_rate_mismatch = 0; +// +// in->in_amn.amn_txcnt++; +// if (txfail) +// in->in_amn.amn_retrycnt++; +// if (tx_resp->failure_frame > 0) +// in->in_amn.amn_retrycnt++; +// } +// } else if (ic->ic_fixed_mcs == -1 && ic->ic_state == IEEE80211_S_RUN && +// (le32toh(tx_resp->initial_rate) & IWM_RATE_MCS_HT_MSK)) { +// uint32_t fw_txmcs = le32toh(tx_resp->initial_rate) & +// (IWM_RATE_HT_MCS_RATE_CODE_MSK | IWM_RATE_HT_MCS_NSS_MSK); +// /* Ignore Tx reports which don't match our last LQ command. */ +// if (fw_txmcs != ni->ni_txmcs) { +// if (++in->lq_rate_mismatch > 15) { +// /* Try to sync firmware with the driver... */ +// iwm_setrates(in, 1); +// in->lq_rate_mismatch = 0; +// } +// } else { +// int mcs = fw_txmcs; +// const struct ieee80211_ra_rate *rs = +// ieee80211_ra_get_rateset(&in->in_rn, ic, ni, fw_txmcs); +// unsigned int retries = 0, i; +// int old_txmcs = ni->ni_txmcs; +// int old_bw = in->in_rn.bw; +// int old_nss = in->in_rn.nss; +// int old_sgi = in->in_rn.sgi; +// +// in->lq_rate_mismatch = 0; +// +// for (i = 0; i < tx_resp->failure_frame; i++) { +// if (mcs > rs->min_mcs) { +// ieee80211_ra_add_stats_ht(&in->in_rn, +// ic, ni, mcs, 1, 1); +// mcs--; +// } else +// retries++; +// } +// +// if (txfail && tx_resp->failure_frame == 0) { +// ieee80211_ra_add_stats_ht(&in->in_rn, ic, ni, +// fw_txmcs, 1, 1); +// } else { +// ieee80211_ra_add_stats_ht(&in->in_rn, ic, ni, +// mcs, retries + 1, retries); +// } +// +// ieee80211_ra_choose(&in->in_rn, ic, ni); +// +// /* +// * If RA has chosen a new TX rate we must update +// * the firmware's LQ rate table. +// * ni_txmcs may change again before the task runs so +// * cache the chosen rate in the iwm_node structure. +// */ +// if (ni->ni_txmcs != old_txmcs || in->in_rn.bw != old_bw || in->in_rn.sgi != old_sgi || in->in_rn.nss != old_nss) +// iwm_setrates(in, 1); +// } +// } +// +// if (txfail) { +// XYLog("%s %d OUTPUT_ERROR status=%d\n", __FUNCTION__, __LINE__, status); +// ifp->netStat->outputErrors++; +// } else { +// DPRINTFN(2, ("%s %d succeed status=%d\n", __FUNCTION__, __LINE__, status)); +// } } void ItlIwm:: @@ -1407,8 +1707,9 @@ iwm_txd_done(struct iwm_softc *sc, struct iwm_tx_data *txd) txd->ampdu_txmcs = 0; txd->txmcs = 0; txd->txrate = 0; - txd->data_type = 0; + txd->fc = 0; txd->ampdu_nframes = 0; + memset(&txd->info, 0, sizeof(struct ieee80211_tx_info)); } void ItlIwm:: @@ -1429,6 +1730,13 @@ iwm_clear_oactive(struct iwm_softc *sc, struct iwm_tx_ring *ring) } } +#define TX_RES_INIT_RATE_INDEX_MSK 0x0f +#define TX_RES_RATE_TABLE_COLOR_POS 4 +#define TX_RES_RATE_TABLE_COLOR_MSK 0x70 +#define TX_RES_INV_RATE_INDEX_MSK 0x80 +#define TX_RES_RATE_TABLE_COL_GET(_f) (((_f) & TX_RES_RATE_TABLE_COLOR_MSK) >>\ + TX_RES_RATE_TABLE_COLOR_POS) + void ItlIwm:: iwm_rx_tx_cmd(struct iwm_softc *sc, struct iwm_rx_packet *pkt, struct iwm_rx_data *data) @@ -1441,6 +1749,7 @@ iwm_rx_tx_cmd(struct iwm_softc *sc, struct iwm_rx_packet *pkt, struct iwm_tx_resp *tx_resp = (struct iwm_tx_resp *)pkt->data; uint32_t ssn; uint32_t len = iwm_rx_packet_len(pkt); + struct iwm_tx_ba *tid_data; bus_dmamap_sync(sc->sc_dmat, data->map, 0, IWM_RBUF_SIZE, BUS_DMASYNC_POSTREAD); @@ -1455,12 +1764,13 @@ iwm_rx_tx_cmd(struct iwm_softc *sc, struct iwm_rx_packet *pkt, if (qid > IWM_LAST_AGG_TX_QUEUE) return; if (sizeof(*tx_resp) + sizeof(ssn) + - tx_resp->frame_count * sizeof(tx_resp->status) > len) + tx_resp->frame_count * sizeof(struct iwm_agg_tx_status) > len) return; - if (tx_resp->frame_count > 1) + if (tx_resp->frame_count > 1) { for (int i = 0; i < tx_resp->frame_count; i++) { - u16 fstatus = le16_to_cpu((&tx_resp->status)[i].status); + struct iwm_agg_tx_status *frame_status = iwl_mvm_get_agg_status(sc, tx_resp); + u16 fstatus = le16_to_cpu(frame_status[i].status); DPRINTFN(3, ("status %s (0x%04x), try-count (%d) qid (%d) seq (0x%x)\n", iwm_get_agg_tx_status(fstatus), @@ -1468,33 +1778,41 @@ iwm_rx_tx_cmd(struct iwm_softc *sc, struct iwm_rx_packet *pkt, (fstatus & IWM_AGG_TX_STATE_TRY_CNT_MSK) >> IWM_AGG_TX_STATE_TRY_CNT_POS, qid, - le16_to_cpu((&tx_resp->status)[i].idx))); - } - - txd = &ring->data[idx]; - if (txd->m == NULL) + le16_to_cpu(frame_status[i].idx))); + } + int tid = cmd_hdr->qid - IWM_FIRST_AGG_TX_QUEUE; + if (tid < 0) + return; + tid_data = &sc->sc_tx_ba[tid]; + tid_data->lq_color = TX_RES_RATE_TABLE_COL_GET(tx_resp->tlc_info); + tid_data->tx_time = le16toh(tx_resp->wireless_media_time); + tid_data->rate_n_flags = le32toh(tx_resp->initial_rate); return; + } DPRINTFN(2, ("%s idx=%d qid=%d txd->txmcs=%d txd->txrate=%d, frame_count=%d len=%d\n", __FUNCTION__, idx, qid, txd->txmcs, txd->txrate, ((struct iwm_tx_resp *)pkt->data)->frame_count, ((struct iwm_tx_resp *)pkt->data)->byte_cnt)); + + iwm_rx_tx_cmd_single(sc, tx_resp, qid, idx); + iwm_clear_oactive(sc, ring); - memcpy(&ssn, &tx_resp->status + tx_resp->frame_count, sizeof(ssn)); - ssn = le32toh(ssn) & 0xfff; - if (qid >= IWM_FIRST_AGG_TX_QUEUE) { - int status; - status = le16toh(tx_resp->status.status) & IWM_TX_STATUS_MSK; - iwm_ampdu_tx_done(sc, cmd_hdr, txd->in, ring, - le32toh(tx_resp->initial_rate), tx_resp->frame_count, - tx_resp->failure_frame, ssn, status, &tx_resp->status); - } else { - /* - * Even though this is not an agg queue, we must only free - * frames before the firmware's starting sequence number. - */ - iwm_rx_tx_cmd_single(sc, tx_resp, txd->in, txd->txmcs, - txd->txrate, qid); - iwm_ampdu_txq_advance(sc, ring, IWM_AGG_SSN_TO_TXQ_IDX(ssn)); - iwm_clear_oactive(sc, ring); - } +// memcpy(&ssn, &tx_resp->status + tx_resp->frame_count, sizeof(ssn)); +// ssn = le32toh(ssn) & 0xfff; +// if (qid >= IWM_FIRST_AGG_TX_QUEUE) { +// int status; +// status = le16toh(tx_resp->status.status) & IWM_TX_STATUS_MSK; +// iwm_ampdu_tx_done(sc, cmd_hdr, txd->in, ring, +// le32toh(tx_resp->initial_rate), tx_resp->frame_count, +// tx_resp->failure_frame, ssn, status, &tx_resp->status); +// } else { +// /* +// * Even though this is not an agg queue, we must only free +// * frames before the firmware's starting sequence number. +// */ +// iwm_rx_tx_cmd_single(sc, tx_resp, txd->in, txd->txmcs, +// txd->txrate, qid); +// iwm_ampdu_txq_advance(sc, ring, IWM_AGG_SSN_TO_TXQ_IDX(ssn)); +// iwm_clear_oactive(sc, ring); +// } } void ItlIwm:: @@ -1848,7 +2166,8 @@ iwm_tx(struct iwm_softc *sc, mbuf_t m, struct ieee80211_node *ni, int ac) data->txrate = ni->ni_txrate; data->totlen = totlen; data->ampdu_txmcs = ni->ni_txmcs; - data->data_type = type; + memcpy(&data->fc, &wh->i_fc[0], sizeof(uint16_t)); + data->info.band = IEEE80211_IS_CHAN_2GHZ(ni->ni_chan) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ; DPRINTFN(3, ("sending data: 嘤嘤嘤 qid=%d idx=%d len=%d nsegs=%d txflags=0x%08x rate_n_flags=0x%08x rateidx=%u txmcs=%d ni_txrate=%d\n", ring->qid, ring->cur, totlen, nsegs, le32toh(tx->tx_flags), @@ -1894,7 +2213,7 @@ iwm_tx(struct iwm_softc *sc, mbuf_t m, struct ieee80211_node *ni, int ac) /* Mark TX ring as full if we reach a certain threshold. */ if (++ring->queued > IWM_TX_RING_HIMARK) { -// XYLog("%s sc->qfullmsk is FULL ring->cur=%d ring->queued=%d\n", __FUNCTION__, ring->cur, ring->queued); + XYLog("%s qid=%d sc->qfullmsk is FULL ring->cur=%d ring->queued=%d\n", __FUNCTION__, ring->qid, ring->cur, ring->queued); sc->qfullmsk |= 1 << ring->qid; } @@ -2286,6 +2605,12 @@ iwm_auth(struct iwm_softc *sc) duration = IEEE80211_DUR_TU; iwm_protect_session(sc, in, duration, in->in_ni.ni_intval / 2); + rs_drv_alloc_sta(sc, &in->in_ni); + + iwl_mvm_rs_rate_init(sc, ic->ic_bss, + IEEE80211_IS_CHAN_2GHZ(ic->ic_bss->ni_chan) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ, + false); + return 0; rm_binding: @@ -2377,6 +2702,7 @@ iwm_deauth(struct iwm_softc *sc) &ic->ic_channels[1], 1, 1, 0); if (err) return err; + rs_drv_free_sta(sc, &in->in_ni); return 0; } @@ -2504,7 +2830,11 @@ iwm_run(struct iwm_softc *sc) /* Start at lowest available bit-rate, AMRR will raise. */ in->in_ni.ni_txrate = 0; in->in_ni.ni_txmcs = 0; - iwm_setrates(in, 0); +// iwm_setrates(in, 0); + + iwl_mvm_rs_rate_init(sc, ic->ic_bss, + IEEE80211_IS_CHAN_2GHZ(ic->ic_bss->ni_chan) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ, + true); timeout_add_msec(&sc->sc_calib_to, 500); iwm_led_enable(sc); @@ -4562,6 +4892,9 @@ iwm_preinit(struct iwm_softc *sc) ieee80211_media_init(ifp); + iwm_rs_free(sc); + iwm_rs_alloc(sc); + return 0; } @@ -4694,6 +5027,7 @@ iwm_attach(struct iwm_softc *sc, struct pci_attach_args *pa) sc->sc_nvm_max_section_size = 16384; sc->nvm_type = IWM_NVM; sc->support_ldpc = 0; + sc->non_shared_ant = IWM_ANT_A; break; case PCI_PRODUCT_INTEL_WL_3165_1: case PCI_PRODUCT_INTEL_WL_3165_2: @@ -4704,6 +5038,7 @@ iwm_attach(struct iwm_softc *sc, struct pci_attach_args *pa) sc->sc_nvm_max_section_size = 16384; sc->nvm_type = IWM_NVM; sc->support_ldpc = 0; + sc->non_shared_ant = IWM_ANT_A; break; case PCI_PRODUCT_INTEL_WL_3168_1: sc->sc_fwname = "iwm-3168-29"; @@ -4713,6 +5048,7 @@ iwm_attach(struct iwm_softc *sc, struct pci_attach_args *pa) sc->sc_nvm_max_section_size = 16384; sc->nvm_type = IWM_NVM_SDP; sc->support_ldpc = 0; + sc->non_shared_ant = IWM_ANT_A; break; case PCI_PRODUCT_INTEL_WL_7260_1: case PCI_PRODUCT_INTEL_WL_7260_2: @@ -4723,6 +5059,7 @@ iwm_attach(struct iwm_softc *sc, struct pci_attach_args *pa) sc->sc_nvm_max_section_size = 16384; sc->nvm_type = IWM_NVM; sc->support_ldpc = 0; + sc->non_shared_ant = IWM_ANT_A; break; case PCI_PRODUCT_INTEL_WL_7265_1: case PCI_PRODUCT_INTEL_WL_7265_2: @@ -4733,6 +5070,7 @@ iwm_attach(struct iwm_softc *sc, struct pci_attach_args *pa) sc->sc_nvm_max_section_size = 16384; sc->nvm_type = IWM_NVM; sc->support_ldpc = 1; + sc->non_shared_ant = IWM_ANT_A; break; case PCI_PRODUCT_INTEL_WL_8260_1: case PCI_PRODUCT_INTEL_WL_8260_2: @@ -4743,6 +5081,7 @@ iwm_attach(struct iwm_softc *sc, struct pci_attach_args *pa) sc->sc_nvm_max_section_size = 32768; sc->nvm_type = IWM_NVM_EXT; sc->support_ldpc = 1; + sc->non_shared_ant = IWM_ANT_A; break; case PCI_PRODUCT_INTEL_WL_8265_1: sc->sc_fwname = "iwm-8265-36"; @@ -4752,6 +5091,7 @@ iwm_attach(struct iwm_softc *sc, struct pci_attach_args *pa) sc->sc_nvm_max_section_size = 32768; sc->nvm_type = IWM_NVM_EXT; sc->support_ldpc = 1; + sc->non_shared_ant = IWM_ANT_A; break; case PCI_PRODUCT_INTEL_WL_9260_1: sc->sc_fwname = "iwm-9260-46"; @@ -4761,6 +5101,7 @@ iwm_attach(struct iwm_softc *sc, struct pci_attach_args *pa) sc->sc_nvm_max_section_size = 32768; sc->sc_mqrx_supported = 1; sc->support_ldpc = 1; + sc->non_shared_ant = IWM_ANT_B; break; case PCI_PRODUCT_INTEL_WL_9560_1: case PCI_PRODUCT_INTEL_WL_9560_2: @@ -4787,6 +5128,7 @@ iwm_attach(struct iwm_softc *sc, struct pci_attach_args *pa) sc->sc_integrated = 1; sc->support_ldpc = 1; sc->sc_xtal_latency = 650; + sc->non_shared_ant = IWM_ANT_B; break; default: XYLog("%s: unknown adapter type\n", DEVNAME(sc)); @@ -4931,6 +5273,9 @@ iwm_attach(struct iwm_softc *sc, struct pci_attach_args *pa) ic->ic_ampdu_params = (IEEE80211_AMPDU_PARAM_SS_4 | 0x3 /* 64k */); ic->ic_caps |= (IEEE80211_C_QOS | IEEE80211_C_TX_AMPDU | IEEE80211_C_AMSDU_IN_AMPDU); ic->ic_caps |= IEEE80211_C_SUPPORTS_VHT_EXT_NSS_BW; +#if 0 + ic->ic_caps |= IEEE80211_C_TX_AMPDU_SETUP_IN_RS; +#endif ic->ic_sup_rates[IEEE80211_MODE_11A] = ieee80211_std_rateset_11a; ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b; @@ -5179,6 +5524,7 @@ iwm_ba_task(void *arg) struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[tid]; int qid = IWM_FIRST_AGG_TX_QUEUE + tid; struct iwm_tx_ring *ring = &sc->txq[qid]; + struct iwm_tx_ba *tx_ba; uint16_t ssn = ba->ba_winstart; if (sc->ba_tx.start_tidmask & (1 << tid)) { uint8_t fifo = iwm_ac_to_tx_fifo[tid_to_mac80211_ac[tid]]; @@ -5208,6 +5554,12 @@ iwm_ba_task(void *arg) ba->ba_bitmap = 0; if (!that->iwm_sta_tx_agg(sc, ni, tid, 0, ssn, 1)) { ieee80211_addba_resp_accept(ic, ni, tid); + sc->lq_sta.rs_drv.lq.agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF; + + XYLog("Tx aggregation enabled on ra = %s tid = %d\n", + ether_sprintf(ni->ni_macaddr), tid); + + iwl_mvm_send_lq_cmd(sc, &sc->lq_sta.rs_drv.lq); } else { out: ieee80211_addba_resp_refuse(ic, ni, tid, @@ -5219,6 +5571,17 @@ iwm_ba_task(void *arg) that->iwm_sta_tx_agg(sc, ni, tid, 0, 0, 0); that->iwm_ampdu_txq_advance(sc, ring, ring->cur); that->iwm_clear_oactive(sc, ring); + /* In DQA-mode the queue isn't removed on agg termination */ + tx_ba = &sc->sc_tx_ba[tid]; + sc->agg_tid_disable |= (1 << tid); + tx_ba->wn = NULL; + tx_ba->lq_color = 0; + tx_ba->rate_n_flags = 0; + tx_ba->tpt_meas_start = 0; + tx_ba->tx_count = 0; + tx_ba->tx_count_last = 0; + tx_ba->tx_time = 0; + ba->ba_bitmap = 0; sc->ba_tx.stop_tidmask &= ~(1 << tid); } } diff --git a/itlwm/hal_iwm/rs.cpp b/itlwm/hal_iwm/rs.cpp new file mode 100644 index 000000000..5cdc54134 --- /dev/null +++ b/itlwm/hal_iwm/rs.cpp @@ -0,0 +1,3685 @@ +// +// rs.cpp +// itlwm +// +// Created by zxystd on 2021/8/27. +// Copyright © 2021 钟先耀. All rights reserved. +// + +#include "ItlIwm.hpp" + +#define IWL_RATE_MAX_WINDOW 62 /* # tx in history window */ + +/* Calculations of success ratio are done in fixed point where 12800 is 100%. + * Use this macro when dealing with thresholds consts set as a percentage + */ +#define RS_PERCENT(x) (128 * x) + +static u8 rs_ht_to_legacy[] = { + [IWL_RATE_MCS_0_INDEX] = IWL_RATE_6M_INDEX, + [IWL_RATE_MCS_1_INDEX] = IWL_RATE_9M_INDEX, + [IWL_RATE_MCS_2_INDEX] = IWL_RATE_12M_INDEX, + [IWL_RATE_MCS_3_INDEX] = IWL_RATE_18M_INDEX, + [IWL_RATE_MCS_4_INDEX] = IWL_RATE_24M_INDEX, + [IWL_RATE_MCS_5_INDEX] = IWL_RATE_36M_INDEX, + [IWL_RATE_MCS_6_INDEX] = IWL_RATE_48M_INDEX, + [IWL_RATE_MCS_7_INDEX] = IWL_RATE_54M_INDEX, + [IWL_RATE_MCS_8_INDEX] = IWL_RATE_54M_INDEX, + [IWL_RATE_MCS_9_INDEX] = IWL_RATE_54M_INDEX, +}; + +static const u8 ant_toggle_lookup[] = { + [ANT_NONE] = ANT_NONE, + [ANT_A] = ANT_B, + [ANT_B] = ANT_A, + [ANT_AB] = ANT_AB, +}; + +#define IWL_DECLARE_RATE_INFO(r, s, rp, rn) \ + [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \ + IWL_RATE_HT_SISO_MCS_##s##_PLCP, \ + IWL_RATE_HT_MIMO2_MCS_##s##_PLCP, \ + IWL_RATE_VHT_SISO_MCS_##s##_PLCP, \ + IWL_RATE_VHT_MIMO2_MCS_##s##_PLCP,\ + IWL_RATE_##rp##M_INDEX, \ + IWL_RATE_##rn##M_INDEX } + +#define IWL_DECLARE_MCS_RATE(s) \ + [IWL_RATE_MCS_##s##_INDEX] = { IWL_RATE_INVM_PLCP, \ + IWL_RATE_HT_SISO_MCS_##s##_PLCP, \ + IWL_RATE_HT_MIMO2_MCS_##s##_PLCP, \ + IWL_RATE_VHT_SISO_MCS_##s##_PLCP, \ + IWL_RATE_VHT_MIMO2_MCS_##s##_PLCP, \ + IWL_RATE_INVM_INDEX, \ + IWL_RATE_INVM_INDEX } + +/* + * Parameter order: + * rate, ht rate, prev rate, next rate + * + * If there isn't a valid next or previous rate then INV is used which + * maps to IWL_RATE_INVALID + * + */ +static const struct iwl_rs_rate_info iwl_rates[IWL_RATE_COUNT] = { + IWL_DECLARE_RATE_INFO(1, INV, INV, 2), /* 1mbps */ + IWL_DECLARE_RATE_INFO(2, INV, 1, 5), /* 2mbps */ + IWL_DECLARE_RATE_INFO(5, INV, 2, 11), /*5.5mbps */ + IWL_DECLARE_RATE_INFO(11, INV, 9, 12), /* 11mbps */ + IWL_DECLARE_RATE_INFO(6, 0, 5, 11), /* 6mbps ; MCS 0 */ + IWL_DECLARE_RATE_INFO(9, INV, 6, 11), /* 9mbps */ + IWL_DECLARE_RATE_INFO(12, 1, 11, 18), /* 12mbps ; MCS 1 */ + IWL_DECLARE_RATE_INFO(18, 2, 12, 24), /* 18mbps ; MCS 2 */ + IWL_DECLARE_RATE_INFO(24, 3, 18, 36), /* 24mbps ; MCS 3 */ + IWL_DECLARE_RATE_INFO(36, 4, 24, 48), /* 36mbps ; MCS 4 */ + IWL_DECLARE_RATE_INFO(48, 5, 36, 54), /* 48mbps ; MCS 5 */ + IWL_DECLARE_RATE_INFO(54, 6, 48, INV), /* 54mbps ; MCS 6 */ + IWL_DECLARE_MCS_RATE(7), /* MCS 7 */ + IWL_DECLARE_MCS_RATE(8), /* MCS 8 */ + IWL_DECLARE_MCS_RATE(9), /* MCS 9 */ +}; + +enum rs_action { + RS_ACTION_STAY = 0, + RS_ACTION_DOWNSCALE = -1, + RS_ACTION_UPSCALE = 1, +}; + +enum rs_column_mode { + RS_INVALID = 0, + RS_LEGACY, + RS_SISO, + RS_MIMO2, +}; + +#define MAX_NEXT_COLUMNS 7 +#define MAX_COLUMN_CHECKS 3 + +struct rs_tx_column; + +typedef bool (*allow_column_func_t) (struct iwm_softc *sc, + struct ieee80211_node *ni, + struct rs_rate *rate, + const struct rs_tx_column *next_col); + +struct rs_tx_column { + enum rs_column_mode mode; + u8 ant; + bool sgi; + enum rs_column next_columns[MAX_NEXT_COLUMNS]; + allow_column_func_t checks[MAX_COLUMN_CHECKS]; +}; + +static bool iwl_mvm_bt_coex_is_ant_avail(struct iwm_softc *sc, u8 ant) +{ + /* there is no other antenna, shared antenna is always available */ +// if (mvm->cfg->bt_shared_single_ant) +// return true; +// +// if (ant & mvm->cfg->non_shared_ant) +// return true; +// +// return le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) < +// BT_HIGH_TRAFFIC; + // TODO: IMP + return true; +} + +static bool rs_ant_allow(struct iwm_softc *sc, struct ieee80211_node *ni, + struct rs_rate *rate, + const struct rs_tx_column *next_col) +{ + return iwl_mvm_bt_coex_is_ant_avail(sc, next_col->ant); +} + +static bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwm_softc *sc, struct ieee80211_node *ni) +{ + //TODO: IMP + return true; +} + +static bool rs_mimo_allow(struct iwm_softc *sc, struct ieee80211_node *ni, + struct rs_rate *rate, + const struct rs_tx_column *next_col) +{ + ItlIwm *that = container_of(sc, ItlIwm, com); + + if (!ieee80211_node_supports_ht(ni)) + return false; + +// if (sta->smps_mode == IEEE80211_SMPS_STATIC) +// return false; + + if (num_of_ant(that->iwm_fw_valid_tx_ant(sc)) < 2) + return false; + + if (!iwl_mvm_bt_coex_is_mimo_allowed(sc, ni)) + return false; + + if (sc->sc_nvm.sku_cap_mimo_disable) + return false; + + return true; +} + +static bool rs_siso_allow(struct iwm_softc *sc, struct ieee80211_node *ni, + struct rs_rate *rate, + const struct rs_tx_column *next_col) +{ + if (!ieee80211_node_supports_ht(ni)) + return false; + + return true; +} + +static bool rs_sgi_allow(struct iwm_softc *sc, struct ieee80211_node *ni, + struct rs_rate *rate, + const struct rs_tx_column *next_col) +{ + if (is_ht20(rate) && (ieee80211_node_supports_ht_sgi20(ni))) + return true; + if (is_ht40(rate) && (ieee80211_node_supports_ht_sgi40(ni))) + return true; + if (is_ht80(rate) && (ieee80211_node_supports_vht_sgi80(ni))) + return true; + if (is_ht160(rate) && (ieee80211_node_supports_vht_sgi160(ni))) + return true; + + return false; +} + +static const struct rs_tx_column rs_tx_columns[] = { + [RS_COLUMN_LEGACY_ANT_A] = { + .mode = RS_LEGACY, + .ant = ANT_A, + .next_columns = { + RS_COLUMN_LEGACY_ANT_B, + RS_COLUMN_SISO_ANT_A, + RS_COLUMN_MIMO2, + RS_COLUMN_INVALID, + RS_COLUMN_INVALID, + RS_COLUMN_INVALID, + RS_COLUMN_INVALID, + }, + .checks = { + rs_ant_allow, + }, + }, + [RS_COLUMN_LEGACY_ANT_B] = { + .mode = RS_LEGACY, + .ant = ANT_B, + .next_columns = { + RS_COLUMN_LEGACY_ANT_A, + RS_COLUMN_SISO_ANT_B, + RS_COLUMN_MIMO2, + RS_COLUMN_INVALID, + RS_COLUMN_INVALID, + RS_COLUMN_INVALID, + RS_COLUMN_INVALID, + }, + .checks = { + rs_ant_allow, + }, + }, + [RS_COLUMN_SISO_ANT_A] = { + .mode = RS_SISO, + .ant = ANT_A, + .next_columns = { + RS_COLUMN_SISO_ANT_B, + RS_COLUMN_MIMO2, + RS_COLUMN_SISO_ANT_A_SGI, + RS_COLUMN_LEGACY_ANT_A, + RS_COLUMN_LEGACY_ANT_B, + RS_COLUMN_INVALID, + RS_COLUMN_INVALID, + }, + .checks = { + rs_siso_allow, + rs_ant_allow, + }, + }, + [RS_COLUMN_SISO_ANT_B] = { + .mode = RS_SISO, + .ant = ANT_B, + .next_columns = { + RS_COLUMN_SISO_ANT_A, + RS_COLUMN_MIMO2, + RS_COLUMN_SISO_ANT_B_SGI, + RS_COLUMN_LEGACY_ANT_A, + RS_COLUMN_LEGACY_ANT_B, + RS_COLUMN_INVALID, + RS_COLUMN_INVALID, + }, + .checks = { + rs_siso_allow, + rs_ant_allow, + }, + }, + [RS_COLUMN_SISO_ANT_A_SGI] = { + .mode = RS_SISO, + .ant = ANT_A, + .sgi = true, + .next_columns = { + RS_COLUMN_SISO_ANT_B_SGI, + RS_COLUMN_MIMO2_SGI, + RS_COLUMN_SISO_ANT_A, + RS_COLUMN_LEGACY_ANT_A, + RS_COLUMN_LEGACY_ANT_B, + RS_COLUMN_INVALID, + RS_COLUMN_INVALID, + }, + .checks = { + rs_siso_allow, + rs_ant_allow, + rs_sgi_allow, + }, + }, + [RS_COLUMN_SISO_ANT_B_SGI] = { + .mode = RS_SISO, + .ant = ANT_B, + .sgi = true, + .next_columns = { + RS_COLUMN_SISO_ANT_A_SGI, + RS_COLUMN_MIMO2_SGI, + RS_COLUMN_SISO_ANT_B, + RS_COLUMN_LEGACY_ANT_A, + RS_COLUMN_LEGACY_ANT_B, + RS_COLUMN_INVALID, + RS_COLUMN_INVALID, + }, + .checks = { + rs_siso_allow, + rs_ant_allow, + rs_sgi_allow, + }, + }, + [RS_COLUMN_MIMO2] = { + .mode = RS_MIMO2, + .ant = ANT_AB, + .next_columns = { + RS_COLUMN_SISO_ANT_A, + RS_COLUMN_MIMO2_SGI, + RS_COLUMN_LEGACY_ANT_A, + RS_COLUMN_LEGACY_ANT_B, + RS_COLUMN_INVALID, + RS_COLUMN_INVALID, + RS_COLUMN_INVALID, + }, + .checks = { + rs_mimo_allow, + }, + }, + [RS_COLUMN_MIMO2_SGI] = { + .mode = RS_MIMO2, + .ant = ANT_AB, + .sgi = true, + .next_columns = { + RS_COLUMN_SISO_ANT_A_SGI, + RS_COLUMN_MIMO2, + RS_COLUMN_LEGACY_ANT_A, + RS_COLUMN_LEGACY_ANT_B, + RS_COLUMN_INVALID, + RS_COLUMN_INVALID, + RS_COLUMN_INVALID, + }, + .checks = { + rs_mimo_allow, + rs_sgi_allow, + }, + }, +}; + +static inline u8 rs_extract_rate(u32 rate_n_flags) +{ + /* also works for HT because bits 7:6 are zero there */ + return (u8)(rate_n_flags & RATE_LEGACY_RATE_MSK); +} + +static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags) +{ + int idx = 0; + + if (rate_n_flags & RATE_MCS_HT_MSK) { + idx = rate_n_flags & RATE_HT_MCS_RATE_CODE_MSK; + idx += IWL_RATE_MCS_0_INDEX; + + /* skip 9M not supported in HT*/ + if (idx >= IWL_RATE_9M_INDEX) + idx += 1; + if ((idx >= IWL_FIRST_HT_RATE) && (idx <= IWL_LAST_HT_RATE)) + return idx; + } else if (rate_n_flags & RATE_MCS_VHT_MSK || + rate_n_flags & RATE_MCS_HE_MSK) { + idx = rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK; + idx += IWL_RATE_MCS_0_INDEX; + + /* skip 9M not supported in VHT*/ + if (idx >= IWL_RATE_9M_INDEX) + idx++; + if ((idx >= IWL_FIRST_VHT_RATE) && (idx <= IWL_LAST_VHT_RATE)) + return idx; + if ((rate_n_flags & RATE_MCS_HE_MSK) && + (idx <= IWL_LAST_HE_RATE)) + return idx; + } else { + /* legacy rate format, search for match in table */ + + u8 legacy_rate = rs_extract_rate(rate_n_flags); + for (idx = 0; idx < ARRAY_SIZE(iwl_rates); idx++) + if (iwl_rates[idx].plcp == legacy_rate) + return idx; + } + + return IWL_RATE_INVALID; +} + +static void rs_rate_scale_perform(struct iwm_softc *sc, + struct ieee80211_node *ni, + struct iwl_lq_sta *lq_sta, + int tid, bool ndp); +static void rs_fill_lq_cmd(struct iwm_softc *sc, + struct ieee80211_node *ni, + struct iwl_lq_sta *lq_sta, + const struct rs_rate *initial_rate); +static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search); + +/* + * The following tables contain the expected throughput metrics for all rates + * + * 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 60 MBits + * + * where invalid entries are zeros. + * + * CCK rates are only valid in legacy table and will only be used in G + * (2.4 GHz) band. + */ +static const u16 expected_tpt_legacy[IWL_RATE_COUNT] = { + 7, 13, 35, 58, 40, 57, 72, 98, 121, 154, 177, 186, 0, 0, 0 +}; + +/* Expected TpT tables. 4 indexes: + * 0 - NGI, 1 - SGI, 2 - AGG+NGI, 3 - AGG+SGI + */ +static const u16 expected_tpt_siso_20MHz[4][IWL_RATE_COUNT] = { + {0, 0, 0, 0, 42, 0, 76, 102, 124, 159, 183, 193, 202, 216, 0}, + {0, 0, 0, 0, 46, 0, 82, 110, 132, 168, 192, 202, 210, 225, 0}, + {0, 0, 0, 0, 49, 0, 97, 145, 192, 285, 375, 420, 464, 551, 0}, + {0, 0, 0, 0, 54, 0, 108, 160, 213, 315, 415, 465, 513, 608, 0}, +}; + +static const u16 expected_tpt_siso_40MHz[4][IWL_RATE_COUNT] = { + {0, 0, 0, 0, 77, 0, 127, 160, 184, 220, 242, 250, 257, 269, 275}, + {0, 0, 0, 0, 83, 0, 135, 169, 193, 229, 250, 257, 264, 275, 280}, + {0, 0, 0, 0, 101, 0, 199, 295, 389, 570, 744, 828, 911, 1070, 1173}, + {0, 0, 0, 0, 112, 0, 220, 326, 429, 629, 819, 912, 1000, 1173, 1284}, +}; + +static const u16 expected_tpt_siso_80MHz[4][IWL_RATE_COUNT] = { + {0, 0, 0, 0, 130, 0, 191, 223, 244, 273, 288, 294, 298, 305, 308}, + {0, 0, 0, 0, 138, 0, 200, 231, 251, 279, 293, 298, 302, 308, 312}, + {0, 0, 0, 0, 217, 0, 429, 634, 834, 1220, 1585, 1760, 1931, 2258, 2466}, + {0, 0, 0, 0, 241, 0, 475, 701, 921, 1343, 1741, 1931, 2117, 2468, 2691}, +}; + +static const u16 expected_tpt_siso_160MHz[4][IWL_RATE_COUNT] = { + {0, 0, 0, 0, 191, 0, 244, 288, 298, 308, 313, 318, 323, 328, 330}, + {0, 0, 0, 0, 200, 0, 251, 293, 302, 312, 317, 322, 327, 332, 334}, + {0, 0, 0, 0, 439, 0, 875, 1307, 1736, 2584, 3419, 3831, 4240, 5049, 5581}, + {0, 0, 0, 0, 488, 0, 972, 1451, 1925, 2864, 3785, 4240, 4691, 5581, 6165}, +}; + +static const u16 expected_tpt_mimo2_20MHz[4][IWL_RATE_COUNT] = { + {0, 0, 0, 0, 74, 0, 123, 155, 179, 213, 235, 243, 250, 261, 0}, + {0, 0, 0, 0, 81, 0, 131, 164, 187, 221, 242, 250, 256, 267, 0}, + {0, 0, 0, 0, 98, 0, 193, 286, 375, 550, 718, 799, 878, 1032, 0}, + {0, 0, 0, 0, 109, 0, 214, 316, 414, 607, 790, 879, 965, 1132, 0}, +}; + +static const u16 expected_tpt_mimo2_40MHz[4][IWL_RATE_COUNT] = { + {0, 0, 0, 0, 123, 0, 182, 214, 235, 264, 279, 285, 289, 296, 300}, + {0, 0, 0, 0, 131, 0, 191, 222, 242, 270, 284, 289, 293, 300, 303}, + {0, 0, 0, 0, 200, 0, 390, 571, 741, 1067, 1365, 1505, 1640, 1894, 2053}, + {0, 0, 0, 0, 221, 0, 430, 630, 816, 1169, 1490, 1641, 1784, 2053, 2221}, +}; + +static const u16 expected_tpt_mimo2_80MHz[4][IWL_RATE_COUNT] = { + {0, 0, 0, 0, 182, 0, 240, 264, 278, 299, 308, 311, 313, 317, 319}, + {0, 0, 0, 0, 190, 0, 247, 269, 282, 302, 310, 313, 315, 319, 320}, + {0, 0, 0, 0, 428, 0, 833, 1215, 1577, 2254, 2863, 3147, 3418, 3913, 4219}, + {0, 0, 0, 0, 474, 0, 920, 1338, 1732, 2464, 3116, 3418, 3705, 4225, 4545}, +}; + +static const u16 expected_tpt_mimo2_160MHz[4][IWL_RATE_COUNT] = { + {0, 0, 0, 0, 240, 0, 278, 308, 313, 319, 322, 324, 328, 330, 334}, + {0, 0, 0, 0, 247, 0, 282, 310, 315, 320, 323, 325, 329, 332, 338}, + {0, 0, 0, 0, 875, 0, 1735, 2582, 3414, 5043, 6619, 7389, 8147, 9629, 10592}, + {0, 0, 0, 0, 971, 0, 1925, 2861, 3779, 5574, 7304, 8147, 8976, 10592, 11640}, +}; + +/* mbps, mcs */ +static const struct iwl_rate_mcs_info iwl_rate_mcs[IWL_RATE_COUNT] = { + { "1", "BPSK DSSS"}, + { "2", "QPSK DSSS"}, + {"5.5", "BPSK CCK"}, + { "11", "QPSK CCK"}, + { "6", "BPSK 1/2"}, + { "9", "BPSK 1/2"}, + { "12", "QPSK 1/2"}, + { "18", "QPSK 3/4"}, + { "24", "16QAM 1/2"}, + { "36", "16QAM 3/4"}, + { "48", "64QAM 2/3"}, + { "54", "64QAM 3/4"}, + { "60", "64QAM 5/6"}, +}; + +#define MCS_INDEX_PER_STREAM (8) + +static const char *rs_pretty_ant(u8 ant) +{ + static const char * const ant_name[] = { + [ANT_NONE] = "None", + [ANT_A] = "A", + [ANT_B] = "B", + [ANT_AB] = "AB", + [ANT_C] = "C", + [ANT_AC] = "AC", + [ANT_BC] = "BC", + [ANT_ABC] = "ABC", + }; + + if (ant > ANT_ABC) + return "UNKNOWN"; + + return ant_name[ant]; +} + +static const char *rs_pretty_lq_type(enum iwl_table_type type) +{ + static const char * const lq_types[] = { + [LQ_NONE] = "NONE", + [LQ_LEGACY_A] = "LEGACY_A", + [LQ_LEGACY_G] = "LEGACY_G", + [LQ_HT_SISO] = "HT SISO", + [LQ_HT_MIMO2] = "HT MIMO", + [LQ_VHT_SISO] = "VHT SISO", + [LQ_VHT_MIMO2] = "VHT MIMO", + [LQ_HE_SISO] = "HE SISO", + [LQ_HE_MIMO2] = "HE MIMO", + }; + + if (type < LQ_NONE || type >= LQ_MAX) + return "UNKNOWN"; + + return lq_types[type]; +} + +static char *rs_pretty_rate(const struct rs_rate *rate) +{ + static char buf[40]; + static const char * const legacy_rates[] = { + [IWL_RATE_1M_INDEX] = "1M", + [IWL_RATE_2M_INDEX] = "2M", + [IWL_RATE_5M_INDEX] = "5.5M", + [IWL_RATE_11M_INDEX] = "11M", + [IWL_RATE_6M_INDEX] = "6M", + [IWL_RATE_9M_INDEX] = "9M", + [IWL_RATE_12M_INDEX] = "12M", + [IWL_RATE_18M_INDEX] = "18M", + [IWL_RATE_24M_INDEX] = "24M", + [IWL_RATE_36M_INDEX] = "36M", + [IWL_RATE_48M_INDEX] = "48M", + [IWL_RATE_54M_INDEX] = "54M", + }; + static const char *const ht_vht_rates[] = { + [IWL_RATE_MCS_0_INDEX] = "MCS0", + [IWL_RATE_MCS_1_INDEX] = "MCS1", + [IWL_RATE_MCS_2_INDEX] = "MCS2", + [IWL_RATE_MCS_3_INDEX] = "MCS3", + [IWL_RATE_MCS_4_INDEX] = "MCS4", + [IWL_RATE_MCS_5_INDEX] = "MCS5", + [IWL_RATE_MCS_6_INDEX] = "MCS6", + [IWL_RATE_MCS_7_INDEX] = "MCS7", + [IWL_RATE_MCS_8_INDEX] = "MCS8", + [IWL_RATE_MCS_9_INDEX] = "MCS9", + }; + const char *rate_str; + + if (is_type_legacy(rate->type) && (rate->index <= IWL_RATE_54M_INDEX)) + rate_str = legacy_rates[rate->index]; + else if ((is_type_ht(rate->type) || is_type_vht(rate->type)) && + (rate->index >= IWL_RATE_MCS_0_INDEX) && + (rate->index <= IWL_RATE_MCS_9_INDEX)) + rate_str = ht_vht_rates[rate->index]; + else + rate_str = "BAD_RATE"; + + snprintf(buf, sizeof(buf), "(%s|%s|%s)", rs_pretty_lq_type(rate->type), + rs_pretty_ant(rate->ant), rate_str); + return buf; +} + +static inline void rs_dump_rate(struct iwm_softc *sc, const struct rs_rate *rate, + const char *prefix) +{ + IWL_DEBUG_RATE(sc, + "%s: %s BW: %d SGI: %d LDPC: %d STBC: %d\n", + prefix, rs_pretty_rate(rate), rate->bw, + rate->sgi, rate->ldpc, rate->stbc); +} + +static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window) +{ + window->data = 0; + window->success_counter = 0; + window->success_ratio = IWL_INVALID_VALUE; + window->counter = 0; + window->average_tpt = IWL_INVALID_VALUE; +} + +static void rs_rate_scale_clear_tbl_windows(struct iwm_softc *sc, + struct iwl_scale_tbl_info *tbl) +{ + int i; + + IWL_DEBUG_RATE(sc, "Clearing up window stats\n"); + for (i = 0; i < IWL_RATE_COUNT; i++) + rs_rate_scale_clear_window(&tbl->win[i]); + + for (i = 0; i < ARRAY_SIZE(tbl->tpc_win); i++) + rs_rate_scale_clear_window(&tbl->tpc_win[i]); +} + +static inline u8 rs_is_valid_ant(u8 valid_antenna, u8 ant_type) +{ + return (ant_type & valid_antenna) == ant_type; +} + +extern int ieee80211_can_use_ampdu(struct ieee80211com *, + struct ieee80211_node *); + +static int rs_tl_turn_on_agg_for_tid(struct iwm_softc *sc, + struct iwl_lq_sta *lq_data, u8 tid, + struct ieee80211_node *ni) +{ + IWL_DEBUG_RATE(sc, "Starting Tx agg: STA: %s tid: %d\n", + ether_sprintf(ni->ni_macaddr), tid); + + /* start BA session until the peer sends del BA */ + if (!ieee80211_can_use_ampdu(&sc->sc_ic, ni)) + return -1; + ieee80211_node_trigger_addba_req(ni, tid); + return 0; +} + +static void rs_tl_turn_on_agg(struct iwm_softc *sc, + u8 tid, struct iwl_lq_sta *lq_sta, + struct ieee80211_node *ni) +{ +#if 0 + struct iwm_tx_ba *tid_data; + struct ieee80211_tx_ba *tx_ba; + + /* + * In AP mode, tid can be equal to IWL_MAX_TID_COUNT + * when the frame is not QoS + */ + if (WARN_ON_ONCE(tid > IWL_MAX_TID_COUNT)) { + IWL_ERR(mvm, "tid exceeds max TID count: %d/%d\n", + tid, IWL_MAX_TID_COUNT); + return; + } else if (tid == IWL_MAX_TID_COUNT) { + return; + } + + tx_ba = &sc->sc_ic.ic_bss->ni_tx_ba[tid]; + tid_data = &sc->sc_tx_ba[tid]; + if (sc->sc_ic.ic_state >= IEEE80211_S_RUN && + tx_ba->ba_state == IEEE80211_BA_INIT && + (lq_sta->tx_agg_tid_en & BIT(tid)) && + tid_data->tx_count_last >= IWL_MVM_RS_AGG_START_THRESHOLD) { + IWL_DEBUG_RATE(mvm, "try to aggregate tid %d\n", tid); + rs_tl_turn_on_agg_for_tid(sc, lq_sta, tid, ni); + } +#else + ; +#endif +} + +static inline int get_num_of_ant_from_rate(u32 rate_n_flags) +{ + return !!(rate_n_flags & RATE_MCS_ANT_A_MSK) + + !!(rate_n_flags & RATE_MCS_ANT_B_MSK) + + !!(rate_n_flags & RATE_MCS_ANT_C_MSK); +} + +/* + * Static function to get the expected throughput from an iwl_scale_tbl_info + * that wraps a NULL pointer check + */ +static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index) +{ + if (tbl->expected_tpt) + return tbl->expected_tpt[rs_index]; + return 0; +} + +/* + * rs_collect_tx_data - Update the success/failure sliding window + * + * We keep a sliding window of the last 62 packets transmitted + * at this rate. window->data contains the bitmask of successful + * packets. + */ +static int _rs_collect_tx_data(struct iwm_softc *sc, + struct iwl_scale_tbl_info *tbl, + int scale_index, int attempts, int successes, + struct iwl_rate_scale_data *window) +{ + static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1)); + s32 fail_count, tpt; + + /* Get expected throughput */ + tpt = get_expected_tpt(tbl, scale_index); + + /* + * Keep track of only the latest 62 tx frame attempts in this rate's + * history window; anything older isn't really relevant any more. + * If we have filled up the sliding window, drop the oldest attempt; + * if the oldest attempt (highest bit in bitmap) shows "success", + * subtract "1" from the success counter (this is the main reason + * we keep these bitmaps!). + */ + while (attempts > 0) { + if (window->counter >= IWL_RATE_MAX_WINDOW) { + /* remove earliest */ + window->counter = IWL_RATE_MAX_WINDOW - 1; + + if (window->data & mask) { + window->data &= ~mask; + window->success_counter--; + } + } + + /* Increment frames-attempted counter */ + window->counter++; + + /* Shift bitmap by one frame to throw away oldest history */ + window->data <<= 1; + + /* Mark the most recent #successes attempts as successful */ + if (successes > 0) { + window->success_counter++; + window->data |= 0x1; + successes--; + } + + attempts--; + } + + /* Calculate current success ratio, avoid divide-by-0! */ + if (window->counter > 0) + window->success_ratio = 128 * (100 * window->success_counter) + / window->counter; + else + window->success_ratio = IWL_INVALID_VALUE; + + fail_count = window->counter - window->success_counter; + + /* Calculate average throughput, if we have enough history. */ + if ((fail_count >= IWL_MVM_RS_RATE_MIN_FAILURE_TH) || + (window->success_counter >= IWL_MVM_RS_RATE_MIN_SUCCESS_TH)) + window->average_tpt = (window->success_ratio * tpt + 64) / 128; + else + window->average_tpt = IWL_INVALID_VALUE; + + return 0; +} + +static int rs_collect_tpc_data(struct iwm_softc *sc, + struct iwl_lq_sta *lq_sta, + struct iwl_scale_tbl_info *tbl, + int scale_index, int attempts, int successes, + u8 reduced_txp) +{ + struct iwl_rate_scale_data *window = NULL; + + if (WARN_ON_ONCE(reduced_txp > TPC_MAX_REDUCTION)) + return -EINVAL; + + window = &tbl->tpc_win[reduced_txp]; + return _rs_collect_tx_data(sc, tbl, scale_index, attempts, successes, + window); +} + +static void rs_update_tid_tpt_stats(struct iwm_softc *sc, + u8 tid, int successes) +{ + if (tid >= IWL_MAX_TID_COUNT) + return; + + struct iwm_tx_ba *tid_data = &sc->sc_tx_ba[tid]; + struct ieee80211_tx_ba *tx_ba = &sc->sc_ic.ic_bss->ni_tx_ba[tid]; + + /* + * Measure if there're enough successful transmits per second. + * These statistics are used only to decide if we can start a + * BA session, so it should be updated only when A-MPDU is + * off. + */ + if (tx_ba->ba_state != IEEE80211_BA_INIT) + return; + + if (time_is_before_jiffies(tid_data->tpt_meas_start + hz) || + (tid_data->tx_count >= IWL_MVM_RS_AGG_START_THRESHOLD)) { + tid_data->tx_count_last = tid_data->tx_count; + tid_data->tx_count = 0; + tid_data->tpt_meas_start = ticks; + } else { + tid_data->tx_count += successes; + } +} + +static int rs_collect_tlc_data(struct iwm_softc *sc, + u8 tid, + struct iwl_scale_tbl_info *tbl, + int scale_index, int attempts, int successes) +{ + struct iwl_rate_scale_data *window = NULL; + + if (scale_index < 0 || scale_index >= IWL_RATE_COUNT) + return -EINVAL; + + if (tbl->column != RS_COLUMN_INVALID) { + struct lq_sta_pers *pers = &sc->lq_sta.rs_drv.pers; + + pers->tx_stats[tbl->column][scale_index].total += attempts; + pers->tx_stats[tbl->column][scale_index].success += successes; + } + + rs_update_tid_tpt_stats(sc, tid, successes); + + /* Select window for current tx bit rate */ + window = &(tbl->win[scale_index]); + return _rs_collect_tx_data(sc, tbl, scale_index, attempts, successes, + window); +} + +/* Convert rs_rate object into ucode rate bitmask */ +static u32 ucode_rate_from_rs_rate(struct iwm_softc *sc, + struct rs_rate *rate) +{ + u32 ucode_rate = 0; + int index = rate->index; + + ucode_rate |= ((rate->ant << RATE_MCS_ANT_POS) & + RATE_MCS_ANT_ABC_MSK); + + if (is_legacy(rate)) { + ucode_rate |= iwl_rates[index].plcp; + if (index >= IWL_FIRST_CCK_RATE && index <= IWL_LAST_CCK_RATE) + ucode_rate |= RATE_MCS_CCK_MSK; + return ucode_rate; + } + + /* set RTS protection for all non legacy rates + * This helps with congested environments reducing the conflict cost to + * RTS retries only, instead of the entire BA packet. + */ + ucode_rate |= RATE_MCS_RTS_REQUIRED_MSK; + + if (is_ht(rate)) { + if (index < IWL_FIRST_HT_RATE || index > IWL_LAST_HT_RATE) { + IWL_ERR(mvm, "Invalid HT rate index %d\n", index); + index = IWL_LAST_HT_RATE; + } + ucode_rate |= RATE_MCS_HT_MSK; + + if (is_ht_siso(rate)) + ucode_rate |= iwl_rates[index].plcp_ht_siso; + else if (is_ht_mimo2(rate)) + ucode_rate |= iwl_rates[index].plcp_ht_mimo2; + else + WARN_ON_ONCE(1); + } else if (is_vht(rate)) { + if (index < IWL_FIRST_VHT_RATE || index > IWL_LAST_VHT_RATE) { + IWL_ERR(mvm, "Invalid VHT rate index %d\n", index); + index = IWL_LAST_VHT_RATE; + } + ucode_rate |= RATE_MCS_VHT_MSK; + if (is_vht_siso(rate)) + ucode_rate |= iwl_rates[index].plcp_vht_siso; + else if (is_vht_mimo2(rate)) + ucode_rate |= iwl_rates[index].plcp_vht_mimo2; + else + WARN_ON_ONCE(1); + + } else { + IWL_ERR(mvm, "Invalid rate->type %d\n", rate->type); + } + + if (is_siso(rate) && rate->stbc) { + /* To enable STBC we need to set both a flag and ANT_AB */ + ucode_rate |= RATE_MCS_ANT_AB_MSK; + ucode_rate |= RATE_MCS_STBC_MSK; + } + + ucode_rate |= rate->bw; + if (rate->sgi) + ucode_rate |= RATE_MCS_SGI_MSK; + if (rate->ldpc) + ucode_rate |= RATE_MCS_LDPC_MSK; + + return ucode_rate; +} + +/* Convert a ucode rate into an rs_rate object */ +static int rs_rate_from_ucode_rate(const u32 ucode_rate, + enum nl80211_band band, + struct rs_rate *rate) +{ + u32 ant_msk = ucode_rate & RATE_MCS_ANT_ABC_MSK; + u8 num_of_ant = get_num_of_ant_from_rate(ucode_rate); + u8 nss; + + memset(rate, 0, sizeof(*rate)); + rate->index = iwl_hwrate_to_plcp_idx(ucode_rate); + + if (rate->index == IWL_RATE_INVALID) + return -EINVAL; + + rate->ant = (ant_msk >> RATE_MCS_ANT_POS); + + /* Legacy */ + if (!(ucode_rate & RATE_MCS_HT_MSK) && + !(ucode_rate & RATE_MCS_VHT_MSK) && + !(ucode_rate & RATE_MCS_HE_MSK)) { + if (num_of_ant == 1) { + if (band == NL80211_BAND_5GHZ) + rate->type = LQ_LEGACY_A; + else + rate->type = LQ_LEGACY_G; + } + + return 0; + } + + /* HT, VHT or HE */ + if (ucode_rate & RATE_MCS_SGI_MSK) + rate->sgi = true; + if (ucode_rate & RATE_MCS_LDPC_MSK) + rate->ldpc = true; + if (ucode_rate & RATE_MCS_STBC_MSK) + rate->stbc = true; + if (ucode_rate & RATE_MCS_BF_MSK) + rate->bfer = true; + + rate->bw = ucode_rate & RATE_MCS_CHAN_WIDTH_MSK; + + if (ucode_rate & RATE_MCS_HT_MSK) { + nss = ((ucode_rate & RATE_HT_MCS_NSS_MSK) >> + RATE_HT_MCS_NSS_POS) + 1; + + if (nss == 1) { + rate->type = LQ_HT_SISO; + WARN_ON(!rate->stbc && !rate->bfer && num_of_ant != 1, + "stbc %d bfer %d", + rate->stbc, rate->bfer); + } else if (nss == 2) { + rate->type = LQ_HT_MIMO2; + WARN_ON_ONCE(num_of_ant != 2); + } else { + WARN_ON_ONCE(1); + } + } else if (ucode_rate & RATE_MCS_VHT_MSK) { + nss = ((ucode_rate & RATE_VHT_MCS_NSS_MSK) >> + RATE_VHT_MCS_NSS_POS) + 1; + + if (nss == 1) { + rate->type = LQ_VHT_SISO; + WARN_ON(!rate->stbc && !rate->bfer && num_of_ant != 1, + "stbc %d bfer %d", + rate->stbc, rate->bfer); + } else if (nss == 2) { + rate->type = LQ_VHT_MIMO2; + WARN_ON_ONCE(num_of_ant != 2); + } else { + WARN_ON_ONCE(1); + } + } else if (ucode_rate & RATE_MCS_HE_MSK) { + nss = ((ucode_rate & RATE_VHT_MCS_NSS_MSK) >> + RATE_VHT_MCS_NSS_POS) + 1; + + if (nss == 1) { + rate->type = LQ_HE_SISO; + WARN_ON(!rate->stbc && !rate->bfer && num_of_ant != 1, + "stbc %d bfer %d", rate->stbc, rate->bfer); + } else if (nss == 2) { + rate->type = LQ_HE_MIMO2; + WARN_ON_ONCE(num_of_ant != 2); + } else { + WARN_ON_ONCE(1); + } + } + + WARN_ON_ONCE(rate->bw == RATE_MCS_CHAN_WIDTH_80 && + !is_he(rate) && !is_vht(rate)); + + return 0; +} + +/* switch to another antenna/antennas and return 1 */ +/* if no other valid antenna found, return 0 */ +static int rs_toggle_antenna(u32 valid_ant, struct rs_rate *rate) +{ + u8 new_ant_type; + + if (!rate->ant || WARN_ON_ONCE(rate->ant & ANT_C)) + return 0; + + if (!rs_is_valid_ant(valid_ant, rate->ant)) + return 0; + + new_ant_type = ant_toggle_lookup[rate->ant]; + + while ((new_ant_type != rate->ant) && + !rs_is_valid_ant(valid_ant, new_ant_type)) + new_ant_type = ant_toggle_lookup[new_ant_type]; + + if (new_ant_type == rate->ant) + return 0; + + rate->ant = new_ant_type; + + return 1; +} + +static u16 rs_get_supported_rates(struct iwl_lq_sta *lq_sta, + struct rs_rate *rate) +{ + if (is_legacy(rate)) + return lq_sta->active_legacy_rate; + else if (is_siso(rate)) + return lq_sta->active_siso_rate; + else if (is_mimo2(rate)) + return lq_sta->active_mimo2_rate; + + WARN_ON_ONCE(1); + return 0; +} + +static u16 rs_get_adjacent_rate(struct iwm_softc *sc, u8 index, u16 rate_mask, + int rate_type) +{ + u8 high = IWL_RATE_INVALID; + u8 low = IWL_RATE_INVALID; + + /* 802.11A or ht walks to the next literal adjacent rate in + * the rate table */ + if (is_type_a_band(rate_type) || !is_type_legacy(rate_type)) { + int i; + u32 mask; + + /* Find the previous rate that is in the rate mask */ + i = index - 1; + if (i >= 0) + mask = BIT(i); + for (; i >= 0; i--, mask >>= 1) { + if (rate_mask & mask) { + low = i; + break; + } + } + + /* Find the next rate that is in the rate mask */ + i = index + 1; + for (mask = (1 << i); i < IWL_RATE_COUNT; i++, mask <<= 1) { + if (rate_mask & mask) { + high = i; + break; + } + } + + return (high << 8) | low; + } + + low = index; + while (low != IWL_RATE_INVALID) { + low = iwl_rates[low].prev_rs; + if (low == IWL_RATE_INVALID) + break; + if (rate_mask & (1 << low)) + break; + } + + high = index; + while (high != IWL_RATE_INVALID) { + high = iwl_rates[high].next_rs; + if (high == IWL_RATE_INVALID) + break; + if (rate_mask & (1 << high)) + break; + } + + return (high << 8) | low; +} + +static inline bool rs_rate_supported(struct iwl_lq_sta *lq_sta, + struct rs_rate *rate) +{ + return BIT(rate->index) & rs_get_supported_rates(lq_sta, rate); +} + +/* Get the next supported lower rate in the current column. + * Return true if bottom rate in the current column was reached + */ +static bool rs_get_lower_rate_in_column(struct iwl_lq_sta *lq_sta, + struct rs_rate *rate) +{ + u8 low; + u16 high_low; + u16 rate_mask; + struct iwm_softc *sc = lq_sta->pers.drv; + + rate_mask = rs_get_supported_rates(lq_sta, rate); + high_low = rs_get_adjacent_rate(sc, rate->index, rate_mask, + rate->type); + low = high_low & 0xff; + + /* Bottom rate of column reached */ + if (low == IWL_RATE_INVALID) + return true; + + rate->index = low; + return false; +} + +/* Get the next rate to use following a column downgrade */ +static void rs_get_lower_rate_down_column(struct iwl_lq_sta *lq_sta, + struct rs_rate *rate) +{ + struct iwm_softc *sc = lq_sta->pers.drv; + ItlIwm *that = container_of(sc, ItlIwm, com); + + if (is_legacy(rate)) { + /* No column to downgrade from Legacy */ + return; + } else if (is_siso(rate)) { + /* Downgrade to Legacy if we were in SISO */ + if (lq_sta->band == NL80211_BAND_5GHZ) + rate->type = LQ_LEGACY_A; + else + rate->type = LQ_LEGACY_G; + + rate->bw = RATE_MCS_CHAN_WIDTH_20; + + WARN_ON_ONCE(rate->index < IWL_RATE_MCS_0_INDEX || + rate->index > IWL_RATE_MCS_9_INDEX); + + rate->index = rs_ht_to_legacy[rate->index]; + rate->ldpc = false; + } else { + /* Downgrade to SISO with same MCS if in MIMO */ + rate->type = is_vht_mimo2(rate) ? + LQ_VHT_SISO : LQ_HT_SISO; + } + + if (num_of_ant(rate->ant) > 1) + rate->ant = first_antenna(that->iwm_fw_valid_tx_ant(sc)); + + /* Relevant in both switching to SISO or Legacy */ + rate->sgi = false; + + if (!rs_rate_supported(lq_sta, rate)) + rs_get_lower_rate_in_column(lq_sta, rate); +} + +/* Check if both rates share the same column */ +static inline bool rs_rate_column_match(struct rs_rate *a, + struct rs_rate *b) +{ + bool ant_match; + + if (a->stbc || a->bfer) + ant_match = (b->ant == ANT_A || b->ant == ANT_B); + else + ant_match = (a->ant == b->ant); + + return (a->type == b->type) && (a->bw == b->bw) && (a->sgi == b->sgi) + && ant_match; +} + +static inline enum rs_column rs_get_column_from_rate(struct rs_rate *rate) +{ + if (is_legacy(rate)) { + if (rate->ant == ANT_A) + return RS_COLUMN_LEGACY_ANT_A; + + if (rate->ant == ANT_B) + return RS_COLUMN_LEGACY_ANT_B; + + goto err; + } + + if (is_siso(rate)) { + if (rate->ant == ANT_A || rate->stbc || rate->bfer) + return rate->sgi ? RS_COLUMN_SISO_ANT_A_SGI : + RS_COLUMN_SISO_ANT_A; + + if (rate->ant == ANT_B) + return rate->sgi ? RS_COLUMN_SISO_ANT_B_SGI : + RS_COLUMN_SISO_ANT_B; + + goto err; + } + + if (is_mimo(rate)) + return rate->sgi ? RS_COLUMN_MIMO2_SGI : RS_COLUMN_MIMO2; + +err: + return RS_COLUMN_INVALID; +} + +/* + * mac80211 sends us Tx status + */ +void rs_drv_mac80211_tx_status(struct iwm_softc *sc, + struct ieee80211_node *sta, + struct ieee80211_tx_info *info, int tid, uint16_t fc, int ssn) +{ + if (!ieee80211_is_data(fc) || + info->flags & IEEE80211_TX_CTL_NO_ACK) + return; + + iwl_mvm_rs_tx_status(sc, sta, tid, info, + false); +} + +/* + * Begin a period of staying with a selected modulation mode. + * Set "stay_in_tbl" flag to prevent any mode switches. + * Set frame tx success limits according to legacy vs. high-throughput, + * and reset overall (spanning all rates) tx success history statistics. + * These control how long we stay using same modulation mode before + * searching for a new mode. + */ +static void rs_set_stay_in_table(struct iwm_softc *mvm, u8 is_legacy, + struct iwl_lq_sta *lq_sta) +{ + IWL_DEBUG_RATE(mvm, "Moving to RS_STATE_STAY_IN_COLUMN\n"); + lq_sta->rs_state = RS_STATE_STAY_IN_COLUMN; + if (is_legacy) { + lq_sta->table_count_limit = IWL_MVM_RS_LEGACY_TABLE_COUNT; + lq_sta->max_failure_limit = IWL_MVM_RS_LEGACY_FAILURE_LIMIT; + lq_sta->max_success_limit = IWL_MVM_RS_LEGACY_SUCCESS_LIMIT; + } else { + lq_sta->table_count_limit = IWL_MVM_RS_NON_LEGACY_TABLE_COUNT; + lq_sta->max_failure_limit = IWL_MVM_RS_NON_LEGACY_FAILURE_LIMIT; + lq_sta->max_success_limit = IWL_MVM_RS_NON_LEGACY_SUCCESS_LIMIT; + } + lq_sta->table_count = 0; + lq_sta->total_failed = 0; + lq_sta->total_success = 0; + lq_sta->flush_timer = ticks; + lq_sta->visited_columns = 0; +} + +static inline int rs_get_max_rate_from_mask(unsigned long rate_mask) +{ + if (rate_mask) + return find_last_bit(&rate_mask, BITS_PER_LONG); + return IWL_RATE_INVALID; +} + +static int rs_get_max_allowed_rate(struct iwl_lq_sta *lq_sta, + const struct rs_tx_column *column) +{ + switch (column->mode) { + case RS_LEGACY: + return lq_sta->max_legacy_rate_idx; + case RS_SISO: + return lq_sta->max_siso_rate_idx; + case RS_MIMO2: + return lq_sta->max_mimo2_rate_idx; + default: + WARN_ON_ONCE(1); + } + + return lq_sta->max_legacy_rate_idx; +} + +static const u16 *rs_get_expected_tpt_table(struct iwl_lq_sta *lq_sta, + const struct rs_tx_column *column, + u32 bw) +{ + /* Used to choose among HT tables */ + const u16 (*ht_tbl_pointer)[IWL_RATE_COUNT]; + + if (WARN_ON_ONCE(column->mode != RS_LEGACY && + column->mode != RS_SISO && + column->mode != RS_MIMO2)) + return expected_tpt_legacy; + + /* Legacy rates have only one table */ + if (column->mode == RS_LEGACY) + return expected_tpt_legacy; + + ht_tbl_pointer = expected_tpt_mimo2_20MHz; + /* Choose among many HT tables depending on number of streams + * (SISO/MIMO2), channel width (20/40/80), SGI, and aggregation + * status */ + if (column->mode == RS_SISO) { + switch (bw) { + case RATE_MCS_CHAN_WIDTH_20: + ht_tbl_pointer = expected_tpt_siso_20MHz; + break; + case RATE_MCS_CHAN_WIDTH_40: + ht_tbl_pointer = expected_tpt_siso_40MHz; + break; + case RATE_MCS_CHAN_WIDTH_80: + ht_tbl_pointer = expected_tpt_siso_80MHz; + break; + case RATE_MCS_CHAN_WIDTH_160: + ht_tbl_pointer = expected_tpt_siso_160MHz; + break; + default: + WARN_ON_ONCE(1); + } + } else if (column->mode == RS_MIMO2) { + switch (bw) { + case RATE_MCS_CHAN_WIDTH_20: + ht_tbl_pointer = expected_tpt_mimo2_20MHz; + break; + case RATE_MCS_CHAN_WIDTH_40: + ht_tbl_pointer = expected_tpt_mimo2_40MHz; + break; + case RATE_MCS_CHAN_WIDTH_80: + ht_tbl_pointer = expected_tpt_mimo2_80MHz; + break; + case RATE_MCS_CHAN_WIDTH_160: + ht_tbl_pointer = expected_tpt_mimo2_160MHz; + break; + default: + WARN_ON_ONCE(1); + } + } else { + WARN_ON_ONCE(1); + } + + if (!column->sgi && !lq_sta->is_agg) /* Normal */ + return ht_tbl_pointer[0]; + else if (column->sgi && !lq_sta->is_agg) /* SGI */ + return ht_tbl_pointer[1]; + else if (!column->sgi && lq_sta->is_agg) /* AGG */ + return ht_tbl_pointer[2]; + else /* AGG+SGI */ + return ht_tbl_pointer[3]; +} + +static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta, + struct iwl_scale_tbl_info *tbl) +{ + struct rs_rate *rate = &tbl->rate; + const struct rs_tx_column *column = &rs_tx_columns[tbl->column]; + + tbl->expected_tpt = rs_get_expected_tpt_table(lq_sta, column, rate->bw); +} + +/* rs uses two tables, one is active and the second is for searching better + * configuration. This function, according to the index of the currently + * active table returns the search table, which is located at the + * index complementary to 1 according to the active table (active = 1, + * search = 0 or active = 0, search = 1). + * Since lq_info is an arary of size 2, make sure index cannot be out of bounds. + */ +static inline u8 rs_search_tbl(u8 active_tbl) +{ + return (active_tbl ^ 1) & 1; +} + +static s32 rs_get_best_rate(struct iwm_softc *sc, + struct iwl_lq_sta *lq_sta, + struct iwl_scale_tbl_info *tbl, /* "search" */ + unsigned long rate_mask, s8 index) +{ + struct iwl_scale_tbl_info *active_tbl = + &(lq_sta->lq_info[lq_sta->active_tbl]); + s32 success_ratio = active_tbl->win[index].success_ratio; + u16 expected_current_tpt = active_tbl->expected_tpt[index]; + const u16 *tpt_tbl = tbl->expected_tpt; + u16 high_low; + u32 target_tpt; + int rate_idx; + + if (success_ratio >= RS_PERCENT(IWL_MVM_RS_SR_NO_DECREASE)) { + target_tpt = 100 * expected_current_tpt; + IWL_DEBUG_RATE(mvm, + "SR %d high. Find rate exceeding EXPECTED_CURRENT %d\n", + success_ratio, target_tpt); + } else { + target_tpt = lq_sta->last_tpt; + IWL_DEBUG_RATE(mvm, + "SR %d not that good. Find rate exceeding ACTUAL_TPT %d\n", + success_ratio, target_tpt); + } + + rate_idx = find_first_bit(&rate_mask, BITS_PER_LONG); + + while (rate_idx != IWL_RATE_INVALID) { + if (target_tpt < (100 * tpt_tbl[rate_idx])) + break; + + high_low = rs_get_adjacent_rate(sc, rate_idx, rate_mask, + tbl->rate.type); + + rate_idx = (high_low >> 8) & 0xff; + } + + IWL_DEBUG_RATE(mvm, "Best rate found %d target_tp %d expected_new %d\n", + rate_idx, target_tpt, + rate_idx != IWL_RATE_INVALID ? + 100 * tpt_tbl[rate_idx] : IWL_INVALID_VALUE); + + return rate_idx; +} + +static u32 rs_bw_from_sta_bw(struct ieee80211_node *ni) +{ + struct ieee80211_vht_cap vht_cap = { + .vht_cap_info = cpu_to_le32(ni->ni_vhtcaps), + .supp_mcs = ni->ni_vht_mcsinfo, + }; + + switch (ni->ni_chw) { + case IEEE80211_CHAN_WIDTH_160: + /* + * Don't use 160 MHz if VHT extended NSS support + * says we cannot use 2 streams, we don't want to + * deal with this. + * We only check MCS 0 - they will support that if + * we got here at all and we don't care which MCS, + * we want to determine a more global state. + */ + if (ieee80211_get_vht_max_nss(&vht_cap, + IEEE80211_VHT_CHANWIDTH_160MHZ, + 0, true, + ni->ni_rx_nss) < ni->ni_rx_nss) + return RATE_MCS_CHAN_WIDTH_80; + return RATE_MCS_CHAN_WIDTH_160; + case IEEE80211_CHAN_WIDTH_80: + return RATE_MCS_CHAN_WIDTH_80; + case IEEE80211_CHAN_WIDTH_40: + return RATE_MCS_CHAN_WIDTH_40; + case IEEE80211_CHAN_WIDTH_20: + default: + return RATE_MCS_CHAN_WIDTH_20; + } +} + +/* + * Check whether we should continue using same modulation mode, or + * begin search for a new mode, based on: + * 1) # tx successes or failures while using this mode + * 2) # times calling this function + * 3) elapsed time in this mode (not used, for now) + */ +static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search) +{ + struct iwl_scale_tbl_info *tbl; + int active_tbl; + int flush_interval_passed = 0; + struct iwm_softc *sc; + + sc = lq_sta->pers.drv; + active_tbl = lq_sta->active_tbl; + + tbl = &(lq_sta->lq_info[active_tbl]); + + /* If we've been disallowing search, see if we should now allow it */ + if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN) { + /* Elapsed time using current modulation mode */ + if (lq_sta->flush_timer) + flush_interval_passed = + time_after(ticks, + (unsigned long)(lq_sta->flush_timer + + (IWL_MVM_RS_STAY_IN_COLUMN_TIMEOUT * hz))); + + /* + * Check if we should allow search for new modulation mode. + * If many frames have failed or succeeded, or we've used + * this same modulation for a long time, allow search, and + * reset history stats that keep track of whether we should + * allow a new search. Also (below) reset all bitmaps and + * stats in active history. + */ + if (force_search || + (lq_sta->total_failed > lq_sta->max_failure_limit) || + (lq_sta->total_success > lq_sta->max_success_limit) || + ((!lq_sta->search_better_tbl) && + (lq_sta->flush_timer) && (flush_interval_passed))) { + IWL_DEBUG_RATE(mvm, + "LQ: stay is expired %d %d %d\n", + lq_sta->total_failed, + lq_sta->total_success, + flush_interval_passed); + + /* Allow search for new mode */ + lq_sta->rs_state = RS_STATE_SEARCH_CYCLE_STARTED; + IWL_DEBUG_RATE(mvm, + "Moving to RS_STATE_SEARCH_CYCLE_STARTED\n"); + lq_sta->total_failed = 0; + lq_sta->total_success = 0; + lq_sta->flush_timer = 0; + /* mark the current column as visited */ + lq_sta->visited_columns = BIT(tbl->column); + /* + * Else if we've used this modulation mode enough repetitions + * (regardless of elapsed time or success/failure), reset + * history bitmaps and rate-specific stats for all rates in + * active table. + */ + } else { + lq_sta->table_count++; + if (lq_sta->table_count >= + lq_sta->table_count_limit) { + lq_sta->table_count = 0; + + IWL_DEBUG_RATE(sc, + "LQ: stay in table clear win\n"); + rs_rate_scale_clear_tbl_windows(sc, tbl); + } + } + + /* If transitioning to allow "search", reset all history + * bitmaps and stats in active table (this will become the new + * "search" table). */ + if (lq_sta->rs_state == RS_STATE_SEARCH_CYCLE_STARTED) { + rs_rate_scale_clear_tbl_windows(sc, tbl); + } + } +} + +static void rs_set_amsdu_len(struct iwm_softc *sc, struct ieee80211_node *ni, + struct iwl_scale_tbl_info *tbl, + enum rs_action scale_action) +{ +// struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); +// int i; +// +// sta->max_amsdu_len = rs_fw_get_max_amsdu_len(sta); +// +// /* +// * In case TLC offload is not active amsdu_enabled is either 0xFFFF +// * or 0, since there is no per-TID alg. +// */ +// if ((!is_vht(&tbl->rate) && !is_ht(&tbl->rate)) || +// tbl->rate.index < IWL_RATE_MCS_5_INDEX || +// scale_action == RS_ACTION_DOWNSCALE) +// mvmsta->amsdu_enabled = 0; +// else +// mvmsta->amsdu_enabled = 0xFFFF; +// +// if (mvmsta->vif->bss_conf.he_support && +// !iwlwifi_mod_params.disable_11ax) +// mvmsta->max_amsdu_len = sta->max_amsdu_len; +// else +// mvmsta->max_amsdu_len = min_t(int, sta->max_amsdu_len, 8500); +// +// sta->max_rc_amsdu_len = mvmsta->max_amsdu_len; +// +// for (i = 0; i < IWL_MAX_TID_COUNT; i++) { +// if (mvmsta->amsdu_enabled) +// sta->max_tid_amsdu_len[i] = +// iwl_mvm_max_amsdu_size(mvm, sta, i); +// else +// /* +// * Not so elegant, but this will effectively +// * prevent AMSDU on this TID +// */ +// sta->max_tid_amsdu_len[i] = 1; +// } + // TODO: IMP +} + +/** + * iwl_mvm_send_lq_cmd() - Send link quality command + * @mvm: Driver data. + * @lq: Link quality command to send. + * + * The link quality command is sent as the last step of station creation. + * This is the special case in which init is set and we call a callback in + * this case to clear the state indicating that station creation is in + * progress. + */ +int iwl_mvm_send_lq_cmd(struct iwm_softc *sc, struct iwm_lq_cmd *lq) +{ + ItlIwm *that = container_of(sc, ItlIwm, com); + + struct iwm_host_cmd cmd = { + .id = IWM_LQ_CMD, + .len = { sizeof(struct iwm_lq_cmd), }, + .flags = IWM_CMD_ASYNC, + .data = { lq, }, + }; + + return that->iwm_send_cmd(sc, &cmd);; +} + +/* + * setup rate table in uCode + */ +static void rs_update_rate_tbl(struct iwm_softc *sc, + struct ieee80211_node *ni, + struct iwl_lq_sta *lq_sta, + struct iwl_scale_tbl_info *tbl) +{ + rs_fill_lq_cmd(sc, ni, lq_sta, &tbl->rate); + iwl_mvm_send_lq_cmd(sc, &lq_sta->lq); +} + +static bool rs_tweak_rate_tbl(struct iwm_softc *sc, + struct ieee80211_node *ni, + struct iwl_lq_sta *lq_sta, + struct iwl_scale_tbl_info *tbl, + enum rs_action scale_action) +{ + if (rs_bw_from_sta_bw(ni) != RATE_MCS_CHAN_WIDTH_80) + return false; + + if (!is_vht_siso(&tbl->rate)) + return false; + + if ((tbl->rate.bw == RATE_MCS_CHAN_WIDTH_80) && + (tbl->rate.index == IWL_RATE_MCS_0_INDEX) && + (scale_action == RS_ACTION_DOWNSCALE)) { + tbl->rate.bw = RATE_MCS_CHAN_WIDTH_20; + tbl->rate.index = IWL_RATE_MCS_4_INDEX; + IWL_DEBUG_RATE(sc, "Switch 80Mhz SISO MCS0 -> 20Mhz MCS4\n"); + goto tweaked; + } + + /* Go back to 80Mhz MCS1 only if we've established that 20Mhz MCS5 is + * sustainable, i.e. we're past the test window. We can't go back + * if MCS5 is just tested as this will happen always after switching + * to 20Mhz MCS4 because the rate stats are cleared. + */ + if ((tbl->rate.bw == RATE_MCS_CHAN_WIDTH_20) && + (((tbl->rate.index == IWL_RATE_MCS_5_INDEX) && + (scale_action == RS_ACTION_STAY)) || + ((tbl->rate.index > IWL_RATE_MCS_5_INDEX) && + (scale_action == RS_ACTION_UPSCALE)))) { + tbl->rate.bw = RATE_MCS_CHAN_WIDTH_80; + tbl->rate.index = IWL_RATE_MCS_1_INDEX; + IWL_DEBUG_RATE(sc, "Switch 20Mhz SISO MCS5 -> 80Mhz MCS1\n"); + goto tweaked; + } + + return false; + +tweaked: + rs_set_expected_tpt_table(lq_sta, tbl); + rs_rate_scale_clear_tbl_windows(sc, tbl); + return true; +} + +static enum rs_column rs_get_next_column(struct iwm_softc *sc, + struct iwl_lq_sta *lq_sta, + struct ieee80211_node *ni, + struct iwl_scale_tbl_info *tbl) +{ + int i, j, max_rate; + enum rs_column next_col_id; + const struct rs_tx_column *curr_col = &rs_tx_columns[tbl->column]; + const struct rs_tx_column *next_col; + allow_column_func_t allow_func; + ItlIwm *that = container_of(sc, ItlIwm, com); + u8 valid_ants = that->iwm_fw_valid_tx_ant(sc); + const u16 *expected_tpt_tbl; + u16 tpt, max_expected_tpt; + + for (i = 0; i < MAX_NEXT_COLUMNS; i++) { + next_col_id = curr_col->next_columns[i]; + + if (next_col_id == RS_COLUMN_INVALID) + continue; + + if (lq_sta->visited_columns & BIT(next_col_id)) { + IWL_DEBUG_RATE(sc, "Skip already visited column %d\n", + next_col_id); + continue; + } + + next_col = &rs_tx_columns[next_col_id]; + + if (!rs_is_valid_ant(valid_ants, next_col->ant)) { + IWL_DEBUG_RATE(sc, + "Skip column %d as ANT config isn't supported by chip. valid_ants 0x%x column ant 0x%x\n", + next_col_id, valid_ants, next_col->ant); + continue; + } + + for (j = 0; j < MAX_COLUMN_CHECKS; j++) { + allow_func = next_col->checks[j]; + if (allow_func && !allow_func(sc, ni, &tbl->rate, + next_col)) + break; + } + + if (j != MAX_COLUMN_CHECKS) { + IWL_DEBUG_RATE(sc, + "Skip column %d: not allowed (check %d failed)\n", + next_col_id, j); + + continue; + } + + tpt = lq_sta->last_tpt / 100; + expected_tpt_tbl = rs_get_expected_tpt_table(lq_sta, next_col, + rs_bw_from_sta_bw(ni)); + if (WARN_ON_ONCE(!expected_tpt_tbl)) + continue; + + max_rate = rs_get_max_allowed_rate(lq_sta, next_col); + if (max_rate == IWL_RATE_INVALID) { + IWL_DEBUG_RATE(sc, + "Skip column %d: no rate is allowed in this column\n", + next_col_id); + continue; + } + + max_expected_tpt = expected_tpt_tbl[max_rate]; + if (tpt >= max_expected_tpt) { + IWL_DEBUG_RATE(sc, + "Skip column %d: can't beat current TPT. Max expected %d current %d\n", + next_col_id, max_expected_tpt, tpt); + continue; + } + + IWL_DEBUG_RATE(sc, + "Found potential column %d. Max expected %d current %d\n", + next_col_id, max_expected_tpt, tpt); + break; + } + + if (i == MAX_NEXT_COLUMNS) + return RS_COLUMN_INVALID; + + return next_col_id; +} + +static int rs_switch_to_column(struct iwm_softc *sc, + struct iwl_lq_sta *lq_sta, + struct ieee80211_node *ni, + enum rs_column col_id) +{ + struct iwl_scale_tbl_info *tbl = &lq_sta->lq_info[lq_sta->active_tbl]; + struct iwl_scale_tbl_info *search_tbl = + &lq_sta->lq_info[rs_search_tbl(lq_sta->active_tbl)]; + struct rs_rate *rate = &search_tbl->rate; + const struct rs_tx_column *column = &rs_tx_columns[col_id]; + const struct rs_tx_column *curr_column = &rs_tx_columns[tbl->column]; + unsigned long rate_mask = 0; + u32 rate_idx = 0; + + memcpy(search_tbl, tbl, offsetof(struct iwl_scale_tbl_info, win)); + + rate->sgi = column->sgi; + rate->ant = column->ant; + + if (column->mode == RS_LEGACY) { + if (lq_sta->band == NL80211_BAND_5GHZ) + rate->type = LQ_LEGACY_A; + else + rate->type = LQ_LEGACY_G; + + rate->bw = RATE_MCS_CHAN_WIDTH_20; + rate->ldpc = false; + rate_mask = lq_sta->active_legacy_rate; + } else if (column->mode == RS_SISO) { + rate->type = lq_sta->is_vht ? LQ_VHT_SISO : LQ_HT_SISO; + rate_mask = lq_sta->active_siso_rate; + } else if (column->mode == RS_MIMO2) { + rate->type = lq_sta->is_vht ? LQ_VHT_MIMO2 : LQ_HT_MIMO2; + rate_mask = lq_sta->active_mimo2_rate; + } else { + WARN_ON(1, "Bad column mode"); + } + + if (column->mode != RS_LEGACY) { + rate->bw = rs_bw_from_sta_bw(ni); + rate->ldpc = lq_sta->ldpc; + } + + search_tbl->column = col_id; + rs_set_expected_tpt_table(lq_sta, search_tbl); + + lq_sta->visited_columns |= BIT(col_id); + + /* Get the best matching rate if we're changing modes. e.g. + * SISO->MIMO, LEGACY->SISO, MIMO->SISO + */ + if (curr_column->mode != column->mode) { + rate_idx = rs_get_best_rate(sc, lq_sta, search_tbl, + rate_mask, rate->index); + + if ((rate_idx == IWL_RATE_INVALID) || + !(BIT(rate_idx) & rate_mask)) { + IWL_DEBUG_RATE(sc, + "can not switch with index %d" + " rate mask %lx\n", + rate_idx, rate_mask); + + goto err; + } + + rate->index = rate_idx; + } + + IWL_DEBUG_RATE(sc, "Switched to column %d: Index %d\n", + col_id, rate->index); + + return 0; + +err: + rate->type = LQ_NONE; + return -1; +} + +static enum rs_action rs_get_rate_action(struct iwm_softc *sc, + struct iwl_scale_tbl_info *tbl, + s32 sr, int low, int high, + int current_tpt, + int low_tpt, int high_tpt) +{ + enum rs_action action = RS_ACTION_STAY; + + if ((sr <= RS_PERCENT(IWL_MVM_RS_SR_FORCE_DECREASE)) || + (current_tpt == 0)) { + IWL_DEBUG_RATE(mvm, + "Decrease rate because of low SR\n"); + return RS_ACTION_DOWNSCALE; + } + + if ((low_tpt == IWL_INVALID_VALUE) && + (high_tpt == IWL_INVALID_VALUE) && + (high != IWL_RATE_INVALID)) { + IWL_DEBUG_RATE(mvm, + "No data about high/low rates. Increase rate\n"); + return RS_ACTION_UPSCALE; + } + + if ((high_tpt == IWL_INVALID_VALUE) && + (high != IWL_RATE_INVALID) && + (low_tpt != IWL_INVALID_VALUE) && + (low_tpt < current_tpt)) { + IWL_DEBUG_RATE(mvm, + "No data about high rate and low rate is worse. Increase rate\n"); + return RS_ACTION_UPSCALE; + } + + if ((high_tpt != IWL_INVALID_VALUE) && + (high_tpt > current_tpt)) { + IWL_DEBUG_RATE(mvm, + "Higher rate is better. Increate rate\n"); + return RS_ACTION_UPSCALE; + } + + if ((low_tpt != IWL_INVALID_VALUE) && + (high_tpt != IWL_INVALID_VALUE) && + (low_tpt < current_tpt) && + (high_tpt < current_tpt)) { + IWL_DEBUG_RATE(mvm, + "Both high and low are worse. Maintain rate\n"); + return RS_ACTION_STAY; + } + + if ((low_tpt != IWL_INVALID_VALUE) && + (low_tpt > current_tpt)) { + IWL_DEBUG_RATE(mvm, + "Lower rate is better\n"); + action = RS_ACTION_DOWNSCALE; + goto out; + } + + if ((low_tpt == IWL_INVALID_VALUE) && + (low != IWL_RATE_INVALID)) { + IWL_DEBUG_RATE(mvm, + "No data about lower rate\n"); + action = RS_ACTION_DOWNSCALE; + goto out; + } + + IWL_DEBUG_RATE(mvm, "Maintain rate\n"); + +out: + if ((action == RS_ACTION_DOWNSCALE) && (low != IWL_RATE_INVALID)) { + if (sr >= RS_PERCENT(IWL_MVM_RS_SR_NO_DECREASE)) { + IWL_DEBUG_RATE(mvm, + "SR is above NO DECREASE. Avoid downscale\n"); + action = RS_ACTION_STAY; + } else if (current_tpt > (100 * tbl->expected_tpt[low])) { + IWL_DEBUG_RATE(mvm, + "Current TPT is higher than max expected in low rate. Avoid downscale\n"); + action = RS_ACTION_STAY; + } else { + IWL_DEBUG_RATE(mvm, "Decrease rate\n"); + } + } + + return action; +} + +static bool rs_stbc_allow(struct iwm_softc *sc, struct ieee80211_node *ni, + struct iwl_lq_sta *lq_sta) +{ + /* Our chip supports Tx STBC and the peer is an HT/VHT STA which + * supports STBC of at least 1*SS + */ + if (!lq_sta->stbc_capable) + return false; + + if (!iwl_mvm_bt_coex_is_mimo_allowed(sc, ni)) + return false; + + return true; +} + +static void rs_get_adjacent_txp(struct iwm_softc *mvm, int index, + int *weaker, int *stronger) +{ + *weaker = index + IWL_MVM_RS_TPC_TX_POWER_STEP; + if (*weaker > TPC_MAX_REDUCTION) + *weaker = TPC_INVALID; + + *stronger = index - IWL_MVM_RS_TPC_TX_POWER_STEP; + if (*stronger < 0) + *stronger = TPC_INVALID; +} + +static bool iwl_mvm_bt_coex_is_tpc_allowed(struct iwm_softc *mvm, + enum nl80211_band band) +{ +// u32 bt_activity = le32_to_cpu(mvm->last_bt_notif.bt_activity_grading); +// + if (band != NL80211_BAND_2GHZ) + return false; +// +// return bt_activity >= BT_LOW_TRAFFIC; + return false; +} + +static bool rs_tpc_allowed(struct iwm_softc *mvm, + struct rs_rate *rate, enum nl80211_band band) +{ + int index = rate->index; + bool cam = /*(iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM)*/ false; + bool sta_ps_disabled = /*(vif->type == NL80211_IFTYPE_STATION && + !vif->bss_conf.ps)*/ true; + + IWL_DEBUG_RATE(mvm, "cam: %d sta_ps_disabled %d\n", + cam, sta_ps_disabled); + /* + * allow tpc only if power management is enabled, or bt coex + * activity grade allows it and we are on 2.4Ghz. + */ + if ((cam || sta_ps_disabled) && + !iwl_mvm_bt_coex_is_tpc_allowed(mvm, band)) + return false; + + IWL_DEBUG_RATE(mvm, "check rate, table type: %d\n", rate->type); + if (is_legacy(rate)) + return index == IWL_RATE_54M_INDEX; + if (is_ht(rate)) + return index == IWL_RATE_MCS_7_INDEX; + if (is_vht(rate)) + return index == IWL_RATE_MCS_9_INDEX; + + WARN_ON_ONCE(1); + return false; +} + +enum tpc_action { + TPC_ACTION_STAY, + TPC_ACTION_DECREASE, + TPC_ACTION_INCREASE, + TPC_ACTION_NO_RESTIRCTION, +}; + +static enum tpc_action rs_get_tpc_action(struct iwm_softc *mvm, + s32 sr, int weak, int strong, + int current_tpt, + int weak_tpt, int strong_tpt) +{ + /* stay until we have valid tpt */ + if (current_tpt == IWL_INVALID_VALUE) { + IWL_DEBUG_RATE(mvm, "no current tpt. stay.\n"); + return TPC_ACTION_STAY; + } + + /* Too many failures, increase txp */ + if (sr <= RS_PERCENT(IWL_MVM_RS_TPC_SR_FORCE_INCREASE) || + current_tpt == 0) { + IWL_DEBUG_RATE(mvm, "increase txp because of weak SR\n"); + return TPC_ACTION_NO_RESTIRCTION; + } + + /* try decreasing first if applicable */ + if (sr >= RS_PERCENT(IWL_MVM_RS_TPC_SR_NO_INCREASE) && + weak != TPC_INVALID) { + if (weak_tpt == IWL_INVALID_VALUE && + (strong_tpt == IWL_INVALID_VALUE || + current_tpt >= strong_tpt)) { + IWL_DEBUG_RATE(mvm, + "no weak txp measurement. decrease txp\n"); + return TPC_ACTION_DECREASE; + } + + if (weak_tpt > current_tpt) { + IWL_DEBUG_RATE(mvm, + "lower txp has better tpt. decrease txp\n"); + return TPC_ACTION_DECREASE; + } + } + + /* next, increase if needed */ + if (sr < RS_PERCENT(IWL_MVM_RS_TPC_SR_NO_INCREASE) && + strong != TPC_INVALID) { + if (weak_tpt == IWL_INVALID_VALUE && + strong_tpt != IWL_INVALID_VALUE && + current_tpt < strong_tpt) { + IWL_DEBUG_RATE(mvm, + "higher txp has better tpt. increase txp\n"); + return TPC_ACTION_INCREASE; + } + + if (weak_tpt < current_tpt && + (strong_tpt == IWL_INVALID_VALUE || + strong_tpt > current_tpt)) { + IWL_DEBUG_RATE(mvm, + "lower txp has worse tpt. increase txp\n"); + return TPC_ACTION_INCREASE; + } + } + + IWL_DEBUG_RATE(mvm, "no need to increase or decrease txp - stay\n"); + return TPC_ACTION_STAY; +} + +static bool rs_tpc_perform(struct iwm_softc *mvm, + struct ieee80211_node *ni, + struct iwl_lq_sta *lq_sta, + struct iwl_scale_tbl_info *tbl) +{ + enum nl80211_band band; + struct iwl_rate_scale_data *window; + struct rs_rate *rate = &tbl->rate; + enum tpc_action action; + s32 sr; + u8 cur = lq_sta->lq.reduced_tpc; + int current_tpt; + int weak, strong; + int weak_tpt = IWL_INVALID_VALUE, strong_tpt = IWL_INVALID_VALUE; + + if (WARN_ON(!ni->ni_chan)) + band = NUM_NL80211_BANDS; + else + band = IEEE80211_IS_CHAN_2GHZ(ni->ni_chan) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ; + + if (!rs_tpc_allowed(mvm, rate, band)) { + IWL_DEBUG_RATE(mvm, + "tpc is not allowed. remove txp restrictions\n"); + lq_sta->lq.reduced_tpc = TPC_NO_REDUCTION; + return cur != TPC_NO_REDUCTION; + } + + rs_get_adjacent_txp(mvm, cur, &weak, &strong); + + /* Collect measured throughputs for current and adjacent rates */ + window = tbl->tpc_win; + sr = window[cur].success_ratio; + current_tpt = window[cur].average_tpt; + if (weak != TPC_INVALID) + weak_tpt = window[weak].average_tpt; + if (strong != TPC_INVALID) + strong_tpt = window[strong].average_tpt; + + IWL_DEBUG_RATE(mvm, + "(TPC: %d): cur_tpt %d SR %d weak %d strong %d weak_tpt %d strong_tpt %d\n", + cur, current_tpt, sr, weak, strong, + weak_tpt, strong_tpt); + + action = rs_get_tpc_action(mvm, sr, weak, strong, + current_tpt, weak_tpt, strong_tpt); + + /* override actions if we are on the edge */ + if (weak == TPC_INVALID && action == TPC_ACTION_DECREASE) { + IWL_DEBUG_RATE(mvm, "already in lowest txp, stay\n"); + action = TPC_ACTION_STAY; + } else if (strong == TPC_INVALID && + (action == TPC_ACTION_INCREASE || + action == TPC_ACTION_NO_RESTIRCTION)) { + IWL_DEBUG_RATE(mvm, "already in highest txp, stay\n"); + action = TPC_ACTION_STAY; + } + + switch (action) { + case TPC_ACTION_DECREASE: + lq_sta->lq.reduced_tpc = weak; + return true; + case TPC_ACTION_INCREASE: + lq_sta->lq.reduced_tpc = strong; + return true; + case TPC_ACTION_NO_RESTIRCTION: + lq_sta->lq.reduced_tpc = TPC_NO_REDUCTION; + return true; + case TPC_ACTION_STAY: + /* do nothing */ + break; + } + return false; +} + +/* + * Do rate scaling and search for new modulation mode. + */ +static void rs_rate_scale_perform(struct iwm_softc *mvm, + struct ieee80211_node *ni, + struct iwl_lq_sta *lq_sta, + int tid, bool ndp) +{ + int low = IWL_RATE_INVALID; + int high = IWL_RATE_INVALID; + int index; + struct iwl_rate_scale_data *window = NULL; + int current_tpt = IWL_INVALID_VALUE; + int low_tpt = IWL_INVALID_VALUE; + int high_tpt = IWL_INVALID_VALUE; + u32 fail_count; + enum rs_action scale_action = RS_ACTION_STAY; + u16 rate_mask; + u8 update_lq = 0; + struct iwl_scale_tbl_info *tbl, *tbl1; + u8 active_tbl = 0; + u8 done_search = 0; + u16 high_low; + s32 sr; + u8 prev_agg = lq_sta->is_agg; + struct rs_rate *rate; + + lq_sta->is_agg = (mvm->sc_tx_ba[EDCA_AC_BE].wn != NULL || + mvm->sc_tx_ba[EDCA_AC_BK].wn != NULL || + mvm->sc_tx_ba[EDCA_AC_VI].wn != NULL || + mvm->sc_tx_ba[EDCA_AC_VO].wn != NULL); + + /* + * Select rate-scale / modulation-mode table to work with in + * the rest of this function: "search" if searching for better + * modulation mode, or "active" if doing rate scaling within a mode. + */ + if (!lq_sta->search_better_tbl) + active_tbl = lq_sta->active_tbl; + else + active_tbl = rs_search_tbl(lq_sta->active_tbl); + + tbl = &(lq_sta->lq_info[active_tbl]); + rate = &tbl->rate; + + if (prev_agg != lq_sta->is_agg) { + IWL_DEBUG_RATE(mvm, + "Aggregation changed: prev %d current %d. Update expected TPT table\n", + prev_agg, lq_sta->is_agg); + rs_set_expected_tpt_table(lq_sta, tbl); + rs_rate_scale_clear_tbl_windows(mvm, tbl); + } + + /* current tx rate */ + index = rate->index; + + /* rates available for this association, and for modulation mode */ + rate_mask = rs_get_supported_rates(lq_sta, rate); + + if (!(BIT(index) & rate_mask)) { + IWL_ERR(mvm, "Current Rate is not valid\n"); + if (lq_sta->search_better_tbl) { + /* revert to active table if search table is not valid*/ + rate->type = LQ_NONE; + lq_sta->search_better_tbl = 0; + tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); + rs_update_rate_tbl(mvm, ni, lq_sta, tbl); + } + return; + } + + /* Get expected throughput table and history window for current rate */ + if (!tbl->expected_tpt) { + IWL_ERR(mvm, "tbl->expected_tpt is NULL\n"); + return; + } + + /* TODO: handle rate_idx_mask and rate_idx_mcs_mask */ + window = &(tbl->win[index]); + + /* + * If there is not enough history to calculate actual average + * throughput, keep analyzing results of more tx frames, without + * changing rate or mode (bypass most of the rest of this function). + * Set up new rate table in uCode only if old rate is not supported + * in current association (use new rate found above). + */ + fail_count = window->counter - window->success_counter; + if ((fail_count < IWL_MVM_RS_RATE_MIN_FAILURE_TH) && + (window->success_counter < IWL_MVM_RS_RATE_MIN_SUCCESS_TH)) { + IWL_DEBUG_RATE(mvm, + "%s: Test Window: succ %d total %d\n", + rs_pretty_rate(rate), + window->success_counter, window->counter); + + /* Can't calculate this yet; not enough history */ + window->average_tpt = IWL_INVALID_VALUE; + + /* Should we stay with this modulation mode, + * or search for a new one? */ + rs_stay_in_table(lq_sta, false); + + return; + } + + /* If we are searching for better modulation mode, check success. */ + if (lq_sta->search_better_tbl) { + /* If good success, continue using the "search" mode; + * no need to send new link quality command, since we're + * continuing to use the setup that we've been trying. */ + if (window->average_tpt > lq_sta->last_tpt) { + IWL_DEBUG_RATE(mvm, + "SWITCHING TO NEW TABLE SR: %d " + "cur-tpt %d old-tpt %d\n", + window->success_ratio, + window->average_tpt, + lq_sta->last_tpt); + + /* Swap tables; "search" becomes "active" */ + lq_sta->active_tbl = active_tbl; + current_tpt = window->average_tpt; + /* Else poor success; go back to mode in "active" table */ + } else { + IWL_DEBUG_RATE(mvm, + "GOING BACK TO THE OLD TABLE: SR %d " + "cur-tpt %d old-tpt %d\n", + window->success_ratio, + window->average_tpt, + lq_sta->last_tpt); + + /* Nullify "search" table */ + rate->type = LQ_NONE; + + /* Revert to "active" table */ + active_tbl = lq_sta->active_tbl; + tbl = &(lq_sta->lq_info[active_tbl]); + + /* Revert to "active" rate and throughput info */ + index = tbl->rate.index; + current_tpt = lq_sta->last_tpt; + + /* Need to set up a new rate table in uCode */ + update_lq = 1; + } + + /* Either way, we've made a decision; modulation mode + * search is done, allow rate adjustment next time. */ + lq_sta->search_better_tbl = 0; + done_search = 1; /* Don't switch modes below! */ + goto lq_update; + } + + /* (Else) not in search of better modulation mode, try for better + * starting rate, while staying in this mode. */ + high_low = rs_get_adjacent_rate(mvm, index, rate_mask, rate->type); + low = high_low & 0xff; + high = (high_low >> 8) & 0xff; + + /* TODO: handle rate_idx_mask and rate_idx_mcs_mask */ + + sr = window->success_ratio; + + /* Collect measured throughputs for current and adjacent rates */ + current_tpt = window->average_tpt; + if (low != IWL_RATE_INVALID) + low_tpt = tbl->win[low].average_tpt; + if (high != IWL_RATE_INVALID) + high_tpt = tbl->win[high].average_tpt; + + IWL_DEBUG_RATE(mvm, + "%s: cur_tpt %d SR %d low %d high %d low_tpt %d high_tpt %d\n", + rs_pretty_rate(rate), current_tpt, sr, + low, high, low_tpt, high_tpt); + + scale_action = rs_get_rate_action(mvm, tbl, sr, low, high, + current_tpt, low_tpt, high_tpt); + + /* Force a search in case BT doesn't like us being in MIMO */ + if (is_mimo(rate) && + !iwl_mvm_bt_coex_is_mimo_allowed(mvm, ni)) { + IWL_DEBUG_RATE(mvm, + "BT Coex forbids MIMO. Search for new config\n"); + rs_stay_in_table(lq_sta, true); + goto lq_update; + } + + switch (scale_action) { + case RS_ACTION_DOWNSCALE: + /* Decrease starting rate, update uCode's rate table */ + if (low != IWL_RATE_INVALID) { + update_lq = 1; + index = low; + } else { + IWL_DEBUG_RATE(mvm, + "At the bottom rate. Can't decrease\n"); + } + + break; + case RS_ACTION_UPSCALE: + /* Increase starting rate, update uCode's rate table */ + if (high != IWL_RATE_INVALID) { + update_lq = 1; + index = high; + } else { + IWL_DEBUG_RATE(mvm, + "At the top rate. Can't increase\n"); + } + + break; + case RS_ACTION_STAY: + /* No change */ + if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN) + update_lq = rs_tpc_perform(mvm, ni, lq_sta, tbl); + break; + default: + break; + } + +lq_update: + /* Replace uCode's rate table for the destination station. */ + if (update_lq) { + tbl->rate.index = index; + if (IWL_MVM_RS_80_20_FAR_RANGE_TWEAK) + rs_tweak_rate_tbl(mvm, ni, lq_sta, tbl, scale_action); + rs_set_amsdu_len(mvm, ni, tbl, scale_action); + rs_update_rate_tbl(mvm, ni, lq_sta, tbl); + } + + rs_stay_in_table(lq_sta, false); + + /* + * Search for new modulation mode if we're: + * 1) Not changing rates right now + * 2) Not just finishing up a search + * 3) Allowing a new search + */ + if (!update_lq && !done_search && + lq_sta->rs_state == RS_STATE_SEARCH_CYCLE_STARTED + && window->counter) { + enum rs_column next_column; + + /* Save current throughput to compare with "search" throughput*/ + lq_sta->last_tpt = current_tpt; + + IWL_DEBUG_RATE(mvm, + "Start Search: update_lq %d done_search %d rs_state %d win->counter %d\n", + update_lq, done_search, lq_sta->rs_state, + window->counter); + + next_column = rs_get_next_column(mvm, lq_sta, ni, tbl); + if (next_column != RS_COLUMN_INVALID) { + int ret = rs_switch_to_column(mvm, lq_sta, ni, + next_column); + if (!ret) + lq_sta->search_better_tbl = 1; + } else { + IWL_DEBUG_RATE(mvm, + "No more columns to explore in search cycle. Go to RS_STATE_SEARCH_CYCLE_ENDED\n"); + lq_sta->rs_state = RS_STATE_SEARCH_CYCLE_ENDED; + } + + /* If new "search" mode was selected, set up in uCode table */ + if (lq_sta->search_better_tbl) { + /* Access the "search" table, clear its history. */ + tbl = &lq_sta->lq_info[rs_search_tbl(lq_sta->active_tbl)]; + rs_rate_scale_clear_tbl_windows(mvm, tbl); + + /* Use new "search" start rate */ + index = tbl->rate.index; + + rs_dump_rate(mvm, &tbl->rate, + "Switch to SEARCH TABLE:"); + rs_update_rate_tbl(mvm, ni, lq_sta, tbl); + } else { + done_search = 1; + } + } + + if (!ndp) + rs_tl_turn_on_agg(mvm, tid, lq_sta, ni); + + if (done_search && lq_sta->rs_state == RS_STATE_SEARCH_CYCLE_ENDED) { + tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]); + rs_set_stay_in_table(mvm, is_legacy(&tbl1->rate), lq_sta); + } +} + +struct rs_init_rate_info { + s8 rssi; + u8 rate_idx; +}; + +static const struct rs_init_rate_info rs_optimal_rates_24ghz_legacy[] = { + { -60, IWL_RATE_54M_INDEX }, + { -64, IWL_RATE_48M_INDEX }, + { -68, IWL_RATE_36M_INDEX }, + { -80, IWL_RATE_24M_INDEX }, + { -84, IWL_RATE_18M_INDEX }, + { -85, IWL_RATE_12M_INDEX }, + { -86, IWL_RATE_11M_INDEX }, + { -88, IWL_RATE_5M_INDEX }, + { -90, IWL_RATE_2M_INDEX }, + { S8_MIN, IWL_RATE_1M_INDEX }, +}; + +static const struct rs_init_rate_info rs_optimal_rates_5ghz_legacy[] = { + { -60, IWL_RATE_54M_INDEX }, + { -64, IWL_RATE_48M_INDEX }, + { -72, IWL_RATE_36M_INDEX }, + { -80, IWL_RATE_24M_INDEX }, + { -84, IWL_RATE_18M_INDEX }, + { -85, IWL_RATE_12M_INDEX }, + { -87, IWL_RATE_9M_INDEX }, + { S8_MIN, IWL_RATE_6M_INDEX }, +}; + +static const struct rs_init_rate_info rs_optimal_rates_ht[] = { + { -60, IWL_RATE_MCS_7_INDEX }, + { -64, IWL_RATE_MCS_6_INDEX }, + { -68, IWL_RATE_MCS_5_INDEX }, + { -72, IWL_RATE_MCS_4_INDEX }, + { -80, IWL_RATE_MCS_3_INDEX }, + { -84, IWL_RATE_MCS_2_INDEX }, + { -85, IWL_RATE_MCS_1_INDEX }, + { S8_MIN, IWL_RATE_MCS_0_INDEX}, +}; + +/* MCS index 9 is not valid for 20MHz VHT channel width, + * but is ok for 40, 80 and 160MHz channels. + */ +static const struct rs_init_rate_info rs_optimal_rates_vht_20mhz[] = { + { -60, IWL_RATE_MCS_8_INDEX }, + { -64, IWL_RATE_MCS_7_INDEX }, + { -68, IWL_RATE_MCS_6_INDEX }, + { -72, IWL_RATE_MCS_5_INDEX }, + { -80, IWL_RATE_MCS_4_INDEX }, + { -84, IWL_RATE_MCS_3_INDEX }, + { -85, IWL_RATE_MCS_2_INDEX }, + { -87, IWL_RATE_MCS_1_INDEX }, + { S8_MIN, IWL_RATE_MCS_0_INDEX}, +}; + +static const struct rs_init_rate_info rs_optimal_rates_vht[] = { + { -60, IWL_RATE_MCS_9_INDEX }, + { -64, IWL_RATE_MCS_8_INDEX }, + { -68, IWL_RATE_MCS_7_INDEX }, + { -72, IWL_RATE_MCS_6_INDEX }, + { -80, IWL_RATE_MCS_5_INDEX }, + { -84, IWL_RATE_MCS_4_INDEX }, + { -85, IWL_RATE_MCS_3_INDEX }, + { -87, IWL_RATE_MCS_2_INDEX }, + { -88, IWL_RATE_MCS_1_INDEX }, + { S8_MIN, IWL_RATE_MCS_0_INDEX }, +}; + +#define IWL_RS_LOW_RSSI_THRESHOLD (-76) /* dBm */ + +/* Init the optimal rate based on STA caps + * This combined with rssi is used to report the last tx rate + * to userspace when we haven't transmitted enough frames. + */ +static void rs_init_optimal_rate(struct iwm_softc *mvm, + struct ieee80211_node *sta, + struct iwl_lq_sta *lq_sta) +{ + struct rs_rate *rate = &lq_sta->optimal_rate; + + if (lq_sta->max_mimo2_rate_idx != IWL_RATE_INVALID) + rate->type = lq_sta->is_vht ? LQ_VHT_MIMO2 : LQ_HT_MIMO2; + else if (lq_sta->max_siso_rate_idx != IWL_RATE_INVALID) + rate->type = lq_sta->is_vht ? LQ_VHT_SISO : LQ_HT_SISO; + else if (lq_sta->band == NL80211_BAND_5GHZ) + rate->type = LQ_LEGACY_A; + else + rate->type = LQ_LEGACY_G; + + rate->bw = rs_bw_from_sta_bw(sta); + rate->sgi = rs_sgi_allow(mvm, sta, rate, NULL); + + /* ANT/LDPC/STBC aren't relevant for the rate reported to userspace */ + + if (is_mimo(rate)) { + lq_sta->optimal_rate_mask = lq_sta->active_mimo2_rate; + } else if (is_siso(rate)) { + lq_sta->optimal_rate_mask = lq_sta->active_siso_rate; + } else { + lq_sta->optimal_rate_mask = lq_sta->active_legacy_rate; + + if (lq_sta->band == NL80211_BAND_5GHZ) { + lq_sta->optimal_rates = rs_optimal_rates_5ghz_legacy; + lq_sta->optimal_nentries = + ARRAY_SIZE(rs_optimal_rates_5ghz_legacy); + } else { + lq_sta->optimal_rates = rs_optimal_rates_24ghz_legacy; + lq_sta->optimal_nentries = + ARRAY_SIZE(rs_optimal_rates_24ghz_legacy); + } + } + + if (is_vht(rate)) { + if (rate->bw == RATE_MCS_CHAN_WIDTH_20) { + lq_sta->optimal_rates = rs_optimal_rates_vht_20mhz; + lq_sta->optimal_nentries = + ARRAY_SIZE(rs_optimal_rates_vht_20mhz); + } else { + lq_sta->optimal_rates = rs_optimal_rates_vht; + lq_sta->optimal_nentries = + ARRAY_SIZE(rs_optimal_rates_vht); + } + } else if (is_ht(rate)) { + lq_sta->optimal_rates = rs_optimal_rates_ht; + lq_sta->optimal_nentries = ARRAY_SIZE(rs_optimal_rates_ht); + } +} + +/* Compute the optimal rate index based on RSSI */ +static struct rs_rate *rs_get_optimal_rate(struct iwm_softc *mvm, + struct iwl_lq_sta *lq_sta) +{ + struct rs_rate *rate = &lq_sta->optimal_rate; + int i; + + rate->index = find_first_bit(&lq_sta->optimal_rate_mask, + BITS_PER_LONG); + + for (i = 0; i < lq_sta->optimal_nentries; i++) { + int rate_idx = lq_sta->optimal_rates[i].rate_idx; + + if ((lq_sta->pers.last_rssi >= lq_sta->optimal_rates[i].rssi) && + (BIT(rate_idx) & lq_sta->optimal_rate_mask)) { + rate->index = rate_idx; + break; + } + } + + return rate; +} + +/* Choose an initial legacy rate and antenna to use based on the RSSI + * of last Rx + */ +static void rs_get_initial_rate(struct iwm_softc *mvm, + struct ieee80211_node *sta, + struct iwl_lq_sta *lq_sta, + enum nl80211_band band, + struct rs_rate *rate) +{ + int i, nentries; + unsigned long active_rate; + s8 best_rssi = S8_MIN; + u8 best_ant = ANT_NONE; + ItlIwm *that = container_of(mvm, ItlIwm, com); + u8 valid_tx_ant = that->iwm_fw_valid_tx_ant(mvm); + const struct rs_init_rate_info *initial_rates; + + for (i = 0; i < ARRAY_SIZE(lq_sta->pers.chain_signal); i++) { + if (!(lq_sta->pers.chains & BIT(i))) + continue; + + if (lq_sta->pers.chain_signal[i] > best_rssi) { + best_rssi = lq_sta->pers.chain_signal[i]; + best_ant = BIT(i); + } + } + + IWL_DEBUG_RATE(mvm, "Best ANT: %s Best RSSI: %d\n", + rs_pretty_ant(best_ant), best_rssi); + + if (best_ant != ANT_A && best_ant != ANT_B) + rate->ant = first_antenna(valid_tx_ant); + else + rate->ant = best_ant; + + rate->sgi = false; + rate->ldpc = false; + rate->bw = RATE_MCS_CHAN_WIDTH_20; + + rate->index = find_first_bit(&lq_sta->active_legacy_rate, + BITS_PER_LONG); + + if (band == NL80211_BAND_5GHZ) { + rate->type = LQ_LEGACY_A; + initial_rates = rs_optimal_rates_5ghz_legacy; + nentries = ARRAY_SIZE(rs_optimal_rates_5ghz_legacy); + } else { + rate->type = LQ_LEGACY_G; + initial_rates = rs_optimal_rates_24ghz_legacy; + nentries = ARRAY_SIZE(rs_optimal_rates_24ghz_legacy); + } + + if (!IWL_MVM_RS_RSSI_BASED_INIT_RATE) + goto out; + + /* Start from a higher rate if the corresponding debug capability + * is enabled. The rate is chosen according to AP capabilities. + * In case of VHT/HT when the rssi is low fallback to the case of + * legacy rates. + */ + if (ieee80211_node_supports_vht(sta) && + best_rssi > IWL_RS_LOW_RSSI_THRESHOLD) { + /* + * In AP mode, when a new station associates, rs is initialized + * immediately upon association completion, before the phy + * context is updated with the association parameters, so the + * sta bandwidth might be wider than the phy context allows. + * To avoid this issue, always initialize rs with 20mhz + * bandwidth rate, and after authorization, when the phy context + * is already up-to-date, re-init rs with the correct bw. + */ + u32 bw = mvm->sc_ic.ic_state < IEEE80211_S_RUN ? + RATE_MCS_CHAN_WIDTH_20 : rs_bw_from_sta_bw(sta); + + switch (bw) { + case RATE_MCS_CHAN_WIDTH_40: + case RATE_MCS_CHAN_WIDTH_80: + case RATE_MCS_CHAN_WIDTH_160: + initial_rates = rs_optimal_rates_vht; + nentries = ARRAY_SIZE(rs_optimal_rates_vht); + break; + case RATE_MCS_CHAN_WIDTH_20: + initial_rates = rs_optimal_rates_vht_20mhz; + nentries = ARRAY_SIZE(rs_optimal_rates_vht_20mhz); + break; + default: + IWL_ERR(mvm, "Invalid BW %d\n", sta->ni_chw); + goto out; + } + + active_rate = lq_sta->active_siso_rate; + rate->type = LQ_VHT_SISO; + rate->bw = bw; + } else if (ieee80211_node_supports_ht(sta) && + best_rssi > IWL_RS_LOW_RSSI_THRESHOLD) { + initial_rates = rs_optimal_rates_ht; + nentries = ARRAY_SIZE(rs_optimal_rates_ht); + active_rate = lq_sta->active_siso_rate; + rate->type = LQ_HT_SISO; + } else { + active_rate = lq_sta->active_legacy_rate; + } + + for (i = 0; i < nentries; i++) { + int rate_idx = initial_rates[i].rate_idx; + + if ((best_rssi >= initial_rates[i].rssi) && + (BIT(rate_idx) & active_rate)) { + rate->index = rate_idx; + break; + } + } + +out: + rs_dump_rate(mvm, rate, "INITIAL"); +} + +/* Save info about RSSI of last Rx */ +void rs_update_last_rssi(struct iwm_softc *mvm, + struct ieee80211_rx_status *rx_status) +{ + struct iwl_lq_sta *lq_sta = &mvm->lq_sta.rs_drv; + int i; + + lq_sta->pers.chains = rx_status->chains; + lq_sta->pers.chain_signal[0] = rx_status->chain_signal[0]; + lq_sta->pers.chain_signal[1] = rx_status->chain_signal[1]; + lq_sta->pers.chain_signal[2] = rx_status->chain_signal[2]; + lq_sta->pers.last_rssi = S8_MIN; + + for (i = 0; i < ARRAY_SIZE(lq_sta->pers.chain_signal); i++) { + if (!(lq_sta->pers.chains & BIT(i))) + continue; + + if (lq_sta->pers.chain_signal[i] > lq_sta->pers.last_rssi) + lq_sta->pers.last_rssi = lq_sta->pers.chain_signal[i]; + } +} + +/* + * rs_initialize_lq - Initialize a station's hardware rate table + * + * The uCode's station table contains a table of fallback rates + * for automatic fallback during transmission. + * + * NOTE: This sets up a default set of values. These will be replaced later + * if the driver's iwl-agn-rs rate scaling algorithm is used, instead of + * rc80211_simple. + * + * NOTE: Run REPLY_ADD_STA command to set up station table entry, before + * calling this function (which runs REPLY_TX_LINK_QUALITY_CMD, + * which requires station table entry to exist). + */ +static void rs_initialize_lq(struct iwm_softc *mvm, + struct ieee80211_node *sta, + struct iwl_lq_sta *lq_sta, + enum nl80211_band band) +{ + struct iwl_scale_tbl_info *tbl; + struct rs_rate *rate; + u8 active_tbl = 0; + + if (!sta || !lq_sta) + return; + + if (!lq_sta->search_better_tbl) + active_tbl = lq_sta->active_tbl; + else + active_tbl = rs_search_tbl(lq_sta->active_tbl); + + tbl = &(lq_sta->lq_info[active_tbl]); + rate = &tbl->rate; + + rs_get_initial_rate(mvm, sta, lq_sta, band, rate); + rs_init_optimal_rate(mvm, sta, lq_sta); + + WARN_ON(rate->ant != ANT_A && rate->ant != ANT_B, + "ant: 0x%x, chains 0x%x, fw tx ant: 0x%x, nvm tx ant: 0x%x\n", + rate->ant, lq_sta->pers.chains, mvm->fw->valid_tx_ant, + mvm->nvm_data ? mvm->nvm_data->valid_tx_ant : ANT_INVALID); + + tbl->column = rs_get_column_from_rate(rate); + + rs_set_expected_tpt_table(lq_sta, tbl); + rs_fill_lq_cmd(mvm, sta, lq_sta, rate); + /* TODO restore station should remember the lq cmd */ + iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq); +} + +static void rs_drv_get_rate(struct iwm_softc *mvm, struct ieee80211_node *sta, + struct ieee80211_tx_rate *r) +{ + struct iwl_lq_sta *lq_sta; + struct rs_rate *optimal_rate; + u32 last_ucode_rate; + + if (sta) { + /* if vif isn't initialized mvm doesn't know about + * this station, so don't do anything with the it + */ + sta = NULL; + } + + lq_sta = &mvm->lq_sta.rs_drv; + iwl_mvm_hwrate_to_tx_rate(lq_sta->last_rate_n_flags, + IEEE80211_IS_CHAN_2GHZ(sta->ni_chan) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ, r); + + /* Report the optimal rate based on rssi and STA caps if we haven't + * converged yet (too little traffic) or exploring other modulations + */ + if (lq_sta->rs_state != RS_STATE_STAY_IN_COLUMN) { + optimal_rate = rs_get_optimal_rate(mvm, lq_sta); + last_ucode_rate = ucode_rate_from_rs_rate(mvm, + optimal_rate); + iwl_mvm_hwrate_to_tx_rate(last_ucode_rate, IEEE80211_IS_CHAN_2GHZ(sta->ni_chan) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ, + r); + } +} + +void *rs_drv_alloc_sta(iwm_softc *sc, struct ieee80211_node *ni) +{ + struct iwl_lq_sta *lq_sta = &sc->lq_sta.rs_drv; + + IWL_DEBUG_RATE(mvm, "create station rate scale window\n"); + + lq_sta->pers.drv = sc; + lq_sta->pers.chains = 0; + memset(lq_sta->pers.chain_signal, 0, sizeof(lq_sta->pers.chain_signal)); + lq_sta->pers.last_rssi = S8_MIN; + + return lq_sta; +} + +void rs_drv_free_sta(iwm_softc *sc, struct ieee80211_node *ni) +{} + +static int rs_vht_highest_rx_mcs_index(struct ieee80211_node *sta, + int nss) +{ + u16 rx_mcs = le16_to_cpu(sta->ni_ic->ic_bss->ni_vht_mcsinfo.rx_mcs_map) & + (0x3 << (2 * (nss - 1))); + rx_mcs >>= (2 * (nss - 1)); + + if (rx_mcs == IEEE80211_VHT_MCS_SUPPORT_0_7) + return IWL_RATE_MCS_7_INDEX; + else if (rx_mcs == IEEE80211_VHT_MCS_SUPPORT_0_8) + return IWL_RATE_MCS_8_INDEX; + else if (rx_mcs == IEEE80211_VHT_MCS_SUPPORT_0_9) + return IWL_RATE_MCS_9_INDEX; + + WARN_ON_ONCE(rx_mcs != IEEE80211_VHT_MCS_NOT_SUPPORTED); + return -1; +} + +static void rs_vht_set_enabled_rates(struct ieee80211_node *sta, + struct iwl_lq_sta *lq_sta) +{ + int i; + int highest_mcs = rs_vht_highest_rx_mcs_index(sta, 1); + + if (highest_mcs >= IWL_RATE_MCS_0_INDEX) { + for (i = IWL_RATE_MCS_0_INDEX; i <= highest_mcs; i++) { + if (i == IWL_RATE_9M_INDEX) + continue; + + /* VHT MCS9 isn't valid for 20Mhz for NSS=1,2 */ + if (i == IWL_RATE_MCS_9_INDEX && + sta->ni_chw == IEEE80211_CHAN_WIDTH_20) + continue; + + lq_sta->active_siso_rate |= BIT(i); + } + } + + if (sta->ni_rx_nss < 2) + return; + + highest_mcs = rs_vht_highest_rx_mcs_index(sta, 2); + if (highest_mcs >= IWL_RATE_MCS_0_INDEX) { + for (i = IWL_RATE_MCS_0_INDEX; i <= highest_mcs; i++) { + if (i == IWL_RATE_9M_INDEX) + continue; + + /* VHT MCS9 isn't valid for 20Mhz for NSS=1,2 */ + if (i == IWL_RATE_MCS_9_INDEX && + sta->ni_chw == IEEE80211_CHAN_WIDTH_20) + continue; + + lq_sta->active_mimo2_rate |= BIT(i); + } + } +} + +static void rs_ht_init(struct iwm_softc *mvm, + struct ieee80211_node *sta, + struct iwl_lq_sta *lq_sta) +{ + ItlIwm *that = container_of(mvm, ItlIwm, com); + /* active_siso_rate mask includes 9 MBits (bit 5), + * and CCK (bits 0-3), supp_rates[] does not; + * shift to convert format, force 9 MBits off. + */ + lq_sta->active_siso_rate = sta->ni_rxmcs[0] << 1; + lq_sta->active_siso_rate |= sta->ni_rxmcs[0] & 0x1; + lq_sta->active_siso_rate &= ~((u16)0x2); + lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE; + + lq_sta->active_mimo2_rate = sta->ni_rxmcs[1] << 1; + lq_sta->active_mimo2_rate |= sta->ni_rxmcs[1] & 0x1; + lq_sta->active_mimo2_rate &= ~((u16)0x2); + lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE; + + if ((sta->ni_htcaps & IEEE80211_HTCAP_LDPC)) + lq_sta->ldpc = true; + + if ((num_of_ant(that->iwm_fw_valid_tx_ant(mvm)) > 1) && + (sta->ni_htcaps & IEEE80211_HTCAP_RXSTBC_MASK)) + lq_sta->stbc_capable = true; + + lq_sta->is_vht = false; +} + +static void rs_vht_init(struct iwm_softc *mvm, + struct ieee80211_node *sta, + struct iwl_lq_sta *lq_sta) +{ + ItlIwm *that = container_of(mvm, ItlIwm, com); + rs_vht_set_enabled_rates(sta, lq_sta); + + if ((sta->ni_vhtcaps & IEEE80211_VHTCAP_RXLDPC)) + lq_sta->ldpc = true; + + if ((num_of_ant(that->iwm_fw_valid_tx_ant(mvm)) > 1) && + (sta->ni_vhtcaps & IEEE80211_VHTCAP_RXSTBC_MASK)) + lq_sta->stbc_capable = true; + + if (isset(mvm->sc_enabled_capa, IWM_UCODE_TLV_CAPA_BEAMFORMER) && + (num_of_ant(that->iwm_fw_valid_tx_ant(mvm)) > 1) && + (sta->ni_vhtcaps & IEEE80211_VHTCAP_SU_BEAMFORMEE_CAPABLE)) + lq_sta->bfer_capable = true; + + lq_sta->is_vht = true; +} + +static u8 iwl_mvm_bt_coex_get_single_ant_msk(struct iwm_softc *mvm, u8 enabled_ants) +{ + if (isset(&mvm->sc_enabled_capa, IWM_UCODE_TLV_CAPA_COEX_SCHEMA_2) && + (mvm->non_shared_ant & enabled_ants)) + return mvm->non_shared_ant; + + return first_antenna(enabled_ants); +} + +/** + * struct ieee80211_rate - bitrate definition + * + * This structure describes a bitrate that an 802.11 PHY can + * operate with. The two values @hw_value and @hw_value_short + * are only for driver use when pointers to this structure are + * passed around. + * + * @flags: rate-specific flags + * @bitrate: bitrate in units of 100 Kbps + * @hw_value: driver/hardware value for this rate + * @hw_value_short: driver/hardware value for this rate when + * short preamble is used + */ +struct ieee80211_rate { + u32 flags; + u16 bitrate; + u16 hw_value, hw_value_short; +}; + +/** + * enum ieee80211_rate_flags - rate flags + * + * Hardware/specification flags for rates. These are structured + * in a way that allows using the same bitrate structure for + * different bands/PHY modes. + * + * @IEEE80211_RATE_SHORT_PREAMBLE: Hardware can send with short + * preamble on this bitrate; only relevant in 2.4GHz band and + * with CCK rates. + * @IEEE80211_RATE_MANDATORY_A: This bitrate is a mandatory rate + * when used with 802.11a (on the 5 GHz band); filled by the + * core code when registering the wiphy. + * @IEEE80211_RATE_MANDATORY_B: This bitrate is a mandatory rate + * when used with 802.11b (on the 2.4 GHz band); filled by the + * core code when registering the wiphy. + * @IEEE80211_RATE_MANDATORY_G: This bitrate is a mandatory rate + * when used with 802.11g (on the 2.4 GHz band); filled by the + * core code when registering the wiphy. + * @IEEE80211_RATE_ERP_G: This is an ERP rate in 802.11g mode. + * @IEEE80211_RATE_SUPPORTS_5MHZ: Rate can be used in 5 MHz mode + * @IEEE80211_RATE_SUPPORTS_10MHZ: Rate can be used in 10 MHz mode + */ +enum ieee80211_rate_flags { + IEEE80211_RATE_SHORT_PREAMBLE = 1<<0, + IEEE80211_RATE_MANDATORY_A = 1<<1, + IEEE80211_RATE_MANDATORY_B = 1<<2, + IEEE80211_RATE_MANDATORY_G = 1<<3, + IEEE80211_RATE_ERP_G = 1<<4, + IEEE80211_RATE_SUPPORTS_5MHZ = 1<<5, + IEEE80211_RATE_SUPPORTS_10MHZ = 1<<6, +}; + +/* rate data (static) */ +static struct ieee80211_rate iwl_cfg80211_rates[] = { + { .bitrate = 1 * 10, .hw_value = 0, .hw_value_short = 0, }, + { .bitrate = 2 * 10, .hw_value = 1, .hw_value_short = 1, + .flags = IEEE80211_RATE_SHORT_PREAMBLE, }, + { .bitrate = (u16)(5.5 * 10), .hw_value = 2, .hw_value_short = 2, + .flags = IEEE80211_RATE_SHORT_PREAMBLE, }, + { .bitrate = 11 * 10, .hw_value = 3, .hw_value_short = 3, + .flags = IEEE80211_RATE_SHORT_PREAMBLE, }, + { .bitrate = 6 * 10, .hw_value = 4, .hw_value_short = 4, }, + { .bitrate = 9 * 10, .hw_value = 5, .hw_value_short = 5, }, + { .bitrate = 12 * 10, .hw_value = 6, .hw_value_short = 6, }, + { .bitrate = 18 * 10, .hw_value = 7, .hw_value_short = 7, }, + { .bitrate = 24 * 10, .hw_value = 8, .hw_value_short = 8, }, + { .bitrate = 36 * 10, .hw_value = 9, .hw_value_short = 9, }, + { .bitrate = 48 * 10, .hw_value = 10, .hw_value_short = 10, }, + { .bitrate = 54 * 10, .hw_value = 11, .hw_value_short = 11, }, +}; +#define RATES_24_OFFS 0 +#define N_RATES_24 ARRAY_SIZE(iwl_cfg80211_rates) +#define RATES_52_OFFS 4 +#define N_RATES_52 (N_RATES_24 - RATES_52_OFFS) + +/* + * Called after adding a new station to initialize rate scaling + */ +static void rs_drv_rate_init(struct iwm_softc *mvm, struct ieee80211_node *sta, + enum nl80211_band band) +{ + int i, j; + struct iwl_lq_sta *lq_sta = &mvm->lq_sta.rs_drv; + ItlIwm *that = container_of(mvm, ItlIwm, com); + uint8_t rate; + +// lockdep_assert_held(&mvmsta->lq_sta.rs_drv.pers.lock); + + /* clear all non-persistent lq data */ + memset(lq_sta, 0, offsetof(typeof(*lq_sta), pers)); + + lq_sta->lq.sta_id = IWM_STATION_ID; +#if 0 + mvm->amsdu_enabled = 0; + mvm->max_amsdu_len = sta->max_amsdu_len; +#endif + + for (j = 0; j < LQ_SIZE; j++) + rs_rate_scale_clear_tbl_windows(mvm, &lq_sta->lq_info[j]); + + lq_sta->flush_timer = 0; + lq_sta->last_tx = ticks; + + IWL_DEBUG_RATE(mvm, + "LQ: *** rate scale station global init for station %d ***\n", + IWM_STATION_ID); + /* TODO: what is a good starting rate for STA? About middle? Maybe not + * the lowest or the highest rate.. Could consider using RSSI from + * previous packets? Need to have IEEE 802.1X auth succeed immediately + * after assoc.. */ + + lq_sta->missed_rate_counter = IWL_MVM_RS_MISSED_RATE_MAX; + lq_sta->band = band; + /* + * active legacy rates as per supported rates bitmap + */ + lq_sta->active_legacy_rate = 0; + for (i = 0; i < sta->ni_rates.rs_nrates; i++) { + rate = sta->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL; + /* Map 802.11 rate to HW rate index. */ + for (j = 0; j <= (band == NL80211_BAND_2GHZ ? N_RATES_24 : N_RATES_52); j++) { + if (iwl_cfg80211_rates[j + (band == NL80211_BAND_2GHZ ? RATES_24_OFFS : RATES_52_OFFS)].bitrate / 5 == rate) + break; + } + lq_sta->active_legacy_rate |= BIT(iwl_cfg80211_rates[j + (band == NL80211_BAND_2GHZ ? RATES_24_OFFS : RATES_52_OFFS)].hw_value); + } + + /* TODO: should probably account for rx_highest for both HT/VHT */ + if ((sta->ni_flags & IEEE80211_NODE_VHT) == 0) + rs_ht_init(mvm, sta, lq_sta); + else + rs_vht_init(mvm, sta, lq_sta); + + lq_sta->max_legacy_rate_idx = + rs_get_max_rate_from_mask(lq_sta->active_legacy_rate); + lq_sta->max_siso_rate_idx = + rs_get_max_rate_from_mask(lq_sta->active_siso_rate); + lq_sta->max_mimo2_rate_idx = + rs_get_max_rate_from_mask(lq_sta->active_mimo2_rate); + + IWL_DEBUG_RATE(mvm, + "LEGACY=%lX SISO=%lX MIMO2=%lX VHT=%d LDPC=%d STBC=%d BFER=%d\n", + lq_sta->active_legacy_rate, + lq_sta->active_siso_rate, + lq_sta->active_mimo2_rate, + lq_sta->is_vht, lq_sta->ldpc, lq_sta->stbc_capable, + lq_sta->bfer_capable); + IWL_DEBUG_RATE(mvm, "MAX RATE: LEGACY=%d SISO=%d MIMO2=%d\n", + lq_sta->max_legacy_rate_idx, + lq_sta->max_siso_rate_idx, + lq_sta->max_mimo2_rate_idx); + + /* These values will be overridden later */ + lq_sta->lq.single_stream_ant_msk = + iwl_mvm_bt_coex_get_single_ant_msk(mvm, that->iwm_fw_valid_tx_ant(mvm)); + lq_sta->lq.dual_stream_ant_msk = ANT_AB; + + /* as default allow aggregation for all tids */ + lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID; + lq_sta->is_agg = 0; + rs_initialize_lq(mvm, sta, lq_sta, band); +} + +void rs_drv_rate_update(struct iwm_softc *mvm, + struct ieee80211_node *sta, + enum nl80211_band band, u32 changed) +{ + /* Stop any ongoing aggregations as rs starts off assuming no agg */ + ieee80211_stop_ampdu_tx(&mvm->sc_ic, sta, 0); + + iwl_mvm_rs_rate_init(mvm, sta, band, true); +} + +static void __iwl_mvm_rs_tx_status(struct iwm_softc *mvm, + struct ieee80211_node *sta, + int tid, struct ieee80211_tx_info *info, + bool ndp) +{ + int legacy_success; + int retries; + int i; + struct iwm_lq_cmd *table; + u32 lq_hwrate; + uint32_t last_rate; + struct rs_rate lq_rate, tx_resp_rate; + struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl; + u32 tlc_info = (u32)(uintptr_t)info->status.status_driver_data[0]; + u8 reduced_txp = tlc_info & RS_DRV_DATA_TXP_MSK; + u8 lq_color = RS_DRV_DATA_LQ_COLOR_GET(tlc_info); + u32 tx_resp_hwrate = (u32)(uintptr_t)info->status.status_driver_data[1]; + struct iwl_lq_sta *lq_sta = &mvm->lq_sta.rs_drv; + char pretty_rate[100]; + + if (!lq_sta->pers.drv) { + IWL_DEBUG_RATE(mvm, "Rate scaling not initialized yet.\n"); + return; + } + + /* This packet was aggregated but doesn't carry status info */ + if ((info->flags & IEEE80211_TX_CTL_AMPDU) && + !(info->flags & IEEE80211_TX_STAT_AMPDU)) + return; + + if (rs_rate_from_ucode_rate(tx_resp_hwrate, (enum nl80211_band)info->band, + &tx_resp_rate)) { + WARN_ON_ONCE(1); + return; + } + + if (time_after(ticks, + (unsigned long)(lq_sta->last_tx + + (IWL_MVM_RS_IDLE_TIMEOUT * hz)))) { + IWL_DEBUG_RATE(mvm, "Tx idle for too long. reinit rs\n"); + /* reach here only in case of driver RS, call directly + * the unlocked version + */ + rs_drv_rate_init(mvm, sta, (nl80211_band)info->band); + return; + } + lq_sta->last_tx = ticks; + + /* Ignore this Tx frame response if its initial rate doesn't match + * that of latest Link Quality command. There may be stragglers + * from a previous Link Quality command, but we're no longer interested + * in those; they're either from the "active" mode while we're trying + * to check "search" mode, or a prior "search" mode after we've moved + * to a new "search" mode (which might become the new "active" mode). + */ + table = &lq_sta->lq; + lq_hwrate = le32_to_cpu(table->rs_table[0]); + if (rs_rate_from_ucode_rate(lq_hwrate, (enum nl80211_band)info->band, &lq_rate)) { + WARN_ON_ONCE(1); + return; + } + + /* Here we actually compare this rate to the latest LQ command */ + if (lq_color != LQ_FLAG_COLOR_GET(table->flags)) { + IWL_DEBUG_RATE(mvm, + "tx resp color 0x%x does not match 0x%x\n", + lq_color, LQ_FLAG_COLOR_GET(table->flags)); + + /* Since rates mis-match, the last LQ command may have failed. + * After IWL_MISSED_RATE_MAX mis-matches, resync the uCode with + * ... driver. + */ + lq_sta->missed_rate_counter++; + if (lq_sta->missed_rate_counter > IWL_MVM_RS_MISSED_RATE_MAX) { + lq_sta->missed_rate_counter = 0; + IWL_DEBUG_RATE(mvm, + "Too many rates mismatch. Send sync LQ. rs_state %d\n", + lq_sta->rs_state); + iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq); + } + /* Regardless, ignore this status info for outdated rate */ + return; + } + + /* Rate did match, so reset the missed_rate_counter */ + lq_sta->missed_rate_counter = 0; + + if (!lq_sta->search_better_tbl) { + curr_tbl = &lq_sta->lq_info[lq_sta->active_tbl]; + other_tbl = &lq_sta->lq_info[rs_search_tbl(lq_sta->active_tbl)]; + } else { + curr_tbl = &lq_sta->lq_info[rs_search_tbl(lq_sta->active_tbl)]; + other_tbl = &lq_sta->lq_info[lq_sta->active_tbl]; + } + + if (WARN_ON_ONCE(!rs_rate_column_match(&lq_rate, &curr_tbl->rate))) { + IWL_DEBUG_RATE(mvm, + "Neither active nor search matches tx rate\n"); + tmp_tbl = &lq_sta->lq_info[lq_sta->active_tbl]; + rs_dump_rate(mvm, &tmp_tbl->rate, "ACTIVE"); + tmp_tbl = &lq_sta->lq_info[rs_search_tbl(lq_sta->active_tbl)]; + rs_dump_rate(mvm, &tmp_tbl->rate, "SEARCH"); + rs_dump_rate(mvm, &lq_rate, "ACTUAL"); + + /* no matching table found, let's by-pass the data collection + * and continue to perform rate scale to find the rate table + */ + rs_stay_in_table(lq_sta, true); + goto done; + } + + /* Updating the frame history depends on whether packets were + * aggregated. + * + * For aggregation, all packets were transmitted at the same rate, the + * first index into rate scale table. + */ + if (info->flags & IEEE80211_TX_STAT_AMPDU) { + rs_collect_tpc_data(mvm, lq_sta, curr_tbl, tx_resp_rate.index, + info->status.ampdu_len, + info->status.ampdu_ack_len, + reduced_txp); + + /* ampdu_ack_len = 0 marks no BA was received. For TLC, treat + * it as a single frame loss as we don't want the success ratio + * to dip too quickly because a BA wasn't received. + * For TPC, there's no need for this optimisation since we want + * to recover very quickly from a bad power reduction and, + * therefore we'd like the success ratio to get an immediate hit + * when failing to get a BA, so we'd switch back to a lower or + * zero power reduction. When FW transmits agg with a rate + * different from the initial rate, it will not use reduced txp + * and will send BA notification twice (one empty with reduced + * txp equal to the value from LQ and one with reduced txp 0). + * We need to update counters for each txp level accordingly. + */ + if (info->status.ampdu_ack_len == 0) + info->status.ampdu_len = 1; + + rs_collect_tlc_data(mvm, tid, curr_tbl, + tx_resp_rate.index, + info->status.ampdu_len, + info->status.ampdu_ack_len); + + /* Update success/fail counts if not searching for new mode */ + if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN) { + lq_sta->total_success += info->status.ampdu_ack_len; + lq_sta->total_failed += (info->status.ampdu_len - + info->status.ampdu_ack_len); + } + } else { + /* For legacy, update frame history with for each Tx retry. */ + retries = info->status.rates[0].count - 1; + /* HW doesn't send more than 15 retries */ + retries = min(retries, 15); + + /* The last transmission may have been successful */ + legacy_success = !!(info->flags & IEEE80211_TX_STAT_ACK); + /* Collect data for each rate used during failed TX attempts */ + for (i = 0; i <= retries; ++i) { + lq_hwrate = le32_to_cpu(table->rs_table[i]); + if (rs_rate_from_ucode_rate(lq_hwrate, (enum nl80211_band)info->band, + &lq_rate)) { + WARN_ON_ONCE(1); + return; + } + + /* Only collect stats if retried rate is in the same RS + * table as active/search. + */ + if (rs_rate_column_match(&lq_rate, &curr_tbl->rate)) + tmp_tbl = curr_tbl; + else if (rs_rate_column_match(&lq_rate, + &other_tbl->rate)) + tmp_tbl = other_tbl; + else + continue; + + rs_collect_tpc_data(mvm, lq_sta, tmp_tbl, + tx_resp_rate.index, 1, + i < retries ? 0 : legacy_success, + reduced_txp); + rs_collect_tlc_data(mvm, tid, tmp_tbl, + tx_resp_rate.index, 1, + i < retries ? 0 : legacy_success); + } + + /* Update success/fail counts if not searching for new mode */ + if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN) { + lq_sta->total_success += legacy_success; + lq_sta->total_failed += retries + (1 - legacy_success); + } + } + /* The last TX rate is cached in lq_sta; it's set in if/else above */ + last_rate = lq_sta->last_rate_n_flags; + lq_sta->last_rate_n_flags = lq_hwrate; + if (last_rate != lq_hwrate) { + rs_pretty_print_rate(pretty_rate, sizeof(pretty_rate), lq_sta->last_rate_n_flags); + XYLog("%s new rate: %s\n", __FUNCTION__, pretty_rate); + } + if ((lq_sta->last_rate_n_flags & RATE_MCS_VHT_MSK) || (lq_sta->last_rate_n_flags & RATE_MCS_HE_MSK)) { + sta->ni_txmcs = (lq_sta->last_rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK); + } else if (lq_sta->last_rate_n_flags & RATE_MCS_HT_MSK) { + sta->ni_txmcs = (lq_sta->last_rate_n_flags & + (RATE_HT_MCS_RATE_CODE_MSK | + RATE_HT_MCS_NSS_MSK)); + } else { + int index = iwl_mvm_legacy_rate_to_mac80211_idx(lq_sta->last_rate_n_flags, (enum nl80211_band)info->band); + if (index < 0 || index >= ieee80211_std_rateset_11g.rs_nrates) + goto done; + + sta->ni_txrate = ieee80211_std_rateset_11g.rs_rates[index] / 2; + } + IWL_DEBUG_RATE(mvm, "reduced txpower: %d\n", reduced_txp); +done: + /* See if there's a better rate or modulation mode to try. */ + if (/*sta->supp_rates[info->band]*/ true) + rs_rate_scale_perform(mvm, sta, lq_sta, tid, ndp); +} + +void iwl_mvm_rs_tx_status(struct iwm_softc *mvm, struct ieee80211_node *sta, + int tid, struct ieee80211_tx_info *info, bool ndp) +{ + /* If it's locked we are in middle of init flow + * just wait for next tx status to update the lq_sta data + */ + if (!IOSimpleLockTryLock(mvm->lq_sta.rs_drv.pers.lock)) + return; + + __iwl_mvm_rs_tx_status(mvm, sta, tid, info, ndp); + IOSimpleLockUnlock(mvm->lq_sta.rs_drv.pers.lock); +} + +static void rs_fill_rates_for_column(struct iwm_softc *mvm, + struct iwl_lq_sta *lq_sta, + struct rs_rate *rate, + __le32 *rs_table, int *rs_table_index, + int num_rates, int num_retries, + u8 valid_tx_ant, bool toggle_ant) +{ + int i, j; + __le32 ucode_rate; + bool bottom_reached = false; + int prev_rate_idx = rate->index; + int end = LINK_QUAL_MAX_RETRY_NUM; + int index = *rs_table_index; + + for (i = 0; i < num_rates && index < end; i++) { + for (j = 0; j < num_retries && index < end; j++, index++) { + ucode_rate = cpu_to_le32(ucode_rate_from_rs_rate(mvm, + rate)); + rs_table[index] = ucode_rate; + if (toggle_ant) + rs_toggle_antenna(valid_tx_ant, rate); + } + + prev_rate_idx = rate->index; + bottom_reached = rs_get_lower_rate_in_column(lq_sta, rate); + if (bottom_reached && !is_legacy(rate)) + break; + } + + if (!bottom_reached && !is_legacy(rate)) + rate->index = prev_rate_idx; + + *rs_table_index = index; +} + +/* Building the rate table is non trivial. When we're in MIMO2/VHT/80Mhz/SGI + * column the rate table should look like this: + * + * rate[0] 0x400F019 VHT | ANT: AB BW: 80Mhz MCS: 9 NSS: 2 SGI + * rate[1] 0x400F019 VHT | ANT: AB BW: 80Mhz MCS: 9 NSS: 2 SGI + * rate[2] 0x400F018 VHT | ANT: AB BW: 80Mhz MCS: 8 NSS: 2 SGI + * rate[3] 0x400F018 VHT | ANT: AB BW: 80Mhz MCS: 8 NSS: 2 SGI + * rate[4] 0x400F017 VHT | ANT: AB BW: 80Mhz MCS: 7 NSS: 2 SGI + * rate[5] 0x400F017 VHT | ANT: AB BW: 80Mhz MCS: 7 NSS: 2 SGI + * rate[6] 0x4005007 VHT | ANT: A BW: 80Mhz MCS: 7 NSS: 1 NGI + * rate[7] 0x4009006 VHT | ANT: B BW: 80Mhz MCS: 6 NSS: 1 NGI + * rate[8] 0x4005005 VHT | ANT: A BW: 80Mhz MCS: 5 NSS: 1 NGI + * rate[9] 0x800B Legacy | ANT: B Rate: 36 Mbps + * rate[10] 0x4009 Legacy | ANT: A Rate: 24 Mbps + * rate[11] 0x8007 Legacy | ANT: B Rate: 18 Mbps + * rate[12] 0x4005 Legacy | ANT: A Rate: 12 Mbps + * rate[13] 0x800F Legacy | ANT: B Rate: 9 Mbps + * rate[14] 0x400D Legacy | ANT: A Rate: 6 Mbps + * rate[15] 0x800D Legacy | ANT: B Rate: 6 Mbps + */ +static void rs_build_rates_table(struct iwm_softc *mvm, + struct ieee80211_node *sta, + struct iwl_lq_sta *lq_sta, + const struct rs_rate *initial_rate) +{ + struct rs_rate rate; + int num_rates, num_retries, index = 0; + u8 valid_tx_ant = 0; + struct iwm_lq_cmd *lq_cmd = &lq_sta->lq; + bool toggle_ant = false; + u32 color; + ItlIwm *that = container_of(mvm, ItlIwm, com); + + memcpy(&rate, initial_rate, sizeof(rate)); + + valid_tx_ant = that->iwm_fw_valid_tx_ant(mvm); + + /* TODO: remove old API when min FW API hits 14 */ + if (!isset(&mvm->sc_ucode_api, IWM_UCODE_TLV_API_LQ_SS_PARAMS) && + rs_stbc_allow(mvm, sta, lq_sta)) + rate.stbc = true; + + if (is_siso(&rate)) { + num_rates = IWL_MVM_RS_INITIAL_SISO_NUM_RATES; + num_retries = IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE; + } else if (is_mimo(&rate)) { + num_rates = IWL_MVM_RS_INITIAL_MIMO_NUM_RATES; + num_retries = IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE; + } else { + num_rates = IWL_MVM_RS_INITIAL_LEGACY_NUM_RATES; + num_retries = IWL_MVM_RS_INITIAL_LEGACY_RETRIES; + toggle_ant = true; + } + + rs_fill_rates_for_column(mvm, lq_sta, &rate, (__le32 *)lq_cmd->rs_table, &index, + num_rates, num_retries, valid_tx_ant, + toggle_ant); + + rs_get_lower_rate_down_column(lq_sta, &rate); + + if (is_siso(&rate)) { + num_rates = IWL_MVM_RS_SECONDARY_SISO_NUM_RATES; + num_retries = IWL_MVM_RS_SECONDARY_SISO_RETRIES; + lq_cmd->mimo_delim = index; + } else if (is_legacy(&rate)) { + num_rates = IWL_MVM_RS_SECONDARY_LEGACY_NUM_RATES; + num_retries = IWL_MVM_RS_SECONDARY_LEGACY_RETRIES; + } else { + WARN_ON_ONCE(1); + } + + toggle_ant = true; + + rs_fill_rates_for_column(mvm, lq_sta, &rate, (__le32 *)lq_cmd->rs_table, &index, + num_rates, num_retries, valid_tx_ant, + toggle_ant); + + rs_get_lower_rate_down_column(lq_sta, &rate); + + num_rates = IWL_MVM_RS_SECONDARY_LEGACY_NUM_RATES; + num_retries = IWL_MVM_RS_SECONDARY_LEGACY_RETRIES; + + rs_fill_rates_for_column(mvm, lq_sta, &rate, (__le32 *)lq_cmd->rs_table, &index, + num_rates, num_retries, valid_tx_ant, + toggle_ant); + + /* update the color of the LQ command (as a counter at bits 1-3) */ + color = LQ_FLAGS_COLOR_INC(LQ_FLAG_COLOR_GET(lq_cmd->flags)); + lq_cmd->flags = LQ_FLAG_COLOR_SET(lq_cmd->flags, color); +} + +//struct rs_bfer_active_iter_data { +// struct ieee80211_node *exclude_sta; +// struct ieee80211_node *bfer_mvmsta; +//}; +// +//static void rs_bfer_active_iter(void *_data, +// struct ieee80211_node *sta) +//{ +// struct rs_bfer_active_iter_data *data = (struct rs_bfer_active_iter_data *)_data; +// struct iwm_lq_cmd *lq_cmd = &sta->ni_ic->lq_sta.rs_drv.lq; +// u32 ss_params = le32_to_cpu(lq_cmd->ss_params); +// +// if (sta == data->exclude_sta) +// return; +// +// /* The current sta has BFER allowed */ +// if (ss_params & LQ_SS_BFER_ALLOWED) { +// WARN_ON_ONCE(data->bfer_mvmsta != NULL); +// +// data->bfer_mvmsta = mvmsta; +// } +//} +// +//static int rs_bfer_priority(struct ieee80211_node *sta) +//{ +// return 1; +//} +// +///* Returns >0 if sta1 has a higher BFER priority compared to sta2 */ +//static int rs_bfer_priority_cmp(struct ieee80211_node *sta1, +// struct ieee80211_node *sta2) +//{ +// int prio1 = rs_bfer_priority(sta1); +// int prio2 = rs_bfer_priority(sta2); +// +// if (prio1 > prio2) +// return 1; +// if (prio1 < prio2) +// return -1; +// return 0; +//} +// +//static inline void ieee80211_iterate_stations_atomic(struct iwm_softc *hw, +// void (*iterator)(void *data, +// struct ieee80211_node *sta), +// void *data) +//{ +// iterator(data, hw->sc_ic.ic_bss); +//} + +static void rs_set_lq_ss_params(struct iwm_softc *mvm, + struct ieee80211_node *sta, + struct iwl_lq_sta *lq_sta, + const struct rs_rate *initial_rate) +{ + struct iwm_lq_cmd *lq_cmd = &lq_sta->lq; +// struct rs_bfer_active_iter_data data = { +// .exclude_sta = sta, +// .bfer_mvmsta = NULL, +// }; + u32 ss_params = LQ_SS_PARAMS_VALID; + + if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta)) + goto out; + + if (lq_sta->stbc_capable) + ss_params |= LQ_SS_STBC_1SS_ALLOWED; + + if (!lq_sta->bfer_capable) + goto out; + +// ieee80211_iterate_stations_atomic(mvm, +// rs_bfer_active_iter, +// &data); +// bfer_mvmsta = data.bfer_mvmsta; +// +// /* This code is safe as it doesn't run concurrently for different +// * stations. This is guaranteed by the fact that calls to +// * ieee80211_tx_status wouldn't run concurrently for a single HW. +// */ +// if (!bfer_mvmsta) { +// IWL_DEBUG_RATE(mvm, "No sta with BFER allowed found. Allow\n"); +// +// ss_params |= LQ_SS_BFER_ALLOWED; +// goto out; +// } +// +// IWL_DEBUG_RATE(mvm, "Found existing sta %d with BFER activated\n", +// bfer_mvmsta->sta_id); +// +// /* Disallow BFER on another STA if active and we're a higher priority */ +// if (rs_bfer_priority_cmp(mvmsta, bfer_mvmsta) > 0) { +// struct iwm_lq_cmd *bfersta_lq_cmd = +// &bfer_mvmsta->lq_sta.rs_drv.lq; +// u32 bfersta_ss_params = le32_to_cpu(bfersta_lq_cmd->ss_params); +// +// bfersta_ss_params &= ~LQ_SS_BFER_ALLOWED; +// bfersta_lq_cmd->ss_params = cpu_to_le32(bfersta_ss_params); +// iwl_mvm_send_lq_cmd(mvm, bfersta_lq_cmd); +// +// ss_params |= LQ_SS_BFER_ALLOWED; +// IWL_DEBUG_RATE(mvm, +// "Lower priority BFER sta found (%d). Switch BFER\n", +// bfer_mvmsta->sta_id); +// } +out: + lq_cmd->ss_params = cpu_to_le32(ss_params); +} + +#define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) +#define LINK_QUAL_AGG_TIME_LIMIT_BT_ACT (1200) + +static u16 iwl_mvm_coex_agg_time_limit(struct iwm_softc *mvm, +struct ieee80211_node *sta) +{ +// if (mvm->last_bt_notif.ttc_status & BIT(phy_ctxt->id)) +// return LINK_QUAL_AGG_TIME_LIMIT_DEF; +// +// if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) < +// BT_HIGH_TRAFFIC) +// return LINK_QUAL_AGG_TIME_LIMIT_DEF; +// +// lut_type = iwl_get_coex_type(mvm, mvmsta->vif); +// +// if (lut_type == BT_COEX_LOOSE_LUT || lut_type == BT_COEX_INVALID_LUT) + return LINK_QUAL_AGG_TIME_LIMIT_DEF; + +// /* tight coex, high bt traffic, reduce AGG time limit */ +// return LINK_QUAL_AGG_TIME_LIMIT_BT_ACT; +} + +static void rs_fill_lq_cmd(struct iwm_softc *mvm, + struct ieee80211_node *sta, + struct iwl_lq_sta *lq_sta, + const struct rs_rate *initial_rate) +{ + struct iwm_lq_cmd *lq_cmd = &lq_sta->lq; + + lq_cmd->agg_disable_start_th = IWL_MVM_RS_AGG_DISABLE_START; + lq_cmd->agg_time_limit = + cpu_to_le16(IWL_MVM_RS_AGG_TIME_LIMIT); + + if (WARN_ON_ONCE(!sta || !initial_rate)) + return; + + rs_build_rates_table(mvm, sta, lq_sta, initial_rate); + + if (isset(&mvm->sc_ucode_api, IWM_UCODE_TLV_API_LQ_SS_PARAMS)) + rs_set_lq_ss_params(mvm, sta, lq_sta, initial_rate); + + if (!isset(&mvm->sc_enabled_capa, IWM_UCODE_TLV_CAPA_COEX_SCHEMA_2) && + num_of_ant(initial_rate->ant) == 1) + lq_cmd->single_stream_ant_msk = initial_rate->ant; + + lq_cmd->agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF; + +#if 0 + if (mvmsta->vif->p2p) + lq_cmd->flags |= LQ_FLAG_USE_RTS_MSK; +#endif + + lq_cmd->agg_time_limit = + cpu_to_le16(iwl_mvm_coex_agg_time_limit(mvm, sta)); +} + +int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate) +{ + + char *type, *bw; + u8 mcs = 0, nss = 0; + u8 ant = (rate & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS; + + if (!(rate & RATE_MCS_HT_MSK) && + !(rate & RATE_MCS_VHT_MSK) && + !(rate & RATE_MCS_HE_MSK)) { + int index = iwl_hwrate_to_plcp_idx(rate); + + return snprintf(buf, bufsz, "Legacy | ANT: %s Rate: %s Mbps", + rs_pretty_ant(ant), + index == IWL_RATE_INVALID ? "BAD" : + iwl_rate_mcs[index].mbps); + } + + if (rate & RATE_MCS_VHT_MSK) { + type = "VHT"; + mcs = rate & RATE_VHT_MCS_RATE_CODE_MSK; + nss = ((rate & RATE_VHT_MCS_NSS_MSK) + >> RATE_VHT_MCS_NSS_POS) + 1; + } else if (rate & RATE_MCS_HT_MSK) { + type = "HT"; + mcs = rate & RATE_HT_MCS_INDEX_MSK; + nss = ((rate & RATE_HT_MCS_NSS_MSK) + >> RATE_HT_MCS_NSS_POS) + 1; + } else if (rate & RATE_MCS_HE_MSK) { + type = "HE"; + mcs = rate & RATE_VHT_MCS_RATE_CODE_MSK; + nss = ((rate & RATE_VHT_MCS_NSS_MSK) + >> RATE_VHT_MCS_NSS_POS) + 1; + } else { + type = "Unknown"; /* shouldn't happen */ + } + + switch (rate & RATE_MCS_CHAN_WIDTH_MSK) { + case RATE_MCS_CHAN_WIDTH_20: + bw = "20Mhz"; + break; + case RATE_MCS_CHAN_WIDTH_40: + bw = "40Mhz"; + break; + case RATE_MCS_CHAN_WIDTH_80: + bw = "80Mhz"; + break; + case RATE_MCS_CHAN_WIDTH_160: + bw = "160Mhz"; + break; + default: + bw = "BAD BW"; + } + + return snprintf(buf, bufsz, + "0x%x: %s | ANT: %s BW: %s MCS: %d NSS: %d %s%s%s%s%s", + rate, type, rs_pretty_ant(ant), bw, mcs, nss, + (rate & RATE_MCS_SGI_MSK) ? "SGI " : "NGI ", + (rate & RATE_MCS_STBC_MSK) ? "STBC " : "", + (rate & RATE_MCS_LDPC_MSK) ? "LDPC " : "", + (rate & RATE_HE_DUAL_CARRIER_MODE_MSK) ? "DCM " : "", + (rate & RATE_MCS_BF_MSK) ? "BF " : ""); +} + +void iwl_mvm_rs_rate_init(struct iwm_softc *mvm, struct ieee80211_node *sta, + enum nl80211_band band, bool update) +{ + IOSimpleLockLock(mvm->lq_sta.rs_drv.pers.lock); + rs_drv_rate_init(mvm, sta, band); + IOSimpleLockUnlock(mvm->lq_sta.rs_drv.pers.lock); +} + +static int rs_drv_tx_protection(struct iwm_softc *mvm, + bool enable) +{ + struct iwm_lq_cmd *lq = &mvm->lq_sta.rs_drv.lq; + + if (enable) { + if (mvm->tx_protection == 0) + lq->flags |= LQ_FLAG_USE_RTS_MSK; + mvm->tx_protection++; + } else { + mvm->tx_protection--; + if (mvm->tx_protection == 0) + lq->flags &= ~LQ_FLAG_USE_RTS_MSK; + } + + return iwl_mvm_send_lq_cmd(mvm, lq); +} + +/** + * iwl_mvm_tx_protection - ask FW to enable RTS/CTS protection + * @mvm: The mvm component + * @mvmsta: The station + * @enable: Enable Tx protection? + */ +int iwl_mvm_tx_protection(struct iwm_softc *mvm, + bool enable) +{ + return rs_drv_tx_protection(mvm, enable); +} + +void +iwm_rs_alloc(struct iwm_softc *sc) +{ + sc->lq_sta.rs_drv.pers.lock = IOSimpleLockAlloc(); +} + +void iwm_rs_free(struct iwm_softc *sc) +{ + if (sc->lq_sta.rs_drv.pers.lock) { + IOSimpleLockFree(sc->lq_sta.rs_drv.pers.lock); + sc->lq_sta.rs_drv.pers.lock = NULL; + } +} diff --git a/itlwm/hal_iwm/rs.h b/itlwm/hal_iwm/rs.h new file mode 100644 index 000000000..0ad3a5f6b --- /dev/null +++ b/itlwm/hal_iwm/rs.h @@ -0,0 +1,1509 @@ +// +// rs.hpp +// itlwm +// +// Created by zxystd on 2021/8/27. +// Copyright © 2021 钟先耀. All rights reserved. +// + +#ifndef rs_hpp +#define rs_hpp + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#define IWL_DEBUG_RATE(sc, fmt, x...) +//#define IWL_DEBUG_RATE(sc, fmt, x...)\ +//do\ +//{\ +//XYLog("%s: " fmt, "RATE", ##x);\ +//}while(0) + +#define IWL_ERR(sc, fmt, x...)\ +do\ +{\ +XYLog("%s: " fmt, "ERR", ##x);\ +}while(0) + +/** + * enum nl80211_band - Frequency band + * @NL80211_BAND_2GHZ: 2.4 GHz ISM band + * @NL80211_BAND_5GHZ: around 5 GHz band (4.9 - 5.7 GHz) + * @NUM_NL80211_BANDS: number of bands, avoid using this in userspace + * since newer kernel versions may support more bands + */ +enum nl80211_band { + NL80211_BAND_2GHZ, + NL80211_BAND_5GHZ, + + NUM_NL80211_BANDS, +}; + +/** + * enum mac80211_tx_info_flags - flags to describe transmission information/status + * + * These flags are used with the @flags member of &ieee80211_tx_info. + * + * @IEEE80211_TX_CTL_REQ_TX_STATUS: require TX status callback for this frame. + * @IEEE80211_TX_CTL_ASSIGN_SEQ: The driver has to assign a sequence + * number to this frame, taking care of not overwriting the fragment + * number and increasing the sequence number only when the + * IEEE80211_TX_CTL_FIRST_FRAGMENT flag is set. mac80211 will properly + * assign sequence numbers to QoS-data frames but cannot do so correctly + * for non-QoS-data and management frames because beacons need them from + * that counter as well and mac80211 cannot guarantee proper sequencing. + * If this flag is set, the driver should instruct the hardware to + * assign a sequence number to the frame or assign one itself. Cf. IEEE + * 802.11-2007 7.1.3.4.1 paragraph 3. This flag will always be set for + * beacons and always be clear for frames without a sequence number field. + * @IEEE80211_TX_CTL_NO_ACK: tell the low level not to wait for an ack + * @IEEE80211_TX_CTL_CLEAR_PS_FILT: clear powersave filter for destination + * station + * @IEEE80211_TX_CTL_FIRST_FRAGMENT: this is a first fragment of the frame + * @IEEE80211_TX_CTL_SEND_AFTER_DTIM: send this frame after DTIM beacon + * @IEEE80211_TX_CTL_AMPDU: this frame should be sent as part of an A-MPDU + * @IEEE80211_TX_CTL_INJECTED: Frame was injected, internal to mac80211. + * @IEEE80211_TX_STAT_TX_FILTERED: The frame was not transmitted + * because the destination STA was in powersave mode. Note that to + * avoid race conditions, the filter must be set by the hardware or + * firmware upon receiving a frame that indicates that the station + * went to sleep (must be done on device to filter frames already on + * the queue) and may only be unset after mac80211 gives the OK for + * that by setting the IEEE80211_TX_CTL_CLEAR_PS_FILT (see above), + * since only then is it guaranteed that no more frames are in the + * hardware queue. + * @IEEE80211_TX_STAT_ACK: Frame was acknowledged + * @IEEE80211_TX_STAT_AMPDU: The frame was aggregated, so status + * is for the whole aggregation. + * @IEEE80211_TX_STAT_AMPDU_NO_BACK: no block ack was returned, + * so consider using block ack request (BAR). + * @IEEE80211_TX_CTL_RATE_CTRL_PROBE: internal to mac80211, can be + * set by rate control algorithms to indicate probe rate, will + * be cleared for fragmented frames (except on the last fragment) + * @IEEE80211_TX_INTFL_OFFCHAN_TX_OK: Internal to mac80211. Used to indicate + * that a frame can be transmitted while the queues are stopped for + * off-channel operation. + * @IEEE80211_TX_CTL_HW_80211_ENCAP: This frame uses hardware encapsulation + * (header conversion) + * @IEEE80211_TX_INTFL_RETRIED: completely internal to mac80211, + * used to indicate that a frame was already retried due to PS + * @IEEE80211_TX_INTFL_DONT_ENCRYPT: completely internal to mac80211, + * used to indicate frame should not be encrypted + * @IEEE80211_TX_CTL_NO_PS_BUFFER: This frame is a response to a poll + * frame (PS-Poll or uAPSD) or a non-bufferable MMPDU and must + * be sent although the station is in powersave mode. + * @IEEE80211_TX_CTL_MORE_FRAMES: More frames will be passed to the + * transmit function after the current frame, this can be used + * by drivers to kick the DMA queue only if unset or when the + * queue gets full. + * @IEEE80211_TX_INTFL_RETRANSMISSION: This frame is being retransmitted + * after TX status because the destination was asleep, it must not + * be modified again (no seqno assignment, crypto, etc.) + * @IEEE80211_TX_INTFL_MLME_CONN_TX: This frame was transmitted by the MLME + * code for connection establishment, this indicates that its status + * should kick the MLME state machine. + * @IEEE80211_TX_INTFL_NL80211_FRAME_TX: Frame was requested through nl80211 + * MLME command (internal to mac80211 to figure out whether to send TX + * status to user space) + * @IEEE80211_TX_CTL_LDPC: tells the driver to use LDPC for this frame + * @IEEE80211_TX_CTL_STBC: Enables Space-Time Block Coding (STBC) for this + * frame and selects the maximum number of streams that it can use. + * @IEEE80211_TX_CTL_TX_OFFCHAN: Marks this packet to be transmitted on + * the off-channel channel when a remain-on-channel offload is done + * in hardware -- normal packets still flow and are expected to be + * handled properly by the device. + * @IEEE80211_TX_INTFL_TKIP_MIC_FAILURE: Marks this packet to be used for TKIP + * testing. It will be sent out with incorrect Michael MIC key to allow + * TKIP countermeasures to be tested. + * @IEEE80211_TX_CTL_NO_CCK_RATE: This frame will be sent at non CCK rate. + * This flag is actually used for management frame especially for P2P + * frames not being sent at CCK rate in 2GHz band. + * @IEEE80211_TX_STATUS_EOSP: This packet marks the end of service period, + * when its status is reported the service period ends. For frames in + * an SP that mac80211 transmits, it is already set; for driver frames + * the driver may set this flag. It is also used to do the same for + * PS-Poll responses. + * @IEEE80211_TX_CTL_USE_MINRATE: This frame will be sent at lowest rate. + * This flag is used to send nullfunc frame at minimum rate when + * the nullfunc is used for connection monitoring purpose. + * @IEEE80211_TX_CTL_DONTFRAG: Don't fragment this packet even if it + * would be fragmented by size (this is optional, only used for + * monitor injection). + * @IEEE80211_TX_STAT_NOACK_TRANSMITTED: A frame that was marked with + * IEEE80211_TX_CTL_NO_ACK has been successfully transmitted without + * any errors (like issues specific to the driver/HW). + * This flag must not be set for frames that don't request no-ack + * behaviour with IEEE80211_TX_CTL_NO_ACK. + * + * Note: If you have to add new flags to the enumeration, then don't + * forget to update %IEEE80211_TX_TEMPORARY_FLAGS when necessary. + */ +enum mac80211_tx_info_flags { + IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0), + IEEE80211_TX_CTL_ASSIGN_SEQ = BIT(1), + IEEE80211_TX_CTL_NO_ACK = BIT(2), + IEEE80211_TX_CTL_CLEAR_PS_FILT = BIT(3), + IEEE80211_TX_CTL_FIRST_FRAGMENT = BIT(4), + IEEE80211_TX_CTL_SEND_AFTER_DTIM = BIT(5), + IEEE80211_TX_CTL_AMPDU = BIT(6), + IEEE80211_TX_CTL_INJECTED = BIT(7), + IEEE80211_TX_STAT_TX_FILTERED = BIT(8), + IEEE80211_TX_STAT_ACK = BIT(9), + IEEE80211_TX_STAT_AMPDU = BIT(10), + IEEE80211_TX_STAT_AMPDU_NO_BACK = BIT(11), + IEEE80211_TX_CTL_RATE_CTRL_PROBE = BIT(12), + IEEE80211_TX_INTFL_OFFCHAN_TX_OK = BIT(13), + IEEE80211_TX_CTL_HW_80211_ENCAP = BIT(14), + IEEE80211_TX_INTFL_RETRIED = BIT(15), + IEEE80211_TX_INTFL_DONT_ENCRYPT = BIT(16), + IEEE80211_TX_CTL_NO_PS_BUFFER = BIT(17), + IEEE80211_TX_CTL_MORE_FRAMES = BIT(18), + IEEE80211_TX_INTFL_RETRANSMISSION = BIT(19), + IEEE80211_TX_INTFL_MLME_CONN_TX = BIT(20), + IEEE80211_TX_INTFL_NL80211_FRAME_TX = BIT(21), + IEEE80211_TX_CTL_LDPC = BIT(22), + IEEE80211_TX_CTL_STBC = BIT(23) | BIT(24), + IEEE80211_TX_CTL_TX_OFFCHAN = BIT(25), + IEEE80211_TX_INTFL_TKIP_MIC_FAILURE = BIT(26), + IEEE80211_TX_CTL_NO_CCK_RATE = BIT(27), + IEEE80211_TX_STATUS_EOSP = BIT(28), + IEEE80211_TX_CTL_USE_MINRATE = BIT(29), + IEEE80211_TX_CTL_DONTFRAG = BIT(30), + IEEE80211_TX_STAT_NOACK_TRANSMITTED = BIT(31), +}; + +/** + * enum mac80211_rate_control_flags - per-rate flags set by the + * Rate Control algorithm. + * + * These flags are set by the Rate control algorithm for each rate during tx, + * in the @flags member of struct ieee80211_tx_rate. + * + * @IEEE80211_TX_RC_USE_RTS_CTS: Use RTS/CTS exchange for this rate. + * @IEEE80211_TX_RC_USE_CTS_PROTECT: CTS-to-self protection is required. + * This is set if the current BSS requires ERP protection. + * @IEEE80211_TX_RC_USE_SHORT_PREAMBLE: Use short preamble. + * @IEEE80211_TX_RC_MCS: HT rate. + * @IEEE80211_TX_RC_VHT_MCS: VHT MCS rate, in this case the idx field is split + * into a higher 4 bits (Nss) and lower 4 bits (MCS number) + * @IEEE80211_TX_RC_GREEN_FIELD: Indicates whether this rate should be used in + * Greenfield mode. + * @IEEE80211_TX_RC_40_MHZ_WIDTH: Indicates if the Channel Width should be 40 MHz. + * @IEEE80211_TX_RC_80_MHZ_WIDTH: Indicates 80 MHz transmission + * @IEEE80211_TX_RC_160_MHZ_WIDTH: Indicates 160 MHz transmission + * (80+80 isn't supported yet) + * @IEEE80211_TX_RC_DUP_DATA: The frame should be transmitted on both of the + * adjacent 20 MHz channels, if the current channel type is + * NL80211_CHAN_HT40MINUS or NL80211_CHAN_HT40PLUS. + * @IEEE80211_TX_RC_SHORT_GI: Short Guard interval should be used for this rate. + */ +enum mac80211_rate_control_flags { + IEEE80211_TX_RC_USE_RTS_CTS = BIT(0), + IEEE80211_TX_RC_USE_CTS_PROTECT = BIT(1), + IEEE80211_TX_RC_USE_SHORT_PREAMBLE = BIT(2), + + /* rate index is an HT/VHT MCS instead of an index */ + IEEE80211_TX_RC_MCS = BIT(3), + IEEE80211_TX_RC_GREEN_FIELD = BIT(4), + IEEE80211_TX_RC_40_MHZ_WIDTH = BIT(5), + IEEE80211_TX_RC_DUP_DATA = BIT(6), + IEEE80211_TX_RC_SHORT_GI = BIT(7), + IEEE80211_TX_RC_VHT_MCS = BIT(8), + IEEE80211_TX_RC_80_MHZ_WIDTH = BIT(9), + IEEE80211_TX_RC_160_MHZ_WIDTH = BIT(10), +}; + +/** + * struct ieee80211_rx_status - receive status + * + * The low-level driver should provide this information (the subset + * supported by hardware) to the 802.11 code with each received + * frame, in the skb's control buffer (cb). + * + * @mactime: value in microseconds of the 64-bit Time Synchronization Function + * (TSF) timer when the first data symbol (MPDU) arrived at the hardware. + * @boottime_ns: CLOCK_BOOTTIME timestamp the frame was received at, this is + * needed only for beacons and probe responses that update the scan cache. + * @device_timestamp: arbitrary timestamp for the device, mac80211 doesn't use + * it but can store it and pass it back to the driver for synchronisation + * @band: the active band when this frame was received + * @freq: frequency the radio was tuned to when receiving this frame, in MHz + * This field must be set for management frames, but isn't strictly needed + * for data (other) frames - for those it only affects radiotap reporting. + * @freq_offset: @freq has a positive offset of 500Khz. + * @signal: signal strength when receiving this frame, either in dBm, in dB or + * unspecified depending on the hardware capabilities flags + * @IEEE80211_HW_SIGNAL_* + * @chains: bitmask of receive chains for which separate signal strength + * values were filled. + * @chain_signal: per-chain signal strength, in dBm (unlike @signal, doesn't + * support dB or unspecified units) + * @antenna: antenna used + * @rate_idx: index of data rate into band's supported rates or MCS index if + * HT or VHT is used (%RX_FLAG_HT/%RX_FLAG_VHT) + * @nss: number of streams (VHT and HE only) + * @flag: %RX_FLAG_\* + * @encoding: &enum mac80211_rx_encoding + * @bw: &enum rate_info_bw + * @enc_flags: uses bits from &enum mac80211_rx_encoding_flags + * @he_ru: HE RU, from &enum nl80211_he_ru_alloc + * @he_gi: HE GI, from &enum nl80211_he_gi + * @he_dcm: HE DCM value + * @rx_flags: internal RX flags for mac80211 + * @ampdu_reference: A-MPDU reference number, must be a different value for + * each A-MPDU but the same for each subframe within one A-MPDU + * @ampdu_delimiter_crc: A-MPDU delimiter CRC + * @zero_length_psdu_type: radiotap type of the 0-length PSDU + */ +struct ieee80211_rx_status { +// u64 mactime; +// u64 boottime_ns; +// u32 device_timestamp; +// u32 ampdu_reference; +// u32 flag; +// u16 freq: 13, freq_offset: 1; +// u8 enc_flags; +// u8 encoding:2, bw:3, he_ru:3; +// u8 he_gi:2, he_dcm:1; +// u8 rate_idx; +// u8 nss; +// u8 rx_flags; +// u8 band; +// u8 antenna; + s8 signal; + u8 chains; + s8 chain_signal[4]; +// u8 ampdu_delimiter_crc; +// u8 zero_length_psdu_type; +}; + +/** + * struct ieee80211_tx_rate - rate selection/status + * + * @idx: rate index to attempt to send with + * @flags: rate control flags (&enum mac80211_rate_control_flags) + * @count: number of tries in this rate before going to the next rate + * + * A value of -1 for @idx indicates an invalid rate and, if used + * in an array of retry rates, that no more rates should be tried. + * + * When used for transmit status reporting, the driver should + * always report the rate along with the flags it used. + * + * &struct ieee80211_tx_info contains an array of these structs + * in the control information, and it will be filled by the rate + * control algorithm according to what should be sent. For example, + * if this array contains, in the format { , } the + * information:: + * + * { 3, 2 }, { 2, 2 }, { 1, 4 }, { -1, 0 }, { -1, 0 } + * + * then this means that the frame should be transmitted + * up to twice at rate 3, up to twice at rate 2, and up to four + * times at rate 1 if it doesn't get acknowledged. Say it gets + * acknowledged by the peer after the fifth attempt, the status + * information should then contain:: + * + * { 3, 2 }, { 2, 2 }, { 1, 1 }, { -1, 0 } ... + * + * since it was transmitted twice at rate 3, twice at rate 2 + * and once at rate 1 after which we received an acknowledgement. + */ +struct ieee80211_tx_rate { + s8 idx; + u16 count:5, + flags:11; +} __packed; + +struct ieee80211_tx_info { + /* common information */ + u32 flags; + u32 band:3, + ack_frame_id:13, + hw_queue:4, + tx_time_est:10; + /* 2 free bits */ + + union { + struct { + struct ieee80211_tx_rate rates[4]; + s32 ack_signal; + u8 ampdu_ack_len; + u8 ampdu_len; + u8 antenna; + u16 tx_time; + bool is_valid_ack_signal; + void *status_driver_data[19 / sizeof(void *)]; + } status; + }; +}; + +/** + * struct ieee80211_mcs_info - MCS information + * @rx_mask: RX mask + * @rx_highest: highest supported RX rate. If set represents + * the highest supported RX data rate in units of 1 Mbps. + * If this field is 0 this value should not be used to + * consider the highest RX data rate supported. + * @tx_params: TX parameters + */ +struct ieee80211_mcs_info { + u8 rx_mask[10]; + __le16 rx_highest; + u8 tx_params; + u8 reserved[3]; +} __packed; + +/** + * struct ieee80211_sta_ht_cap - STA's HT capabilities + * + * This structure describes most essential parameters needed + * to describe 802.11n HT capabilities for an STA. + * + * @ht_supported: is HT supported by the STA + * @cap: HT capabilities map as described in 802.11n spec + * @ampdu_factor: Maximum A-MPDU length factor + * @ampdu_density: Minimum A-MPDU spacing + * @mcs: Supported MCS rates + */ +struct ieee80211_sta_ht_cap { + u16 cap; /* use IEEE80211_HT_CAP_ */ + bool ht_supported; + u8 ampdu_factor; + u8 ampdu_density; + struct ieee80211_mcs_info mcs; +}; + +/** + * struct ieee80211_sta_vht_cap - STA's VHT capabilities + * + * This structure describes most essential parameters needed + * to describe 802.11ac VHT capabilities for an STA. + * + * @vht_supported: is VHT supported by the STA + * @cap: VHT capabilities map as described in 802.11ac spec + * @vht_mcs: Supported VHT MCS rates + */ +struct ieee80211_sta_vht_cap { + bool vht_supported; + u32 cap; /* use IEEE80211_VHT_CAP_ */ + struct ieee80211_vht_mcs_info vht_mcs; +}; + +/** + * struct ieee80211_vht_cap - VHT capabilities + * + * This structure is the "VHT capabilities element" as + * described in 802.11ac D3.0 8.4.2.160 + * @vht_cap_info: VHT capability info + * @supp_mcs: VHT MCS supported rates + */ +struct ieee80211_vht_cap { + __le32 vht_cap_info; + struct ieee80211_vht_mcs_info supp_mcs; +} __packed; + +static inline int ieee80211_get_vht_max_nss(struct ieee80211_vht_cap *cap, + int bw, + int mcs, bool ext_nss_bw_capable, + unsigned int max_vht_nss) +{ + u16 map = le16_to_cpu(cap->supp_mcs.rx_mcs_map); + int ext_nss_bw; + int supp_width; + int i, mcs_encoding; + + if (map == 0xffff) + return 0; + + if (WARN_ON(mcs > 9 || max_vht_nss > 8)) + return 0; + if (mcs <= 7) + mcs_encoding = 0; + else if (mcs == 8) + mcs_encoding = 1; + else + mcs_encoding = 2; + + if (!max_vht_nss) { + /* find max_vht_nss for the given MCS */ + for (i = 7; i >= 0; i--) { + int supp = (map >> (2 * i)) & 3; + + if (supp == 3) + continue; + + if (supp >= mcs_encoding) { + max_vht_nss = i + 1; + break; + } + } + } + + if (!(cap->supp_mcs.tx_mcs_map & + cpu_to_le16(IEEE80211_VHT_EXT_NSS_BW_CAPABLE))) + return max_vht_nss; + + ext_nss_bw = le32_get_bits(cap->vht_cap_info, + IEEE80211_VHTCAP_EXT_NSS_BW_MASK); + supp_width = le32_get_bits(cap->vht_cap_info, + IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_MASK); + + /* if not capable, treat ext_nss_bw as 0 */ + if (!ext_nss_bw_capable) + ext_nss_bw = 0; + + /* This is invalid */ + if (supp_width == 3) + return 0; + + /* This is an invalid combination so pretend nothing is supported */ + if (supp_width == 2 && (ext_nss_bw == 1 || ext_nss_bw == 2)) + return 0; + + /* + * Cover all the special cases according to IEEE 802.11-2016 + * Table 9-250. All other cases are either factor of 1 or not + * valid/supported. + */ + switch (bw) { + case IEEE80211_VHT_CHANWIDTH_USE_HT: + case IEEE80211_VHT_CHANWIDTH_80MHZ: + if ((supp_width == 1 || supp_width == 2) && + ext_nss_bw == 3) + return 2 * max_vht_nss; + break; + case IEEE80211_VHT_CHANWIDTH_160MHZ: + if (supp_width == 0 && + (ext_nss_bw == 1 || ext_nss_bw == 2)) + return max_vht_nss / 2; + if (supp_width == 0 && + ext_nss_bw == 3) + return (3 * max_vht_nss) / 4; + if (supp_width == 1 && + ext_nss_bw == 3) + return 2 * max_vht_nss; + break; + case IEEE80211_VHT_CHANWIDTH_80P80MHZ: + if (supp_width == 0 && ext_nss_bw == 1) + return 0; /* not possible */ + if (supp_width == 0 && + ext_nss_bw == 2) + return max_vht_nss / 2; + if (supp_width == 0 && + ext_nss_bw == 3) + return (3 * max_vht_nss) / 4; + if (supp_width == 1 && + ext_nss_bw == 0) + return 0; /* not possible */ + if (supp_width == 1 && + ext_nss_bw == 1) + return max_vht_nss / 2; + if (supp_width == 1 && + ext_nss_bw == 2) + return (3 * max_vht_nss) / 4; + break; + } + + /* not covered or invalid combination received */ + return max_vht_nss; +} + +#define IWL_MVM_UAPSD_NOAGG_BSSIDS_NUM 20 + +#define IWL_MVM_DEFAULT_PS_TX_DATA_TIMEOUT (100 * USEC_PER_MSEC) +#define IWL_MVM_DEFAULT_PS_RX_DATA_TIMEOUT (100 * USEC_PER_MSEC) +#define IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT (10 * USEC_PER_MSEC) +#define IWL_MVM_WOWLAN_PS_RX_DATA_TIMEOUT (10 * USEC_PER_MSEC) +#define IWL_MVM_SHORT_PS_TX_DATA_TIMEOUT (2 * 1024) /* defined in TU */ +#define IWL_MVM_SHORT_PS_RX_DATA_TIMEOUT (40 * 1024) /* defined in TU */ +#define IWL_MVM_P2P_LOWLATENCY_PS_ENABLE 0 +#define IWL_MVM_UAPSD_RX_DATA_TIMEOUT (50 * USEC_PER_MSEC) +#define IWL_MVM_UAPSD_TX_DATA_TIMEOUT (50 * USEC_PER_MSEC) +#define IWL_MVM_UAPSD_QUEUES (IEEE80211_WMM_IE_STA_QOSINFO_AC_VO |\ + IEEE80211_WMM_IE_STA_QOSINFO_AC_VI |\ + IEEE80211_WMM_IE_STA_QOSINFO_AC_BK |\ + IEEE80211_WMM_IE_STA_QOSINFO_AC_BE) +#define IWL_MVM_PS_HEAVY_TX_THLD_PACKETS 20 +#define IWL_MVM_PS_HEAVY_RX_THLD_PACKETS 8 +#define IWL_MVM_PS_SNOOZE_HEAVY_TX_THLD_PACKETS 30 +#define IWL_MVM_PS_SNOOZE_HEAVY_RX_THLD_PACKETS 20 +#define IWL_MVM_PS_HEAVY_TX_THLD_PERCENT 50 +#define IWL_MVM_PS_HEAVY_RX_THLD_PERCENT 50 +#define IWL_MVM_PS_SNOOZE_INTERVAL 25 +#define IWL_MVM_PS_SNOOZE_WINDOW 50 +#define IWL_MVM_WOWLAN_PS_SNOOZE_WINDOW 25 +#define IWL_MVM_LOWLAT_QUOTA_MIN_PERCENT 64 +#define IWL_MVM_BT_COEX_EN_RED_TXP_THRESH 62 +#define IWL_MVM_BT_COEX_DIS_RED_TXP_THRESH 65 +#define IWL_MVM_BT_COEX_SYNC2SCO 1 +#define IWL_MVM_BT_COEX_MPLUT 1 +#define IWL_MVM_BT_COEX_RRC 1 +#define IWL_MVM_BT_COEX_TTC 1 +#define IWL_MVM_BT_COEX_MPLUT_REG0 0x22002200 +#define IWL_MVM_BT_COEX_MPLUT_REG1 0x11118451 +#define IWL_MVM_BT_COEX_ANTENNA_COUPLING_THRS 30 +#define IWL_MVM_FW_MCAST_FILTER_PASS_ALL 0 +#define IWL_MVM_FW_BCAST_FILTER_PASS_ALL 0 +#define IWL_MVM_QUOTA_THRESHOLD 4 +#define IWL_MVM_RS_RSSI_BASED_INIT_RATE 0 +#define IWL_MVM_RS_80_20_FAR_RANGE_TWEAK 1 +#define IWL_MVM_TOF_IS_RESPONDER 0 +#define IWL_MVM_HW_CSUM_DISABLE 0 +#define IWL_MVM_PARSE_NVM 0 +#define IWL_MVM_ADWELL_ENABLE 1 +#define IWL_MVM_ADWELL_MAX_BUDGET 0 +#define IWL_MVM_TCM_LOAD_MEDIUM_THRESH 10 /* percentage */ +#define IWL_MVM_TCM_LOAD_HIGH_THRESH 50 /* percentage */ +#define IWL_MVM_TCM_LOWLAT_ENABLE_THRESH 100 /* packets/10 seconds */ +#define IWL_MVM_UAPSD_NONAGG_PERIOD 5000 /* msecs */ +#define IWL_MVM_UAPSD_NOAGG_LIST_LEN IWL_MVM_UAPSD_NOAGG_BSSIDS_NUM +#define IWL_MVM_NON_TRANSMITTING_AP 0 +#define IWL_MVM_RS_NUM_TRY_BEFORE_ANT_TOGGLE 1 +#define IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE 2 +#define IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE_TW 1 +#define IWL_MVM_RS_INITIAL_MIMO_NUM_RATES 3 +#define IWL_MVM_RS_INITIAL_SISO_NUM_RATES 3 +#define IWL_MVM_RS_INITIAL_LEGACY_NUM_RATES 2 +#define IWL_MVM_RS_INITIAL_LEGACY_RETRIES 2 +#define IWL_MVM_RS_SECONDARY_LEGACY_RETRIES 1 +#define IWL_MVM_RS_SECONDARY_LEGACY_NUM_RATES 16 +#define IWL_MVM_RS_SECONDARY_SISO_NUM_RATES 3 +#define IWL_MVM_RS_SECONDARY_SISO_RETRIES 1 +#define IWL_MVM_RS_RATE_MIN_FAILURE_TH 3 +#define IWL_MVM_RS_RATE_MIN_SUCCESS_TH 8 +#define IWL_MVM_RS_STAY_IN_COLUMN_TIMEOUT 5 /* Seconds */ +#define IWL_MVM_RS_IDLE_TIMEOUT 5 /* Seconds */ +#define IWL_MVM_RS_MISSED_RATE_MAX 15 +#define IWL_MVM_RS_LEGACY_FAILURE_LIMIT 160 +#define IWL_MVM_RS_LEGACY_SUCCESS_LIMIT 480 +#define IWL_MVM_RS_LEGACY_TABLE_COUNT 160 +#define IWL_MVM_RS_NON_LEGACY_FAILURE_LIMIT 400 +#define IWL_MVM_RS_NON_LEGACY_SUCCESS_LIMIT 4500 +#define IWL_MVM_RS_NON_LEGACY_TABLE_COUNT 1500 +#define IWL_MVM_RS_SR_FORCE_DECREASE 15 /* percent */ +#define IWL_MVM_RS_SR_NO_DECREASE 85 /* percent */ +#define IWL_MVM_RS_AGG_TIME_LIMIT 4000 /* 4 msecs. valid 100-8000 */ +#define IWL_MVM_RS_AGG_DISABLE_START 3 +#define IWL_MVM_RS_AGG_START_THRESHOLD 10 /* num frames per second */ +#define IWL_MVM_RS_TPC_SR_FORCE_INCREASE 75 /* percent */ +#define IWL_MVM_RS_TPC_SR_NO_INCREASE 85 /* percent */ +#define IWL_MVM_RS_TPC_TX_POWER_STEP 3 +#define IWL_MVM_ENABLE_EBS 1 +#define IWL_MVM_FTM_INITIATOR_ALGO IWL_TOF_ALGO_TYPE_MAX_LIKE +#define IWL_MVM_FTM_INITIATOR_DYNACK true +#define IWL_MVM_FTM_R2I_MAX_REP 7 +#define IWL_MVM_FTM_I2R_MAX_REP 7 +#define IWL_MVM_FTM_R2I_MAX_STS 1 +#define IWL_MVM_FTM_I2R_MAX_STS 1 +#define IWL_MVM_FTM_R2I_MAX_TOTAL_LTF 3 +#define IWL_MVM_FTM_I2R_MAX_TOTAL_LTF 3 +#define IWL_MVM_FTM_INITIATOR_SECURE_LTF false +#define IWL_MVM_FTM_RESP_NDP_SUPPORT true +#define IWL_MVM_FTM_RESP_LMR_FEEDBACK_SUPPORT true +#define IWL_MVM_D3_DEBUG false +#define IWL_MVM_USE_TWT true +#define IWL_MVM_AMPDU_CONSEC_DROPS_DELBA 10 +#define IWL_MVM_USE_NSSN_SYNC 0 +#define IWL_MVM_PHY_FILTER_CHAIN_A 0 +#define IWL_MVM_PHY_FILTER_CHAIN_B 0 +#define IWL_MVM_PHY_FILTER_CHAIN_C 0 +#define IWL_MVM_PHY_FILTER_CHAIN_D 0 +#define IWL_MVM_FTM_INITIATOR_ENABLE_SMOOTH false +#define IWL_MVM_FTM_INITIATOR_SMOOTH_ALPHA 40 +/* 20016 pSec is 6 meter RTT, meaning 3 meter range */ +#define IWL_MVM_FTM_INITIATOR_SMOOTH_UNDERSHOOT 20016 +#define IWL_MVM_FTM_INITIATOR_SMOOTH_OVERSHOOT 20016 +#define IWL_MVM_FTM_INITIATOR_SMOOTH_AGE_SEC 2 +#define IWL_MVM_DISABLE_AP_FILS false +#define IWL_MVM_6GHZ_PASSIVE_SCAN_TIMEOUT 3000 /* in seconds */ +#define IWL_MVM_6GHZ_PASSIVE_SCAN_ASSOC_TIMEOUT 60 /* in seconds */ + +#define IWL_MAX_TID_COUNT 8 +#define IWL_MGMT_TID 15 +#define IWL_FRAME_LIMIT 64 +#define IWL_MAX_RX_HW_QUEUES 16 +#define IWL_9000_MAX_RX_HW_QUEUES 6 + +/* Antenna presence definitions */ +#define ANT_NONE 0x0 +#define ANT_INVALID 0xff +#define ANT_A BIT(0) +#define ANT_B BIT(1) +#define ANT_C BIT(2) +#define ANT_AB (ANT_A | ANT_B) +#define ANT_AC (ANT_A | ANT_C) +#define ANT_BC (ANT_B | ANT_C) +#define ANT_ABC (ANT_A | ANT_B | ANT_C) +#define MAX_ANT_NUM 3 + +#define IWL_RATE_BIT_MSK(r) BIT(IWL_RATE_##r##M_INDEX) + +/* fw API values for legacy bit rates, both OFDM and CCK */ +enum { + IWL_RATE_6M_PLCP = 13, + IWL_RATE_9M_PLCP = 15, + IWL_RATE_12M_PLCP = 5, + IWL_RATE_18M_PLCP = 7, + IWL_RATE_24M_PLCP = 9, + IWL_RATE_36M_PLCP = 11, + IWL_RATE_48M_PLCP = 1, + IWL_RATE_54M_PLCP = 3, + IWL_RATE_1M_PLCP = 10, + IWL_RATE_2M_PLCP = 20, + IWL_RATE_5M_PLCP = 55, + IWL_RATE_11M_PLCP = 110, + IWL_RATE_INVM_PLCP = 0xff, +}; + +static inline u8 num_of_ant(u8 mask) +{ + return !!((mask) & ANT_A) + + !!((mask) & ANT_B) + + !!((mask) & ANT_C); +} + +/* + * Returns the first antenna as ANT_[ABC], as defined in iwl-config.h. + * The parameter should also be a combination of ANT_[ABC]. + */ +static inline u8 first_antenna(u8 mask) +{ + BUILD_BUG_ON(ANT_A != BIT(0)); /* using ffs is wrong if not */ + if (WARN_ON_ONCE(!mask)) /* ffs will return 0 if mask is zeroed */ + return BIT(0); + return BIT(ffs(mask) - 1); +} + +/* + * These serve as indexes into + * struct iwl_rate_info fw_rate_idx_to_plcp[IWL_RATE_COUNT]; + * TODO: avoid overlap between legacy and HT rates + */ +enum { + IWL_RATE_1M_INDEX = 0, + IWL_FIRST_CCK_RATE = IWL_RATE_1M_INDEX, + IWL_RATE_2M_INDEX, + IWL_RATE_5M_INDEX, + IWL_RATE_11M_INDEX, + IWL_LAST_CCK_RATE = IWL_RATE_11M_INDEX, + IWL_RATE_6M_INDEX, + IWL_FIRST_OFDM_RATE = IWL_RATE_6M_INDEX, + IWL_RATE_MCS_0_INDEX = IWL_RATE_6M_INDEX, + IWL_FIRST_HT_RATE = IWL_RATE_MCS_0_INDEX, + IWL_FIRST_VHT_RATE = IWL_RATE_MCS_0_INDEX, + IWL_RATE_9M_INDEX, + IWL_RATE_12M_INDEX, + IWL_RATE_MCS_1_INDEX = IWL_RATE_12M_INDEX, + IWL_RATE_18M_INDEX, + IWL_RATE_MCS_2_INDEX = IWL_RATE_18M_INDEX, + IWL_RATE_24M_INDEX, + IWL_RATE_MCS_3_INDEX = IWL_RATE_24M_INDEX, + IWL_RATE_36M_INDEX, + IWL_RATE_MCS_4_INDEX = IWL_RATE_36M_INDEX, + IWL_RATE_48M_INDEX, + IWL_RATE_MCS_5_INDEX = IWL_RATE_48M_INDEX, + IWL_RATE_54M_INDEX, + IWL_RATE_MCS_6_INDEX = IWL_RATE_54M_INDEX, + IWL_LAST_NON_HT_RATE = IWL_RATE_54M_INDEX, + IWL_RATE_60M_INDEX, + IWL_RATE_MCS_7_INDEX = IWL_RATE_60M_INDEX, + IWL_LAST_HT_RATE = IWL_RATE_MCS_7_INDEX, + IWL_RATE_MCS_8_INDEX, + IWL_RATE_MCS_9_INDEX, + IWL_LAST_VHT_RATE = IWL_RATE_MCS_9_INDEX, + IWL_RATE_MCS_10_INDEX, + IWL_RATE_MCS_11_INDEX, + IWL_LAST_HE_RATE = IWL_RATE_MCS_11_INDEX, + IWL_RATE_COUNT_LEGACY = IWL_LAST_NON_HT_RATE + 1, + IWL_RATE_COUNT = IWL_LAST_HE_RATE + 1, +}; + +/* + * rate_n_flags bit fields + * + * The 32-bit value has different layouts in the low 8 bites depending on the + * format. There are three formats, HT, VHT and legacy (11abg, with subformats + * for CCK and OFDM). + * + * High-throughput (HT) rate format + * bit 8 is 1, bit 26 is 0, bit 9 is 0 (OFDM) + * Very High-throughput (VHT) rate format + * bit 8 is 0, bit 26 is 1, bit 9 is 0 (OFDM) + * Legacy OFDM rate format for bits 7:0 + * bit 8 is 0, bit 26 is 0, bit 9 is 0 (OFDM) + * Legacy CCK rate format for bits 7:0: + * bit 8 is 0, bit 26 is 0, bit 9 is 1 (CCK) + */ + +/* Bit 8: (1) HT format, (0) legacy or VHT format */ +#define RATE_MCS_HT_POS 8 +#define RATE_MCS_HT_MSK (1 << RATE_MCS_HT_POS) + +/* Bit 9: (1) CCK, (0) OFDM. HT (bit 8) must be "0" for this bit to be valid */ +#define RATE_MCS_CCK_POS 9 +#define RATE_MCS_CCK_MSK (1 << RATE_MCS_CCK_POS) + +/* Bit 26: (1) VHT format, (0) legacy format in bits 8:0 */ +#define RATE_MCS_VHT_POS 26 +#define RATE_MCS_VHT_MSK (1 << RATE_MCS_VHT_POS) + + +/* + * High-throughput (HT) rate format for bits 7:0 + * + * 2-0: MCS rate base + * 0) 6 Mbps + * 1) 12 Mbps + * 2) 18 Mbps + * 3) 24 Mbps + * 4) 36 Mbps + * 5) 48 Mbps + * 6) 54 Mbps + * 7) 60 Mbps + * 4-3: 0) Single stream (SISO) + * 1) Dual stream (MIMO) + * 2) Triple stream (MIMO) + * 5: Value of 0x20 in bits 7:0 indicates 6 Mbps HT40 duplicate data + * (bits 7-6 are zero) + * + * Together the low 5 bits work out to the MCS index because we don't + * support MCSes above 15/23, and 0-7 have one stream, 8-15 have two + * streams and 16-23 have three streams. We could also support MCS 32 + * which is the duplicate 20 MHz MCS (bit 5 set, all others zero.) + */ +#define RATE_HT_MCS_RATE_CODE_MSK 0x7 +#define RATE_HT_MCS_NSS_POS 3 +#define RATE_HT_MCS_NSS_MSK (3 << RATE_HT_MCS_NSS_POS) + +/* Bit 10: (1) Use Green Field preamble */ +#define RATE_HT_MCS_GF_POS 10 +#define RATE_HT_MCS_GF_MSK (1 << RATE_HT_MCS_GF_POS) + +#define RATE_HT_MCS_INDEX_MSK 0x3f + +/* + * Very High-throughput (VHT) rate format for bits 7:0 + * + * 3-0: VHT MCS (0-9) + * 5-4: number of streams - 1: + * 0) Single stream (SISO) + * 1) Dual stream (MIMO) + * 2) Triple stream (MIMO) + */ + +/* Bit 4-5: (0) SISO, (1) MIMO2 (2) MIMO3 */ +#define RATE_VHT_MCS_RATE_CODE_MSK 0xf +#define RATE_VHT_MCS_NSS_POS 4 +#define RATE_VHT_MCS_NSS_MSK (3 << RATE_VHT_MCS_NSS_POS) + +/* + * Legacy OFDM rate format for bits 7:0 + * + * 3-0: 0xD) 6 Mbps + * 0xF) 9 Mbps + * 0x5) 12 Mbps + * 0x7) 18 Mbps + * 0x9) 24 Mbps + * 0xB) 36 Mbps + * 0x1) 48 Mbps + * 0x3) 54 Mbps + * (bits 7-4 are 0) + * + * Legacy CCK rate format for bits 7:0: + * bit 8 is 0, bit 26 is 0, bit 9 is 1 (CCK): + * + * 6-0: 10) 1 Mbps + * 20) 2 Mbps + * 55) 5.5 Mbps + * 110) 11 Mbps + * (bit 7 is 0) + */ +#define RATE_LEGACY_RATE_MSK 0xff + +/* Bit 10 - OFDM HE */ +#define RATE_MCS_HE_POS 10 +#define RATE_MCS_HE_MSK BIT(RATE_MCS_HE_POS) + +/* + * Bit 11-12: (0) 20MHz, (1) 40MHz, (2) 80MHz, (3) 160MHz + * 0 and 1 are valid for HT and VHT, 2 and 3 only for VHT + */ +#define RATE_MCS_CHAN_WIDTH_POS 11 +#define RATE_MCS_CHAN_WIDTH_MSK (3 << RATE_MCS_CHAN_WIDTH_POS) +#define RATE_MCS_CHAN_WIDTH_20 (0 << RATE_MCS_CHAN_WIDTH_POS) +#define RATE_MCS_CHAN_WIDTH_40 (1 << RATE_MCS_CHAN_WIDTH_POS) +#define RATE_MCS_CHAN_WIDTH_80 (2 << RATE_MCS_CHAN_WIDTH_POS) +#define RATE_MCS_CHAN_WIDTH_160 (3 << RATE_MCS_CHAN_WIDTH_POS) + +/* Bit 13: (1) Short guard interval (0.4 usec), (0) normal GI (0.8 usec) */ +#define RATE_MCS_SGI_POS 13 +#define RATE_MCS_SGI_MSK (1 << RATE_MCS_SGI_POS) + +/* Bit 14-16: Antenna selection (1) Ant A, (2) Ant B, (4) Ant C */ +#define RATE_MCS_ANT_POS 14 +#define RATE_MCS_ANT_A_MSK (1 << RATE_MCS_ANT_POS) +#define RATE_MCS_ANT_B_MSK (2 << RATE_MCS_ANT_POS) +#define RATE_MCS_ANT_C_MSK (4 << RATE_MCS_ANT_POS) +#define RATE_MCS_ANT_AB_MSK (RATE_MCS_ANT_A_MSK | \ + RATE_MCS_ANT_B_MSK) +#define RATE_MCS_ANT_ABC_MSK (RATE_MCS_ANT_AB_MSK | \ + RATE_MCS_ANT_C_MSK) +#define RATE_MCS_ANT_MSK RATE_MCS_ANT_ABC_MSK + +/* Bit 17: (0) SS, (1) SS*2 */ +#define RATE_MCS_STBC_POS 17 +#define RATE_MCS_STBC_MSK BIT(RATE_MCS_STBC_POS) + +/* Bit 18: OFDM-HE dual carrier mode */ +#define RATE_HE_DUAL_CARRIER_MODE 18 +#define RATE_HE_DUAL_CARRIER_MODE_MSK BIT(RATE_HE_DUAL_CARRIER_MODE) + +/* Bit 19: (0) Beamforming is off, (1) Beamforming is on */ +#define RATE_MCS_BF_POS 19 +#define RATE_MCS_BF_MSK (1 << RATE_MCS_BF_POS) + +/* + * Bit 20-21: HE LTF type and guard interval + * HE (ext) SU: + * 0 1xLTF+0.8us + * 1 2xLTF+0.8us + * 2 2xLTF+1.6us + * 3 & SGI (bit 13) clear 4xLTF+3.2us + * 3 & SGI (bit 13) set 4xLTF+0.8us + * HE MU: + * 0 4xLTF+0.8us + * 1 2xLTF+0.8us + * 2 2xLTF+1.6us + * 3 4xLTF+3.2us + * HE TRIG: + * 0 1xLTF+1.6us + * 1 2xLTF+1.6us + * 2 4xLTF+3.2us + * 3 (does not occur) + */ +#define RATE_MCS_HE_GI_LTF_POS 20 +#define RATE_MCS_HE_GI_LTF_MSK (3 << RATE_MCS_HE_GI_LTF_POS) + +/* Bit 22-23: HE type. (0) SU, (1) SU_EXT, (2) MU, (3) trigger based */ +#define RATE_MCS_HE_TYPE_POS 22 +#define RATE_MCS_HE_TYPE_SU (0 << RATE_MCS_HE_TYPE_POS) +#define RATE_MCS_HE_TYPE_EXT_SU (1 << RATE_MCS_HE_TYPE_POS) +#define RATE_MCS_HE_TYPE_MU (2 << RATE_MCS_HE_TYPE_POS) +#define RATE_MCS_HE_TYPE_TRIG (3 << RATE_MCS_HE_TYPE_POS) +#define RATE_MCS_HE_TYPE_MSK (3 << RATE_MCS_HE_TYPE_POS) + +/* Bit 24-25: (0) 20MHz (no dup), (1) 2x20MHz, (2) 4x20MHz, 3 8x20MHz */ +#define RATE_MCS_DUP_POS 24 +#define RATE_MCS_DUP_MSK (3 << RATE_MCS_DUP_POS) + +/* Bit 27: (1) LDPC enabled, (0) LDPC disabled */ +#define RATE_MCS_LDPC_POS 27 +#define RATE_MCS_LDPC_MSK (1 << RATE_MCS_LDPC_POS) + +/* Bit 28: (1) 106-tone RX (8 MHz RU), (0) normal bandwidth */ +#define RATE_MCS_HE_106T_POS 28 +#define RATE_MCS_HE_106T_MSK (1 << RATE_MCS_HE_106T_POS) + +/* Bit 30-31: (1) RTS, (2) CTS */ +#define RATE_MCS_RTS_REQUIRED_POS (30) +#define RATE_MCS_RTS_REQUIRED_MSK (0x1 << RATE_MCS_RTS_REQUIRED_POS) + +#define RATE_MCS_CTS_REQUIRED_POS (31) +#define RATE_MCS_CTS_REQUIRED_MSK (0x1 << RATE_MCS_CTS_REQUIRED_POS) + +/* Link Quality definitions */ + +/* # entries in rate scale table to support Tx retries */ +#define LQ_MAX_RETRY_NUM 16 + +/* Link quality command flags bit fields */ + +/* Bit 0: (0) Don't use RTS (1) Use RTS */ +#define LQ_FLAG_USE_RTS_POS 0 +#define LQ_FLAG_USE_RTS_MSK (1 << LQ_FLAG_USE_RTS_POS) + +/* Bit 1-3: LQ command color. Used to match responses to LQ commands */ +#define LQ_FLAG_COLOR_POS 1 +#define LQ_FLAG_COLOR_MSK (7 << LQ_FLAG_COLOR_POS) +#define LQ_FLAG_COLOR_GET(_f) (((_f) & LQ_FLAG_COLOR_MSK) >>\ + LQ_FLAG_COLOR_POS) +#define LQ_FLAGS_COLOR_INC(_c) ((((_c) + 1) << LQ_FLAG_COLOR_POS) &\ + LQ_FLAG_COLOR_MSK) +#define LQ_FLAG_COLOR_SET(_f, _c) ((_c) | ((_f) & ~LQ_FLAG_COLOR_MSK)) + +/* Bit 4-5: Tx RTS BW Signalling + * (0) No RTS BW signalling + * (1) Static BW signalling + * (2) Dynamic BW signalling + */ +#define LQ_FLAG_RTS_BW_SIG_POS 4 +#define LQ_FLAG_RTS_BW_SIG_NONE (0 << LQ_FLAG_RTS_BW_SIG_POS) +#define LQ_FLAG_RTS_BW_SIG_STATIC (1 << LQ_FLAG_RTS_BW_SIG_POS) +#define LQ_FLAG_RTS_BW_SIG_DYNAMIC (2 << LQ_FLAG_RTS_BW_SIG_POS) + +/* Bit 6: (0) No dynamic BW selection (1) Allow dynamic BW selection + * Dyanmic BW selection allows Tx with narrower BW then requested in rates + */ +#define LQ_FLAG_DYNAMIC_BW_POS 6 +#define LQ_FLAG_DYNAMIC_BW_MSK (1 << LQ_FLAG_DYNAMIC_BW_POS) + +/* Single Stream Tx Parameters (lq_cmd->ss_params) + * Flags to control a smart FW decision about whether BFER/STBC/SISO will be + * used for single stream Tx. + */ + +/* Bit 0-1: Max STBC streams allowed. Can be 0-3. + * (0) - No STBC allowed + * (1) - 2x1 STBC allowed (HT/VHT) + * (2) - 4x2 STBC allowed (HT/VHT) + * (3) - 3x2 STBC allowed (HT only) + * All our chips are at most 2 antennas so only (1) is valid for now. + */ +#define LQ_SS_STBC_ALLOWED_POS 0 +#define LQ_SS_STBC_ALLOWED_MSK (3 << LQ_SS_STBC_ALLOWED_MSK) + +/* 2x1 STBC is allowed */ +#define LQ_SS_STBC_1SS_ALLOWED (1 << LQ_SS_STBC_ALLOWED_POS) + +/* Bit 2: Beamformer (VHT only) is allowed */ +#define LQ_SS_BFER_ALLOWED_POS 2 +#define LQ_SS_BFER_ALLOWED (1 << LQ_SS_BFER_ALLOWED_POS) + +/* Bit 3: Force BFER or STBC for testing + * If this is set: + * If BFER is allowed then force the ucode to choose BFER else + * If STBC is allowed then force the ucode to choose STBC over SISO + */ +#define LQ_SS_FORCE_POS 3 +#define LQ_SS_FORCE (1 << LQ_SS_FORCE_POS) + +/* Bit 31: ss_params field is valid. Used for FW backward compatibility + * with other drivers which don't support the ss_params API yet + */ +#define LQ_SS_PARAMS_VALID_POS 31 +#define LQ_SS_PARAMS_VALID (1 << LQ_SS_PARAMS_VALID_POS) + +struct iwl_rs_rate_info { + u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */ + u8 plcp_ht_siso; /* uCode API: IWL_RATE_SISO_6M_PLCP, etc. */ + u8 plcp_ht_mimo2; /* uCode API: IWL_RATE_MIMO2_6M_PLCP, etc. */ + u8 plcp_vht_siso; + u8 plcp_vht_mimo2; + u8 prev_rs; /* previous rate used in rs algo */ + u8 next_rs; /* next rate used in rs algo */ +}; + +#define IWL_RATE_60M_PLCP 3 + +enum { + IWL_RATE_INVM_INDEX = IWL_RATE_COUNT, + IWL_RATE_INVALID = IWL_RATE_COUNT, +}; + +#define LINK_QUAL_MAX_RETRY_NUM 16 + +enum { + IWL_RATE_6M_INDEX_TABLE = 0, + IWL_RATE_9M_INDEX_TABLE, + IWL_RATE_12M_INDEX_TABLE, + IWL_RATE_18M_INDEX_TABLE, + IWL_RATE_24M_INDEX_TABLE, + IWL_RATE_36M_INDEX_TABLE, + IWL_RATE_48M_INDEX_TABLE, + IWL_RATE_54M_INDEX_TABLE, + IWL_RATE_1M_INDEX_TABLE, + IWL_RATE_2M_INDEX_TABLE, + IWL_RATE_5M_INDEX_TABLE, + IWL_RATE_11M_INDEX_TABLE, + IWL_RATE_INVM_INDEX_TABLE = IWL_RATE_INVM_INDEX - 1, +}; + +/* #define vs. enum to keep from defaulting to 'large integer' */ +#define IWL_RATE_6M_MASK (1 << IWL_RATE_6M_INDEX) +#define IWL_RATE_9M_MASK (1 << IWL_RATE_9M_INDEX) +#define IWL_RATE_12M_MASK (1 << IWL_RATE_12M_INDEX) +#define IWL_RATE_18M_MASK (1 << IWL_RATE_18M_INDEX) +#define IWL_RATE_24M_MASK (1 << IWL_RATE_24M_INDEX) +#define IWL_RATE_36M_MASK (1 << IWL_RATE_36M_INDEX) +#define IWL_RATE_48M_MASK (1 << IWL_RATE_48M_INDEX) +#define IWL_RATE_54M_MASK (1 << IWL_RATE_54M_INDEX) +#define IWL_RATE_60M_MASK (1 << IWL_RATE_60M_INDEX) +#define IWL_RATE_1M_MASK (1 << IWL_RATE_1M_INDEX) +#define IWL_RATE_2M_MASK (1 << IWL_RATE_2M_INDEX) +#define IWL_RATE_5M_MASK (1 << IWL_RATE_5M_INDEX) +#define IWL_RATE_11M_MASK (1 << IWL_RATE_11M_INDEX) + + +/* uCode API values for HT/VHT bit rates */ +enum { + IWL_RATE_HT_SISO_MCS_0_PLCP = 0, + IWL_RATE_HT_SISO_MCS_1_PLCP = 1, + IWL_RATE_HT_SISO_MCS_2_PLCP = 2, + IWL_RATE_HT_SISO_MCS_3_PLCP = 3, + IWL_RATE_HT_SISO_MCS_4_PLCP = 4, + IWL_RATE_HT_SISO_MCS_5_PLCP = 5, + IWL_RATE_HT_SISO_MCS_6_PLCP = 6, + IWL_RATE_HT_SISO_MCS_7_PLCP = 7, + IWL_RATE_HT_MIMO2_MCS_0_PLCP = 0x8, + IWL_RATE_HT_MIMO2_MCS_1_PLCP = 0x9, + IWL_RATE_HT_MIMO2_MCS_2_PLCP = 0xA, + IWL_RATE_HT_MIMO2_MCS_3_PLCP = 0xB, + IWL_RATE_HT_MIMO2_MCS_4_PLCP = 0xC, + IWL_RATE_HT_MIMO2_MCS_5_PLCP = 0xD, + IWL_RATE_HT_MIMO2_MCS_6_PLCP = 0xE, + IWL_RATE_HT_MIMO2_MCS_7_PLCP = 0xF, + IWL_RATE_VHT_SISO_MCS_0_PLCP = 0, + IWL_RATE_VHT_SISO_MCS_1_PLCP = 1, + IWL_RATE_VHT_SISO_MCS_2_PLCP = 2, + IWL_RATE_VHT_SISO_MCS_3_PLCP = 3, + IWL_RATE_VHT_SISO_MCS_4_PLCP = 4, + IWL_RATE_VHT_SISO_MCS_5_PLCP = 5, + IWL_RATE_VHT_SISO_MCS_6_PLCP = 6, + IWL_RATE_VHT_SISO_MCS_7_PLCP = 7, + IWL_RATE_VHT_SISO_MCS_8_PLCP = 8, + IWL_RATE_VHT_SISO_MCS_9_PLCP = 9, + IWL_RATE_VHT_MIMO2_MCS_0_PLCP = 0x10, + IWL_RATE_VHT_MIMO2_MCS_1_PLCP = 0x11, + IWL_RATE_VHT_MIMO2_MCS_2_PLCP = 0x12, + IWL_RATE_VHT_MIMO2_MCS_3_PLCP = 0x13, + IWL_RATE_VHT_MIMO2_MCS_4_PLCP = 0x14, + IWL_RATE_VHT_MIMO2_MCS_5_PLCP = 0x15, + IWL_RATE_VHT_MIMO2_MCS_6_PLCP = 0x16, + IWL_RATE_VHT_MIMO2_MCS_7_PLCP = 0x17, + IWL_RATE_VHT_MIMO2_MCS_8_PLCP = 0x18, + IWL_RATE_VHT_MIMO2_MCS_9_PLCP = 0x19, + IWL_RATE_HT_SISO_MCS_INV_PLCP, + IWL_RATE_HT_MIMO2_MCS_INV_PLCP = IWL_RATE_HT_SISO_MCS_INV_PLCP, + IWL_RATE_VHT_SISO_MCS_INV_PLCP = IWL_RATE_HT_SISO_MCS_INV_PLCP, + IWL_RATE_VHT_MIMO2_MCS_INV_PLCP = IWL_RATE_HT_SISO_MCS_INV_PLCP, + IWL_RATE_HT_SISO_MCS_8_PLCP = IWL_RATE_HT_SISO_MCS_INV_PLCP, + IWL_RATE_HT_SISO_MCS_9_PLCP = IWL_RATE_HT_SISO_MCS_INV_PLCP, + IWL_RATE_HT_MIMO2_MCS_8_PLCP = IWL_RATE_HT_SISO_MCS_INV_PLCP, + IWL_RATE_HT_MIMO2_MCS_9_PLCP = IWL_RATE_HT_SISO_MCS_INV_PLCP, +}; + +#define IWL_RATES_MASK ((1 << IWL_RATE_COUNT) - 1) + +#define IWL_INVALID_VALUE 0xff + +#define TPC_MAX_REDUCTION 15 +#define TPC_NO_REDUCTION 0 +#define TPC_INVALID 0xff + +#define LINK_QUAL_AGG_FRAME_LIMIT_DEF (63) +#define LINK_QUAL_AGG_FRAME_LIMIT_MAX (63) +/* + * FIXME - various places in firmware API still use u8, + * e.g. LQ command and SCD config command. + * This should be 256 instead. + */ +#define LINK_QUAL_AGG_FRAME_LIMIT_GEN2_DEF (255) +#define LINK_QUAL_AGG_FRAME_LIMIT_GEN2_MAX (255) +#define LINK_QUAL_AGG_FRAME_LIMIT_MIN (0) + +#define LQ_SIZE 2 /* 2 mode tables: "Active" and "Search" */ + +/* load per tid defines for A-MPDU activation */ +#define IWL_AGG_TPT_THREHOLD 0 +#define IWL_AGG_ALL_TID 0xff + +enum iwl_table_type { + LQ_NONE, + LQ_LEGACY_G, /* legacy types */ + LQ_LEGACY_A, + LQ_HT_SISO, /* HT types */ + LQ_HT_MIMO2, + LQ_VHT_SISO, /* VHT types */ + LQ_VHT_MIMO2, + LQ_HE_SISO, /* HE types */ + LQ_HE_MIMO2, + LQ_MAX, +}; + +struct rs_rate { + int index; + enum iwl_table_type type; + u8 ant; + u32 bw; + bool sgi; + bool ldpc; + bool stbc; + bool bfer; +}; + +#define is_type_legacy(type) (((type) == LQ_LEGACY_G) || \ + ((type) == LQ_LEGACY_A)) +#define is_type_ht_siso(type) ((type) == LQ_HT_SISO) +#define is_type_ht_mimo2(type) ((type) == LQ_HT_MIMO2) +#define is_type_vht_siso(type) ((type) == LQ_VHT_SISO) +#define is_type_vht_mimo2(type) ((type) == LQ_VHT_MIMO2) +#define is_type_he_siso(type) ((type) == LQ_HE_SISO) +#define is_type_he_mimo2(type) ((type) == LQ_HE_MIMO2) +#define is_type_siso(type) (is_type_ht_siso(type) || is_type_vht_siso(type) || \ + is_type_he_siso(type)) +#define is_type_mimo2(type) (is_type_ht_mimo2(type) || \ + is_type_vht_mimo2(type) || is_type_he_mimo2(type)) +#define is_type_mimo(type) (is_type_mimo2(type)) +#define is_type_ht(type) (is_type_ht_siso(type) || is_type_ht_mimo2(type)) +#define is_type_vht(type) (is_type_vht_siso(type) || is_type_vht_mimo2(type)) +#define is_type_he(type) (is_type_he_siso(type) || is_type_he_mimo2(type)) +#define is_type_a_band(type) ((type) == LQ_LEGACY_A) +#define is_type_g_band(type) ((type) == LQ_LEGACY_G) + +#define is_legacy(rate) is_type_legacy((rate)->type) +#define is_ht_siso(rate) is_type_ht_siso((rate)->type) +#define is_ht_mimo2(rate) is_type_ht_mimo2((rate)->type) +#define is_vht_siso(rate) is_type_vht_siso((rate)->type) +#define is_vht_mimo2(rate) is_type_vht_mimo2((rate)->type) +#define is_siso(rate) is_type_siso((rate)->type) +#define is_mimo2(rate) is_type_mimo2((rate)->type) +#define is_mimo(rate) is_type_mimo((rate)->type) +#define is_ht(rate) is_type_ht((rate)->type) +#define is_vht(rate) is_type_vht((rate)->type) +#define is_he(rate) is_type_he((rate)->type) +#define is_a_band(rate) is_type_a_band((rate)->type) +#define is_g_band(rate) is_type_g_band((rate)->type) + +#define is_ht20(rate) ((rate)->bw == RATE_MCS_CHAN_WIDTH_20) +#define is_ht40(rate) ((rate)->bw == RATE_MCS_CHAN_WIDTH_40) +#define is_ht80(rate) ((rate)->bw == RATE_MCS_CHAN_WIDTH_80) +#define is_ht160(rate) ((rate)->bw == RATE_MCS_CHAN_WIDTH_160) + +#define IWL_MAX_MCS_DISPLAY_SIZE 12 + +struct iwl_rate_mcs_info { + char mbps[IWL_MAX_MCS_DISPLAY_SIZE]; + char mcs[IWL_MAX_MCS_DISPLAY_SIZE]; +}; + +/** + * struct iwl_lq_sta_rs_fw - rate and related statistics for RS in FW + * @last_rate_n_flags: last rate reported by FW + * @sta_id: the id of the station +#ifdef CONFIG_MAC80211_DEBUGFS + * @dbg_fixed_rate: for debug, use fixed rate if not 0 + * @dbg_agg_frame_count_lim: for debug, max number of frames in A-MPDU +#endif + * @chains: bitmask of chains reported in %chain_signal + * @chain_signal: per chain signal strength + * @last_rssi: last rssi reported + * @drv: pointer back to the driver data + */ + +struct iwl_lq_sta_rs_fw { + /* last tx rate_n_flags */ + u32 last_rate_n_flags; + + /* persistent fields - initialized only once - keep last! */ + struct lq_sta_pers_rs_fw { + u32 sta_id; + u8 chains; + s8 chain_signal[4]; + s8 last_rssi; + struct iwm_softc *drv; + } pers; +}; + +/** + * struct iwl_rate_scale_data -- tx success history for one rate + */ +struct iwl_rate_scale_data { + u64 data; /* bitmap of successful frames */ + s32 success_counter; /* number of frames successful */ + s32 success_ratio; /* per-cent * 128 */ + s32 counter; /* number of frames attempted */ + s32 average_tpt; /* success ratio * expected throughput */ +}; + +/* Possible Tx columns + * Tx Column = a combo of legacy/siso/mimo x antenna x SGI + */ +enum rs_column { + RS_COLUMN_LEGACY_ANT_A = 0, + RS_COLUMN_LEGACY_ANT_B, + RS_COLUMN_SISO_ANT_A, + RS_COLUMN_SISO_ANT_B, + RS_COLUMN_SISO_ANT_A_SGI, + RS_COLUMN_SISO_ANT_B_SGI, + RS_COLUMN_MIMO2, + RS_COLUMN_MIMO2_SGI, + + RS_COLUMN_LAST = RS_COLUMN_MIMO2_SGI, + RS_COLUMN_COUNT = RS_COLUMN_LAST + 1, + RS_COLUMN_INVALID, +}; + +enum rs_ss_force_opt { + RS_SS_FORCE_NONE = 0, + RS_SS_FORCE_STBC, + RS_SS_FORCE_BFER, + RS_SS_FORCE_SISO, +}; + +/* Packet stats per rate */ +struct rs_rate_stats { + u64 success; + u64 total; +}; + +/** + * struct iwl_scale_tbl_info -- tx params and success history for all rates + * + * There are two of these in struct iwl_lq_sta, + * one for "active", and one for "search". + */ +struct iwl_scale_tbl_info { + struct rs_rate rate; + enum rs_column column; + const u16 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */ + struct iwl_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */ + /* per txpower-reduction history */ + struct iwl_rate_scale_data tpc_win[TPC_MAX_REDUCTION + 1]; +}; + +enum { + RS_STATE_SEARCH_CYCLE_STARTED, + RS_STATE_SEARCH_CYCLE_ENDED, + RS_STATE_STAY_IN_COLUMN, +}; + +struct lq_sta_pers { + u8 chains; + s8 chain_signal[4]; + s8 last_rssi; + struct rs_rate_stats tx_stats[RS_COLUMN_COUNT][IWL_RATE_COUNT]; + struct iwm_softc *drv; + IOSimpleLock *lock; /* for races in reinit/update table */ +}; + +/** + * struct iwl_lq_sta -- driver's rate scaling private structure + * + * Pointer to this gets passed back and forth between driver and mac80211. + */ +struct iwl_lq_sta { + u8 active_tbl; /* index of active table, range 0-1 */ + u8 rs_state; /* RS_STATE_* */ + u8 search_better_tbl; /* 1: currently trying alternate mode */ + s32 last_tpt; + + /* The following determine when to search for a new mode */ + u32 table_count_limit; + u32 max_failure_limit; /* # failed frames before new search */ + u32 max_success_limit; /* # successful frames before new search */ + u32 table_count; + u32 total_failed; /* total failed frames, any/all rates */ + u32 total_success; /* total successful frames, any/all rates */ + u64 flush_timer; /* time staying in mode before new search */ + + u32 visited_columns; /* Bitmask marking which Tx columns were + * explored during a search cycle + */ + u64 last_tx; + bool is_vht; + bool ldpc; /* LDPC Rx is supported by the STA */ + bool stbc_capable; /* Tx STBC is supported by chip and Rx by STA */ + bool bfer_capable; /* Remote supports beamformee and we BFer */ + + enum nl80211_band band; + + /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */ + unsigned long active_legacy_rate; + unsigned long active_siso_rate; + unsigned long active_mimo2_rate; + + /* Highest rate per Tx mode */ + u8 max_legacy_rate_idx; + u8 max_siso_rate_idx; + u8 max_mimo2_rate_idx; + + /* Optimal rate based on RSSI and STA caps. + * Used only to reflect link speed to userspace. + */ + struct rs_rate optimal_rate; + unsigned long optimal_rate_mask; + const struct rs_init_rate_info *optimal_rates; + int optimal_nentries; + + u8 missed_rate_counter; + + struct iwm_lq_cmd lq; + struct iwl_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */ + u8 tx_agg_tid_en; + + /* last tx rate_n_flags */ + u32 last_rate_n_flags; + /* packets destined for this STA are aggregated */ + u8 is_agg; + + /* tx power reduce for this sta */ + int tpc_reduce; + + /* persistent fields - initialized only once - keep last! */ + struct lq_sta_pers pers; +}; + +/* ieee80211_tx_info's status_driver_data[0] is packed with lq color and txp + * Note, it's iwlmvm <-> mac80211 interface. + * bits 0-7: reduced tx power + * bits 8-10: LQ command's color + */ +#define RS_DRV_DATA_TXP_MSK 0xff +#define RS_DRV_DATA_LQ_COLOR_POS 8 +#define RS_DRV_DATA_LQ_COLOR_MSK (7 << RS_DRV_DATA_LQ_COLOR_POS) +#define RS_DRV_DATA_LQ_COLOR_GET(_f) (((_f) & RS_DRV_DATA_LQ_COLOR_MSK) >>\ + RS_DRV_DATA_LQ_COLOR_POS) +#define RS_DRV_DATA_PACK(_c, _p) ((void *)(uintptr_t)\ + (((uintptr_t)_p) |\ + ((_c) << RS_DRV_DATA_LQ_COLOR_POS))) + +#define IWL_DECLARE_RATE_INFO(r) \ + [IWL_RATE_##r##M_INDEX] = IWL_RATE_##r##M_PLCP + +/* + * Translate from fw_rate_index (IWL_RATE_XXM_INDEX) to PLCP + */ +static const u8 fw_rate_idx_to_plcp[IWL_RATE_COUNT] = { + IWL_DECLARE_RATE_INFO(1), + IWL_DECLARE_RATE_INFO(2), + IWL_DECLARE_RATE_INFO(5), + IWL_DECLARE_RATE_INFO(11), + IWL_DECLARE_RATE_INFO(6), + IWL_DECLARE_RATE_INFO(9), + IWL_DECLARE_RATE_INFO(12), + IWL_DECLARE_RATE_INFO(18), + IWL_DECLARE_RATE_INFO(24), + IWL_DECLARE_RATE_INFO(36), + IWL_DECLARE_RATE_INFO(48), + IWL_DECLARE_RATE_INFO(54), +}; + +#undef IWL_DECLARE_RATE_INFO + +static inline int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags, + enum nl80211_band band) +{ + int rate = rate_n_flags & RATE_LEGACY_RATE_MSK; + int idx; + int band_offset = 0; + + /* Legacy rate format, search for match in table */ + if (band != NL80211_BAND_2GHZ) + band_offset = IWL_FIRST_OFDM_RATE; + for (idx = band_offset; idx < IWL_RATE_COUNT_LEGACY; idx++) + if (fw_rate_idx_to_plcp[idx] == rate) + return idx - band_offset; + + return -1; +} + +static inline u8 iwl_mvm_mac80211_idx_to_hwrate(int rate_idx) +{ + /* Get PLCP rate for tx_cmd->rate_n_flags */ + return fw_rate_idx_to_plcp[rate_idx]; +} + +static inline void ieee80211_rate_set_vht(struct ieee80211_tx_rate *rate, + u8 mcs, u8 nss) +{ + WARN_ON(mcs & ~0xF); + WARN_ON((nss - 1) & ~0x7); + rate->idx = ((nss - 1) << 4) | mcs; +} + +static inline void iwl_mvm_hwrate_to_tx_rate(u32 rate_n_flags, + enum nl80211_band band, + struct ieee80211_tx_rate *r) +{ + if (rate_n_flags & RATE_HT_MCS_GF_MSK) + r->flags |= IEEE80211_TX_RC_GREEN_FIELD; + switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) { + case RATE_MCS_CHAN_WIDTH_20: + break; + case RATE_MCS_CHAN_WIDTH_40: + r->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; + break; + case RATE_MCS_CHAN_WIDTH_80: + r->flags |= IEEE80211_TX_RC_80_MHZ_WIDTH; + break; + case RATE_MCS_CHAN_WIDTH_160: + r->flags |= IEEE80211_TX_RC_160_MHZ_WIDTH; + break; + } + if (rate_n_flags & RATE_MCS_SGI_MSK) + r->flags |= IEEE80211_TX_RC_SHORT_GI; + if (rate_n_flags & RATE_MCS_HT_MSK) { + r->flags |= IEEE80211_TX_RC_MCS; + r->idx = rate_n_flags & RATE_HT_MCS_INDEX_MSK; + } else if (rate_n_flags & RATE_MCS_VHT_MSK) { + ieee80211_rate_set_vht( + r, rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK, + ((rate_n_flags & RATE_VHT_MCS_NSS_MSK) >> + RATE_VHT_MCS_NSS_POS) + 1); + r->flags |= IEEE80211_TX_RC_VHT_MCS; + } else { + r->idx = iwl_mvm_legacy_rate_to_mac80211_idx(rate_n_flags, + band); + } +} + +/* + * translate ucode response to mac80211 tx status control values + */ +static inline void iwl_mvm_hwrate_to_tx_status(u32 rate_n_flags, + struct ieee80211_tx_info *info) +{ + struct ieee80211_tx_rate *r = &info->status.rates[0]; + + info->status.antenna = + ((rate_n_flags & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS); + iwl_mvm_hwrate_to_tx_rate(rate_n_flags, (enum nl80211_band)info->band, r); +} + +int iwl_mvm_send_lq_cmd(struct iwm_softc *sc, struct iwm_lq_cmd *lq); + +/* Initialize station's rate scaling information after adding station */ +void iwl_mvm_rs_rate_init(struct iwm_softc *mvm, struct ieee80211_node *sta, + enum nl80211_band band, bool init); + +/* Notify RS about Tx status */ +void iwl_mvm_rs_tx_status(struct iwm_softc *mvm, struct ieee80211_node *sta, + int tid, struct ieee80211_tx_info *info, bool ndp); + +void rs_drv_mac80211_tx_status(struct iwm_softc *sc, + struct ieee80211_node *sta, + struct ieee80211_tx_info *info, int tid, uint16_t fc, int ssn); + +void rs_update_last_rssi(struct iwm_softc *mvm, + struct ieee80211_rx_status *rx_status); + +int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate); + +void rs_drv_rate_update(struct iwm_softc *mvm, + struct ieee80211_node *sta, + enum nl80211_band band, u32 changed); + +void *rs_drv_alloc_sta(iwm_softc *sc, struct ieee80211_node *ni); + +void rs_drv_free_sta(iwm_softc *sc, struct ieee80211_node *ni); + +void iwm_rs_alloc(struct iwm_softc *sc); + +void iwm_rs_free(struct iwm_softc *sc); + +#endif /* rs_hpp */ diff --git a/itlwm/hal_iwm/rx.cpp b/itlwm/hal_iwm/rx.cpp index 775771511..2b3e1c7e1 100644 --- a/itlwm/hal_iwm/rx.cpp +++ b/itlwm/hal_iwm/rx.cpp @@ -354,6 +354,7 @@ iwm_rx_mpdu(struct iwm_softc *sc, mbuf_t m, void *pktdata, { struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_rxinfo rxi; + struct ieee80211_rx_status rx_status; struct iwm_rx_phy_info *phy_info; struct iwm_rx_mpdu_res_start *rx_res; int device_timestamp; @@ -363,6 +364,7 @@ iwm_rx_mpdu(struct iwm_softc *sc, mbuf_t m, void *pktdata, int rssi, chanidx, rate_n_flags; memset(&rxi, 0, sizeof(rxi)); + memset(&rx_status, 0, sizeof(struct ieee80211_rx_status)); phy_info = &sc->sc_last_phy_info; rx_res = (struct iwm_rx_mpdu_res_start *)pktdata; @@ -415,7 +417,8 @@ iwm_rx_mpdu(struct iwm_softc *sc, mbuf_t m, void *pktdata, phy_flags = letoh16(phy_info->phy_flags); rate_n_flags = le32toh(phy_info->rate_n_flags); - rssi = iwm_get_signal_strength(sc, phy_info); + rssi = iwm_get_signal_strength(sc, &rx_status, phy_info); + rs_update_last_rssi(sc, &rx_status); rssi = (0 - IWM_MIN_DBM) + rssi; /* normalize */ rssi = MIN(rssi, ic->ic_max_rssi); /* clip to max. 100% */ @@ -823,6 +826,7 @@ iwm_rx_mpdu_mq(struct iwm_softc *sc, mbuf_t m, void *pktdata, { struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_rxinfo rxi; + struct ieee80211_rx_status rx_status; struct iwm_rx_mpdu_desc *desc; uint32_t len, hdrlen, rate_n_flags, device_timestamp; int rssi; @@ -830,6 +834,7 @@ iwm_rx_mpdu_mq(struct iwm_softc *sc, mbuf_t m, void *pktdata, uint16_t phy_info; memset(&rxi, 0, sizeof(rxi)); + memset(&rx_status, 0, sizeof(struct ieee80211_rx_status)); desc = (struct iwm_rx_mpdu_desc *)pktdata; @@ -950,7 +955,8 @@ iwm_rx_mpdu_mq(struct iwm_softc *sc, mbuf_t m, void *pktdata, chanidx = desc->v1.channel; device_timestamp = desc->v1.gp2_on_air_rise; - rssi = iwm_rxmq_get_signal_strength(sc, desc); + rssi = iwm_rxmq_get_signal_strength(sc, &rx_status, rate_n_flags, desc); + rs_update_last_rssi(sc, &rx_status); rssi = (0 - IWM_MIN_DBM) + rssi; /* normalize */ rssi = MIN(rssi, ic->ic_max_rssi); /* clip to max. 100% */ From ab2977d94fe2fe65d59f353cac5a2e81abe0d835 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Mon, 28 Mar 2022 01:16:41 +0800 Subject: [PATCH 002/114] rs now we run. --- itlwm/hal_iwm/ItlIwm.hpp | 1 - itlwm/hal_iwm/mac80211.cpp | 180 +++---------------------------------- 2 files changed, 14 insertions(+), 167 deletions(-) diff --git a/itlwm/hal_iwm/ItlIwm.hpp b/itlwm/hal_iwm/ItlIwm.hpp index 976cf6e4f..448ea3feb 100644 --- a/itlwm/hal_iwm/ItlIwm.hpp +++ b/itlwm/hal_iwm/ItlIwm.hpp @@ -292,7 +292,6 @@ class ItlIwm : public ItlHalService, ItlDriverInfo, ItlDriverController { struct ieee80211_frame *, struct iwm_tx_cmd *); void iwm_txd_done(struct iwm_softc *, struct iwm_tx_data *); void iwm_ampdu_txq_advance(struct iwm_softc *, struct iwm_tx_ring *, int); - void iwm_tx_reclaim(struct iwm_softc *, struct ieee80211_tx_info *tx_info, int, int, int, uint32_t, bool); void iwm_clear_oactive(struct iwm_softc *, struct iwm_tx_ring *); void iwm_ra_choose(struct iwm_softc *, struct ieee80211_node *); int iwm_tx(struct iwm_softc *, mbuf_t, struct ieee80211_node *, int); diff --git a/itlwm/hal_iwm/mac80211.cpp b/itlwm/hal_iwm/mac80211.cpp index 461720989..9952a3de0 100644 --- a/itlwm/hal_iwm/mac80211.cpp +++ b/itlwm/hal_iwm/mac80211.cpp @@ -1040,25 +1040,6 @@ static int ieee80211_tx_get_rates(struct iwm_softc *sc, return i - 1; } -static void __ieee80211_tx_status(struct iwm_softc *sc, - struct ieee80211_tx_info *info, - int rates_idx, int retry_count, int tid, uint16_t fc, int ssn) -{ - bool acked; - bool noack_success; - - acked = !!(info->flags & IEEE80211_TX_STAT_ACK); - noack_success = !!(info->flags & - IEEE80211_TX_STAT_NOACK_TRANSMITTED); - - if ((info->flags & IEEE80211_TX_STAT_AMPDU_NO_BACK) && - (ieee80211_is_data_qos(fc))) { - - ieee80211_tx_compressed_bar(&sc->sc_ic, sc->sc_ic.ic_bss, tid, ssn); - XYLog("%s sending bar ssn=%d tid=%d\n", __FUNCTION__, ssn, tid); - } -} - void ieee80211_tx_status(struct iwm_softc *sc, struct ieee80211_tx_info *info, int tid, uint16_t fc, int ssn) { int rates_idx, retry_count; @@ -1069,9 +1050,6 @@ void ieee80211_tx_status(struct iwm_softc *sc, struct ieee80211_tx_info *info, i rates_idx = ieee80211_tx_get_rates(sc, info, &retry_count); rs_drv_mac80211_tx_status(sc, sc->sc_ic.ic_bss, info, tid, fc, ssn); - - if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP)) - __ieee80211_tx_status(sc, info, rates_idx, retry_count, tid, fc, ssn); } void ItlIwm:: @@ -1093,74 +1071,6 @@ iwm_ampdu_txq_advance(struct iwm_softc *sc, struct iwm_tx_ring *ring, int idx) } } -void ItlIwm:: -iwm_tx_reclaim(struct iwm_softc *sc, struct ieee80211_tx_info *tx_info, int tid, int qid, int ssn, uint32_t rate, bool is_flush) -{ - XYLog("%s ssn %d\n", __FUNCTION__, ssn); - struct iwm_tx_data *txd; - int idx = IWM_AGG_SSN_TO_TXQ_IDX(ssn); - struct iwm_tx_ring *ring = &sc->txq[qid]; - struct iwm_tx_ba *tid_data = &sc->sc_tx_ba[tid]; - int freed = 0; - bool rs_update = false; - - /* pack lq color from tid_data along the reduced txp */ - tx_info->status.status_driver_data[0] = - RS_DRV_DATA_PACK(tid_data->lq_color, - tx_info->status.status_driver_data[0]); - tx_info->status.status_driver_data[1] = (void *)(uintptr_t)rate; - while (ring->tail != idx) { - txd = &ring->data[ring->tail]; - struct ieee80211_tx_info *info = &txd->info; - if (txd->m != NULL) { - rs_update = true; - iwm_reset_sched(sc, ring->qid, ring->tail, IWM_STATION_ID); - - memset(&info->status, 0, sizeof(info->status)); - /* Packet was transmitted successfully, failures come as single - * frames because before failing a frame the firmware transmits - * it without aggregation at least once. - */ - if (!is_flush) - info->flags |= IEEE80211_TX_STAT_ACK; - - if (!is_flush) { - if (ieee80211_is_data_qos(txd->fc)) - freed++; - else - WARN_ON_ONCE(tid != IWL_MAX_TID_COUNT); - } - - /* this is the first skb we deliver in this batch */ - /* put the rate scaling data there */ - if (freed == 1) { - info->flags |= IEEE80211_TX_STAT_AMPDU; - memcpy(&info->status, &tx_info->status, - sizeof(tx_info->status)); - iwl_mvm_hwrate_to_tx_status(rate, info); - } - - ieee80211_tx_status(sc, info, tid, txd->fc, ssn); - - iwm_txd_done(sc, txd); - ring->queued--; - } - ring->tail = (ring->tail + 1) % IWM_TX_RING_COUNT; - XYLog("%s tail %d\n", __FUNCTION__, ring->tail); - } - - /* We got a BA notif with 0 acked or scd_ssn didn't progress which is - * possible (i.e. first MPDU in the aggregation wasn't acked) - * Still it's important to update RS about sent vs. acked. - */ - if (!is_flush && !rs_update) { - tx_info->band = IEEE80211_IS_CHAN_2GHZ(sc->sc_ic.ic_bss->ni_chan) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ; - iwl_mvm_hwrate_to_tx_status(rate, tx_info); - XYLog("No reclaim. Update rs directly\n"); - iwl_mvm_rs_tx_status(sc, sc->sc_ic.ic_bss, tid, tx_info, false); - } -} - void ItlIwm:: iwm_ampdu_rate_control(struct iwm_softc *sc, struct ieee80211_node *ni, struct iwm_tx_ring *ring, uint16_t seq, uint16_t ssn, struct ieee80211_tx_info *tx_info, int tid, uint32_t rate_n_flags) @@ -1336,8 +1246,8 @@ iwm_rx_tx_ba_notif(struct iwm_softc *sc, struct iwm_rx_packet *pkt, struct iwm_r ba_info.status.status_driver_data[0] = (void *)(uintptr_t)ba_notif->reduced_txp; -// if (SEQ_LT(ssn, ba->ba_winstart)) -// return; + if (SEQ_LT(ssn, ba->ba_winstart)) + return; /* Skip rate control if our Tx rate is fixed. */ if (ic->ic_fixed_mcs == -1) @@ -1383,35 +1293,6 @@ iwm_ampdu_tx_done(struct iwm_softc *sc, struct iwm_cmd_header *cmd_hdr, return; if (nframes > 1) { - int i; - - /* - * Collect information about this A-MPDU. - */ - for (i = 0; i < nframes; i++) { - uint8_t qid = agg_status[i].qid; - uint8_t idx = agg_status[i].idx; - uint16_t txstatus = (le16toh(agg_status[i].status) & - IWM_AGG_TX_STATE_STATUS_MSK); - - if (status != IWM_TX_STATUS_SUCCESS && ieee80211_is_mgmt(txdata->fc)) { - iwm_toggle_tx_ant(sc, &sc->sc_mgmt_last_antenna_idx); - } - - if (txstatus != IWM_AGG_TX_STATE_TRANSMITTED) - continue; - - if (qid != cmd_hdr->qid) - continue; - - txdata = &txq->data[idx]; - if (txdata->m == NULL) - continue; - - /* The Tx rate was the same for all subframes. */ - txdata->ampdu_txmcs = rate; - txdata->ampdu_nframes = nframes; - } return; } @@ -1429,28 +1310,6 @@ iwm_ampdu_tx_done(struct iwm_softc *sc, struct iwm_cmd_header *cmd_hdr, "bitmap=0x%llx\n", __func__, status, cmd_hdr->qid, txq->queued, cmd_hdr->idx, ssn, ba->ba_bitmap)); - /* - * Skip rate control if our Tx rate is fixed. - * Don't report frames to MiRA which were sent at a different - * Tx rate than ni->ni_txmcs. - */ - if (ic->ic_fixed_mcs == -1) { - if (txdata->ampdu_nframes > 1) { - /* - * This frame was once part of an A-MPDU. - * Report one failed A-MPDU Tx attempt. - * The firmware might have made several such - * attempts but we don't keep track of this. - */ - ieee80211_ra_add_stats_ht(&in->in_rn, ic, ni, - txdata->ampdu_txmcs, 1, 1); - } - - /* Report the final single-frame Tx attempt. */ - iwm_ht_single_rate_control(sc, ni, rate, initial_rate, - failure_frame, txfail); - } - if (txfail) { ieee80211_tx_compressed_bar(ic, ni, tid, ssn); XYLog("%s sending bar ssn=%d tid=%d\n", __FUNCTION__, ssn, tid); @@ -1462,8 +1321,6 @@ iwm_ampdu_tx_done(struct iwm_softc *sc, struct iwm_cmd_header *cmd_hdr, * frames before its BA window so mark them all as done. */ ieee80211_output_ba_move_window(ic, ni, tid, ssn); - iwm_ampdu_txq_advance(sc, txq, IWM_AGG_SSN_TO_TXQ_IDX(ssn)); - iwm_clear_oactive(sc, txq); } #define IWL_MVM_TX_RES_GET_TID(_ra_tid) ((_ra_tid) & 0x0f) @@ -1792,27 +1649,18 @@ iwm_rx_tx_cmd(struct iwm_softc *sc, struct iwm_rx_packet *pkt, DPRINTFN(2, ("%s idx=%d qid=%d txd->txmcs=%d txd->txrate=%d, frame_count=%d len=%d\n", __FUNCTION__, idx, qid, txd->txmcs, txd->txrate, ((struct iwm_tx_resp *)pkt->data)->frame_count, ((struct iwm_tx_resp *)pkt->data)->byte_cnt)); - iwm_rx_tx_cmd_single(sc, tx_resp, qid, idx); + ssn = iwm_get_scd_ssn(tx_resp); + iwm_rx_tx_cmd_single(sc, tx_resp, qid, IWM_AGG_SSN_TO_TXQ_IDX(ssn)); + if (qid >= IWM_FIRST_AGG_TX_QUEUE) { + int status; + + status = le16toh(iwl_mvm_get_agg_status(sc, tx_resp)->status) & IWM_TX_STATUS_MSK; + iwm_ampdu_tx_done(sc, cmd_hdr, txd->in, ring, + le32toh(tx_resp->initial_rate), tx_resp->frame_count, + tx_resp->failure_frame, ssn, status, iwl_mvm_get_agg_status(sc, tx_resp)); + } + iwm_clear_oactive(sc, ring); - -// memcpy(&ssn, &tx_resp->status + tx_resp->frame_count, sizeof(ssn)); -// ssn = le32toh(ssn) & 0xfff; -// if (qid >= IWM_FIRST_AGG_TX_QUEUE) { -// int status; -// status = le16toh(tx_resp->status.status) & IWM_TX_STATUS_MSK; -// iwm_ampdu_tx_done(sc, cmd_hdr, txd->in, ring, -// le32toh(tx_resp->initial_rate), tx_resp->frame_count, -// tx_resp->failure_frame, ssn, status, &tx_resp->status); -// } else { -// /* -// * Even though this is not an agg queue, we must only free -// * frames before the firmware's starting sequence number. -// */ -// iwm_rx_tx_cmd_single(sc, tx_resp, txd->in, txd->txmcs, -// txd->txrate, qid); -// iwm_ampdu_txq_advance(sc, ring, IWM_AGG_SSN_TO_TXQ_IDX(ssn)); -// iwm_clear_oactive(sc, ring); -// } } void ItlIwm:: @@ -2213,7 +2061,7 @@ iwm_tx(struct iwm_softc *sc, mbuf_t m, struct ieee80211_node *ni, int ac) /* Mark TX ring as full if we reach a certain threshold. */ if (++ring->queued > IWM_TX_RING_HIMARK) { - XYLog("%s qid=%d sc->qfullmsk is FULL ring->cur=%d ring->queued=%d\n", __FUNCTION__, ring->qid, ring->cur, ring->queued); +// XYLog("%s qid=%d sc->qfullmsk is FULL ring->cur=%d ring->queued=%d\n", __FUNCTION__, ring->qid, ring->cur, ring->queued); sc->qfullmsk |= 1 << ring->qid; } From 7968e9f06046538be311fd9b0e86a4c05ecb6cd5 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Mon, 28 Mar 2022 14:44:07 +0800 Subject: [PATCH 003/114] Clean. --- itlwm/hal_iwm/ItlIwm.hpp | 6 +- itlwm/hal_iwm/coex.cpp | 64 ++++++++- itlwm/hal_iwm/mac80211.cpp | 5 +- itlwm/hal_iwm/rs.cpp | 259 ++++++++++++++++--------------------- itlwm/hal_iwm/rs.h | 9 +- 5 files changed, 184 insertions(+), 159 deletions(-) diff --git a/itlwm/hal_iwm/ItlIwm.hpp b/itlwm/hal_iwm/ItlIwm.hpp index 448ea3feb..ef0d4737d 100644 --- a/itlwm/hal_iwm/ItlIwm.hpp +++ b/itlwm/hal_iwm/ItlIwm.hpp @@ -93,8 +93,11 @@ class ItlIwm : public ItlHalService, ItlDriverInfo, ItlDriverController { struct iwm_scan_channel_cfg_umac *chan, int n_ssids, int bgscan); //coex - uint16_t iwm_coex_agg_time_limit(struct iwm_softc *); + uint16_t iwm_coex_agg_time_limit(struct iwm_softc *, struct ieee80211_node *); uint8_t iwm_coex_tx_prio(struct iwm_softc *, struct ieee80211_frame *, uint8_t); + static bool iwm_coex_is_ant_avail(struct iwm_softc *, u8); + static bool iwm_coex_is_mimo_allowed(struct iwm_softc *, struct ieee80211_node *); + static bool iwm_coex_is_tpc_allowed(struct iwm_softc *, bool); uint8_t iwm_lookup_cmd_ver(struct iwm_softc *, uint8_t, uint8_t); int iwm_is_mimo_ht_plcp(uint8_t); @@ -206,6 +209,7 @@ class ItlIwm : public ItlHalService, ItlDriverInfo, ItlDriverController { uint8_t); static void iwm_rx_ba_session_expired(void *); static void iwm_reorder_timer_expired(void *); + static uint8_t iwm_num_of_ant(uint8_t mask); int iwm_sta_rx_agg(struct iwm_softc *, struct ieee80211_node *, uint8_t, uint16_t, uint16_t, int, int); static int iwm_ampdu_tx_start(struct ieee80211com *, struct ieee80211_node *, diff --git a/itlwm/hal_iwm/coex.cpp b/itlwm/hal_iwm/coex.cpp index d70b69f8c..16d7e0e4f 100644 --- a/itlwm/hal_iwm/coex.cpp +++ b/itlwm/hal_iwm/coex.cpp @@ -23,7 +23,7 @@ #define LINK_QUAL_AGG_TIME_LIMIT_BT_ACT (1200) uint16_t ItlIwm:: -iwm_coex_agg_time_limit(struct iwm_softc *sc) +iwm_coex_agg_time_limit(struct iwm_softc *sc, struct ieee80211_node *ni) { return LINK_QUAL_AGG_TIME_LIMIT_DEF; } @@ -69,3 +69,65 @@ iwm_coex_tx_prio(struct iwm_softc *sc, struct ieee80211_frame *wh, uint8_t ac) return 0; } + +bool ItlIwm:: +iwm_coex_is_ant_avail(struct iwm_softc *sc, u8 ant) +{ +#if 0 + /* there is no other antenna, shared antenna is always available */ + if (mvm->cfg->bt_shared_single_ant) + return true; +#endif + + if (ant & sc->non_shared_ant) + return true; + +#ifdef notyet_coex + return le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) < + BT_HIGH_TRAFFIC; +#else + return true; +#endif +} + +bool ItlIwm:: +iwm_coex_is_mimo_allowed(struct iwm_softc *sc, struct ieee80211_node *ni) +{ +#ifdef notyet_coex + struct iwm_node *in = (struct iwm_node *)ni; + struct iwm_phy_ctxt *phy_ctxt = in->in_phyctxt; + enum iwl_bt_coex_lut_type lut_type; + + if (sc->last_bt_notif.ttc_status & BIT(phy_ctxt->id)) + return true; + + if (le32_to_cpu(sc->last_bt_notif.bt_activity_grading) < + BT_HIGH_TRAFFIC) + return true; + + /* + * In Tight / TxTxDis, BT can't Rx while we Tx, so use both antennas + * since BT is already killed. + * In Loose, BT can Rx while we Tx, so forbid MIMO to let BT Rx while + * we Tx. + * When we are in 5GHz, we'll get BT_COEX_INVALID_LUT allowing MIMO. + */ + lut_type = iwl_get_coex_type(mvm, mvmsta->vif); + return lut_type != BT_COEX_LOOSE_LUT; +#else + return true; +#endif +} + +bool ItlIwm:: +iwm_coex_is_tpc_allowed(struct iwm_softc *mvm, bool is5G) +{ + if (is5G) + return false; + +#ifdef notyet_coex + return le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) >= BT_LOW_TRAFFIC; +#else + return true; +#endif +} diff --git a/itlwm/hal_iwm/mac80211.cpp b/itlwm/hal_iwm/mac80211.cpp index 9952a3de0..f04872ebe 100644 --- a/itlwm/hal_iwm/mac80211.cpp +++ b/itlwm/hal_iwm/mac80211.cpp @@ -438,7 +438,8 @@ iwm_reorder_timer_expired(void *arg) splx(s); } -static inline uint8_t iwm_num_of_ant(uint8_t mask) +uint8_t ItlIwm:: +iwm_num_of_ant(uint8_t mask) { return !!((mask) & IWM_ANT_A) + !!((mask) & IWM_ANT_B) + @@ -3088,7 +3089,7 @@ iwm_setrates(struct iwm_node *in, int async) lqcmd.single_stream_ant_msk = IWM_ANT_A; lqcmd.dual_stream_ant_msk = IWM_ANT_AB; - lqcmd.agg_time_limit = htole16(iwm_coex_agg_time_limit(sc)); + lqcmd.agg_time_limit = htole16(iwm_coex_agg_time_limit(sc, ni)); lqcmd.agg_disable_start_th = 3; lqcmd.agg_frame_cnt_limit = 0x3f; diff --git a/itlwm/hal_iwm/rs.cpp b/itlwm/hal_iwm/rs.cpp index 5cdc54134..37cf83921 100644 --- a/itlwm/hal_iwm/rs.cpp +++ b/itlwm/hal_iwm/rs.cpp @@ -110,32 +110,16 @@ struct rs_tx_column { allow_column_func_t checks[MAX_COLUMN_CHECKS]; }; -static bool iwl_mvm_bt_coex_is_ant_avail(struct iwm_softc *sc, u8 ant) -{ - /* there is no other antenna, shared antenna is always available */ -// if (mvm->cfg->bt_shared_single_ant) -// return true; -// -// if (ant & mvm->cfg->non_shared_ant) -// return true; -// -// return le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) < -// BT_HIGH_TRAFFIC; - // TODO: IMP - return true; -} - static bool rs_ant_allow(struct iwm_softc *sc, struct ieee80211_node *ni, struct rs_rate *rate, const struct rs_tx_column *next_col) { - return iwl_mvm_bt_coex_is_ant_avail(sc, next_col->ant); + return ItlIwm::iwm_coex_is_ant_avail(sc, next_col->ant); } static bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwm_softc *sc, struct ieee80211_node *ni) { - //TODO: IMP - return true; + return ItlIwm::iwm_coex_is_mimo_allowed(sc, ni); } static bool rs_mimo_allow(struct iwm_softc *sc, struct ieee80211_node *ni, @@ -150,7 +134,7 @@ static bool rs_mimo_allow(struct iwm_softc *sc, struct ieee80211_node *ni, // if (sta->smps_mode == IEEE80211_SMPS_STATIC) // return false; - if (num_of_ant(that->iwm_fw_valid_tx_ant(sc)) < 2) + if (that->iwm_num_of_ant(that->iwm_fw_valid_tx_ant(sc)) < 2) return false; if (!iwl_mvm_bt_coex_is_mimo_allowed(sc, ni)) @@ -632,7 +616,7 @@ static void rs_tl_turn_on_agg(struct iwm_softc *sc, return; } - tx_ba = &sc->sc_ic.ic_bss->ni_tx_ba[tid]; + tx_ba = &ni->ni_tx_ba[tid]; tid_data = &sc->sc_tx_ba[tid]; if (sc->sc_ic.ic_state >= IEEE80211_S_RUN && tx_ba->ba_state == IEEE80211_BA_INIT && @@ -759,7 +743,6 @@ static void rs_update_tid_tpt_stats(struct iwm_softc *sc, return; struct iwm_tx_ba *tid_data = &sc->sc_tx_ba[tid]; - struct ieee80211_tx_ba *tx_ba = &sc->sc_ic.ic_bss->ni_tx_ba[tid]; /* * Measure if there're enough successful transmits per second. @@ -767,7 +750,7 @@ static void rs_update_tid_tpt_stats(struct iwm_softc *sc, * BA session, so it should be updated only when A-MPDU is * off. */ - if (tx_ba->ba_state != IEEE80211_BA_INIT) + if (tid_data->wn != NULL) return; if (time_is_before_jiffies(tid_data->tpt_meas_start + hz) || @@ -1124,7 +1107,7 @@ static void rs_get_lower_rate_down_column(struct iwl_lq_sta *lq_sta, LQ_VHT_SISO : LQ_HT_SISO; } - if (num_of_ant(rate->ant) > 1) + if (that->iwm_num_of_ant(rate->ant) > 1) rate->ant = first_antenna(that->iwm_fw_valid_tx_ant(sc)); /* Relevant in both switching to SISO or Legacy */ @@ -1899,13 +1882,7 @@ static void rs_get_adjacent_txp(struct iwm_softc *mvm, int index, static bool iwl_mvm_bt_coex_is_tpc_allowed(struct iwm_softc *mvm, enum nl80211_band band) { -// u32 bt_activity = le32_to_cpu(mvm->last_bt_notif.bt_activity_grading); -// - if (band != NL80211_BAND_2GHZ) - return false; -// -// return bt_activity >= BT_LOW_TRAFFIC; - return false; + return ItlIwm::iwm_coex_is_tpc_allowed(mvm, band == NL80211_BAND_5GHZ); } static bool rs_tpc_allowed(struct iwm_softc *mvm, @@ -2756,7 +2733,7 @@ void rs_drv_free_sta(iwm_softc *sc, struct ieee80211_node *ni) static int rs_vht_highest_rx_mcs_index(struct ieee80211_node *sta, int nss) { - u16 rx_mcs = le16_to_cpu(sta->ni_ic->ic_bss->ni_vht_mcsinfo.rx_mcs_map) & + u16 rx_mcs = le16_to_cpu(sta->ni_vht_mcsinfo.rx_mcs_map) & (0x3 << (2 * (nss - 1))); rx_mcs >>= (2 * (nss - 1)); @@ -2832,7 +2809,7 @@ static void rs_ht_init(struct iwm_softc *mvm, if ((sta->ni_htcaps & IEEE80211_HTCAP_LDPC)) lq_sta->ldpc = true; - if ((num_of_ant(that->iwm_fw_valid_tx_ant(mvm)) > 1) && + if ((that->iwm_num_of_ant(that->iwm_fw_valid_tx_ant(mvm)) > 1) && (sta->ni_htcaps & IEEE80211_HTCAP_RXSTBC_MASK)) lq_sta->stbc_capable = true; @@ -2849,12 +2826,12 @@ static void rs_vht_init(struct iwm_softc *mvm, if ((sta->ni_vhtcaps & IEEE80211_VHTCAP_RXLDPC)) lq_sta->ldpc = true; - if ((num_of_ant(that->iwm_fw_valid_tx_ant(mvm)) > 1) && + if ((that->iwm_num_of_ant(that->iwm_fw_valid_tx_ant(mvm)) > 1) && (sta->ni_vhtcaps & IEEE80211_VHTCAP_RXSTBC_MASK)) lq_sta->stbc_capable = true; if (isset(mvm->sc_enabled_capa, IWM_UCODE_TLV_CAPA_BEAMFORMER) && - (num_of_ant(that->iwm_fw_valid_tx_ant(mvm)) > 1) && + (that->iwm_num_of_ant(that->iwm_fw_valid_tx_ant(mvm)) > 1) && (sta->ni_vhtcaps & IEEE80211_VHTCAP_SU_BEAMFORMEE_CAPABLE)) lq_sta->bfer_capable = true; @@ -3011,14 +2988,13 @@ static void rs_drv_rate_init(struct iwm_softc *mvm, struct ieee80211_node *sta, lq_sta->max_mimo2_rate_idx = rs_get_max_rate_from_mask(lq_sta->active_mimo2_rate); - IWL_DEBUG_RATE(mvm, - "LEGACY=%lX SISO=%lX MIMO2=%lX VHT=%d LDPC=%d STBC=%d BFER=%d\n", + XYLog("LEGACY=%lX SISO=%lX MIMO2=%lX VHT=%d LDPC=%d STBC=%d BFER=%d\n", lq_sta->active_legacy_rate, lq_sta->active_siso_rate, lq_sta->active_mimo2_rate, lq_sta->is_vht, lq_sta->ldpc, lq_sta->stbc_capable, lq_sta->bfer_capable); - IWL_DEBUG_RATE(mvm, "MAX RATE: LEGACY=%d SISO=%d MIMO2=%d\n", + XYLog("MAX RATE: LEGACY=%d SISO=%d MIMO2=%d\n", lq_sta->max_legacy_rate_idx, lq_sta->max_siso_rate_idx, lq_sta->max_mimo2_rate_idx); @@ -3403,55 +3379,58 @@ static void rs_build_rates_table(struct iwm_softc *mvm, lq_cmd->flags = LQ_FLAG_COLOR_SET(lq_cmd->flags, color); } -//struct rs_bfer_active_iter_data { -// struct ieee80211_node *exclude_sta; -// struct ieee80211_node *bfer_mvmsta; -//}; -// -//static void rs_bfer_active_iter(void *_data, -// struct ieee80211_node *sta) -//{ -// struct rs_bfer_active_iter_data *data = (struct rs_bfer_active_iter_data *)_data; -// struct iwm_lq_cmd *lq_cmd = &sta->ni_ic->lq_sta.rs_drv.lq; -// u32 ss_params = le32_to_cpu(lq_cmd->ss_params); -// -// if (sta == data->exclude_sta) -// return; -// -// /* The current sta has BFER allowed */ -// if (ss_params & LQ_SS_BFER_ALLOWED) { -// WARN_ON_ONCE(data->bfer_mvmsta != NULL); -// -// data->bfer_mvmsta = mvmsta; -// } -//} -// -//static int rs_bfer_priority(struct ieee80211_node *sta) -//{ -// return 1; -//} -// -///* Returns >0 if sta1 has a higher BFER priority compared to sta2 */ -//static int rs_bfer_priority_cmp(struct ieee80211_node *sta1, -// struct ieee80211_node *sta2) -//{ -// int prio1 = rs_bfer_priority(sta1); -// int prio2 = rs_bfer_priority(sta2); -// -// if (prio1 > prio2) -// return 1; -// if (prio1 < prio2) -// return -1; -// return 0; -//} -// -//static inline void ieee80211_iterate_stations_atomic(struct iwm_softc *hw, -// void (*iterator)(void *data, -// struct ieee80211_node *sta), -// void *data) -//{ -// iterator(data, hw->sc_ic.ic_bss); -//} +#if 0 +struct rs_bfer_active_iter_data { + struct ieee80211_node *exclude_sta; + struct ieee80211_node *bfer_mvmsta; +}; + +static void rs_bfer_active_iter(void *_data, + struct ieee80211_node *sta) +{ + struct rs_bfer_active_iter_data *data = (struct rs_bfer_active_iter_data *)_data; + struct iwm_lq_cmd *lq_cmd = &sta->ni_ic->lq_sta.rs_drv.lq; + u32 ss_params = le32_to_cpu(lq_cmd->ss_params); + + if (sta == data->exclude_sta) + return; + + /* The current sta has BFER allowed */ + if (ss_params & LQ_SS_BFER_ALLOWED) { + WARN_ON_ONCE(data->bfer_mvmsta != NULL); + + data->bfer_mvmsta = mvmsta; + } +} + +static int rs_bfer_priority(struct ieee80211_node *sta) +{ + return 1; +} + +/* Returns >0 if sta1 has a higher BFER priority compared to sta2 */ +static int rs_bfer_priority_cmp(struct ieee80211_node *sta1, + struct ieee80211_node *sta2) +{ + int prio1 = rs_bfer_priority(sta1); + int prio2 = rs_bfer_priority(sta2); + + if (prio1 > prio2) + return 1; + if (prio1 < prio2) + return -1; + return 0; +} + +static inline void ieee80211_iterate_stations_atomic(struct iwm_softc *hw, + void (*iterator)(void *data, + struct ieee80211_node *sta), + void *data) +{ + iterator(data, hw->sc_ic.ic_bss); +} + +#endif static void rs_set_lq_ss_params(struct iwm_softc *mvm, struct ieee80211_node *sta, @@ -3459,10 +3438,12 @@ static void rs_set_lq_ss_params(struct iwm_softc *mvm, const struct rs_rate *initial_rate) { struct iwm_lq_cmd *lq_cmd = &lq_sta->lq; -// struct rs_bfer_active_iter_data data = { -// .exclude_sta = sta, -// .bfer_mvmsta = NULL, -// }; +#if 0 + struct rs_bfer_active_iter_data data = { + .exclude_sta = sta, + .bfer_mvmsta = NULL, + }; +#endif u32 ss_params = LQ_SS_PARAMS_VALID; if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta)) @@ -3471,67 +3452,50 @@ static void rs_set_lq_ss_params(struct iwm_softc *mvm, if (lq_sta->stbc_capable) ss_params |= LQ_SS_STBC_1SS_ALLOWED; +#if 0 if (!lq_sta->bfer_capable) goto out; -// ieee80211_iterate_stations_atomic(mvm, -// rs_bfer_active_iter, -// &data); -// bfer_mvmsta = data.bfer_mvmsta; -// -// /* This code is safe as it doesn't run concurrently for different -// * stations. This is guaranteed by the fact that calls to -// * ieee80211_tx_status wouldn't run concurrently for a single HW. -// */ -// if (!bfer_mvmsta) { -// IWL_DEBUG_RATE(mvm, "No sta with BFER allowed found. Allow\n"); -// -// ss_params |= LQ_SS_BFER_ALLOWED; -// goto out; -// } -// -// IWL_DEBUG_RATE(mvm, "Found existing sta %d with BFER activated\n", -// bfer_mvmsta->sta_id); -// -// /* Disallow BFER on another STA if active and we're a higher priority */ -// if (rs_bfer_priority_cmp(mvmsta, bfer_mvmsta) > 0) { -// struct iwm_lq_cmd *bfersta_lq_cmd = -// &bfer_mvmsta->lq_sta.rs_drv.lq; -// u32 bfersta_ss_params = le32_to_cpu(bfersta_lq_cmd->ss_params); -// -// bfersta_ss_params &= ~LQ_SS_BFER_ALLOWED; -// bfersta_lq_cmd->ss_params = cpu_to_le32(bfersta_ss_params); -// iwl_mvm_send_lq_cmd(mvm, bfersta_lq_cmd); -// -// ss_params |= LQ_SS_BFER_ALLOWED; -// IWL_DEBUG_RATE(mvm, -// "Lower priority BFER sta found (%d). Switch BFER\n", -// bfer_mvmsta->sta_id); -// } -out: - lq_cmd->ss_params = cpu_to_le32(ss_params); -} + ieee80211_iterate_stations_atomic(mvm, + rs_bfer_active_iter, + &data); + bfer_mvmsta = data.bfer_mvmsta; -#define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) -#define LINK_QUAL_AGG_TIME_LIMIT_BT_ACT (1200) + /* This code is safe as it doesn't run concurrently for different + * stations. This is guaranteed by the fact that calls to + * ieee80211_tx_status wouldn't run concurrently for a single HW. + */ + if (!bfer_mvmsta) { + IWL_DEBUG_RATE(mvm, "No sta with BFER allowed found. Allow\n"); -static u16 iwl_mvm_coex_agg_time_limit(struct iwm_softc *mvm, -struct ieee80211_node *sta) -{ -// if (mvm->last_bt_notif.ttc_status & BIT(phy_ctxt->id)) -// return LINK_QUAL_AGG_TIME_LIMIT_DEF; -// -// if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) < -// BT_HIGH_TRAFFIC) -// return LINK_QUAL_AGG_TIME_LIMIT_DEF; -// -// lut_type = iwl_get_coex_type(mvm, mvmsta->vif); -// -// if (lut_type == BT_COEX_LOOSE_LUT || lut_type == BT_COEX_INVALID_LUT) - return LINK_QUAL_AGG_TIME_LIMIT_DEF; + ss_params |= LQ_SS_BFER_ALLOWED; + goto out; + } -// /* tight coex, high bt traffic, reduce AGG time limit */ -// return LINK_QUAL_AGG_TIME_LIMIT_BT_ACT; + IWL_DEBUG_RATE(mvm, "Found existing sta %d with BFER activated\n", + bfer_mvmsta->sta_id); + + /* Disallow BFER on another STA if active and we're a higher priority */ + if (rs_bfer_priority_cmp(mvmsta, bfer_mvmsta) > 0) { + struct iwm_lq_cmd *bfersta_lq_cmd = + &bfer_mvmsta->lq_sta.rs_drv.lq; + u32 bfersta_ss_params = le32_to_cpu(bfersta_lq_cmd->ss_params); + + bfersta_ss_params &= ~LQ_SS_BFER_ALLOWED; + bfersta_lq_cmd->ss_params = cpu_to_le32(bfersta_ss_params); + iwl_mvm_send_lq_cmd(mvm, bfersta_lq_cmd); + + ss_params |= LQ_SS_BFER_ALLOWED; + IWL_DEBUG_RATE(mvm, + "Lower priority BFER sta found (%d). Switch BFER\n", + bfer_mvmsta->sta_id); + } +#else + if (lq_sta->bfer_capable) + ss_params |= LQ_SS_BFER_ALLOWED; +#endif +out: + lq_cmd->ss_params = cpu_to_le32(ss_params); } static void rs_fill_lq_cmd(struct iwm_softc *mvm, @@ -3540,6 +3504,7 @@ static void rs_fill_lq_cmd(struct iwm_softc *mvm, const struct rs_rate *initial_rate) { struct iwm_lq_cmd *lq_cmd = &lq_sta->lq; + ItlIwm *that = container_of(mvm, ItlIwm, com); lq_cmd->agg_disable_start_th = IWL_MVM_RS_AGG_DISABLE_START; lq_cmd->agg_time_limit = @@ -3554,7 +3519,7 @@ static void rs_fill_lq_cmd(struct iwm_softc *mvm, rs_set_lq_ss_params(mvm, sta, lq_sta, initial_rate); if (!isset(&mvm->sc_enabled_capa, IWM_UCODE_TLV_CAPA_COEX_SCHEMA_2) && - num_of_ant(initial_rate->ant) == 1) + that->iwm_num_of_ant(initial_rate->ant) == 1) lq_cmd->single_stream_ant_msk = initial_rate->ant; lq_cmd->agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF; @@ -3565,7 +3530,7 @@ static void rs_fill_lq_cmd(struct iwm_softc *mvm, #endif lq_cmd->agg_time_limit = - cpu_to_le16(iwl_mvm_coex_agg_time_limit(mvm, sta)); + cpu_to_le16(that->iwm_coex_agg_time_limit(mvm, sta)); } int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate) diff --git a/itlwm/hal_iwm/rs.h b/itlwm/hal_iwm/rs.h index 0ad3a5f6b..ebf3027e1 100644 --- a/itlwm/hal_iwm/rs.h +++ b/itlwm/hal_iwm/rs.h @@ -36,7 +36,7 @@ #define IWL_ERR(sc, fmt, x...)\ do\ {\ -XYLog("%s: " fmt, "ERR", ##x);\ +XYLog("RS %s: " fmt, "ERR", ##x);\ }while(0) /** @@ -670,13 +670,6 @@ enum { IWL_RATE_INVM_PLCP = 0xff, }; -static inline u8 num_of_ant(u8 mask) -{ - return !!((mask) & ANT_A) + - !!((mask) & ANT_B) + - !!((mask) & ANT_C); -} - /* * Returns the first antenna as ANT_[ABC], as defined in iwl-config.h. * The parameter should also be a combination of ANT_[ABC]. From 4dfcd4f6ca6e9f2a8e8806baa5f475e4c27a2731 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Mon, 28 Mar 2022 14:57:36 +0800 Subject: [PATCH 004/114] Clean unused. --- itlwm/hal_iwm/ItlIwm.hpp | 3 - itlwm/hal_iwm/mac80211.cpp | 164 ++----------------------------------- 2 files changed, 5 insertions(+), 162 deletions(-) diff --git a/itlwm/hal_iwm/ItlIwm.hpp b/itlwm/hal_iwm/ItlIwm.hpp index ef0d4737d..a9b943037 100644 --- a/itlwm/hal_iwm/ItlIwm.hpp +++ b/itlwm/hal_iwm/ItlIwm.hpp @@ -266,8 +266,6 @@ class ItlIwm : public ItlHalService, ItlDriverInfo, ItlDriverController { void iwm_rx_tx_cmd(struct iwm_softc *, struct iwm_rx_packet *, struct iwm_rx_data *); void iwm_ampdu_rate_control(struct iwm_softc *, struct ieee80211_node *, struct iwm_tx_ring *, uint16_t, uint16_t, struct ieee80211_tx_info *, int, uint32_t); - void iwm_ht_single_rate_control(struct iwm_softc *, struct ieee80211_node *, - uint8_t, uint8_t, uint8_t, int); void iwm_rx_mpdu_mq(struct iwm_softc *sc, mbuf_t m, void *pktdata, size_t maxlen, struct mbuf_list *ml); void iwm_rx_bmiss(struct iwm_softc *, struct iwm_rx_packet *, @@ -297,7 +295,6 @@ class ItlIwm : public ItlHalService, ItlDriverInfo, ItlDriverController { void iwm_txd_done(struct iwm_softc *, struct iwm_tx_data *); void iwm_ampdu_txq_advance(struct iwm_softc *, struct iwm_tx_ring *, int); void iwm_clear_oactive(struct iwm_softc *, struct iwm_tx_ring *); - void iwm_ra_choose(struct iwm_softc *, struct ieee80211_node *); int iwm_tx(struct iwm_softc *, mbuf_t, struct ieee80211_node *, int); int iwm_flush_tx_path(struct iwm_softc *, int); void iwm_led_enable(struct iwm_softc *); diff --git a/itlwm/hal_iwm/mac80211.cpp b/itlwm/hal_iwm/mac80211.cpp index f04872ebe..79c5e16ab 100644 --- a/itlwm/hal_iwm/mac80211.cpp +++ b/itlwm/hal_iwm/mac80211.cpp @@ -1043,6 +1043,7 @@ static int ieee80211_tx_get_rates(struct iwm_softc *sc, void ieee80211_tx_status(struct iwm_softc *sc, struct ieee80211_tx_info *info, int tid, uint16_t fc, int ssn) { + struct _ifnet *ifp = &sc->sc_ic.ic_ac.ac_if; int rates_idx, retry_count; if (!info) @@ -1051,6 +1052,10 @@ void ieee80211_tx_status(struct iwm_softc *sc, struct ieee80211_tx_info *info, i rates_idx = ieee80211_tx_get_rates(sc, info, &retry_count); rs_drv_mac80211_tx_status(sc, sc->sc_ic.ic_bss, info, tid, fc, ssn); + if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) && + (info->flags & IEEE80211_TX_STAT_AMPDU_NO_BACK) && + (ieee80211_is_data_qos(fc))) + ifp->netStat->outputErrors++; } void ItlIwm:: @@ -1076,8 +1081,6 @@ void ItlIwm:: iwm_ampdu_rate_control(struct iwm_softc *sc, struct ieee80211_node *ni, struct iwm_tx_ring *ring, uint16_t seq, uint16_t ssn, struct ieee80211_tx_info *tx_info, int tid, uint32_t rate_n_flags) { - struct ieee80211com *ic = &sc->sc_ic; - struct iwm_node *wn = (struct iwm_node *)ni; int idx, end_idx; struct iwm_tx_ba *tid_data = &sc->sc_tx_ba[tid]; int freed = 0; @@ -1139,51 +1142,6 @@ iwm_ampdu_rate_control(struct iwm_softc *sc, struct ieee80211_node *ni, } } -void ItlIwm:: -iwm_ht_single_rate_control(struct iwm_softc *sc, struct ieee80211_node *ni, - uint8_t rate, uint8_t rflags, uint8_t ackfailcnt, int txfail) -{ - struct ieee80211com *ic = (struct ieee80211com *)&sc->sc_ic; - struct iwm_node *wn = (struct iwm_node *)ni; - int mcs = rate; - const struct ieee80211_ra_rate *rs; - unsigned int retries = 0, i; - - /* - * Ignore Tx reports which don't match our last LQ command. - */ - if (rate != ni->ni_txmcs) { - if (++wn->lq_rate_mismatch > 15) { - /* Try to sync firmware with driver. */ - iwm_setrates(wn, 1); - wn->lq_rate_mismatch = 0; - } - return; - } - - wn->lq_rate_mismatch = 0; - - rs = ieee80211_ra_get_rateset(&wn->in_rn, ic, ni, rate); - /* - * Firmware has attempted rates in this rate set in sequence. - * Retries at a basic rate are counted against the minimum MCS. - */ - for (i = 0; i < ackfailcnt; i++) { - if (mcs > rs->min_mcs) { - ieee80211_ra_add_stats_ht(&wn->in_rn, ic, ni, mcs, 1, 1); - mcs--; - } else - retries++; - } - - if (txfail && ackfailcnt == 0) - ieee80211_ra_add_stats_ht(&wn->in_rn, ic, ni, mcs, 1, 1); - else - ieee80211_ra_add_stats_ht(&wn->in_rn, ic, ni, mcs, retries + 1, retries); - - iwm_ra_choose(sc, ni); -} - void ItlIwm:: iwm_rx_tx_ba_notif(struct iwm_softc *sc, struct iwm_rx_packet *pkt, struct iwm_rx_data *data) { @@ -1349,18 +1307,11 @@ void ItlIwm:: iwm_rx_tx_cmd_single(struct iwm_softc *sc, struct iwm_tx_resp *tx_resp, int qid, int idx) { - struct ieee80211com *ic = &sc->sc_ic; - struct iwm_node *in = (struct iwm_node *)ic->ic_bss; - struct ieee80211_node *ni = &in->in_ni; - struct _ifnet *ifp = IC2IFP(ic); u32 status = le16toh(iwl_mvm_get_agg_status(sc, tx_resp)->status); u16 ssn = iwl_mvm_get_scd_ssn(sc, tx_resp); - ssn = le32toh(ssn) & 0xfff; - int txfail; int tid = IWL_MVM_TX_RES_GET_TID(tx_resp->ra_tid); struct iwm_tx_data *txd; struct iwm_tx_ring *ring = &sc->txq[qid]; - struct iwm_tx_ba *tid_data = &sc->sc_tx_ba[tid]; u8 skb_freed = 0; u8 lq_color; @@ -1438,111 +1389,6 @@ iwm_rx_tx_cmd_single(struct iwm_softc *sc, struct iwm_tx_resp *tx_resp, } ring->tail = (ring->tail + 1) % IWM_TX_RING_COUNT; } - -// status = status & IWM_TX_STATUS_MSK; -// txfail = (status != IWM_TX_STATUS_SUCCESS && -// status != IWM_TX_STATUS_DIRECT_DONE); -// -// /* -// * Update rate control statistics. -// * Only report frames which were actually queued with the currently -// * selected Tx rate. Because Tx queues are relatively long we may -// * encounter previously selected rates here during Tx bursts. -// * Providing feedback based on such frames can lead to suboptimal -// * Tx rate control decisions. -// */ -// if ((ni->ni_flags & IEEE80211_NODE_HT) == 0) { -// if (ring->data[idx].txrate != ni->ni_txrate) { -// if (++in->lq_rate_mismatch > 15) { -// /* Try to sync firmware with the driver... */ -// iwm_setrates(in, 1); -// in->lq_rate_mismatch = 0; -// } -// } else { -// in->lq_rate_mismatch = 0; -// -// in->in_amn.amn_txcnt++; -// if (txfail) -// in->in_amn.amn_retrycnt++; -// if (tx_resp->failure_frame > 0) -// in->in_amn.amn_retrycnt++; -// } -// } else if (ic->ic_fixed_mcs == -1 && ic->ic_state == IEEE80211_S_RUN && -// (le32toh(tx_resp->initial_rate) & IWM_RATE_MCS_HT_MSK)) { -// uint32_t fw_txmcs = le32toh(tx_resp->initial_rate) & -// (IWM_RATE_HT_MCS_RATE_CODE_MSK | IWM_RATE_HT_MCS_NSS_MSK); -// /* Ignore Tx reports which don't match our last LQ command. */ -// if (fw_txmcs != ni->ni_txmcs) { -// if (++in->lq_rate_mismatch > 15) { -// /* Try to sync firmware with the driver... */ -// iwm_setrates(in, 1); -// in->lq_rate_mismatch = 0; -// } -// } else { -// int mcs = fw_txmcs; -// const struct ieee80211_ra_rate *rs = -// ieee80211_ra_get_rateset(&in->in_rn, ic, ni, fw_txmcs); -// unsigned int retries = 0, i; -// int old_txmcs = ni->ni_txmcs; -// int old_bw = in->in_rn.bw; -// int old_nss = in->in_rn.nss; -// int old_sgi = in->in_rn.sgi; -// -// in->lq_rate_mismatch = 0; -// -// for (i = 0; i < tx_resp->failure_frame; i++) { -// if (mcs > rs->min_mcs) { -// ieee80211_ra_add_stats_ht(&in->in_rn, -// ic, ni, mcs, 1, 1); -// mcs--; -// } else -// retries++; -// } -// -// if (txfail && tx_resp->failure_frame == 0) { -// ieee80211_ra_add_stats_ht(&in->in_rn, ic, ni, -// fw_txmcs, 1, 1); -// } else { -// ieee80211_ra_add_stats_ht(&in->in_rn, ic, ni, -// mcs, retries + 1, retries); -// } -// -// ieee80211_ra_choose(&in->in_rn, ic, ni); -// -// /* -// * If RA has chosen a new TX rate we must update -// * the firmware's LQ rate table. -// * ni_txmcs may change again before the task runs so -// * cache the chosen rate in the iwm_node structure. -// */ -// if (ni->ni_txmcs != old_txmcs || in->in_rn.bw != old_bw || in->in_rn.sgi != old_sgi || in->in_rn.nss != old_nss) -// iwm_setrates(in, 1); -// } -// } -// -// if (txfail) { -// XYLog("%s %d OUTPUT_ERROR status=%d\n", __FUNCTION__, __LINE__, status); -// ifp->netStat->outputErrors++; -// } else { -// DPRINTFN(2, ("%s %d succeed status=%d\n", __FUNCTION__, __LINE__, status)); -// } -} - -void ItlIwm:: -iwm_ra_choose(struct iwm_softc *sc, struct ieee80211_node *ni) -{ - struct ieee80211com *ic = &sc->sc_ic; - struct iwm_node *in = (struct iwm_node *)ni; - int old_txmcs = ni->ni_txmcs; - int old_bw = in->in_rn.bw; - int old_nss = in->in_rn.nss; - int old_sgi = in->in_rn.sgi; - - ieee80211_ra_choose(&in->in_rn, ic, ni); - - /* Update firmware's LQ retry table if RA has chosen a new MCS. */ - if (ni->ni_txmcs != old_txmcs || in->in_rn.bw != old_bw || in->in_rn.sgi != old_sgi || in->in_rn.nss != old_nss) - iwm_setrates(in, 1); } void ItlIwm:: From 0e2f349f1795a969b6baa11b7964d4a6594f0f8a Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Tue, 29 Mar 2022 01:24:33 +0800 Subject: [PATCH 005/114] Clean old iwm rate definition. --- itlwm/hal_iwm/ItlIwm.hpp | 12 +- itlwm/hal_iwm/coex.cpp | 13 +- itlwm/hal_iwm/fw.cpp | 37 ++--- itlwm/hal_iwm/if_iwmreg.h | 275 ---------------------------------- itlwm/hal_iwm/if_iwmvar.h | 2 +- itlwm/hal_iwm/itlhdr.h | 86 ----------- itlwm/hal_iwm/mac80211.cpp | 293 +++++-------------------------------- itlwm/hal_iwm/rs.cpp | 2 +- itlwm/hal_iwm/rs.h | 5 +- itlwm/hal_iwm/scan.cpp | 52 +++---- 10 files changed, 92 insertions(+), 685 deletions(-) diff --git a/itlwm/hal_iwm/ItlIwm.hpp b/itlwm/hal_iwm/ItlIwm.hpp index a9b943037..d6576d44b 100644 --- a/itlwm/hal_iwm/ItlIwm.hpp +++ b/itlwm/hal_iwm/ItlIwm.hpp @@ -84,9 +84,11 @@ class ItlIwm : public ItlHalService, ItlDriverInfo, ItlDriverController { int iwm_send_bt_init_conf(struct iwm_softc *); //fw - uint8_t iwm_fw_valid_tx_ant(struct iwm_softc *sc); - uint8_t iwm_fw_valid_rx_ant(struct iwm_softc *sc); + static uint8_t iwm_fw_valid_tx_ant(struct iwm_softc *sc); + static uint8_t iwm_fw_valid_rx_ant(struct iwm_softc *sc); void iwm_toggle_tx_ant(struct iwm_softc *sc, uint8_t *ant); + uint32_t iwm_get_tx_ant(struct iwm_softc *sc, struct ieee80211_node *ni, + int type, struct ieee80211_frame *wh); //scan uint8_t iwm_umac_scan_fill_channels(struct iwm_softc *sc, @@ -98,11 +100,9 @@ class ItlIwm : public ItlHalService, ItlDriverInfo, ItlDriverController { static bool iwm_coex_is_ant_avail(struct iwm_softc *, u8); static bool iwm_coex_is_mimo_allowed(struct iwm_softc *, struct ieee80211_node *); static bool iwm_coex_is_tpc_allowed(struct iwm_softc *, bool); + static bool iwm_coex_is_shared_ant_avail(struct iwm_softc *); uint8_t iwm_lookup_cmd_ver(struct iwm_softc *, uint8_t, uint8_t); - int iwm_is_mimo_ht_plcp(uint8_t); - int iwm_is_mimo_vht_plcp(uint8_t); - int iwm_is_mimo_mcs(int); int iwm_store_cscheme(struct iwm_softc *, uint8_t *, size_t); int iwm_firmware_store_section(struct iwm_softc *, enum iwm_ucode_type, uint8_t *, size_t); @@ -332,7 +332,6 @@ class ItlIwm : public ItlHalService, ItlDriverInfo, ItlDriverController { int iwm_umac_scan(struct iwm_softc *, int); void iwm_mcc_update(struct iwm_softc *, struct iwm_mcc_chub_notif *); uint8_t iwm_ridx2rate(struct ieee80211_rateset *, int); - int iwm_rval2ridx(int); void iwm_ack_rates(struct iwm_softc *, struct iwm_node *, int *, int *); void iwm_mac_ctxt_cmd_common(struct iwm_softc *, struct iwm_node *, struct iwm_mac_ctx_cmd *, uint32_t); @@ -363,7 +362,6 @@ class ItlIwm : public ItlHalService, ItlDriverInfo, ItlDriverController { static void iwm_delete_key(struct ieee80211com *, struct ieee80211_node *, struct ieee80211_key *); static void iwm_calib_timeout(void *); - void iwm_setrates(struct iwm_node *, int); int iwm_media_change(struct _ifnet *); static void iwm_newstate_task(void *); static int iwm_newstate(struct ieee80211com *, enum ieee80211_state, int); diff --git a/itlwm/hal_iwm/coex.cpp b/itlwm/hal_iwm/coex.cpp index 16d7e0e4f..6857dcc12 100644 --- a/itlwm/hal_iwm/coex.cpp +++ b/itlwm/hal_iwm/coex.cpp @@ -128,6 +128,17 @@ iwm_coex_is_tpc_allowed(struct iwm_softc *mvm, bool is5G) #ifdef notyet_coex return le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) >= BT_LOW_TRAFFIC; #else - return true; + return false; +#endif +} + +bool ItlIwm:: +iwm_coex_is_shared_ant_avail(struct iwm_softc *mvm) +{ +#ifdef notyet_coex + return le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) < BT_HIGH_TRAFFIC; +#else + return mvm->sc_device_family == IWM_DEVICE_FAMILY_9000 && + (iwm_fw_valid_tx_ant(mvm) & IWM_ANT_B); #endif } diff --git a/itlwm/hal_iwm/fw.cpp b/itlwm/hal_iwm/fw.cpp index a513e86cc..9fba2d728 100644 --- a/itlwm/hal_iwm/fw.cpp +++ b/itlwm/hal_iwm/fw.cpp @@ -120,6 +120,7 @@ */ #include "ItlIwm.hpp" +#include "rs.h" #include uint8_t ItlIwm:: @@ -137,28 +138,6 @@ iwm_lookup_cmd_ver(struct iwm_softc *sc, uint8_t grp, uint8_t cmd) return IWM_FW_CMD_VER_UNKNOWN; } -int ItlIwm:: -iwm_is_mimo_ht_plcp(uint8_t ht_plcp) -{ - return (ht_plcp != IWM_RATE_HT_SISO_MCS_INV_PLCP && - (ht_plcp & IWM_RATE_HT_MCS_NSS_MSK)); -} - -int ItlIwm:: -iwm_is_mimo_vht_plcp(uint8_t ht_plcp) -{ - return (ht_plcp != IWM_RATE_VHT_SISO_MCS_INV_PLCP && - (ht_plcp & IWM_RATE_VHT_MCS_NSS_MSK)); -} - -int ItlIwm:: -iwm_is_mimo_mcs(int mcs) -{ - int ridx = iwm_mcs2ridx[mcs]; - return iwm_is_mimo_ht_plcp(iwm_rates[ridx].ht_plcp); - -} - int ItlIwm:: iwm_store_cscheme(struct iwm_softc *sc, uint8_t *data, size_t dlen) { @@ -739,6 +718,20 @@ iwm_fw_valid_rx_ant(struct iwm_softc *sc) return rx_ant; } +uint32_t ItlIwm:: +iwm_get_tx_ant(struct iwm_softc *sc, struct ieee80211_node *ni, + int type, struct ieee80211_frame *wh) +{ + if (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan) && + !ItlIwm::iwm_coex_is_shared_ant_avail(sc)) + return sc->non_shared_ant << RATE_MCS_ANT_POS; + + if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && type == IEEE80211_FC0_TYPE_DATA) + return ((1 << sc->sc_tx_ant) << RATE_MCS_ANT_POS); + + return ((1 << sc->sc_mgmt_last_antenna_idx) << RATE_MCS_ANT_POS); +} + void ItlIwm:: iwm_toggle_tx_ant(struct iwm_softc *sc, uint8_t *ant) { diff --git a/itlwm/hal_iwm/if_iwmreg.h b/itlwm/hal_iwm/if_iwmreg.h index 44ebf1842..cdddd973c 100644 --- a/itlwm/hal_iwm/if_iwmreg.h +++ b/itlwm/hal_iwm/if_iwmreg.h @@ -4399,232 +4399,6 @@ struct iwm_beacon_filter_cmd { .bf_escape_timer = htole32(IWM_BF_ESCAPE_TIMER_DEFAULT), \ .ba_escape_timer = htole32(IWM_BA_ESCAPE_TIMER_DEFAULT) -/* uCode API values for HT/VHT bit rates */ -#define IWM_RATE_HT_SISO_MCS_0_PLCP 0 -#define IWM_RATE_HT_SISO_MCS_1_PLCP 1 -#define IWM_RATE_HT_SISO_MCS_2_PLCP 2 -#define IWM_RATE_HT_SISO_MCS_3_PLCP 3 -#define IWM_RATE_HT_SISO_MCS_4_PLCP 4 -#define IWM_RATE_HT_SISO_MCS_5_PLCP 5 -#define IWM_RATE_HT_SISO_MCS_6_PLCP 6 -#define IWM_RATE_HT_SISO_MCS_7_PLCP 7 -#define IWM_RATE_HT_MIMO2_MCS_8_PLCP 0x8 -#define IWM_RATE_HT_MIMO2_MCS_9_PLCP 0x9 -#define IWM_RATE_HT_MIMO2_MCS_10_PLCP 0xA -#define IWM_RATE_HT_MIMO2_MCS_11_PLCP 0xB -#define IWM_RATE_HT_MIMO2_MCS_12_PLCP 0xC -#define IWM_RATE_HT_MIMO2_MCS_13_PLCP 0xD -#define IWM_RATE_HT_MIMO2_MCS_14_PLCP 0xE -#define IWM_RATE_HT_MIMO2_MCS_15_PLCP 0xF -#define IWM_RATE_VHT_SISO_MCS_0_PLCP 0 -#define IWM_RATE_VHT_SISO_MCS_1_PLCP 1 -#define IWM_RATE_VHT_SISO_MCS_2_PLCP 2 -#define IWM_RATE_VHT_SISO_MCS_3_PLCP 3 -#define IWM_RATE_VHT_SISO_MCS_4_PLCP 4 -#define IWM_RATE_VHT_SISO_MCS_5_PLCP 5 -#define IWM_RATE_VHT_SISO_MCS_6_PLCP 6 -#define IWM_RATE_VHT_SISO_MCS_7_PLCP 7 -#define IWM_RATE_VHT_SISO_MCS_8_PLCP 8 -#define IWM_RATE_VHT_SISO_MCS_9_PLCP 9 -#define IWM_RATE_VHT_MIMO2_MCS_0_PLCP 0x10 -#define IWM_RATE_VHT_MIMO2_MCS_1_PLCP 0x11 -#define IWM_RATE_VHT_MIMO2_MCS_2_PLCP 0x12 -#define IWM_RATE_VHT_MIMO2_MCS_3_PLCP 0x13 -#define IWM_RATE_VHT_MIMO2_MCS_4_PLCP 0x14 -#define IWM_RATE_VHT_MIMO2_MCS_5_PLCP 0x15 -#define IWM_RATE_VHT_MIMO2_MCS_6_PLCP 0x16 -#define IWM_RATE_VHT_MIMO2_MCS_7_PLCP 0x17 -#define IWM_RATE_VHT_MIMO2_MCS_8_PLCP 0x18 -#define IWM_RATE_VHT_MIMO2_MCS_9_PLCP 0x19 -#define IWM_RATE_HT_SISO_MCS_INV_PLCP 0x1A -#define IWM_RATE_HT_MIMO2_MCS_INV_PLCP IWM_RATE_HT_SISO_MCS_INV_PLCP -#define IWM_RATE_VHT_SISO_MCS_INV_PLCP IWM_RATE_HT_SISO_MCS_INV_PLCP -#define IWM_RATE_VHT_MIMO2_MCS_INV_PLCP IWM_RATE_HT_SISO_MCS_INV_PLCP -#define IWM_RATE_HT_SISO_MCS_8_PLCP IWM_RATE_HT_SISO_MCS_INV_PLCP -#define IWM_RATE_HT_SISO_MCS_9_PLCP IWM_RATE_HT_SISO_MCS_INV_PLCP - -/* - * These serve as indexes into struct iwm_rate iwm_rates[IWM_RIDX_MAX]. - */ -enum { - IWM_RATE_1M_INDEX = 0, - IWM_FIRST_CCK_RATE = IWM_RATE_1M_INDEX, - IWM_RATE_2M_INDEX, - IWM_RATE_5M_INDEX, - IWM_RATE_11M_INDEX, - IWM_LAST_CCK_RATE = IWM_RATE_11M_INDEX, - IWM_RATE_6M_INDEX, - IWM_FIRST_OFDM_RATE = IWM_RATE_6M_INDEX, - IWM_RATE_MCS_0_INDEX = IWM_RATE_6M_INDEX, - IWM_FIRST_HT_RATE = IWM_RATE_MCS_0_INDEX, - IWM_FIRST_VHT_RATE = IWM_RATE_MCS_0_INDEX, - IWM_RATE_9M_INDEX, - IWM_RATE_12M_INDEX, - IWM_RATE_MCS_1_INDEX = IWM_RATE_12M_INDEX, - IWM_RATE_MCS_8_INDEX, - IWM_FIRST_HT_MIMO2_RATE = IWM_RATE_MCS_8_INDEX, - IWM_RATE_18M_INDEX, - IWM_RATE_MCS_2_INDEX = IWM_RATE_18M_INDEX, - IWM_RATE_24M_INDEX, - IWM_RATE_MCS_3_INDEX = IWM_RATE_24M_INDEX, - IWM_RATE_MCS_9_INDEX, - IWM_RATE_36M_INDEX, - IWM_RATE_MCS_4_INDEX = IWM_RATE_36M_INDEX, - IWM_RATE_MCS_10_INDEX, - IWM_RATE_48M_INDEX, - IWM_RATE_MCS_5_INDEX = IWM_RATE_48M_INDEX, - IWM_RATE_MCS_11_INDEX, - IWM_RATE_54M_INDEX, - IWM_RATE_MCS_6_INDEX = IWM_RATE_54M_INDEX, - IWM_LAST_NON_HT_RATE = IWM_RATE_54M_INDEX, - IWM_RATE_MCS_7_INDEX, - IWM_LAST_HT_SISO_RATE = IWM_RATE_MCS_7_INDEX, - IWM_RATE_MCS_12_INDEX, - IWM_RATE_MCS_13_INDEX, - IWM_RATE_MCS_14_INDEX, - IWM_RATE_MCS_15_INDEX, - IWM_LAST_VHT_SISO_RATE = IWM_RATE_MCS_13_INDEX, - IWM_LAST_HT_RATE = IWM_RATE_MCS_15_INDEX, - IWM_LAST_VHT_RATE = IWM_RATE_MCS_15_INDEX + 3, - IWM_RATE_COUNT_LEGACY = IWM_LAST_NON_HT_RATE + 1, - IWM_RATE_COUNT = IWM_LAST_VHT_RATE + 1, -}; - -#define IWM_RATE_BIT_MSK(r) (1 << (IWM_RATE_##r##M_INDEX)) - -/* fw API values for legacy bit rates, both OFDM and CCK */ -#define IWM_RATE_6M_PLCP 13 -#define IWM_RATE_9M_PLCP 15 -#define IWM_RATE_12M_PLCP 5 -#define IWM_RATE_18M_PLCP 7 -#define IWM_RATE_24M_PLCP 9 -#define IWM_RATE_36M_PLCP 11 -#define IWM_RATE_48M_PLCP 1 -#define IWM_RATE_54M_PLCP 3 -#define IWM_RATE_1M_PLCP 10 -#define IWM_RATE_2M_PLCP 20 -#define IWM_RATE_5M_PLCP 55 -#define IWM_RATE_11M_PLCP 110 -#define IWM_RATE_INVM_PLCP 0xff - -/* - * rate_n_flags bit fields - * - * The 32-bit value has different layouts in the low 8 bites depending on the - * format. There are three formats, HT, VHT and legacy (11abg, with subformats - * for CCK and OFDM). - * - * High-throughput (HT) rate format - * bit 8 is 1, bit 26 is 0, bit 9 is 0 (OFDM) - * Very High-throughput (VHT) rate format - * bit 8 is 0, bit 26 is 1, bit 9 is 0 (OFDM) - * Legacy OFDM rate format for bits 7:0 - * bit 8 is 0, bit 26 is 0, bit 9 is 0 (OFDM) - * Legacy CCK rate format for bits 7:0: - * bit 8 is 0, bit 26 is 0, bit 9 is 1 (CCK) - */ - -/* Bit 8: (1) HT format, (0) legacy or VHT format */ -#define IWM_RATE_MCS_HT_POS 8 -#define IWM_RATE_MCS_HT_MSK (1 << IWM_RATE_MCS_HT_POS) - -/* Bit 9: (1) CCK, (0) OFDM. HT (bit 8) must be "0" for this bit to be valid */ -#define IWM_RATE_MCS_CCK_POS 9 -#define IWM_RATE_MCS_CCK_MSK (1 << IWM_RATE_MCS_CCK_POS) - -/* Bit 26: (1) VHT format, (0) legacy format in bits 8:0 */ -#define IWM_RATE_MCS_VHT_POS 26 -#define IWM_RATE_MCS_VHT_MSK (1 << IWM_RATE_MCS_VHT_POS) - - -/* - * High-throughput (HT) rate format for bits 7:0 - * - * 2-0: MCS rate base - * 0) 6 Mbps - * 1) 12 Mbps - * 2) 18 Mbps - * 3) 24 Mbps - * 4) 36 Mbps - * 5) 48 Mbps - * 6) 54 Mbps - * 7) 60 Mbps - * 4-3: 0) Single stream (SISO) - * 1) Dual stream (MIMO) - * 2) Triple stream (MIMO) - * 5: Value of 0x20 in bits 7:0 indicates 6 Mbps HT40 duplicate data - * (bits 7-6 are zero) - * - * Together the low 5 bits work out to the MCS index because we don't - * support MCSes above 15/23, and 0-7 have one stream, 8-15 have two - * streams and 16-23 have three streams. We could also support MCS 32 - * which is the duplicate 20 MHz MCS (bit 5 set, all others zero.) - */ -#define IWM_RATE_HT_MCS_RATE_CODE_MSK 0x7 -#define IWM_RATE_HT_MCS_NSS_POS 3 -#define IWM_RATE_HT_MCS_NSS_MSK (3 << IWM_RATE_HT_MCS_NSS_POS) - -/* Bit 10: (1) Use Green Field preamble */ -#define IWM_RATE_HT_MCS_GF_POS 10 -#define IWM_RATE_HT_MCS_GF_MSK (1 << IWM_RATE_HT_MCS_GF_POS) - -#define IWM_RATE_HT_MCS_INDEX_MSK 0x3f - -/* - * Very High-throughput (VHT) rate format for bits 7:0 - * - * 3-0: VHT MCS (0-9) - * 5-4: number of streams - 1: - * 0) Single stream (SISO) - * 1) Dual stream (MIMO) - * 2) Triple stream (MIMO) - */ - -/* Bit 4-5: (0) SISO, (1) MIMO2 (2) MIMO3 */ -#define IWM_RATE_VHT_MCS_RATE_CODE_MSK 0xf -#define IWM_RATE_VHT_MCS_NSS_POS 4 -#define IWM_RATE_VHT_MCS_NSS_MSK (3 << IWM_RATE_VHT_MCS_NSS_POS) - -/* - * Legacy OFDM rate format for bits 7:0 - * - * 3-0: 0xD) 6 Mbps - * 0xF) 9 Mbps - * 0x5) 12 Mbps - * 0x7) 18 Mbps - * 0x9) 24 Mbps - * 0xB) 36 Mbps - * 0x1) 48 Mbps - * 0x3) 54 Mbps - * (bits 7-4 are 0) - * - * Legacy CCK rate format for bits 7:0: - * bit 8 is 0, bit 26 is 0, bit 9 is 1 (CCK): - * - * 6-0: 10) 1 Mbps - * 20) 2 Mbps - * 55) 5.5 Mbps - * 110) 11 Mbps - * (bit 7 is 0) - */ -#define IWM_RATE_LEGACY_RATE_MSK 0xff - - -/* - * Bit 11-12: (0) 20MHz, (1) 40MHz, (2) 80MHz, (3) 160MHz - * 0 and 1 are valid for HT and VHT, 2 and 3 only for VHT - */ -#define IWM_RATE_MCS_CHAN_WIDTH_POS 11 -#define IWM_RATE_MCS_CHAN_WIDTH_MSK (3 << IWM_RATE_MCS_CHAN_WIDTH_POS) -#define IWM_RATE_MCS_CHAN_WIDTH_20 (0 << IWM_RATE_MCS_CHAN_WIDTH_POS) -#define IWM_RATE_MCS_CHAN_WIDTH_40 (1 << IWM_RATE_MCS_CHAN_WIDTH_POS) -#define IWM_RATE_MCS_CHAN_WIDTH_80 (2 << IWM_RATE_MCS_CHAN_WIDTH_POS) -#define IWM_RATE_MCS_CHAN_WIDTH_160 (3 << IWM_RATE_MCS_CHAN_WIDTH_POS) - -/* Bit 13: (1) Short guard interval (0.4 usec), (0) normal GI (0.8 usec) */ -#define IWM_RATE_MCS_SGI_POS 13 -#define IWM_RATE_MCS_SGI_MSK (1 << IWM_RATE_MCS_SGI_POS) - /* Bit 14-16: Antenna selection (1) Ant A, (2) Ant B, (4) Ant C */ #define IWM_RATE_MCS_ANT_POS 14 #define IWM_RATE_MCS_ANT_A_MSK (1 << IWM_RATE_MCS_ANT_POS) @@ -4637,58 +4411,9 @@ enum { #define IWM_RATE_MCS_ANT_MSK IWM_RATE_MCS_ANT_ABC_MSK #define IWM_RATE_MCS_ANT_NUM 3 -/* Bit 17-18: (0) SS, (1) SS*2 */ -#define IWM_RATE_MCS_STBC_POS 17 -#define IWM_RATE_MCS_STBC_MSK (1 << IWM_RATE_MCS_STBC_POS) - -/* Bit 19: (0) Beamforming is off, (1) Beamforming is on */ -#define IWM_RATE_MCS_BF_POS 19 -#define IWM_RATE_MCS_BF_MSK (1 << IWM_RATE_MCS_BF_POS) - -/* Bit 20: (0) ZLF is off, (1) ZLF is on */ -#define IWM_RATE_MCS_ZLF_POS 20 -#define IWM_RATE_MCS_ZLF_MSK (1 << IWM_RATE_MCS_ZLF_POS) - -/* Bit 24-25: (0) 20MHz (no dup), (1) 2x20MHz, (2) 4x20MHz, 3 8x20MHz */ -#define IWM_RATE_MCS_DUP_POS 24 -#define IWM_RATE_MCS_DUP_MSK (3 << IWM_RATE_MCS_DUP_POS) - -/* Bit 27: (1) LDPC enabled, (0) LDPC disabled */ -#define IWM_RATE_MCS_LDPC_POS 27 -#define IWM_RATE_MCS_LDPC_MSK (1 << IWM_RATE_MCS_LDPC_POS) - - -/* Link Quality definitions */ - /* # entries in rate scale table to support Tx retries */ #define IWM_LQ_MAX_RETRY_NUM 16 -/* Link quality command flags bit fields */ - -/* Bit 0: (0) Don't use RTS (1) Use RTS */ -#define IWM_LQ_FLAG_USE_RTS_POS 0 -#define IWM_LQ_FLAG_USE_RTS_MSK (1 << IWM_LQ_FLAG_USE_RTS_POS) - -/* Bit 1-3: LQ command color. Used to match responses to LQ commands */ -#define IWM_LQ_FLAG_COLOR_POS 1 -#define IWM_LQ_FLAG_COLOR_MSK (7 << IWM_LQ_FLAG_COLOR_POS) - -/* Bit 4-5: Tx RTS BW Signalling - * (0) No RTS BW signalling - * (1) Static BW signalling - * (2) Dynamic BW signalling - */ -#define IWM_LQ_FLAG_RTS_BW_SIG_POS 4 -#define IWM_LQ_FLAG_RTS_BW_SIG_NONE (0 << IWM_LQ_FLAG_RTS_BW_SIG_POS) -#define IWM_LQ_FLAG_RTS_BW_SIG_STATIC (1 << IWM_LQ_FLAG_RTS_BW_SIG_POS) -#define IWM_LQ_FLAG_RTS_BW_SIG_DYNAMIC (2 << IWM_LQ_FLAG_RTS_BW_SIG_POS) - -/* Bit 6: (0) No dynamic BW selection (1) Allow dynamic BW selection - * Dyanmic BW selection allows Tx with narrower BW then requested in rates - */ -#define IWM_LQ_FLAG_DYNAMIC_BW_POS 6 -#define IWM_LQ_FLAG_DYNAMIC_BW_MSK (1 << IWM_LQ_FLAG_DYNAMIC_BW_POS) - /* Antenna flags. */ #define IWM_ANT_A (1 << 0) #define IWM_ANT_B (1 << 1) diff --git a/itlwm/hal_iwm/if_iwmvar.h b/itlwm/hal_iwm/if_iwmvar.h index 3d48b00fa..8624e10ec 100644 --- a/itlwm/hal_iwm/if_iwmvar.h +++ b/itlwm/hal_iwm/if_iwmvar.h @@ -551,6 +551,7 @@ struct iwm_softc { int cmdqid; uint8_t sc_mgmt_last_antenna_idx; + uint8_t sc_tx_ant; int sc_sf_state; @@ -713,7 +714,6 @@ struct iwm_node { uint16_t in_color; struct ieee80211_amrr_node in_amn; - struct ieee80211_ra_node in_rn; int lq_rate_mismatch; uint32_t next_ampdu_id; diff --git a/itlwm/hal_iwm/itlhdr.h b/itlwm/hal_iwm/itlhdr.h index f6af6e578..d8092946b 100644 --- a/itlwm/hal_iwm/itlhdr.h +++ b/itlwm/hal_iwm/itlhdr.h @@ -181,92 +181,6 @@ const uint8_t iwm_nvm_channels_8000[] = { #define IWM_FIRST_2GHZ_HT_MINUS 5 #define IWM_LAST_2GHZ_HT_PLUS 9 -const struct iwm_rate { - uint16_t rate; - uint8_t plcp; - uint8_t ht_plcp; - uint8_t vht_plcp; -} iwm_rates[] = { - /* Legacy */ /* HT */ - { 2, IWM_RATE_1M_PLCP, IWM_RATE_HT_SISO_MCS_INV_PLCP, IWM_RATE_VHT_SISO_MCS_INV_PLCP }, - { 4, IWM_RATE_2M_PLCP, IWM_RATE_HT_SISO_MCS_INV_PLCP, IWM_RATE_VHT_SISO_MCS_INV_PLCP }, - { 11, IWM_RATE_5M_PLCP, IWM_RATE_HT_SISO_MCS_INV_PLCP, IWM_RATE_VHT_SISO_MCS_INV_PLCP }, - { 22, IWM_RATE_11M_PLCP, IWM_RATE_HT_SISO_MCS_INV_PLCP, IWM_RATE_VHT_SISO_MCS_INV_PLCP }, - { 12, IWM_RATE_6M_PLCP, IWM_RATE_HT_SISO_MCS_0_PLCP, IWM_RATE_VHT_SISO_MCS_0_PLCP }, - { 18, IWM_RATE_9M_PLCP, IWM_RATE_HT_SISO_MCS_INV_PLCP, IWM_RATE_VHT_SISO_MCS_INV_PLCP }, - { 24, IWM_RATE_12M_PLCP, IWM_RATE_HT_SISO_MCS_1_PLCP, IWM_RATE_VHT_SISO_MCS_1_PLCP }, - { 26, IWM_RATE_12M_PLCP, IWM_RATE_HT_MIMO2_MCS_8_PLCP, IWM_RATE_VHT_MIMO2_MCS_0_PLCP }, - { 36, IWM_RATE_18M_PLCP, IWM_RATE_HT_SISO_MCS_2_PLCP, IWM_RATE_VHT_SISO_MCS_2_PLCP }, - { 48, IWM_RATE_24M_PLCP, IWM_RATE_HT_SISO_MCS_3_PLCP, IWM_RATE_VHT_SISO_MCS_3_PLCP }, - { 52, IWM_RATE_24M_PLCP, IWM_RATE_HT_MIMO2_MCS_9_PLCP, IWM_RATE_VHT_MIMO2_MCS_1_PLCP }, - { 72, IWM_RATE_36M_PLCP, IWM_RATE_HT_SISO_MCS_4_PLCP, IWM_RATE_VHT_SISO_MCS_4_PLCP }, - { 78, IWM_RATE_36M_PLCP, IWM_RATE_HT_MIMO2_MCS_10_PLCP, IWM_RATE_VHT_MIMO2_MCS_2_PLCP }, - { 96, IWM_RATE_48M_PLCP, IWM_RATE_HT_SISO_MCS_5_PLCP, IWM_RATE_VHT_SISO_MCS_5_PLCP }, - { 104, IWM_RATE_48M_PLCP, IWM_RATE_HT_MIMO2_MCS_11_PLCP, IWM_RATE_VHT_MIMO2_MCS_3_PLCP }, - { 108, IWM_RATE_54M_PLCP, IWM_RATE_HT_SISO_MCS_6_PLCP, IWM_RATE_VHT_SISO_MCS_6_PLCP }, - { 128, IWM_RATE_54M_PLCP, IWM_RATE_HT_SISO_MCS_7_PLCP, IWM_RATE_VHT_SISO_MCS_7_PLCP }, - { 156, IWM_RATE_54M_PLCP, IWM_RATE_HT_MIMO2_MCS_12_PLCP, IWM_RATE_VHT_SISO_MCS_8_PLCP }, - { 208, IWM_RATE_54M_PLCP, IWM_RATE_HT_MIMO2_MCS_13_PLCP, IWM_RATE_VHT_SISO_MCS_9_PLCP }, - { 234, IWM_RATE_54M_PLCP, IWM_RATE_HT_MIMO2_MCS_14_PLCP, IWM_RATE_VHT_MIMO2_MCS_4_PLCP }, - { 260, IWM_RATE_54M_PLCP, IWM_RATE_HT_MIMO2_MCS_15_PLCP, IWM_RATE_VHT_MIMO2_MCS_5_PLCP }, - { 312, IWM_RATE_54M_PLCP, IWM_RATE_HT_SISO_MCS_INV_PLCP, IWM_RATE_VHT_MIMO2_MCS_6_PLCP }, - { 360, IWM_RATE_54M_PLCP, IWM_RATE_HT_SISO_MCS_INV_PLCP, IWM_RATE_VHT_MIMO2_MCS_7_PLCP }, - { 720, IWM_RATE_54M_PLCP, IWM_RATE_HT_SISO_MCS_INV_PLCP, IWM_RATE_VHT_MIMO2_MCS_8_PLCP }, - { 780, IWM_RATE_54M_PLCP, IWM_RATE_HT_SISO_MCS_INV_PLCP, IWM_RATE_VHT_MIMO2_MCS_9_PLCP }, -}; -#define IWM_RIDX_CCK 0 -#define IWM_RIDX_OFDM 4 -#define IWM_RIDX_MAX (nitems(iwm_rates)-1) -#define IWM_RIDX_IS_CCK(_i_) ((_i_) < IWM_RIDX_OFDM) -#define IWM_RIDX_IS_OFDM(_i_) ((_i_) >= IWM_RIDX_OFDM) -#define IWM_RVAL_IS_OFDM(_i_) ((_i_) >= 12 && (_i_) != 22) - -/* Convert an MCS index into an iwm_rates[] index. */ -const int iwm_mcs2ridx[] = { - IWM_RATE_MCS_0_INDEX, - IWM_RATE_MCS_1_INDEX, - IWM_RATE_MCS_2_INDEX, - IWM_RATE_MCS_3_INDEX, - IWM_RATE_MCS_4_INDEX, - IWM_RATE_MCS_5_INDEX, - IWM_RATE_MCS_6_INDEX, - IWM_RATE_MCS_7_INDEX, - IWM_RATE_MCS_8_INDEX, - IWM_RATE_MCS_9_INDEX, - IWM_RATE_MCS_10_INDEX, - IWM_RATE_MCS_11_INDEX, - IWM_RATE_MCS_12_INDEX, - IWM_RATE_MCS_13_INDEX, - IWM_RATE_MCS_14_INDEX, - IWM_RATE_MCS_15_INDEX, -}; - -const int iwm_vht_siso_mcs2ridx[] = { - IWM_RATE_MCS_0_INDEX, - IWM_RATE_MCS_1_INDEX, - IWM_RATE_MCS_2_INDEX, - IWM_RATE_MCS_3_INDEX, - IWM_RATE_MCS_4_INDEX, - IWM_RATE_MCS_5_INDEX, - IWM_RATE_MCS_6_INDEX, - IWM_RATE_MCS_7_INDEX, - IWM_RATE_MCS_12_INDEX, - IWM_RATE_MCS_13_INDEX, -}; - -const int iwm_vht_mimo_mcs2ridx[] = { - IWM_RATE_MCS_8_INDEX, - IWM_RATE_MCS_9_INDEX, - IWM_RATE_MCS_10_INDEX, - IWM_RATE_MCS_11_INDEX, - IWM_RATE_MCS_14_INDEX, - IWM_RATE_MCS_15_INDEX, - IWM_RATE_MCS_15_INDEX+1, - IWM_RATE_MCS_15_INDEX+2, - IWM_RATE_MCS_15_INDEX+3, - IWM_RATE_MCS_15_INDEX+4, -}; - struct iwm_nvm_section { uint16_t length; uint8_t *data; diff --git a/itlwm/hal_iwm/mac80211.cpp b/itlwm/hal_iwm/mac80211.cpp index 79c5e16ab..965a62c2e 100644 --- a/itlwm/hal_iwm/mac80211.cpp +++ b/itlwm/hal_iwm/mac80211.cpp @@ -1236,15 +1236,6 @@ iwm_ampdu_tx_done(struct iwm_softc *sc, struct iwm_cmd_header *cmd_hdr, int txfail = (status != IWM_TX_STATUS_SUCCESS && status != IWM_TX_STATUS_DIRECT_DONE); struct ieee80211_tx_ba *ba; - int rate = 0; - if (initial_rate & IWM_RATE_MCS_VHT_MSK) { - rate = (initial_rate & - IWM_RATE_VHT_MCS_RATE_CODE_MSK); - } else if (initial_rate & IWM_RATE_MCS_HT_MSK) { - rate = (initial_rate & - (IWM_RATE_HT_MCS_RATE_CODE_MSK | - IWM_RATE_HT_MCS_NSS_MSK)); - } sc->sc_tx_timer = 0; @@ -1348,6 +1339,11 @@ iwm_rx_tx_cmd_single(struct iwm_softc *sc, struct iwm_tx_resp *tx_resp, if ((status & IWM_TX_STATUS_MSK) != IWM_TX_STATUS_SUCCESS && ieee80211_is_mgmt(txd->fc)) iwm_toggle_tx_ant(sc, &sc->sc_mgmt_last_antenna_idx); + + if ((status & IWM_TX_STATUS_MSK) != IWM_TX_STATUS_SUCCESS && + sc->sc_ic.ic_state <= IEEE80211_S_RUN) + iwm_toggle_tx_ant(sc, &sc->sc_tx_ant); + /* * If we are freeing multiple frames, mark all the frames @@ -1554,77 +1550,51 @@ iwm_tx_fill_cmd(struct iwm_softc *sc, struct iwm_node *in, { struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_node *ni = &in->in_ni; - const struct iwm_rate *rinfo; + const struct iwm_rate *rinfo = NULL; int type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; int subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; int ridx, rate_flags; + int min_ridx = (IEEE80211_IS_CHAN_5GHZ(ni->ni_chan)) ? + IWL_FIRST_OFDM_RATE : IWL_FIRST_CCK_RATE; + int i; + + int min_rate = ieee80211_min_basic_rate(ic); + for (i = 0; i < ieee80211_std_rateset_11g.rs_nrates; i++) { + if (ieee80211_std_rateset_11g.rs_rates[i] == min_rate) { + min_ridx = i; + break; + } + } + ridx = min_ridx; tx->rts_retry_limit = IWM_RTS_DFAULT_RETRY_LIMIT; - if (type == IEEE80211_FC0_TYPE_CTL && subtype == IEEE80211_FC0_SUBTYPE_BAR) { + if (type == IEEE80211_FC0_TYPE_CTL && subtype == IEEE80211_FC0_SUBTYPE_BAR) tx->data_retry_limit = IWM_BAR_DFAULT_RETRY_LIMIT; - } else { + else tx->data_retry_limit = IWM_DEFAULT_TX_RETRY; - } /* * for data packets, rate info comes from the table inside the fw. This * table is controlled by LINK_QUALITY commands */ if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && type == IEEE80211_FC0_TYPE_DATA) { - int i; tx->initial_rate_index = 0; tx->tx_flags |= cpu_to_le32(IWM_TX_CMD_FLG_STA_RATE); - if (ni->ni_flags & IEEE80211_NODE_VHT) { - ridx = (in->in_rn.nss > 1 ? iwm_vht_mimo_mcs2ridx[ni->ni_txmcs] : iwm_vht_siso_mcs2ridx[ni->ni_txmcs]); - return &iwm_rates[ridx]; - } else if (ni->ni_flags & IEEE80211_NODE_HT) { - ridx = iwm_mcs2ridx[ni->ni_txmcs]; - return &iwm_rates[ridx]; - } - ridx = (IEEE80211_IS_CHAN_5GHZ(ni->ni_chan)) ? - IWM_RIDX_OFDM : IWM_RIDX_CCK; - for (i = 0; i < ni->ni_rates.rs_nrates; i++) { - if (iwm_rates[i].rate == (ni->ni_txrate & - IEEE80211_RATE_VAL)) { - ridx = i; - break; - } - } - return &iwm_rates[ridx]; - } else if (type == IEEE80211_FC0_TYPE_CTL && subtype == IEEE80211_FC0_SUBTYPE_BAR) { + return rinfo; + } else if (type == IEEE80211_FC0_TYPE_CTL && subtype == IEEE80211_FC0_SUBTYPE_BAR) tx->tx_flags |= htole32(IWM_TX_CMD_FLG_ACK | IWM_TX_CMD_FLG_BAR); - } - - ridx = (IEEE80211_IS_CHAN_5GHZ(ni->ni_chan)) ? - IWM_RIDX_OFDM : IWM_RIDX_CCK; - for (int i = 0; i < ni->ni_rates.rs_nrates; i++) { - if (iwm_rates[i].rate == (ni->ni_txrate & - IEEE80211_RATE_VAL)) { - ridx = i; - break; - } - } - if (ni->ni_flags & IEEE80211_NODE_VHT) { - ridx = (in->in_rn.nss > 1 ? iwm_vht_mimo_mcs2ridx[ni->ni_txmcs] : iwm_vht_siso_mcs2ridx[ni->ni_txmcs]); - } else if (ni->ni_flags & IEEE80211_NODE_HT) { - ridx = iwm_mcs2ridx[ni->ni_txmcs]; - } - if (ic->ic_fixed_mcs != -1) { + + if (ic->ic_fixed_mcs != -1) ridx = sc->sc_fixed_ridx; - } - rinfo = &iwm_rates[ridx]; - if (iwm_is_mimo_ht_plcp(rinfo->ht_plcp) || iwm_is_mimo_vht_plcp(rinfo->vht_plcp)) - rate_flags = IWM_RATE_MCS_ANT_AB_MSK; - else if (sc->sc_device_family == IWM_DEVICE_FAMILY_9000 && - (iwm_fw_valid_tx_ant(sc) & IWM_ANT_B)) - rate_flags = IWM_RATE_MCS_ANT_B_MSK; - else - rate_flags = IWM_RATE_MCS_ANT_A_MSK; - if (IWM_RIDX_IS_CCK(ridx)) - rate_flags |= IWM_RATE_MCS_CCK_MSK; - tx->rate_n_flags = htole32(rate_flags | rinfo->plcp); + XYLog("%s ridx=%d\n", __FUNCTION__, ridx); + + rate_flags = iwm_get_tx_ant(sc, ni, type, wh); + /* Set CCK flag as needed */ + if ((ridx >= IWL_FIRST_CCK_RATE) && (ridx <= IWL_LAST_CCK_RATE)) + rate_flags |= RATE_MCS_CCK_MSK; + tx->rate_n_flags = htole32(rate_flags | iwl_mvm_mac80211_idx_to_hwrate(ridx)); return rinfo; } @@ -2287,6 +2257,8 @@ iwm_auth(struct iwm_softc *sc) goto rm_binding; } + iwm_toggle_tx_ant(sc, &sc->sc_tx_ant); + if (ic->ic_opmode == IEEE80211_M_MONITOR) return 0; @@ -2515,7 +2487,6 @@ iwm_run(struct iwm_softc *sc) } ieee80211_amrr_node_init(&sc->sc_amrr, &in->in_amn); - ieee80211_ra_node_init(ic, &in->in_rn, &in->in_ni); if (ic->ic_opmode == IEEE80211_M_MONITOR) { iwm_led_blink_start(sc); @@ -2525,7 +2496,6 @@ iwm_run(struct iwm_softc *sc) /* Start at lowest available bit-rate, AMRR will raise. */ in->in_ni.ni_txrate = 0; in->in_ni.ni_txmcs = 0; -// iwm_setrates(in, 0); iwl_mvm_rs_rate_init(sc, ic->ic_bss, IEEE80211_IS_CHAN_2GHZ(ic->ic_bss->ni_chan) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ, @@ -2760,7 +2730,7 @@ iwm_calib_timeout(void *arg) */ if (ni->ni_txrate != old_txrate) { XYLog("iwm_calib_timeout in->ni_txrate=%d\n", in->in_ni.ni_txrate); - that->iwm_setrates(in, 1); + iwl_mvm_send_lq_cmd(sc, &sc->lq_sta.rs_drv.lq); } } @@ -2769,180 +2739,6 @@ iwm_calib_timeout(void *arg) timeout_add_msec(&sc->sc_calib_to, 500); } -void ItlIwm:: -iwm_setrates(struct iwm_node *in, int async) -{ - struct ieee80211_node *ni = &in->in_ni; - struct ieee80211com *ic = ni->ni_ic; - struct iwm_softc *sc = (struct iwm_softc *)IC2IFP(ic)->if_softc; - struct iwm_lq_cmd lqcmd; - struct ieee80211_rateset *rs = &ni->ni_rates; - const struct ieee80211_ra_rate *ra_rate = ieee80211_ra_get_rateset(&in->in_rn, ic, ni, ni->ni_txmcs); - int i, ridx, ridx_min, ridx_max, j, sgi_ok = 0, mimo, tab = 0, is_40mhz = 0, is_80mhz = 0, is_160mhz = 0, ldpc = 0; - struct iwm_host_cmd cmd = { - .id = IWM_LQ_CMD, - .len = { sizeof(lqcmd), }, - }; - - cmd.flags = async ? IWM_CMD_ASYNC : 0; - - memset(&lqcmd, 0, sizeof(lqcmd)); - lqcmd.sta_id = IWM_STATION_ID; - - if (ic->ic_flags & IEEE80211_F_USEPROT) - lqcmd.flags |= IWM_LQ_FLAG_USE_RTS_MSK; - - if (ni->ni_chw == IEEE80211_CHAN_WIDTH_80P80 || ni->ni_chw == IEEE80211_CHAN_WIDTH_160) { - is_160mhz = 1; - } else if (ni->ni_chw == IEEE80211_CHAN_WIDTH_80) { - is_80mhz = 1; - } else if (ni->ni_chw == IEEE80211_CHAN_WIDTH_40) { - is_40mhz = 1; - } - - sgi_ok = ra_rate->sgi; - - if (ni->ni_flags & IEEE80211_NODE_VHT) { - if ((ni->ni_vhtcaps & IEEE80211_VHTCAP_RXLDPC) && (ic->ic_vhtcaps & IEEE80211_VHTCAP_RXLDPC)) - ldpc = 1; - } else if (ni->ni_flags & IEEE80211_NODE_HT) { - if ((ni->ni_htcaps & IEEE80211_HTCAP_LDPC) && (ic->ic_htcaps & IEEE80211_HTCAP_LDPC)) - ldpc = 1; - } - - /* - * Fill the LQ rate selection table with legacy and/or HT rates - * in descending order, i.e. with the node's current TX rate first. - * In cases where throughput of an HT rate corresponds to a legacy - * rate it makes no sense to add both. We rely on the fact that - * iwm_rates is laid out such that equivalent HT/legacy rates share - * the same IWM_RATE_*_INDEX value. Also, rates not applicable to - * legacy/HT are assumed to be marked with an 'invalid' PLCP value. - */ - j = 0; - ridx_min = iwm_rval2ridx(ieee80211_min_basic_rate(ic)); - mimo = ra_rate->nss > 1; - ridx_max = (mimo ? IWM_RIDX_MAX : ((ni->ni_flags & IEEE80211_NODE_VHT) ? IWM_LAST_VHT_SISO_RATE : IWM_LAST_HT_SISO_RATE)); - for (ridx = ridx_max; ridx >= ridx_min; ridx--) { - uint8_t plcp = iwm_rates[ridx].plcp; - uint8_t ht_plcp = iwm_rates[ridx].ht_plcp; - uint8_t vht_plcp = iwm_rates[ridx].vht_plcp; - - if (j >= nitems(lqcmd.rs_table)) - break; - tab = 0; - if (ni->ni_flags & IEEE80211_NODE_VHT) { - if (vht_plcp == IWM_RATE_VHT_SISO_MCS_INV_PLCP || vht_plcp == IWM_RATE_VHT_MIMO2_MCS_INV_PLCP) - continue; - if ((mimo && !iwm_is_mimo_vht_plcp(vht_plcp)) || - (!mimo && iwm_is_mimo_vht_plcp(vht_plcp))) - continue; - for (i = ni->ni_txmcs; i >= 0; i--) { - if ((in->in_rn.valid_rates & (1 << i)) == 0) - continue; - if (ridx == (mimo ? iwm_vht_mimo_mcs2ridx[i] : iwm_vht_siso_mcs2ridx[i])) { - tab = vht_plcp; - tab |= IWM_RATE_MCS_VHT_MSK; - if (is_40mhz) - tab |= IWM_RATE_MCS_CHAN_WIDTH_40; - if (is_80mhz) - tab |= IWM_RATE_MCS_CHAN_WIDTH_80; - if (is_160mhz) - tab |= IWM_RATE_MCS_CHAN_WIDTH_160; - if (sgi_ok) - tab |= IWM_RATE_MCS_SGI_MSK; - if (ldpc) - tab |= IWM_RATE_MCS_LDPC_MSK; - break; - } - } - } else if (ni->ni_flags & IEEE80211_NODE_HT) { - if (ht_plcp == IWM_RATE_HT_SISO_MCS_INV_PLCP) - continue; - /* Do not mix SISO and MIMO HT rates. */ - if ((mimo && !iwm_is_mimo_ht_plcp(ht_plcp)) || - (!mimo && iwm_is_mimo_ht_plcp(ht_plcp))) - continue; - for (i = ni->ni_txmcs; i >= 0; i--) { - if (isclr(ni->ni_rxmcs, i)) - continue; - if (ridx == iwm_mcs2ridx[i]) { - tab = ht_plcp; - tab |= IWM_RATE_MCS_HT_MSK; - if (sgi_ok) - tab |= IWM_RATE_MCS_SGI_MSK; - /* TODO: If we enable 40mhz Tx rate in 2.4ghz band, the data will all sent fail */ - if (is_40mhz && IEEE80211_IS_CHAN_5GHZ(ni->ni_chan)) - tab |= IWM_RATE_MCS_CHAN_WIDTH_40; - if (ldpc) - tab |= IWM_RATE_MCS_LDPC_MSK; - break; - } - } - } else if (plcp != IWM_RATE_INVM_PLCP) { - for (i = ni->ni_txmcs; i >= 0; i--) { - if (iwm_rates[ridx].rate == (rs->rs_rates[i] & - IEEE80211_RATE_VAL)) { - tab = plcp; - break; - } - } - } - - if (tab == 0) - continue; - - if (ni->ni_flags & IEEE80211_NODE_VHT) { - if (iwm_is_mimo_vht_plcp(vht_plcp)) - tab |= IWM_RATE_MCS_ANT_AB_MSK; - else if (sc->sc_device_family == IWM_DEVICE_FAMILY_9000 && - (iwm_fw_valid_tx_ant(sc) & IWM_ANT_B)) - tab |= IWM_RATE_MCS_ANT_B_MSK; - else - tab |= IWM_RATE_MCS_ANT_A_MSK; - } else if (iwm_is_mimo_ht_plcp(ht_plcp)) - tab |= IWM_RATE_MCS_ANT_AB_MSK; - else if (sc->sc_device_family == IWM_DEVICE_FAMILY_9000 && - (iwm_fw_valid_tx_ant(sc) & IWM_ANT_B)) - tab |= IWM_RATE_MCS_ANT_B_MSK; - else - tab |= IWM_RATE_MCS_ANT_A_MSK; - - if (IWM_RIDX_IS_CCK(ridx)) - tab |= IWM_RATE_MCS_CCK_MSK; - lqcmd.rs_table[j++] = htole32(tab); - } - - lqcmd.mimo_delim = (mimo ? j : 0); - - /* Fill the rest with the lowest possible rate */ - while (j < nitems(lqcmd.rs_table)) { - tab = iwm_rates[ridx_min].plcp; - if (IWM_RIDX_IS_CCK(ridx_min)) - tab |= IWM_RATE_MCS_CCK_MSK; - if (sc->sc_device_family == IWM_DEVICE_FAMILY_9000 && - (iwm_fw_valid_tx_ant(sc) & IWM_ANT_B)) - tab |= IWM_RATE_MCS_ANT_B_MSK; - else - tab |= IWM_RATE_MCS_ANT_A_MSK; - lqcmd.rs_table[j++] = htole32(tab); - } - - if (sc->sc_device_family == IWM_DEVICE_FAMILY_9000 && - (iwm_fw_valid_tx_ant(sc) & IWM_ANT_B)) - lqcmd.single_stream_ant_msk = IWM_ANT_B; - else - lqcmd.single_stream_ant_msk = IWM_ANT_A; - lqcmd.dual_stream_ant_msk = IWM_ANT_AB; - - lqcmd.agg_time_limit = htole16(iwm_coex_agg_time_limit(sc, ni)); - lqcmd.agg_disable_start_th = 3; - lqcmd.agg_frame_cnt_limit = 0x3f; - - cmd.data[0] = &lqcmd; - iwm_send_cmd(sc, &cmd); -} - /* Allow multicast from our BSSID. */ int ItlIwm:: iwm_allow_mcast(struct iwm_softc *sc) @@ -3133,18 +2929,6 @@ int ItlIwm::iwm_media_change(struct _ifnet *ifp) if (err != ENETRESET) return err; - if (ic->ic_fixed_mcs != -1) - sc->sc_fixed_ridx = iwm_mcs2ridx[ic->ic_fixed_mcs]; - else if (ic->ic_fixed_rate != -1) { - rate = ic->ic_sup_rates[ic->ic_curmode]. - rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL; - /* Map 802.11 rate to HW rate index. */ - for (ridx = 0; ridx <= IWM_RIDX_MAX; ridx++) - if (iwm_rates[ridx].rate == rate) - break; - sc->sc_fixed_ridx = ridx; - } - if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING)) { iwm_stop(ifp); @@ -5171,12 +4955,9 @@ iwm_chan_ctxt_task(void *arg) splx(s); return; } - - if (in->in_rn.bw != in->in_ni.ni_chw) { - ieee80211_ra_node_init(ic, &in->in_rn, &in->in_ni); - ieee80211_ra_choose(&in->in_rn, ic, &in->in_ni); - } - that->iwm_setrates((struct iwm_node *)ic->ic_bss, 0); + + rs_drv_rate_update(sc, &in->in_ni, IEEE80211_IS_CHAN_2GHZ(in->in_ni.ni_chan) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ, true); + iwl_mvm_send_lq_cmd(sc, &sc->lq_sta.rs_drv.lq); // refcnt_rele_wake(&sc->task_refs); splx(s); diff --git a/itlwm/hal_iwm/rs.cpp b/itlwm/hal_iwm/rs.cpp index 37cf83921..c28029571 100644 --- a/itlwm/hal_iwm/rs.cpp +++ b/itlwm/hal_iwm/rs.cpp @@ -61,7 +61,7 @@ static const u8 ant_toggle_lookup[] = { * maps to IWL_RATE_INVALID * */ -static const struct iwl_rs_rate_info iwl_rates[IWL_RATE_COUNT] = { +struct iwl_rs_rate_info iwl_rates[IWL_RATE_COUNT] = { IWL_DECLARE_RATE_INFO(1, INV, INV, 2), /* 1mbps */ IWL_DECLARE_RATE_INFO(2, INV, 1, 5), /* 2mbps */ IWL_DECLARE_RATE_INFO(5, INV, 2, 11), /*5.5mbps */ diff --git a/itlwm/hal_iwm/rs.h b/itlwm/hal_iwm/rs.h index ebf3027e1..66c945b99 100644 --- a/itlwm/hal_iwm/rs.h +++ b/itlwm/hal_iwm/rs.h @@ -921,9 +921,6 @@ enum { /* Link Quality definitions */ -/* # entries in rate scale table to support Tx retries */ -#define LQ_MAX_RETRY_NUM 16 - /* Link quality command flags bit fields */ /* Bit 0: (0) Don't use RTS (1) Use RTS */ @@ -1001,6 +998,8 @@ struct iwl_rs_rate_info { u8 next_rs; /* next rate used in rs algo */ }; +extern struct iwl_rs_rate_info iwl_rates[IWL_RATE_COUNT]; + #define IWL_RATE_60M_PLCP 3 enum { diff --git a/itlwm/hal_iwm/scan.cpp b/itlwm/hal_iwm/scan.cpp index 7342aaff0..78e85ddf2 100644 --- a/itlwm/hal_iwm/scan.cpp +++ b/itlwm/hal_iwm/scan.cpp @@ -120,6 +120,7 @@ */ #include "ItlIwm.hpp" +#include "rs.h" uint16_t ItlIwm:: iwm_scan_rx_chain(struct iwm_softc *sc) @@ -152,10 +153,10 @@ iwm_scan_rate_n_flags(struct iwm_softc *sc, int flags, int no_cck) tx_ant = (1 << sc->sc_scan_last_antenna) << IWM_RATE_MCS_ANT_POS; if ((flags & IEEE80211_CHAN_2GHZ) && !no_cck) - return htole32(IWM_RATE_1M_PLCP | IWM_RATE_MCS_CCK_MSK | + return htole32(IWL_RATE_1M_PLCP | RATE_MCS_CCK_MSK | tx_ant); else - return htole32(IWM_RATE_6M_PLCP | tx_ant); + return htole32(IWL_RATE_6M_PLCP | tx_ant); } uint8_t ItlIwm:: @@ -763,28 +764,13 @@ iwm_ridx2rate(struct ieee80211_rateset *rs, int ridx) for (i = 0; i < rs->rs_nrates; i++) { rval = (rs->rs_rates[i] & IEEE80211_RATE_VAL); - if (rval == iwm_rates[ridx].rate) + if (rval == ieee80211_std_rateset_11g.rs_rates[ridx]) return rs->rs_rates[i]; } return 0; } -int ItlIwm:: -iwm_rval2ridx(int rval) -{ - int ridx; - - for (ridx = 0; ridx < nitems(iwm_rates); ridx++) { - if (iwm_rates[ridx].plcp == IWM_RATE_INVM_PLCP) - continue; - if (rval == iwm_rates[ridx].rate) - break; - } - - return ridx; -} - void ItlIwm:: iwm_ack_rates(struct iwm_softc *sc, struct iwm_node *in, int *cck_rates, int *ofdm_rates) @@ -799,7 +785,7 @@ iwm_ack_rates(struct iwm_softc *sc, struct iwm_node *in, int *cck_rates, if (ni->ni_chan == IEEE80211_CHAN_ANYC || IEEE80211_IS_CHAN_2GHZ(ni->ni_chan)) { - for (i = IWM_FIRST_CCK_RATE; i < IWM_FIRST_OFDM_RATE; i++) { + for (i = IWL_FIRST_CCK_RATE; i < IWL_FIRST_OFDM_RATE; i++) { if ((iwm_ridx2rate(rs, i) & IEEE80211_RATE_BASIC) == 0) continue; cck |= (1 << i); @@ -807,10 +793,10 @@ iwm_ack_rates(struct iwm_softc *sc, struct iwm_node *in, int *cck_rates, lowest_present_cck = i; } } - for (i = IWM_FIRST_OFDM_RATE; i <= IWM_LAST_NON_HT_RATE; i++) { + for (i = IWL_FIRST_OFDM_RATE; i <= IWL_LAST_NON_HT_RATE; i++) { if ((iwm_ridx2rate(rs, i) & IEEE80211_RATE_BASIC) == 0) continue; - ofdm |= (1 << (i - IWM_FIRST_OFDM_RATE)); + ofdm |= (1 << (i - IWL_FIRST_OFDM_RATE)); if (lowest_present_ofdm == -1 || lowest_present_ofdm > i) lowest_present_ofdm = i; } @@ -838,12 +824,12 @@ iwm_ack_rates(struct iwm_softc *sc, struct iwm_node *in, int *cck_rates, * lower than all of the basic rates to these bitmaps. */ - if (IWM_RATE_24M_INDEX < lowest_present_ofdm) - ofdm |= IWM_RATE_BIT_MSK(24) >> IWM_FIRST_OFDM_RATE; - if (IWM_RATE_12M_INDEX < lowest_present_ofdm) - ofdm |= IWM_RATE_BIT_MSK(12) >> IWM_FIRST_OFDM_RATE; + if (IWL_RATE_24M_INDEX < lowest_present_ofdm) + ofdm |= IWL_RATE_BIT_MSK(24) >> IWL_FIRST_OFDM_RATE; + if (IWL_RATE_12M_INDEX < lowest_present_ofdm) + ofdm |= IWL_RATE_BIT_MSK(12) >> IWL_FIRST_OFDM_RATE; /* 6M already there or needed so always add */ - ofdm |= IWM_RATE_BIT_MSK(6) >> IWM_FIRST_OFDM_RATE; + ofdm |= IWL_RATE_BIT_MSK(6) >> IWL_FIRST_OFDM_RATE; /* * CCK is a bit more complex with DSSS vs. HR/DSSS vs. ERP. @@ -858,14 +844,14 @@ iwm_ack_rates(struct iwm_softc *sc, struct iwm_node *in, int *cck_rates, * As a consequence, it's not as complicated as it sounds, just add * any lower rates to the ACK rate bitmap. */ - if (IWM_RATE_11M_INDEX < lowest_present_cck) - cck |= IWM_RATE_BIT_MSK(11) >> IWM_FIRST_CCK_RATE; - if (IWM_RATE_5M_INDEX < lowest_present_cck) - cck |= IWM_RATE_BIT_MSK(5) >> IWM_FIRST_CCK_RATE; - if (IWM_RATE_2M_INDEX < lowest_present_cck) - cck |= IWM_RATE_BIT_MSK(2) >> IWM_FIRST_CCK_RATE; + if (IWL_RATE_11M_INDEX < lowest_present_cck) + cck |= IWL_RATE_BIT_MSK(11) >> IWL_FIRST_CCK_RATE; + if (IWL_RATE_5M_INDEX < lowest_present_cck) + cck |= IWL_RATE_BIT_MSK(5) >> IWL_FIRST_CCK_RATE; + if (IWL_RATE_2M_INDEX < lowest_present_cck) + cck |= IWL_RATE_BIT_MSK(2) >> IWL_FIRST_CCK_RATE; /* 1M already there or needed so always add */ - cck |= IWM_RATE_BIT_MSK(1) >> IWM_FIRST_CCK_RATE; + cck |= IWL_RATE_BIT_MSK(1) >> IWL_FIRST_CCK_RATE; *cck_rates = cck; *ofdm_rates = ofdm; From 0f790dba6ae2c108c9d5e72c46cb2cef6547b2c9 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Tue, 29 Mar 2022 18:31:49 +0800 Subject: [PATCH 006/114] Adapt PLCP index. --- itlwm/hal_iwm/ItlIwm.hpp | 2 +- itlwm/hal_iwm/mac80211.cpp | 43 +++++++++++++++++++++++++++++--------- itlwm/hal_iwm/rs.h | 25 ++++++++++++++++++++++ 3 files changed, 59 insertions(+), 11 deletions(-) diff --git a/itlwm/hal_iwm/ItlIwm.hpp b/itlwm/hal_iwm/ItlIwm.hpp index d6576d44b..082a6d883 100644 --- a/itlwm/hal_iwm/ItlIwm.hpp +++ b/itlwm/hal_iwm/ItlIwm.hpp @@ -290,7 +290,7 @@ class ItlIwm : public ItlHalService, ItlDriverInfo, ItlDriverController { void iwm_cmd_done(struct iwm_softc *, int, int, int); void iwm_update_sched(struct iwm_softc *, int, int, uint8_t, uint16_t); void iwm_reset_sched(struct iwm_softc *, int, int, uint8_t); - const struct iwm_rate *iwm_tx_fill_cmd(struct iwm_softc *, struct iwm_node *, + const struct iwl_rs_rate_info *iwm_tx_fill_cmd(struct iwm_softc *, struct iwm_node *, struct ieee80211_frame *, struct iwm_tx_cmd *); void iwm_txd_done(struct iwm_softc *, struct iwm_tx_data *); void iwm_ampdu_txq_advance(struct iwm_softc *, struct iwm_tx_ring *, int); diff --git a/itlwm/hal_iwm/mac80211.cpp b/itlwm/hal_iwm/mac80211.cpp index 965a62c2e..e1360f13e 100644 --- a/itlwm/hal_iwm/mac80211.cpp +++ b/itlwm/hal_iwm/mac80211.cpp @@ -1544,13 +1544,12 @@ iwm_rx_bmiss(struct iwm_softc *sc, struct iwm_rx_packet *pkt, * unfilled for data frames (firmware takes care of that). * Return the selected TX rate. */ -const struct iwm_rate * ItlIwm:: +const struct iwl_rs_rate_info *ItlIwm:: iwm_tx_fill_cmd(struct iwm_softc *sc, struct iwm_node *in, struct ieee80211_frame *wh, struct iwm_tx_cmd *tx) { struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_node *ni = &in->in_ni; - const struct iwm_rate *rinfo = NULL; int type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; int subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; int ridx, rate_flags; @@ -1578,25 +1577,33 @@ iwm_tx_fill_cmd(struct iwm_softc *sc, struct iwm_node *in, * for data packets, rate info comes from the table inside the fw. This * table is controlled by LINK_QUALITY commands */ - if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && type == IEEE80211_FC0_TYPE_DATA) { + if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && + type == IEEE80211_FC0_TYPE_DATA) { tx->initial_rate_index = 0; tx->tx_flags |= cpu_to_le32(IWM_TX_CMD_FLG_STA_RATE); - return rinfo; - } else if (type == IEEE80211_FC0_TYPE_CTL && subtype == IEEE80211_FC0_SUBTYPE_BAR) + return &iwl_rates[ridx]; + } else if (type == IEEE80211_FC0_TYPE_CTL && + subtype == IEEE80211_FC0_SUBTYPE_BAR) tx->tx_flags |= htole32(IWM_TX_CMD_FLG_ACK | IWM_TX_CMD_FLG_BAR); - if (ic->ic_fixed_mcs != -1) + if (ic->ic_fixed_mcs != -1 || + ic->ic_fixed_rate != -1) ridx = sc->sc_fixed_ridx; - - XYLog("%s ridx=%d\n", __FUNCTION__, ridx); + else { + if (ni->ni_flags & IEEE80211_NODE_VHT) + ridx = iwm_vht_mcs2ridx[ni->ni_txmcs]; + else if (ni->ni_flags & IEEE80211_NODE_HT) + ridx = iwm_ht_mcs2ridx[ni->ni_txmcs % 8]; + } rate_flags = iwm_get_tx_ant(sc, ni, type, wh); + XYLog("%s ridx=%d ant=%d\n", __FUNCTION__, ridx, (rate_flags >> RATE_MCS_ANT_POS)); /* Set CCK flag as needed */ if ((ridx >= IWL_FIRST_CCK_RATE) && (ridx <= IWL_LAST_CCK_RATE)) rate_flags |= RATE_MCS_CCK_MSK; tx->rate_n_flags = htole32(rate_flags | iwl_mvm_mac80211_idx_to_hwrate(ridx)); - return rinfo; + return &iwl_rates[ridx]; } #define TB0_SIZE 20 @@ -1612,7 +1619,7 @@ iwm_tx(struct iwm_softc *sc, mbuf_t m, struct ieee80211_node *ni, int ac) struct iwm_tx_cmd *tx; struct ieee80211_frame *wh; struct ieee80211_key *k = NULL; - const struct iwm_rate *rinfo; + const struct iwl_rs_rate_info *rinfo; uint8_t *ivp; uint32_t flags; u_int hdrlen; @@ -2922,6 +2929,7 @@ int ItlIwm::iwm_media_change(struct _ifnet *ifp) XYLog("%s\n", __FUNCTION__); struct iwm_softc *sc = (struct iwm_softc*)ifp->if_softc; struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211_node *ni = ic->ic_bss; uint8_t rate, ridx; int err; @@ -2929,6 +2937,21 @@ int ItlIwm::iwm_media_change(struct _ifnet *ifp) if (err != ENETRESET) return err; + if (ic->ic_fixed_mcs != -1) { + if (ni->ni_flags & IEEE80211_NODE_VHT) + sc->sc_fixed_ridx = iwm_vht_mcs2ridx[ic->ic_fixed_mcs]; + else if (ni->ni_flags & IEEE80211_NODE_HT) + sc->sc_fixed_ridx = iwm_ht_mcs2ridx[ic->ic_fixed_mcs % 8]; + } else if (ic->ic_fixed_rate != -1) { + rate = ic->ic_sup_rates[ic->ic_curmode]. + rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL; + /* Map 802.11 rate to HW rate index. */ + for (ridx = 0; ridx <= ieee80211_std_rateset_11g.rs_nrates; ridx++) + if (ieee80211_std_rateset_11g.rs_rates[ridx] == rate) + break; + sc->sc_fixed_ridx = ridx; + } + if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING)) { iwm_stop(ifp); diff --git a/itlwm/hal_iwm/rs.h b/itlwm/hal_iwm/rs.h index 66c945b99..914f628e1 100644 --- a/itlwm/hal_iwm/rs.h +++ b/itlwm/hal_iwm/rs.h @@ -1387,6 +1387,31 @@ static const u8 fw_rate_idx_to_plcp[IWL_RATE_COUNT] = { #undef IWL_DECLARE_RATE_INFO +/* Convert an MCS index into an iwm_rates[] index. */ +const int iwm_ht_mcs2ridx[] = { + IWL_RATE_MCS_0_INDEX, + IWL_RATE_MCS_1_INDEX, + IWL_RATE_MCS_2_INDEX, + IWL_RATE_MCS_3_INDEX, + IWL_RATE_MCS_4_INDEX, + IWL_RATE_MCS_5_INDEX, + IWL_RATE_MCS_6_INDEX, + IWL_RATE_MCS_7_INDEX, +}; + +const int iwm_vht_mcs2ridx[] = { + IWL_RATE_MCS_0_INDEX, + IWL_RATE_MCS_1_INDEX, + IWL_RATE_MCS_2_INDEX, + IWL_RATE_MCS_3_INDEX, + IWL_RATE_MCS_4_INDEX, + IWL_RATE_MCS_5_INDEX, + IWL_RATE_MCS_6_INDEX, + IWL_RATE_MCS_7_INDEX, + IWL_RATE_MCS_8_INDEX, + IWL_RATE_MCS_9_INDEX, +}; + static inline int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags, enum nl80211_band band) { From 568ba48bb9b8dce2ceb284d9f8d076645e5c05a3 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Wed, 30 Mar 2022 00:26:50 +0800 Subject: [PATCH 007/114] add ride limitation. --- itlwm/hal_iwm/mac80211.cpp | 6 ++++-- itlwm/hal_iwm/rs.h | 36 ++++++++++++++++++------------------ 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/itlwm/hal_iwm/mac80211.cpp b/itlwm/hal_iwm/mac80211.cpp index e1360f13e..51ec37c49 100644 --- a/itlwm/hal_iwm/mac80211.cpp +++ b/itlwm/hal_iwm/mac80211.cpp @@ -1552,7 +1552,7 @@ iwm_tx_fill_cmd(struct iwm_softc *sc, struct iwm_node *in, struct ieee80211_node *ni = &in->in_ni; int type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; int subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; - int ridx, rate_flags; + int ridx = -1, rate_flags; int min_ridx = (IEEE80211_IS_CHAN_5GHZ(ni->ni_chan)) ? IWL_FIRST_OFDM_RATE : IWL_FIRST_CCK_RATE; int i; @@ -1565,7 +1565,6 @@ iwm_tx_fill_cmd(struct iwm_softc *sc, struct iwm_node *in, } } - ridx = min_ridx; tx->rts_retry_limit = IWM_RTS_DFAULT_RETRY_LIMIT; if (type == IEEE80211_FC0_TYPE_CTL && subtype == IEEE80211_FC0_SUBTYPE_BAR) @@ -1596,6 +1595,9 @@ iwm_tx_fill_cmd(struct iwm_softc *sc, struct iwm_node *in, ridx = iwm_ht_mcs2ridx[ni->ni_txmcs % 8]; } + if (ridx == -1 || ridx >= IWL_RATE_COUNT_LEGACY) + ridx = min_ridx; + rate_flags = iwm_get_tx_ant(sc, ni, type, wh); XYLog("%s ridx=%d ant=%d\n", __FUNCTION__, ridx, (rate_flags >> RATE_MCS_ANT_POS)); /* Set CCK flag as needed */ diff --git a/itlwm/hal_iwm/rs.h b/itlwm/hal_iwm/rs.h index 914f628e1..0c5743ddd 100644 --- a/itlwm/hal_iwm/rs.h +++ b/itlwm/hal_iwm/rs.h @@ -1389,27 +1389,27 @@ static const u8 fw_rate_idx_to_plcp[IWL_RATE_COUNT] = { /* Convert an MCS index into an iwm_rates[] index. */ const int iwm_ht_mcs2ridx[] = { - IWL_RATE_MCS_0_INDEX, - IWL_RATE_MCS_1_INDEX, - IWL_RATE_MCS_2_INDEX, - IWL_RATE_MCS_3_INDEX, - IWL_RATE_MCS_4_INDEX, - IWL_RATE_MCS_5_INDEX, - IWL_RATE_MCS_6_INDEX, - IWL_RATE_MCS_7_INDEX, + IWL_RATE_6M_INDEX, + IWL_RATE_12M_INDEX, + IWL_RATE_18M_INDEX, + IWL_RATE_24M_INDEX, + IWL_RATE_36M_INDEX, + IWL_RATE_48M_INDEX, + IWL_RATE_54M_INDEX, + IWL_RATE_54M_INDEX, }; const int iwm_vht_mcs2ridx[] = { - IWL_RATE_MCS_0_INDEX, - IWL_RATE_MCS_1_INDEX, - IWL_RATE_MCS_2_INDEX, - IWL_RATE_MCS_3_INDEX, - IWL_RATE_MCS_4_INDEX, - IWL_RATE_MCS_5_INDEX, - IWL_RATE_MCS_6_INDEX, - IWL_RATE_MCS_7_INDEX, - IWL_RATE_MCS_8_INDEX, - IWL_RATE_MCS_9_INDEX, + IWL_RATE_6M_INDEX, + IWL_RATE_12M_INDEX, + IWL_RATE_18M_INDEX, + IWL_RATE_24M_INDEX, + IWL_RATE_36M_INDEX, + IWL_RATE_48M_INDEX, + IWL_RATE_54M_INDEX, + IWL_RATE_54M_INDEX, + IWL_RATE_54M_INDEX, + IWL_RATE_54M_INDEX, }; static inline int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags, From 2270b236fdf65c88632ef9a149310e4c767f8c4a Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Thu, 31 Mar 2022 19:41:32 +0800 Subject: [PATCH 008/114] collapse --- itlwm/hal_iwm/mac80211.cpp | 8 ++-- itlwm/hal_iwm/rs.cpp | 82 +++++++++++++++++++------------------- itlwm/hal_iwm/rs.h | 13 +----- 3 files changed, 47 insertions(+), 56 deletions(-) diff --git a/itlwm/hal_iwm/mac80211.cpp b/itlwm/hal_iwm/mac80211.cpp index 51ec37c49..70818d8bf 100644 --- a/itlwm/hal_iwm/mac80211.cpp +++ b/itlwm/hal_iwm/mac80211.cpp @@ -1590,9 +1590,9 @@ iwm_tx_fill_cmd(struct iwm_softc *sc, struct iwm_node *in, ridx = sc->sc_fixed_ridx; else { if (ni->ni_flags & IEEE80211_NODE_VHT) - ridx = iwm_vht_mcs2ridx[ni->ni_txmcs]; + ridx = iwm_mcs2ridx[ni->ni_txmcs]; else if (ni->ni_flags & IEEE80211_NODE_HT) - ridx = iwm_ht_mcs2ridx[ni->ni_txmcs % 8]; + ridx = iwm_mcs2ridx[ni->ni_txmcs % 8]; } if (ridx == -1 || ridx >= IWL_RATE_COUNT_LEGACY) @@ -2941,9 +2941,9 @@ int ItlIwm::iwm_media_change(struct _ifnet *ifp) if (ic->ic_fixed_mcs != -1) { if (ni->ni_flags & IEEE80211_NODE_VHT) - sc->sc_fixed_ridx = iwm_vht_mcs2ridx[ic->ic_fixed_mcs]; + sc->sc_fixed_ridx = iwm_mcs2ridx[ic->ic_fixed_mcs]; else if (ni->ni_flags & IEEE80211_NODE_HT) - sc->sc_fixed_ridx = iwm_ht_mcs2ridx[ic->ic_fixed_mcs % 8]; + sc->sc_fixed_ridx = iwm_mcs2ridx[ic->ic_fixed_mcs % 8]; } else if (ic->ic_fixed_rate != -1) { rate = ic->ic_sup_rates[ic->ic_curmode]. rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL; diff --git a/itlwm/hal_iwm/rs.cpp b/itlwm/hal_iwm/rs.cpp index c28029571..dcdb373f5 100644 --- a/itlwm/hal_iwm/rs.cpp +++ b/itlwm/hal_iwm/rs.cpp @@ -1486,42 +1486,43 @@ static void rs_set_amsdu_len(struct iwm_softc *sc, struct ieee80211_node *ni, struct iwl_scale_tbl_info *tbl, enum rs_action scale_action) { -// struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); -// int i; -// -// sta->max_amsdu_len = rs_fw_get_max_amsdu_len(sta); -// -// /* -// * In case TLC offload is not active amsdu_enabled is either 0xFFFF -// * or 0, since there is no per-TID alg. -// */ -// if ((!is_vht(&tbl->rate) && !is_ht(&tbl->rate)) || -// tbl->rate.index < IWL_RATE_MCS_5_INDEX || -// scale_action == RS_ACTION_DOWNSCALE) -// mvmsta->amsdu_enabled = 0; -// else -// mvmsta->amsdu_enabled = 0xFFFF; -// -// if (mvmsta->vif->bss_conf.he_support && -// !iwlwifi_mod_params.disable_11ax) -// mvmsta->max_amsdu_len = sta->max_amsdu_len; -// else -// mvmsta->max_amsdu_len = min_t(int, sta->max_amsdu_len, 8500); -// -// sta->max_rc_amsdu_len = mvmsta->max_amsdu_len; -// -// for (i = 0; i < IWL_MAX_TID_COUNT; i++) { -// if (mvmsta->amsdu_enabled) -// sta->max_tid_amsdu_len[i] = -// iwl_mvm_max_amsdu_size(mvm, sta, i); -// else -// /* -// * Not so elegant, but this will effectively -// * prevent AMSDU on this TID -// */ -// sta->max_tid_amsdu_len[i] = 1; -// } - // TODO: IMP +#if 0 + struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); + int i; + + sta->max_amsdu_len = rs_fw_get_max_amsdu_len(sta); + + /* + * In case TLC offload is not active amsdu_enabled is either 0xFFFF + * or 0, since there is no per-TID alg. + */ + if ((!is_vht(&tbl->rate) && !is_ht(&tbl->rate)) || + tbl->rate.index < IWL_RATE_MCS_5_INDEX || + scale_action == RS_ACTION_DOWNSCALE) + mvmsta->amsdu_enabled = 0; + else + mvmsta->amsdu_enabled = 0xFFFF; + + if (mvmsta->vif->bss_conf.he_support && + !iwlwifi_mod_params.disable_11ax) + mvmsta->max_amsdu_len = sta->max_amsdu_len; + else + mvmsta->max_amsdu_len = min_t(int, sta->max_amsdu_len, 8500); + + sta->max_rc_amsdu_len = mvmsta->max_amsdu_len; + + for (i = 0; i < IWL_MAX_TID_COUNT; i++) { + if (mvmsta->amsdu_enabled) + sta->max_tid_amsdu_len[i] = + iwl_mvm_max_amsdu_size(mvm, sta, i); + else + /* + * Not so elegant, but this will effectively + * prevent AMSDU on this TID + */ + sta->max_tid_amsdu_len[i] = 1; + } +#endif } /** @@ -2102,8 +2103,7 @@ static void rs_rate_scale_perform(struct iwm_softc *mvm, rate = &tbl->rate; if (prev_agg != lq_sta->is_agg) { - IWL_DEBUG_RATE(mvm, - "Aggregation changed: prev %d current %d. Update expected TPT table\n", + XYLog("Aggregation changed: prev %d current %d. Update expected TPT table\n", prev_agg, lq_sta->is_agg); rs_set_expected_tpt_table(lq_sta, tbl); rs_rate_scale_clear_tbl_windows(mvm, tbl); @@ -2806,7 +2806,8 @@ static void rs_ht_init(struct iwm_softc *mvm, lq_sta->active_mimo2_rate &= ~((u16)0x2); lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE; - if ((sta->ni_htcaps & IEEE80211_HTCAP_LDPC)) + if ((sta->ni_htcaps & IEEE80211_HTCAP_LDPC) && + mvm->support_ldpc) lq_sta->ldpc = true; if ((that->iwm_num_of_ant(that->iwm_fw_valid_tx_ant(mvm)) > 1) && @@ -2823,7 +2824,8 @@ static void rs_vht_init(struct iwm_softc *mvm, ItlIwm *that = container_of(mvm, ItlIwm, com); rs_vht_set_enabled_rates(sta, lq_sta); - if ((sta->ni_vhtcaps & IEEE80211_VHTCAP_RXLDPC)) + if ((sta->ni_vhtcaps & IEEE80211_VHTCAP_RXLDPC) && + mvm->support_ldpc) lq_sta->ldpc = true; if ((that->iwm_num_of_ant(that->iwm_fw_valid_tx_ant(mvm)) > 1) && diff --git a/itlwm/hal_iwm/rs.h b/itlwm/hal_iwm/rs.h index 0c5743ddd..19e032a9a 100644 --- a/itlwm/hal_iwm/rs.h +++ b/itlwm/hal_iwm/rs.h @@ -1388,19 +1388,9 @@ static const u8 fw_rate_idx_to_plcp[IWL_RATE_COUNT] = { #undef IWL_DECLARE_RATE_INFO /* Convert an MCS index into an iwm_rates[] index. */ -const int iwm_ht_mcs2ridx[] = { +const int iwm_mcs2ridx[] = { IWL_RATE_6M_INDEX, IWL_RATE_12M_INDEX, - IWL_RATE_18M_INDEX, - IWL_RATE_24M_INDEX, - IWL_RATE_36M_INDEX, - IWL_RATE_48M_INDEX, - IWL_RATE_54M_INDEX, - IWL_RATE_54M_INDEX, -}; - -const int iwm_vht_mcs2ridx[] = { - IWL_RATE_6M_INDEX, IWL_RATE_12M_INDEX, IWL_RATE_18M_INDEX, IWL_RATE_24M_INDEX, @@ -1409,7 +1399,6 @@ const int iwm_vht_mcs2ridx[] = { IWL_RATE_54M_INDEX, IWL_RATE_54M_INDEX, IWL_RATE_54M_INDEX, - IWL_RATE_54M_INDEX, }; static inline int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags, From 1c9a7eb2466d3a0b8fa7f338e416b798edf7d1a0 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Fri, 1 Apr 2022 01:05:06 +0800 Subject: [PATCH 009/114] Fix agg condition --- itlwm/hal_iwm/rs.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/itlwm/hal_iwm/rs.cpp b/itlwm/hal_iwm/rs.cpp index dcdb373f5..bff2713e3 100644 --- a/itlwm/hal_iwm/rs.cpp +++ b/itlwm/hal_iwm/rs.cpp @@ -2083,11 +2083,15 @@ static void rs_rate_scale_perform(struct iwm_softc *mvm, s32 sr; u8 prev_agg = lq_sta->is_agg; struct rs_rate *rate; - - lq_sta->is_agg = (mvm->sc_tx_ba[EDCA_AC_BE].wn != NULL || - mvm->sc_tx_ba[EDCA_AC_BK].wn != NULL || - mvm->sc_tx_ba[EDCA_AC_VI].wn != NULL || - mvm->sc_tx_ba[EDCA_AC_VO].wn != NULL); + int i; + + lq_sta->is_agg = false; + for (i = 0; i <= IWM_MAX_TID_COUNT; i++) { + if (mvm->sc_tx_ba[i].wn != NULL) { + lq_sta->is_agg = true; + break; + } + } /* * Select rate-scale / modulation-mode table to work with in From 9e023a0f9de30ce28d70c543dfbb74a36179132b Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Fri, 1 Apr 2022 01:05:30 +0800 Subject: [PATCH 010/114] Enable Tx agg for RS. --- itlwm/hal_iwm/mac80211.cpp | 2 +- itlwm/hal_iwm/rs.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/itlwm/hal_iwm/mac80211.cpp b/itlwm/hal_iwm/mac80211.cpp index 70818d8bf..2f0bc4fca 100644 --- a/itlwm/hal_iwm/mac80211.cpp +++ b/itlwm/hal_iwm/mac80211.cpp @@ -4777,7 +4777,7 @@ iwm_attach(struct iwm_softc *sc, struct pci_attach_args *pa) ic->ic_ampdu_params = (IEEE80211_AMPDU_PARAM_SS_4 | 0x3 /* 64k */); ic->ic_caps |= (IEEE80211_C_QOS | IEEE80211_C_TX_AMPDU | IEEE80211_C_AMSDU_IN_AMPDU); ic->ic_caps |= IEEE80211_C_SUPPORTS_VHT_EXT_NSS_BW; -#if 0 +#if 1 ic->ic_caps |= IEEE80211_C_TX_AMPDU_SETUP_IN_RS; #endif diff --git a/itlwm/hal_iwm/rs.cpp b/itlwm/hal_iwm/rs.cpp index bff2713e3..4508c093d 100644 --- a/itlwm/hal_iwm/rs.cpp +++ b/itlwm/hal_iwm/rs.cpp @@ -600,7 +600,7 @@ static void rs_tl_turn_on_agg(struct iwm_softc *sc, u8 tid, struct iwl_lq_sta *lq_sta, struct ieee80211_node *ni) { -#if 0 +#if 1 struct iwm_tx_ba *tid_data; struct ieee80211_tx_ba *tx_ba; @@ -622,7 +622,7 @@ static void rs_tl_turn_on_agg(struct iwm_softc *sc, tx_ba->ba_state == IEEE80211_BA_INIT && (lq_sta->tx_agg_tid_en & BIT(tid)) && tid_data->tx_count_last >= IWL_MVM_RS_AGG_START_THRESHOLD) { - IWL_DEBUG_RATE(mvm, "try to aggregate tid %d\n", tid); + XYLog("RS: try to aggregate tid %d\n", tid); rs_tl_turn_on_agg_for_tid(sc, lq_sta, tid, ni); } #else From 05c4b1ff413b68d33158802c7828eef8fb1b75b3 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Fri, 1 Apr 2022 08:00:50 +0800 Subject: [PATCH 011/114] Add legacy rate --- itlwm/hal_iwm/mac80211.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/itlwm/hal_iwm/mac80211.cpp b/itlwm/hal_iwm/mac80211.cpp index 2f0bc4fca..6d0fa1db2 100644 --- a/itlwm/hal_iwm/mac80211.cpp +++ b/itlwm/hal_iwm/mac80211.cpp @@ -1593,6 +1593,14 @@ iwm_tx_fill_cmd(struct iwm_softc *sc, struct iwm_node *in, ridx = iwm_mcs2ridx[ni->ni_txmcs]; else if (ni->ni_flags & IEEE80211_NODE_HT) ridx = iwm_mcs2ridx[ni->ni_txmcs % 8]; + else { + for (i = 0; i < ieee80211_std_rateset_11g.rs_nrates; i++) { + if (ieee80211_std_rateset_11g.rs_rates[i] == ni->ni_txrate) { + ridx = i; + break; + } + } + } } if (ridx == -1 || ridx >= IWL_RATE_COUNT_LEGACY) From eb180f61188cf3d7ed010bdb8073905a4ac157e9 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Wed, 24 Aug 2022 23:21:29 +0800 Subject: [PATCH 012/114] disable tid correctly --- itlwm/hal_iwm/mac80211.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/itlwm/hal_iwm/mac80211.cpp b/itlwm/hal_iwm/mac80211.cpp index 6d0fa1db2..3163ce994 100644 --- a/itlwm/hal_iwm/mac80211.cpp +++ b/itlwm/hal_iwm/mac80211.cpp @@ -5077,12 +5077,12 @@ iwm_ba_task(void *arg) that->iwm_nic_unlock(sc); sc->ba_tx.start_tidmask &= ~(1 << tid); } else if (sc->ba_tx.stop_tidmask & (1 << tid)) { + sc->agg_tid_disable |= (1 << tid); that->iwm_sta_tx_agg(sc, ni, tid, 0, 0, 0); that->iwm_ampdu_txq_advance(sc, ring, ring->cur); that->iwm_clear_oactive(sc, ring); /* In DQA-mode the queue isn't removed on agg termination */ tx_ba = &sc->sc_tx_ba[tid]; - sc->agg_tid_disable |= (1 << tid); tx_ba->wn = NULL; tx_ba->lq_color = 0; tx_ba->rate_n_flags = 0; From ee574e358e2ad144dc4bf8eb820c055f483dbe37 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Wed, 24 Aug 2022 23:22:59 +0800 Subject: [PATCH 013/114] Don't enable TX Aggregation queue again if it was already enabled before, only happens on one of the aggregation queue disable and enable again. --- itlwm/hal_iwm/tx.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/itlwm/hal_iwm/tx.cpp b/itlwm/hal_iwm/tx.cpp index 02c85454b..2ed600e61 100644 --- a/itlwm/hal_iwm/tx.cpp +++ b/itlwm/hal_iwm/tx.cpp @@ -295,6 +295,10 @@ iwm_enable_txq(struct iwm_softc *sc, int sta_id, int qid, int fifo, int ssn, int struct iwm_tx_ring *ring = &sc->txq[qid]; bool scd_bug = false; + if (agg && + (sc->agg_queue_mask & (1 << qid))) + return 0; + iwm_nic_assert_locked(sc); /* From 7af1cfc223669e7abb8cb2c67302509a291c20d6 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Wed, 24 Aug 2022 23:30:28 +0800 Subject: [PATCH 014/114] Silent aggregate trying log. --- itlwm/hal_iwm/rs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/itlwm/hal_iwm/rs.cpp b/itlwm/hal_iwm/rs.cpp index 4508c093d..6d8eb10cc 100644 --- a/itlwm/hal_iwm/rs.cpp +++ b/itlwm/hal_iwm/rs.cpp @@ -622,7 +622,7 @@ static void rs_tl_turn_on_agg(struct iwm_softc *sc, tx_ba->ba_state == IEEE80211_BA_INIT && (lq_sta->tx_agg_tid_en & BIT(tid)) && tid_data->tx_count_last >= IWL_MVM_RS_AGG_START_THRESHOLD) { - XYLog("RS: try to aggregate tid %d\n", tid); + IWL_DEBUG_RATE("RS: try to aggregate tid %d\n", tid); rs_tl_turn_on_agg_for_tid(sc, lq_sta, tid, ni); } #else From 5efde5cf1565247121424ca6f6df4985fcc6741c Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Mon, 29 Aug 2022 23:49:19 +0800 Subject: [PATCH 015/114] Missing ifq.cpp compiled in Ventura --- itlwm.xcodeproj/project.pbxproj | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/itlwm.xcodeproj/project.pbxproj b/itlwm.xcodeproj/project.pbxproj index fb638124d..d170fa256 100644 --- a/itlwm.xcodeproj/project.pbxproj +++ b/itlwm.xcodeproj/project.pbxproj @@ -317,13 +317,6 @@ 5088ECBF252884AF0068A63D /* libkmod.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5088ECBC252884870068A63D /* libkmod.a */; }; 5088ECC0252884C10068A63D /* libkmod.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5088ECBC252884870068A63D /* libkmod.a */; }; 5088ECC1252884D70068A63D /* libkmod.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5088ECBC252884870068A63D /* libkmod.a */; }; - A5FA2AE428A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; - A5FA2AE528A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; - A5FA2AE628A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; - A5FA2AE728A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; - A5FA2AE828A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; - A5FA2AE928A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; - A5FA2AEA28A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; A5DD111526D93B5F00BA01EF /* rs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5DD111326D93B5F00BA01EF /* rs.cpp */; }; A5DD111626D93B5F00BA01EF /* rs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5DD111326D93B5F00BA01EF /* rs.cpp */; }; A5DD111726D93B5F00BA01EF /* rs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5DD111326D93B5F00BA01EF /* rs.cpp */; }; @@ -336,6 +329,13 @@ A5DD111E26D93B5F00BA01EF /* rs.h in Headers */ = {isa = PBXBuildFile; fileRef = A5DD111426D93B5F00BA01EF /* rs.h */; }; A5DD111F26D93B5F00BA01EF /* rs.h in Headers */ = {isa = PBXBuildFile; fileRef = A5DD111426D93B5F00BA01EF /* rs.h */; }; A5DD112026D93B5F00BA01EF /* rs.h in Headers */ = {isa = PBXBuildFile; fileRef = A5DD111426D93B5F00BA01EF /* rs.h */; }; + A5FA2AE428A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; + A5FA2AE528A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; + A5FA2AE628A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; + A5FA2AE728A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; + A5FA2AE828A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; + A5FA2AE928A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; + A5FA2AEA28A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; F800DD9B24FBEBF000789320 /* ItlDriverController.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F800DD9A24FBEBF000789320 /* ItlDriverController.hpp */; }; F8294FE424FCBF5100239253 /* FwBinary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5076FA7F24CC71E40011B2BB /* FwBinary.cpp */; }; F837C91D2724577F00B2C499 /* coex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F837C91C2724577F00B2C499 /* coex.cpp */; }; @@ -344,6 +344,7 @@ F837C9202724577F00B2C499 /* coex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F837C91C2724577F00B2C499 /* coex.cpp */; }; F837C9212724577F00B2C499 /* coex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F837C91C2724577F00B2C499 /* coex.cpp */; }; F837C9222724577F00B2C499 /* coex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F837C91C2724577F00B2C499 /* coex.cpp */; }; + F8876A4E28B71F5400A21E42 /* rs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5DD111326D93B5F00BA01EF /* rs.cpp */; }; F88CB91424FBE9130060B1A5 /* ItlDriverInfo.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F88CB91324FBE9130060B1A5 /* ItlDriverInfo.hpp */; }; F88D2B3D2414E64000BBE700 /* sha1-pbkdf2.c in Sources */ = {isa = PBXBuildFile; fileRef = F88D2B3B2414E64000BBE700 /* sha1-pbkdf2.c */; }; F897ECBA266EFF93005EE8F7 /* debug.h in Headers */ = {isa = PBXBuildFile; fileRef = F89B6C2225027609000F77FF /* debug.h */; }; @@ -840,9 +841,9 @@ A5213EBC27A0C3ED00D7EAB1 /* iwm-8000C-36 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "iwm-8000C-36"; sourceTree = ""; }; A5213EBD27A0C3ED00D7EAB1 /* iwm-9260-46 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "iwm-9260-46"; sourceTree = ""; }; A5213EBE27A0C3ED00D7EAB1 /* iwm-8265-36 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "iwm-8265-36"; sourceTree = ""; }; - A5FA2AE328A797B200847103 /* _ifq.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = _ifq.cpp; sourceTree = ""; }; A5DD111326D93B5F00BA01EF /* rs.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = rs.cpp; sourceTree = ""; }; A5DD111426D93B5F00BA01EF /* rs.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = rs.h; sourceTree = ""; }; + A5FA2AE328A797B200847103 /* _ifq.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = _ifq.cpp; sourceTree = ""; }; F800DD9A24FBEBF000789320 /* ItlDriverController.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ItlDriverController.hpp; sourceTree = ""; }; F837C91C2724577F00B2C499 /* coex.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = coex.cpp; sourceTree = ""; }; F837C9252724732B00B2C499 /* iwlwifi-so-a0-gf-a0.pnvm */ = {isa = PBXFileReference; lastKnownFileType = file; path = "iwlwifi-so-a0-gf-a0.pnvm"; sourceTree = ""; }; @@ -2359,6 +2360,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F8876A4E28B71F5400A21E42 /* rs.cpp in Sources */, F8AE650A285471560085B4CF /* _mbuf.cpp in Sources */, F8AE650B285471560085B4CF /* ieee80211_ra.c in Sources */, F8AE650C285471560085B4CF /* _task.cpp in Sources */, From bc76086f310fb5e090f873e6ee03e4e59ac14f44 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Thu, 1 Jun 2023 01:38:26 +0800 Subject: [PATCH 016/114] net80211: Use universal malloc and free function --- itl80211/openbsd/net80211/ieee80211_crypto.c | 4 +-- .../openbsd/net80211/ieee80211_crypto_bip.c | 4 +-- .../openbsd/net80211/ieee80211_crypto_ccmp.c | 4 +-- .../openbsd/net80211/ieee80211_crypto_tkip.c | 4 +-- .../openbsd/net80211/ieee80211_crypto_wep.c | 4 +-- itl80211/openbsd/net80211/ieee80211_input.c | 12 +++---- itl80211/openbsd/net80211/ieee80211_node.c | 34 +++++++++---------- itl80211/openbsd/net80211/ieee80211_proto.c | 3 +- itl80211/openbsd/net80211/ieee80211_var.h | 9 ----- 9 files changed, 32 insertions(+), 46 deletions(-) diff --git a/itl80211/openbsd/net80211/ieee80211_crypto.c b/itl80211/openbsd/net80211/ieee80211_crypto.c index 9aa4845a5..079e20430 100644 --- a/itl80211/openbsd/net80211/ieee80211_crypto.c +++ b/itl80211/openbsd/net80211/ieee80211_crypto.c @@ -98,7 +98,7 @@ ieee80211_crypto_detach(struct _ifnet *ifp) while ((pmk = TAILQ_FIRST(&ic->ic_pmksa)) != NULL) { TAILQ_REMOVE(&ic->ic_pmksa, pmk, pmk_next); explicit_bzero(pmk, sizeof(*pmk)); - IOFree(pmk, sizeof(*pmk)); + free(pmk); } /* clear all group keys from memory */ @@ -654,7 +654,7 @@ ieee80211_pmksa_add(struct ieee80211com *ic, enum ieee80211_akm akm, } if (pmk == NULL) { /* allocate a new PMKSA entry */ - if ((pmk = (struct ieee80211_pmk *)_MallocZero(sizeof(*pmk))) == NULL) + if ((pmk = (struct ieee80211_pmk *)malloc(sizeof(*pmk), 0, 0)) == NULL) return NULL; pmk->pmk_akm = akm; IEEE80211_ADDR_COPY(pmk->pmk_macaddr, macaddr); diff --git a/itl80211/openbsd/net80211/ieee80211_crypto_bip.c b/itl80211/openbsd/net80211/ieee80211_crypto_bip.c index 3be27d3e1..bdf09bf78 100644 --- a/itl80211/openbsd/net80211/ieee80211_crypto_bip.c +++ b/itl80211/openbsd/net80211/ieee80211_crypto_bip.c @@ -70,7 +70,7 @@ ieee80211_bip_set_key(struct ieee80211com *ic, struct ieee80211_key *k) { struct ieee80211_bip_ctx *ctx; - ctx = (struct ieee80211_bip_ctx *)_MallocZero(sizeof(*ctx)); + ctx = (struct ieee80211_bip_ctx *)malloc(sizeof(*ctx), 0, 0); if (ctx == NULL) return ENOMEM; AES_CMAC_SetKey(&ctx->cmac, k->k_key); @@ -83,7 +83,7 @@ ieee80211_bip_delete_key(struct ieee80211com *ic, struct ieee80211_key *k) { if (k->k_priv != NULL) { explicit_bzero(k->k_priv, sizeof(struct ieee80211_bip_ctx)); - IOFree(k->k_priv, sizeof(struct ieee80211_bip_ctx)); + free(k->k_priv); } k->k_priv = NULL; } diff --git a/itl80211/openbsd/net80211/ieee80211_crypto_ccmp.c b/itl80211/openbsd/net80211/ieee80211_crypto_ccmp.c index e7537a90d..ca5ff9b48 100644 --- a/itl80211/openbsd/net80211/ieee80211_crypto_ccmp.c +++ b/itl80211/openbsd/net80211/ieee80211_crypto_ccmp.c @@ -68,7 +68,7 @@ ieee80211_ccmp_set_key(struct ieee80211com *ic, struct ieee80211_key *k) { struct ieee80211_ccmp_ctx *ctx; - ctx = (struct ieee80211_ccmp_ctx *)_MallocZero(sizeof(*ctx)); + ctx = (struct ieee80211_ccmp_ctx *)malloc(sizeof(*ctx), 0, 0); if (ctx == NULL) return ENOMEM; AES_Setkey(&ctx->aesctx, k->k_key, 16); @@ -81,7 +81,7 @@ ieee80211_ccmp_delete_key(struct ieee80211com *ic, struct ieee80211_key *k) { if (k->k_priv != NULL) { explicit_bzero(k->k_priv, sizeof(struct ieee80211_ccmp_ctx)); - IOFree(k->k_priv, sizeof(struct ieee80211_ccmp_ctx)); + free(k->k_priv); } k->k_priv = NULL; } diff --git a/itl80211/openbsd/net80211/ieee80211_crypto_tkip.c b/itl80211/openbsd/net80211/ieee80211_crypto_tkip.c index 063a311a5..a4569698b 100644 --- a/itl80211/openbsd/net80211/ieee80211_crypto_tkip.c +++ b/itl80211/openbsd/net80211/ieee80211_crypto_tkip.c @@ -84,7 +84,7 @@ ieee80211_tkip_set_key(struct ieee80211com *ic, struct ieee80211_key *k) { struct ieee80211_tkip_ctx *ctx; - ctx = (struct ieee80211_tkip_ctx *)_MallocZero(sizeof(*ctx)); + ctx = (struct ieee80211_tkip_ctx *)malloc(sizeof(*ctx), 0, 0); if (ctx == NULL) return ENOMEM; /* @@ -117,7 +117,7 @@ ieee80211_tkip_delete_key(struct ieee80211com *ic, struct ieee80211_key *k) { if (k->k_priv != NULL) { explicit_bzero(k->k_priv, sizeof(struct ieee80211_tkip_ctx)); - IOFree(k->k_priv, sizeof(struct ieee80211_tkip_ctx)); + free(k->k_priv); } k->k_priv = NULL; } diff --git a/itl80211/openbsd/net80211/ieee80211_crypto_wep.c b/itl80211/openbsd/net80211/ieee80211_crypto_wep.c index d8cbb6d5f..407b54a60 100644 --- a/itl80211/openbsd/net80211/ieee80211_crypto_wep.c +++ b/itl80211/openbsd/net80211/ieee80211_crypto_wep.c @@ -70,7 +70,7 @@ ieee80211_wep_set_key(struct ieee80211com *ic, struct ieee80211_key *k) { struct ieee80211_wep_ctx *ctx; - ctx = (struct ieee80211_wep_ctx *)_MallocZero(sizeof(*ctx)); + ctx = (struct ieee80211_wep_ctx *)malloc(sizeof(*ctx), 0, 0); if (ctx == NULL) return ENOMEM; k->k_priv = ctx; @@ -82,7 +82,7 @@ ieee80211_wep_delete_key(struct ieee80211com *ic, struct ieee80211_key *k) { if (k->k_priv != NULL) { explicit_bzero(k->k_priv, sizeof(struct ieee80211_wep_ctx)); - IOFree(k->k_priv, sizeof(struct ieee80211_wep_ctx)); + free(k->k_priv); } k->k_priv = NULL; } diff --git a/itl80211/openbsd/net80211/ieee80211_input.c b/itl80211/openbsd/net80211/ieee80211_input.c index ab0070f7c..c1eb1c014 100644 --- a/itl80211/openbsd/net80211/ieee80211_input.c +++ b/itl80211/openbsd/net80211/ieee80211_input.c @@ -1600,8 +1600,8 @@ ieee80211_save_ie(const u_int8_t *frm, u_int8_t **ie) if (*ie == NULL || olen != len) { if (*ie != NULL) - IOFree(*ie, olen); - *ie = (u_int8_t *)_MallocZero(len); + free(*ie); + *ie = (u_int8_t *)malloc(len, 0, 0); if (*ie == NULL) return ENOMEM; } @@ -3068,7 +3068,7 @@ ieee80211_recv_addba_req(struct ieee80211com *ic, mbuf_t m, ba->ba_winstart = ssn; ba->ba_winend = (ba->ba_winstart + ba->ba_winsize - 1) & 0xfff; /* allocate and setup our reordering buffer */ - ba->ba_buf = (struct ieee80211_ba_buf*)_MallocZero(IEEE80211_BA_MAX_WINSZ * sizeof(struct ieee80211_ba_buf)); + ba->ba_buf = (struct ieee80211_ba_buf*)malloc(IEEE80211_BA_MAX_WINSZ * sizeof(struct ieee80211_ba_buf), 0, 0); if (ba->ba_buf == NULL) goto refuse; @@ -3118,8 +3118,7 @@ ieee80211_addba_req_refuse(struct ieee80211com *ic, struct ieee80211_node *ni, { struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid]; - IOFree(ba->ba_buf, - IEEE80211_BA_MAX_WINSZ * sizeof(*ba->ba_buf)); + free(ba->ba_buf); ba->ba_buf = NULL; ba->ba_state = IEEE80211_BA_INIT; @@ -3299,8 +3298,7 @@ ieee80211_recv_delba(struct ieee80211com *ic, mbuf_t m, for (i = 0; i < IEEE80211_BA_MAX_WINSZ; i++) mbuf_freem(ba->ba_buf[i].m); /* free reordering buffer */ - IOFree(ba->ba_buf, - IEEE80211_BA_MAX_WINSZ * sizeof(*ba->ba_buf)); + free(ba->ba_buf); ba->ba_buf = NULL; } } else { diff --git a/itl80211/openbsd/net80211/ieee80211_node.c b/itl80211/openbsd/net80211/ieee80211_node.c index 26837ef4d..b691ee6ef 100644 --- a/itl80211/openbsd/net80211/ieee80211_node.c +++ b/itl80211/openbsd/net80211/ieee80211_node.c @@ -220,7 +220,7 @@ ieee80211_del_ess(struct ieee80211com *ic, char *nwid, int len, int all) memcmp(ess->essid, nwid, len) == 0)) { TAILQ_REMOVE(&ic->ic_ess, ess, ess_next); explicit_bzero(ess, sizeof(*ess)); - IOFree(ess, sizeof(*ess)); + free(ess); if (TAILQ_EMPTY(&ic->ic_ess)) ic->ic_flags &= ~IEEE80211_F_AUTO_JOIN; if (all != 1) @@ -396,7 +396,7 @@ ieee80211_add_ess(struct ieee80211com *ic, struct ieee80211_join *join) if (ness > IEEE80211_CACHE_SIZE) return (ERANGE); new_value = 1; - ess = (struct ieee80211_ess *)_MallocZero(sizeof(*ess)); + ess = (struct ieee80211_ess *)malloc(sizeof(*ess), 0, 0); if (ess == NULL) return (ENOMEM); memcpy(ess->essid, join->i_nwid, join->i_len); @@ -406,7 +406,7 @@ ieee80211_add_ess(struct ieee80211com *ic, struct ieee80211_join *join) if (join->i_flags & IEEE80211_JOIN_WPA) { if (join->i_wpaparams.i_enabled) { if (!(ic->ic_caps & IEEE80211_C_RSN)) { - IOFree(ess, sizeof(*ess)); + free(ess); return ENODEV; } ieee80211_ess_setwpaparms(ess, @@ -424,7 +424,7 @@ ieee80211_add_ess(struct ieee80211com *ic, struct ieee80211_join *join) } else if (join->i_flags & IEEE80211_JOIN_NWKEY) { if (join->i_nwkey.i_wepon) { if (!(ic->ic_caps & IEEE80211_C_WEP)) { - IOFree(ess, sizeof(*ess)); + free(ess); return ENODEV; } ieee80211_ess_setnwkeys(ess, &join->i_nwkey); @@ -732,7 +732,7 @@ ieee80211_node_attach(struct _ifnet *ifp) ic->ic_max_aid = IEEE80211_AID_MAX; #ifndef IEEE80211_STA_ONLY size = howmany(ic->ic_max_aid, 32) * sizeof(u_int32_t); - ic->ic_aid_bitmap = (u_int32_t *)_MallocZero(size); + ic->ic_aid_bitmap = (u_int32_t *)malloc(size, 0, 0); if (ic->ic_aid_bitmap == NULL) { /* XXX no way to recover */ XYLog("%s: no memory for AID bitmap!\n", __FUNCTION__); @@ -740,7 +740,7 @@ ieee80211_node_attach(struct _ifnet *ifp) } if (ic->ic_caps & (IEEE80211_C_HOSTAP | IEEE80211_C_IBSS)) { ic->ic_tim_len = howmany(ic->ic_max_aid, 8); - ic->ic_tim_bitmap = (u_int8_t*)_MallocZero(ic->ic_tim_len); + ic->ic_tim_bitmap = (u_int8_t*)malloc(ic->ic_tim_len, 0, 0); if (ic->ic_tim_bitmap == NULL) { XYLog("%s: no memory for TIM bitmap!\n", __FUNCTION__); ic->ic_tim_len = 0; @@ -799,9 +799,8 @@ ieee80211_node_detach(struct _ifnet *ifp) ieee80211_del_ess(ic, NULL, 0, 1); ieee80211_free_allnodes(ic, 1); #ifndef IEEE80211_STA_ONLY - IOFree(ic->ic_aid_bitmap, - howmany(ic->ic_max_aid, 32) * sizeof(u_int32_t)); - IOFree(ic->ic_tim_bitmap, ic->ic_tim_len); + free(ic->ic_aid_bitmap); + free(ic->ic_tim_bitmap); timeout_del(&ic->ic_inact_timeout); timeout_free(&ic->ic_inact_timeout); timeout_del(&ic->ic_node_cache_timeout); @@ -1197,7 +1196,7 @@ ieee80211_node_switch_bss(struct ieee80211com *ic, struct ieee80211_node *ni) splassert(IPL_NET); if ((ic->ic_flags & IEEE80211_F_BGSCAN) == 0) { - IOFree(sba, sizeof(*sba)); + free(sba); return; } @@ -1205,7 +1204,7 @@ ieee80211_node_switch_bss(struct ieee80211com *ic, struct ieee80211_node *ni) selbs = ieee80211_find_node(ic, sba->sel_macaddr); if (selbs == NULL) { - IOFree(sba, sizeof(*sba)); + free(sba); ic->ic_flags &= ~IEEE80211_F_BGSCAN; ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); return; @@ -1213,7 +1212,7 @@ ieee80211_node_switch_bss(struct ieee80211com *ic, struct ieee80211_node *ni) curbs = ieee80211_find_node(ic, sba->cur_macaddr); if (curbs == NULL) { - IOFree(sba, sizeof(*sba)); + free(sba); ic->ic_flags &= ~IEEE80211_F_BGSCAN; ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); return; @@ -1529,7 +1528,7 @@ ieee80211_end_scan(struct _ifnet *ifp) return; } - arg = (struct ieee80211_node_switch_bss_arg *)_MallocZero(sizeof(*arg)); + arg = (struct ieee80211_node_switch_bss_arg *)malloc(sizeof(*arg), 0, 0); if (arg == NULL) { ic->ic_flags &= ~IEEE80211_F_BGSCAN; return; @@ -1547,7 +1546,7 @@ ieee80211_end_scan(struct _ifnet *ifp) IEEE80211_FC0_SUBTYPE_DEAUTH, IEEE80211_REASON_AUTH_LEAVE) != 0) { ic->ic_flags &= ~IEEE80211_F_BGSCAN; - IOFree(arg, sizeof(*arg)); + free(arg); return; } @@ -1659,7 +1658,7 @@ ieee80211_node_cleanup(struct ieee80211com *ic, struct ieee80211_node *ni) return; } if (ni->ni_rsnie != NULL) { - IOFree(ni->ni_rsnie, 2 + ni->ni_rsnie[1]); + free(ni->ni_rsnie); ni->ni_rsnie = NULL; } if (ni->ni_rsnie_tlv != NULL && ni->ni_rsnie_tlv_len > 0) { @@ -1670,7 +1669,7 @@ ieee80211_node_cleanup(struct ieee80211com *ic, struct ieee80211_node *ni) ieee80211_ba_del(ni); ieee80211_ba_free(ni); if (ni->ni_unref_arg != NULL) { - IOFree(ni->ni_unref_arg, ni->ni_unref_arg_size); + free(ni->ni_unref_arg); ni->ni_unref_arg = NULL; ni->ni_unref_arg_size = 0; } @@ -3190,8 +3189,7 @@ ieee80211_node_leave_ht(struct ieee80211com *ic, struct ieee80211_node *ni) if (ba->ba_buf != NULL) { for (i = 0; i < IEEE80211_BA_MAX_WINSZ; i++) mbuf_freem(ba->ba_buf[i].m); - IOFree(ba->ba_buf, - IEEE80211_BA_MAX_WINSZ * sizeof(*ba->ba_buf)); + free(ba->ba_buf); ba->ba_buf = NULL; } } diff --git a/itl80211/openbsd/net80211/ieee80211_proto.c b/itl80211/openbsd/net80211/ieee80211_proto.c index 118fa81c7..3e61d1b5b 100644 --- a/itl80211/openbsd/net80211/ieee80211_proto.c +++ b/itl80211/openbsd/net80211/ieee80211_proto.c @@ -1078,8 +1078,7 @@ ieee80211_delba_request(struct ieee80211com *ic, struct ieee80211_node *ni, for (i = 0; i < IEEE80211_BA_MAX_WINSZ; i++) mbuf_freem(ba->ba_buf[i].m); /* free reordering buffer */ - IOFree(ba->ba_buf, - IEEE80211_BA_MAX_WINSZ * sizeof(*ba->ba_buf)); + free(ba->ba_buf); ba->ba_buf = NULL; } } diff --git a/itl80211/openbsd/net80211/ieee80211_var.h b/itl80211/openbsd/net80211/ieee80211_var.h index 96ad077ad..5d9fbe120 100644 --- a/itl80211/openbsd/net80211/ieee80211_var.h +++ b/itl80211/openbsd/net80211/ieee80211_var.h @@ -95,15 +95,6 @@ extern int _start(struct kmod_info*, void*); extern int timingsafe_bcmp(const void *b1, const void *b2, size_t n); -static inline void* _MallocZero(vm_size_t size) -{ - void *ret = IOMalloc(size); - if (ret != NULL) { - bzero(ret, size); - } - return ret; -} - /* * ppsratecheck(): packets (or events) per second limitation. */ From b83c11172c1abee202b28628ad583cb397e00c38 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Sun, 5 Sep 2021 22:58:40 +0800 Subject: [PATCH 017/114] implement Linux iwlwifi generic rate control RS algorithm for iwm --- itl80211/linux/bitfield.h | 91 +- itl80211/linux/kernel.h | 1 + itl80211/linux/types.h | 4 + itl80211/openbsd/net80211/ieee80211.h | 29 +- itl80211/openbsd/net80211/ieee80211_output.c | 3 +- itl80211/openbsd/net80211/ieee80211_var.h | 1 + itlwm.xcodeproj/project.pbxproj | 28 + itlwm/hal_iwm/ItlIwm.cpp | 1 + itlwm/hal_iwm/ItlIwm.hpp | 9 +- itlwm/hal_iwm/if_iwmreg.h | 13 +- itlwm/hal_iwm/if_iwmvar.h | 17 +- itlwm/hal_iwm/mac80211.cpp | 641 ++- itlwm/hal_iwm/rs.cpp | 3685 ++++++++++++++++++ itlwm/hal_iwm/rs.h | 1509 +++++++ itlwm/hal_iwm/rx.cpp | 10 +- 15 files changed, 5878 insertions(+), 164 deletions(-) create mode 100644 itlwm/hal_iwm/rs.cpp create mode 100644 itlwm/hal_iwm/rs.h diff --git a/itl80211/linux/bitfield.h b/itl80211/linux/bitfield.h index faf0b53e8..6eafe987a 100644 --- a/itl80211/linux/bitfield.h +++ b/itl80211/linux/bitfield.h @@ -44,13 +44,100 @@ ({ \ ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); \ }) + +static inline int +find_first_zero_bit(volatile void *p, int max) +{ + int b; + volatile u_int *ptr = (volatile u_int *)p; + + for (b = 0; b < max; b += 32) { + if (ptr[b >> 5] != ~0) { + for (;;) { + if ((ptr[b >> 5] & (1 << (b & 0x1f))) == 0) + return b; + b++; + } + } + } + return max; +} + +static inline int +find_next_zero_bit(volatile void *p, int max, int b) +{ + volatile u_int *ptr = (volatile u_int *)p; + + for (; b < max; b += 32) { + if (ptr[b >> 5] != ~0) { + for (;;) { + if ((ptr[b >> 5] & (1 << (b & 0x1f))) == 0) + return b; + b++; + } + } + } + return max; +} + +static inline int +find_first_bit(volatile void *p, int max) +{ + int b; + volatile u_int *ptr = (volatile u_int *)p; + + for (b = 0; b < max; b += 32) { + if (ptr[b >> 5] != 0) { + for (;;) { + if (ptr[b >> 5] & (1 << (b & 0x1f))) + return b; + b++; + } + } + } + return max; +} + +static inline int +find_next_bit(volatile void *p, int max, int b) +{ + volatile u_int *ptr = (volatile u_int *)p; + + for (; b < max; b+= 32) { + if (ptr[b >> 5] != 0) { + for (;;) { + if (ptr[b >> 5] & (1 << (b & 0x1f))) + return b; + b++; + } + } + } + return max; +} + +static inline int +find_last_bit(volatile void *p, int max) +{ + int b; + volatile u_int *ptr = (volatile u_int *)p; + + for (b = max; b > 0; b -= 32) { + if (ptr[b >> 5] != 0) { + for (;;) { + if (ptr[b >> 5] & (1 << (b & 0x1f))) + return b; + b--; + } + } + } + return max; +} + #define for_each_set_bit(bit, addr, size) \ for ((bit) = find_first_bit((addr), (size)); \ (bit) < (size); \ (bit) = find_next_bit((addr), (size), (bit) + 1)) -#define find_first_bit(addr, size) find_next_bit((addr), (size), 0) - #define GENMASK(h, l) \ (((~(0UL)) - ((1UL) << (l)) + 1) & \ (~(0UL) >> (BITS_PER_LONG - 1 - (h)))) diff --git a/itl80211/linux/kernel.h b/itl80211/linux/kernel.h index cc63a15f0..d410944e1 100644 --- a/itl80211/linux/kernel.h +++ b/itl80211/linux/kernel.h @@ -185,6 +185,7 @@ pointer_t __mptr = (pointer_t)(ptr); \ #define time_after(a,b) \ ((long)(b) - (long)(a) < 0) +#define time_is_before_jiffies(a) time_after(ticks, a) #define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1)) diff --git a/itl80211/linux/types.h b/itl80211/linux/types.h index befe717b4..b52204d56 100644 --- a/itl80211/linux/types.h +++ b/itl80211/linux/types.h @@ -147,6 +147,10 @@ typedef UInt16 __sum16; typedef u64 dma_addr_t; +#define U8_MAX ((u8)~0U) +#define S8_MAX ((s8)(U8_MAX >> 1)) +#define S8_MIN ((s8)(-S8_MAX - 1)) + #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) #define upper_32_bits(n) ((u32)(((n) >> 16) >> 16)) diff --git a/itl80211/openbsd/net80211/ieee80211.h b/itl80211/openbsd/net80211/ieee80211.h index 70d45295c..0052c1a2d 100644 --- a/itl80211/openbsd/net80211/ieee80211.h +++ b/itl80211/openbsd/net80211/ieee80211.h @@ -356,24 +356,35 @@ ieee80211_get_qos(const struct ieee80211_frame *wh) } static __inline int -ieee80211_is_ctl(const struct ieee80211_frame *wh) +ieee80211_is_ctl(uint16_t fc) { - return (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == - IEEE80211_FC0_TYPE_CTL; + return (fc & htole16(IEEE80211_FC0_TYPE_MASK)) == + htole16(IEEE80211_FC0_TYPE_CTL); } static __inline int -ieee80211_is_data(const struct ieee80211_frame *wh) +ieee80211_is_data(uint16_t fc) { - return (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == - IEEE80211_FC0_TYPE_DATA; + return (fc & htole16(IEEE80211_FC0_TYPE_MASK)) == + htole16(IEEE80211_FC0_TYPE_DATA); } static __inline int -ieee80211_is_mgmt(const struct ieee80211_frame *wh) +ieee80211_is_mgmt(uint16_t fc) { - return (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == - IEEE80211_FC0_TYPE_MGT; + return (fc & htole16(IEEE80211_FC0_TYPE_MASK)) == + htole16(IEEE80211_FC0_TYPE_MGT); +} + +static __inline int +ieee80211_is_data_qos(uint16_t fc) +{ + /* + * mask with QOS_DATA rather than IEEE80211_FCTL_STYPE as we just need + * to check the one bit + */ + return (fc & htole16(IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_QOS)) == + htole16(IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS); } static __inline int diff --git a/itl80211/openbsd/net80211/ieee80211_output.c b/itl80211/openbsd/net80211/ieee80211_output.c index 2da63b462..429d36c10 100644 --- a/itl80211/openbsd/net80211/ieee80211_output.c +++ b/itl80211/openbsd/net80211/ieee80211_output.c @@ -637,7 +637,8 @@ ieee80211_encap(struct _ifnet *ifp, mbuf_t m, struct ieee80211_node **pni) if (ba->ba_state != IEEE80211_BA_AGREED) { hdrlen = sizeof(struct ieee80211_frame); addqos = 0; - if (ieee80211_can_use_ampdu(ic, ni)) + if ((ic->ic_caps & IEEE80211_C_TX_AMPDU_SETUP_IN_RS) == 0 && + ieee80211_can_use_ampdu(ic, ni)) ieee80211_node_trigger_addba_req(ni, tid); } else { hdrlen = sizeof(struct ieee80211_qosframe); diff --git a/itl80211/openbsd/net80211/ieee80211_var.h b/itl80211/openbsd/net80211/ieee80211_var.h index 5d9fbe120..6464ef997 100644 --- a/itl80211/openbsd/net80211/ieee80211_var.h +++ b/itl80211/openbsd/net80211/ieee80211_var.h @@ -650,6 +650,7 @@ struct ieee80211_ess { #define IEEE80211_C_AMSDU_IN_AMPDU 0x00020000 /* CAPABILITY: Rx AMSDU inside AMPDU */ #define IEEE80211_C_TX_AMPDU_SETUP_IN_HW 0x00040000 /* CAPABILITY: BA negotiation in HW */ #define IEEE80211_C_SUPPORTS_VHT_EXT_NSS_BW 0x00080000 /* CAPABILITY: for 160mhz */ +#define IEEE80211_C_TX_AMPDU_SETUP_IN_RS 0x00100000 /* flags for ieee80211_fix_rate() */ #define IEEE80211_F_DOSORT 0x00000001 /* sort rate list */ diff --git a/itlwm.xcodeproj/project.pbxproj b/itlwm.xcodeproj/project.pbxproj index ab4856f24..cd40795da 100644 --- a/itlwm.xcodeproj/project.pbxproj +++ b/itlwm.xcodeproj/project.pbxproj @@ -324,6 +324,18 @@ A5FA2AE828A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; A5FA2AE928A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; A5FA2AEA28A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; + A5DD111526D93B5F00BA01EF /* rs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5DD111326D93B5F00BA01EF /* rs.cpp */; }; + A5DD111626D93B5F00BA01EF /* rs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5DD111326D93B5F00BA01EF /* rs.cpp */; }; + A5DD111726D93B5F00BA01EF /* rs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5DD111326D93B5F00BA01EF /* rs.cpp */; }; + A5DD111826D93B5F00BA01EF /* rs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5DD111326D93B5F00BA01EF /* rs.cpp */; }; + A5DD111926D93B5F00BA01EF /* rs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5DD111326D93B5F00BA01EF /* rs.cpp */; }; + A5DD111A26D93B5F00BA01EF /* rs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5DD111326D93B5F00BA01EF /* rs.cpp */; }; + A5DD111B26D93B5F00BA01EF /* rs.h in Headers */ = {isa = PBXBuildFile; fileRef = A5DD111426D93B5F00BA01EF /* rs.h */; }; + A5DD111C26D93B5F00BA01EF /* rs.h in Headers */ = {isa = PBXBuildFile; fileRef = A5DD111426D93B5F00BA01EF /* rs.h */; }; + A5DD111D26D93B5F00BA01EF /* rs.h in Headers */ = {isa = PBXBuildFile; fileRef = A5DD111426D93B5F00BA01EF /* rs.h */; }; + A5DD111E26D93B5F00BA01EF /* rs.h in Headers */ = {isa = PBXBuildFile; fileRef = A5DD111426D93B5F00BA01EF /* rs.h */; }; + A5DD111F26D93B5F00BA01EF /* rs.h in Headers */ = {isa = PBXBuildFile; fileRef = A5DD111426D93B5F00BA01EF /* rs.h */; }; + A5DD112026D93B5F00BA01EF /* rs.h in Headers */ = {isa = PBXBuildFile; fileRef = A5DD111426D93B5F00BA01EF /* rs.h */; }; F800DD9B24FBEBF000789320 /* ItlDriverController.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F800DD9A24FBEBF000789320 /* ItlDriverController.hpp */; }; F8294FE424FCBF5100239253 /* FwBinary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5076FA7F24CC71E40011B2BB /* FwBinary.cpp */; }; F837C91D2724577F00B2C499 /* coex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F837C91C2724577F00B2C499 /* coex.cpp */; }; @@ -829,6 +841,8 @@ A5213EBD27A0C3ED00D7EAB1 /* iwm-9260-46 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "iwm-9260-46"; sourceTree = ""; }; A5213EBE27A0C3ED00D7EAB1 /* iwm-8265-36 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "iwm-8265-36"; sourceTree = ""; }; A5FA2AE328A797B200847103 /* _ifq.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = _ifq.cpp; sourceTree = ""; }; + A5DD111326D93B5F00BA01EF /* rs.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = rs.cpp; sourceTree = ""; }; + A5DD111426D93B5F00BA01EF /* rs.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = rs.h; sourceTree = ""; }; F800DD9A24FBEBF000789320 /* ItlDriverController.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ItlDriverController.hpp; sourceTree = ""; }; F837C91C2724577F00B2C499 /* coex.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = coex.cpp; sourceTree = ""; }; F837C9252724732B00B2C499 /* iwlwifi-so-a0-gf-a0.pnvm */ = {isa = PBXFileReference; lastKnownFileType = file; path = "iwlwifi-so-a0-gf-a0.pnvm"; sourceTree = ""; }; @@ -1259,6 +1273,8 @@ F837C91C2724577F00B2C499 /* coex.cpp */, F8AF3A2F24F9F35B008911C1 /* ItlIwm.cpp */, F8AF3A3024F9F35B008911C1 /* ItlIwm.hpp */, + A5DD111326D93B5F00BA01EF /* rs.cpp */, + A5DD111426D93B5F00BA01EF /* rs.h */, ); path = hal_iwm; sourceTree = ""; @@ -1427,6 +1443,7 @@ 024A085423FCBC6C009FBA6C /* podd.h in Headers */, F8C2EC562408031A007A9422 /* ieee80211_node.h in Headers */, F8C2EC9524080557007A9422 /* _mbuf.h in Headers */, + A5DD111B26D93B5F00BA01EF /* rs.h in Headers */, 024A084423FCBC6C009FBA6C /* sha2.h in Headers */, 024A088C23FCBE38009FBA6C /* if_iwmvar.h in Headers */, 024A083A23FCBC6C009FBA6C /* blf.h in Headers */, @@ -1468,6 +1485,7 @@ F8F7EA4D252D834600520FD4 /* IO80211Interface.h in Headers */, F8F7EA49252D834600520FD4 /* IO80211SkywalkInterface.h in Headers */, 35CBE666251CB89700435CBC /* AirportItlwm.hpp in Headers */, + A5DD111F26D93B5F00BA01EF /* rs.h in Headers */, F8F7EA3D252D834600520FD4 /* IO80211VirtualInterface.h in Headers */, F8F7EA41252D834600520FD4 /* IO80211Controller.h in Headers */, F8C594DC25FD935B0007D19C /* ieee80211_ra.h in Headers */, @@ -1489,6 +1507,7 @@ F8F7EA4B252D834600520FD4 /* IO80211Interface.h in Headers */, F8F7EA47252D834600520FD4 /* IO80211SkywalkInterface.h in Headers */, 35CBE6D0251CB8BF00435CBC /* AirportItlwm.hpp in Headers */, + A5DD111D26D93B5F00BA01EF /* rs.h in Headers */, F8F7EA3B252D834600520FD4 /* IO80211VirtualInterface.h in Headers */, F8F7EA3F252D834600520FD4 /* IO80211Controller.h in Headers */, F8C594DA25FD935B0007D19C /* ieee80211_ra.h in Headers */, @@ -1510,6 +1529,7 @@ F8F7EA4A252D834600520FD4 /* IO80211Interface.h in Headers */, F8F7EA46252D834600520FD4 /* IO80211SkywalkInterface.h in Headers */, 35CBE73B251CB8CA00435CBC /* AirportItlwm.hpp in Headers */, + A5DD111C26D93B5F00BA01EF /* rs.h in Headers */, F8F7EA3A252D834600520FD4 /* IO80211VirtualInterface.h in Headers */, F8F7EA3E252D834600520FD4 /* IO80211Controller.h in Headers */, F8C594D925FD935B0007D19C /* ieee80211_ra.h in Headers */, @@ -1527,6 +1547,7 @@ F897ECBD266EFF93005EE8F7 /* IO80211P2PInterface.h in Headers */, F897ECBE266EFF93005EE8F7 /* IO80211WorkLoop.h in Headers */, F897ECBF266EFF93005EE8F7 /* apple80211_var.h in Headers */, + A5DD112026D93B5F00BA01EF /* rs.h in Headers */, F897ECC0266EFF93005EE8F7 /* AirportItlwmInterface.hpp in Headers */, F897ECC1266EFF93005EE8F7 /* IO80211Interface.h in Headers */, F897ECC2266EFF93005EE8F7 /* (null) in Headers */, @@ -1554,6 +1575,7 @@ F8F7EA4C252D834600520FD4 /* IO80211Interface.h in Headers */, F8F7EA48252D834600520FD4 /* IO80211SkywalkInterface.h in Headers */, F89B6BBC25021C9C000F77FF /* AirportItlwm.hpp in Headers */, + A5DD111E26D93B5F00BA01EF /* rs.h in Headers */, F8F7EA3C252D834600520FD4 /* IO80211VirtualInterface.h in Headers */, F8F7EA40252D834600520FD4 /* IO80211Controller.h in Headers */, F8C594DB25FD935B0007D19C /* ieee80211_ra.h in Headers */, @@ -1903,6 +1925,7 @@ 024A08CE23FCE67F009FBA6C /* nvm.cpp in Sources */, 024A083D23FCBC6C009FBA6C /* sha1.c in Sources */, 17FD7F10255E4AC800611406 /* ItlIwn.cpp in Sources */, + A5DD111526D93B5F00BA01EF /* rs.cpp in Sources */, 024A085923FCBC6C009FBA6C /* idgen.c in Sources */, F8C2EC522408031A007A9422 /* ieee80211_ioctl.c in Sources */, F8C594D325FD935B0007D19C /* ieee80211_ra.c in Sources */, @@ -1980,6 +2003,7 @@ 35CBE697251CB89700435CBC /* md5.c in Sources */, 35CBE698251CB89700435CBC /* arc4.c in Sources */, 35CBE699251CB89700435CBC /* blf.c in Sources */, + A5DD111926D93B5F00BA01EF /* rs.cpp in Sources */, 35CBE69A251CB89700435CBC /* poly1305.c in Sources */, 35CBE69B251CB89700435CBC /* key_wrap.c in Sources */, 35CBE69C251CB89700435CBC /* gmac.c in Sources */, @@ -2058,6 +2082,7 @@ 35CBE701251CB8BF00435CBC /* md5.c in Sources */, 35CBE702251CB8BF00435CBC /* arc4.c in Sources */, 35CBE703251CB8BF00435CBC /* blf.c in Sources */, + A5DD111726D93B5F00BA01EF /* rs.cpp in Sources */, 35CBE704251CB8BF00435CBC /* poly1305.c in Sources */, 35CBE705251CB8BF00435CBC /* key_wrap.c in Sources */, 35CBE706251CB8BF00435CBC /* gmac.c in Sources */, @@ -2136,6 +2161,7 @@ 35CBE76C251CB8CA00435CBC /* md5.c in Sources */, 35CBE76D251CB8CA00435CBC /* arc4.c in Sources */, 35CBE76E251CB8CA00435CBC /* blf.c in Sources */, + A5DD111626D93B5F00BA01EF /* rs.cpp in Sources */, 35CBE76F251CB8CA00435CBC /* poly1305.c in Sources */, 35CBE770251CB8CA00435CBC /* key_wrap.c in Sources */, 35CBE771251CB8CA00435CBC /* gmac.c in Sources */, @@ -2207,6 +2233,7 @@ F897ECEC266EFF93005EE8F7 /* cast.c in Sources */, F897ECED266EFF93005EE8F7 /* michael.c in Sources */, F897ECEE266EFF93005EE8F7 /* sha1.c in Sources */, + A5DD111A26D93B5F00BA01EF /* rs.cpp in Sources */, F897ECEF266EFF93005EE8F7 /* cmac.c in Sources */, F897ECF0266EFF93005EE8F7 /* ecb_enc.c in Sources */, F897ECF1266EFF93005EE8F7 /* chachapoly.c in Sources */, @@ -2293,6 +2320,7 @@ F89B6C16250231E4000F77FF /* md5.c in Sources */, F89B6C17250231E4000F77FF /* arc4.c in Sources */, F89B6C18250231E4000F77FF /* blf.c in Sources */, + A5DD111826D93B5F00BA01EF /* rs.cpp in Sources */, F89B6C19250231E4000F77FF /* poly1305.c in Sources */, F89B6C1A250231E4000F77FF /* key_wrap.c in Sources */, F89B6C1B250231E4000F77FF /* gmac.c in Sources */, diff --git a/itlwm/hal_iwm/ItlIwm.cpp b/itlwm/hal_iwm/ItlIwm.cpp index 49d2c729d..cbbd64070 100644 --- a/itlwm/hal_iwm/ItlIwm.cpp +++ b/itlwm/hal_iwm/ItlIwm.cpp @@ -25,6 +25,7 @@ detach(IOPCIDevice *device) for (int txq_i = 0; txq_i < nitems(sc->txq); txq_i++) iwm_free_tx_ring(sc, &sc->txq[txq_i]); + iwm_rs_free(sc); iwm_free_rx_ring(sc, &sc->rxq); iwm_dma_contig_free(&sc->ict_dma); iwm_dma_contig_free(&sc->kw_dma); diff --git a/itlwm/hal_iwm/ItlIwm.hpp b/itlwm/hal_iwm/ItlIwm.hpp index cdc2bc3d8..976cf6e4f 100644 --- a/itlwm/hal_iwm/ItlIwm.hpp +++ b/itlwm/hal_iwm/ItlIwm.hpp @@ -242,8 +242,8 @@ class ItlIwm : public ItlHalService, ItlDriverInfo, ItlDriverController { int iwm_run_init_mvm_ucode(struct iwm_softc *, int); int iwm_config_ltr(struct iwm_softc *); int iwm_rx_addbuf(struct iwm_softc *, int, int); - int iwm_get_signal_strength(struct iwm_softc *, struct iwm_rx_phy_info *); - int iwm_rxmq_get_signal_strength(struct iwm_softc *, struct iwm_rx_mpdu_desc *); + int iwm_get_signal_strength(struct iwm_softc *, struct ieee80211_rx_status *, struct iwm_rx_phy_info *); + int iwm_rxmq_get_signal_strength(struct iwm_softc *, struct ieee80211_rx_status *, uint32_t, struct iwm_rx_mpdu_desc *); void iwm_rx_rx_phy_cmd(struct iwm_softc *, struct iwm_rx_packet *, struct iwm_rx_data *); int iwm_get_noise(const struct iwm_statistics_rx_non_phy *); @@ -254,14 +254,14 @@ class ItlIwm : public ItlHalService, ItlDriverInfo, ItlDriverController { void iwm_rx_frame(struct iwm_softc *, mbuf_t, int, uint32_t, int, int, uint32_t, struct ieee80211_rxinfo *, struct mbuf_list *); void iwm_rx_tx_cmd_single(struct iwm_softc *, struct iwm_tx_resp *, - struct iwm_node *, int, int, int); + int, int); void iwm_ampdu_tx_done(struct iwm_softc *, struct iwm_cmd_header *, struct iwm_node *, struct iwm_tx_ring *, uint32_t, uint8_t, uint8_t, uint16_t, int, struct iwm_agg_tx_status *); void iwm_rx_tx_ba_notif(struct iwm_softc *, struct iwm_rx_packet *, struct iwm_rx_data *); void iwm_rx_tx_cmd(struct iwm_softc *, struct iwm_rx_packet *, struct iwm_rx_data *); - void iwm_ampdu_rate_control(struct iwm_softc *, struct ieee80211_node *, struct iwm_tx_ring *, uint16_t, uint16_t); + void iwm_ampdu_rate_control(struct iwm_softc *, struct ieee80211_node *, struct iwm_tx_ring *, uint16_t, uint16_t, struct ieee80211_tx_info *, int, uint32_t); void iwm_ht_single_rate_control(struct iwm_softc *, struct ieee80211_node *, uint8_t, uint8_t, uint8_t, int); void iwm_rx_mpdu_mq(struct iwm_softc *sc, mbuf_t m, void *pktdata, @@ -292,6 +292,7 @@ class ItlIwm : public ItlHalService, ItlDriverInfo, ItlDriverController { struct ieee80211_frame *, struct iwm_tx_cmd *); void iwm_txd_done(struct iwm_softc *, struct iwm_tx_data *); void iwm_ampdu_txq_advance(struct iwm_softc *, struct iwm_tx_ring *, int); + void iwm_tx_reclaim(struct iwm_softc *, struct ieee80211_tx_info *tx_info, int, int, int, uint32_t, bool); void iwm_clear_oactive(struct iwm_softc *, struct iwm_tx_ring *); void iwm_ra_choose(struct iwm_softc *, struct ieee80211_node *); int iwm_tx(struct iwm_softc *, mbuf_t, struct ieee80211_node *, int); diff --git a/itlwm/hal_iwm/if_iwmreg.h b/itlwm/hal_iwm/if_iwmreg.h index 170aba648..44ebf1842 100644 --- a/itlwm/hal_iwm/if_iwmreg.h +++ b/itlwm/hal_iwm/if_iwmreg.h @@ -933,6 +933,7 @@ enum iwm_msix_ivar_for_cause { #define IWM_UCODE_TLV_CAPA_BINDING_CDB_SUPPORT 39 #define IWM_UCODE_TLV_CAPA_CDB_SUPPORT 40 #define IWM_UCODE_TLV_CAPA_DYNAMIC_QUOTA 44 +#define IWM_UCODE_TLV_CAPA_COEX_SCHEMA_2 45 #define IWM_UCODE_TLV_CAPA_ULTRA_HB_CHANNELS 48 #define IWM_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE 64 #define IWM_UCODE_TLV_CAPA_SHORT_PM_TIMEOUTS 65 @@ -4719,11 +4720,11 @@ enum { * 2 - 0x3f: maximal number of frames (up to 3f == 63) * @rs_table: array of rates for each TX try, each is rate_n_flags, * meaning it is a combination of IWM_RATE_MCS_* and IWM_RATE_*_PLCP - * @bf_params: beam forming params, currently not used + * @ss_params: single stream features. declare whether STBC or BFER are allowed. */ struct iwm_lq_cmd { uint8_t sta_id; - uint8_t reserved1; + uint8_t reduced_tpc; uint16_t control; /* LINK_QUAL_GENERAL_PARAMS_API_S_VER_1 */ uint8_t flags; @@ -4737,7 +4738,7 @@ struct iwm_lq_cmd { uint8_t agg_frame_cnt_limit; uint32_t reserved2; uint32_t rs_table[IWM_LQ_MAX_RETRY_NUM]; - uint32_t bf_params; + uint32_t ss_params; }; /* LINK_QUALITY_CMD_API_S_VER_1 */ /** @@ -5137,7 +5138,8 @@ struct iwm_tx_resp { uint8_t pa_integ_res_b[3]; uint8_t pa_integ_res_c[3]; uint16_t measurement_req_id; - uint16_t reserved; + uint8_t reduced_tpc; + uint8_t reserved; uint32_t tfd_info; uint16_t seq_ctl; @@ -5145,8 +5147,7 @@ struct iwm_tx_resp { uint8_t tlc_info; uint8_t ra_tid; uint16_t frame_ctrl; - - struct iwm_agg_tx_status status; + struct iwm_agg_tx_status status[]; } __packed; /* IWM_TX_RSP_API_S_VER_3 */ /** diff --git a/itlwm/hal_iwm/if_iwmvar.h b/itlwm/hal_iwm/if_iwmvar.h index 0ae7b539a..3d48b00fa 100644 --- a/itlwm/hal_iwm/if_iwmvar.h +++ b/itlwm/hal_iwm/if_iwmvar.h @@ -124,6 +124,8 @@ #include #include +#include "rs.h" + struct iwm_rx_radiotap_header { struct ieee80211_radiotap_header wr_ihdr; uint64_t wr_tsft; @@ -285,11 +287,12 @@ struct iwm_tx_data { int txmcs; int txrate; int totlen; - int data_type; + uint16_t fc; /* A-MPDU subframes */ int ampdu_txmcs; int ampdu_nframes; + struct ieee80211_tx_info info; }; struct iwm_tx_ring { @@ -489,6 +492,12 @@ struct iwm_rxq_dup_data { struct iwm_tx_ba { struct iwm_node * wn; + uint32_t rate_n_flags; + uint8_t lq_color; + uint16_t tx_time; + uint32_t tx_count_last; + uint32_t tx_count; + unsigned long tpt_meas_start; }; struct iwm_ba_task_data { @@ -655,6 +664,7 @@ struct iwm_softc { int sc_ltr_enabled; enum iwm_nvm_type nvm_type; int support_ldpc; + uint8_t non_shared_ant; int sc_mqrx_supported; int sc_integrated; @@ -687,6 +697,11 @@ struct iwm_softc { #define sc_txtap sc_txtapu.th int sc_txtap_len; #endif + union { + struct iwl_lq_sta_rs_fw rs_fw; + struct iwl_lq_sta rs_drv; + } lq_sta; + int tx_protection; }; struct iwm_node { diff --git a/itlwm/hal_iwm/mac80211.cpp b/itlwm/hal_iwm/mac80211.cpp index a3ef0f581..461720989 100644 --- a/itlwm/hal_iwm/mac80211.cpp +++ b/itlwm/hal_iwm/mac80211.cpp @@ -123,6 +123,7 @@ #include #include #include +#include "rs.h" #ifdef IWM_DEBUG int iwm_debug = 1; @@ -727,7 +728,7 @@ iwm_set_hw_address_8000(struct iwm_softc *sc, struct iwm_nvm_data *data, * values by -256dBm: practically 0 power and a non-feasible 8 bit value. */ int ItlIwm:: -iwm_get_signal_strength(struct iwm_softc *sc, struct iwm_rx_phy_info *phy_info) +iwm_get_signal_strength(struct iwm_softc *sc, struct ieee80211_rx_status *rx_status, struct iwm_rx_phy_info *phy_info) { int energy_a, energy_b, energy_c, max_energy; uint32_t val; @@ -745,11 +746,19 @@ iwm_get_signal_strength(struct iwm_softc *sc, struct iwm_rx_phy_info *phy_info) max_energy = MAX(energy_a, energy_b); max_energy = MAX(max_energy, energy_c); + rx_status->signal = max_energy; + rx_status->chains = (le16toh(phy_info->phy_flags) & + IWM_RX_RES_PHY_FLAGS_ANTENNA) + >> IWM_RX_RES_PHY_FLAGS_ANTENNA_POS; + rx_status->chain_signal[0] = energy_a; + rx_status->chain_signal[1] = energy_b; + rx_status->chain_signal[2] = energy_c; + return max_energy; } int ItlIwm:: -iwm_rxmq_get_signal_strength(struct iwm_softc *sc, +iwm_rxmq_get_signal_strength(struct iwm_softc *sc, struct ieee80211_rx_status *rx_status, uint32_t rate_n_flags, struct iwm_rx_mpdu_desc *desc) { int energy_a, energy_b; @@ -758,7 +767,13 @@ iwm_rxmq_get_signal_strength(struct iwm_softc *sc, energy_b = desc->v1.energy_b; energy_a = energy_a ? -energy_a : -256; energy_b = energy_b ? -energy_b : -256; - return MAX(energy_a, energy_b); + rx_status->signal = MAX(energy_a, energy_b); + rx_status->chains = (rate_n_flags & RATE_MCS_ANT_AB_MSK) >> RATE_MCS_ANT_POS; + rx_status->chain_signal[0] = energy_a; + rx_status->chain_signal[1] = energy_b; + rx_status->chain_signal[2] = S8_MIN; + + return rx_status->signal; } /* @@ -989,6 +1004,76 @@ static const char *iwm_get_agg_tx_status(u16 status) return "UNKNOWN"; } +#define IEEE80211_TX_MAX_RATES 4 + +static int ieee80211_tx_get_rates(struct iwm_softc *sc, + struct ieee80211_tx_info *info, + int *retry_count) +{ + int count = -1; + int i; + int max_report_rates = 1; + + for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { + if ((info->flags & IEEE80211_TX_CTL_AMPDU) && + !(info->flags & IEEE80211_TX_STAT_AMPDU)) { + /* just the first aggr frame carry status info */ + info->status.rates[i].idx = -1; + info->status.rates[i].count = 0; + break; + } else if (info->status.rates[i].idx < 0) { + break; + } else if (i >= max_report_rates) { + /* the HW cannot have attempted that rate */ + info->status.rates[i].idx = -1; + info->status.rates[i].count = 0; + break; + } + + count += info->status.rates[i].count; + } + + if (count < 0) + count = 0; + + *retry_count = count; + return i - 1; +} + +static void __ieee80211_tx_status(struct iwm_softc *sc, + struct ieee80211_tx_info *info, + int rates_idx, int retry_count, int tid, uint16_t fc, int ssn) +{ + bool acked; + bool noack_success; + + acked = !!(info->flags & IEEE80211_TX_STAT_ACK); + noack_success = !!(info->flags & + IEEE80211_TX_STAT_NOACK_TRANSMITTED); + + if ((info->flags & IEEE80211_TX_STAT_AMPDU_NO_BACK) && + (ieee80211_is_data_qos(fc))) { + + ieee80211_tx_compressed_bar(&sc->sc_ic, sc->sc_ic.ic_bss, tid, ssn); + XYLog("%s sending bar ssn=%d tid=%d\n", __FUNCTION__, ssn, tid); + } +} + +void ieee80211_tx_status(struct iwm_softc *sc, struct ieee80211_tx_info *info, int tid, uint16_t fc, int ssn) +{ + int rates_idx, retry_count; + + if (!info) + return; + + rates_idx = ieee80211_tx_get_rates(sc, info, &retry_count); + + rs_drv_mac80211_tx_status(sc, sc->sc_ic.ic_bss, info, tid, fc, ssn); + + if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP)) + __ieee80211_tx_status(sc, info, rates_idx, retry_count, tid, fc, ssn); +} + void ItlIwm:: iwm_ampdu_txq_advance(struct iwm_softc *sc, struct iwm_tx_ring *ring, int idx) { @@ -1008,14 +1093,90 @@ iwm_ampdu_txq_advance(struct iwm_softc *sc, struct iwm_tx_ring *ring, int idx) } } +void ItlIwm:: +iwm_tx_reclaim(struct iwm_softc *sc, struct ieee80211_tx_info *tx_info, int tid, int qid, int ssn, uint32_t rate, bool is_flush) +{ + XYLog("%s ssn %d\n", __FUNCTION__, ssn); + struct iwm_tx_data *txd; + int idx = IWM_AGG_SSN_TO_TXQ_IDX(ssn); + struct iwm_tx_ring *ring = &sc->txq[qid]; + struct iwm_tx_ba *tid_data = &sc->sc_tx_ba[tid]; + int freed = 0; + bool rs_update = false; + + /* pack lq color from tid_data along the reduced txp */ + tx_info->status.status_driver_data[0] = + RS_DRV_DATA_PACK(tid_data->lq_color, + tx_info->status.status_driver_data[0]); + tx_info->status.status_driver_data[1] = (void *)(uintptr_t)rate; + while (ring->tail != idx) { + txd = &ring->data[ring->tail]; + struct ieee80211_tx_info *info = &txd->info; + if (txd->m != NULL) { + rs_update = true; + iwm_reset_sched(sc, ring->qid, ring->tail, IWM_STATION_ID); + + memset(&info->status, 0, sizeof(info->status)); + /* Packet was transmitted successfully, failures come as single + * frames because before failing a frame the firmware transmits + * it without aggregation at least once. + */ + if (!is_flush) + info->flags |= IEEE80211_TX_STAT_ACK; + + if (!is_flush) { + if (ieee80211_is_data_qos(txd->fc)) + freed++; + else + WARN_ON_ONCE(tid != IWL_MAX_TID_COUNT); + } + + /* this is the first skb we deliver in this batch */ + /* put the rate scaling data there */ + if (freed == 1) { + info->flags |= IEEE80211_TX_STAT_AMPDU; + memcpy(&info->status, &tx_info->status, + sizeof(tx_info->status)); + iwl_mvm_hwrate_to_tx_status(rate, info); + } + + ieee80211_tx_status(sc, info, tid, txd->fc, ssn); + + iwm_txd_done(sc, txd); + ring->queued--; + } + ring->tail = (ring->tail + 1) % IWM_TX_RING_COUNT; + XYLog("%s tail %d\n", __FUNCTION__, ring->tail); + } + + /* We got a BA notif with 0 acked or scd_ssn didn't progress which is + * possible (i.e. first MPDU in the aggregation wasn't acked) + * Still it's important to update RS about sent vs. acked. + */ + if (!is_flush && !rs_update) { + tx_info->band = IEEE80211_IS_CHAN_2GHZ(sc->sc_ic.ic_bss->ni_chan) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ; + iwl_mvm_hwrate_to_tx_status(rate, tx_info); + XYLog("No reclaim. Update rs directly\n"); + iwl_mvm_rs_tx_status(sc, sc->sc_ic.ic_bss, tid, tx_info, false); + } +} + void ItlIwm:: iwm_ampdu_rate_control(struct iwm_softc *sc, struct ieee80211_node *ni, - struct iwm_tx_ring *ring, uint16_t seq, uint16_t ssn) + struct iwm_tx_ring *ring, uint16_t seq, uint16_t ssn, struct ieee80211_tx_info *tx_info, int tid, uint32_t rate_n_flags) { struct ieee80211com *ic = &sc->sc_ic; struct iwm_node *wn = (struct iwm_node *)ni; int idx, end_idx; - + struct iwm_tx_ba *tid_data = &sc->sc_tx_ba[tid]; + int freed = 0; + bool rs_update = false; + + /* pack lq color from tid_data along the reduced txp */ + tx_info->status.status_driver_data[0] = + RS_DRV_DATA_PACK(tid_data->lq_color, + tx_info->status.status_driver_data[0]); + tx_info->status.status_driver_data[1] = (void *)(uintptr_t)rate_n_flags; /* * Update Tx rate statistics for A-MPDUs before firmware's BA window. */ @@ -1023,25 +1184,48 @@ iwm_ampdu_rate_control(struct iwm_softc *sc, struct ieee80211_node *ni, end_idx = IWM_AGG_SSN_TO_TXQ_IDX(ssn); while (idx != end_idx) { struct iwm_tx_data *txdata = &ring->data[idx]; + struct ieee80211_tx_info *info = &txdata->info; - if (txdata->m != NULL && txdata->ampdu_nframes > 1) { - /* - * We can assume that this subframe has been ACKed - * because ACK failures come as single frames and - * before failing an A-MPDU subframe the firmware - * sends it as a single frame at least once. + if (txdata->m != NULL) { + rs_update = true; + + memset(&info->status, 0, sizeof(info->status)); + /* Packet was transmitted successfully, failures come as single + * frames because before failing a frame the firmware transmits + * it without aggregation at least once. */ - ieee80211_ra_add_stats_ht(&wn->in_rn, ic, ni, - txdata->ampdu_txmcs, 1, 0); - - /* Report this frame only once. */ - txdata->ampdu_nframes = 0; + info->flags |= IEEE80211_TX_STAT_ACK; + + if (ieee80211_is_data_qos(txdata->fc)) + freed++; + else + WARN_ON_ONCE(tid != IWL_MAX_TID_COUNT); + + /* this is the first skb we deliver in this batch */ + /* put the rate scaling data there */ + if (freed == 1) { + info->flags |= IEEE80211_TX_STAT_AMPDU; + memcpy(&info->status, &tx_info->status, + sizeof(tx_info->status)); + iwl_mvm_hwrate_to_tx_status(rate_n_flags, info); + } + + ieee80211_tx_status(sc, info, tid, txdata->fc, ssn); } idx = (idx + 1) % IWM_TX_RING_COUNT; } - iwm_ra_choose(sc, ni); + /* We got a BA notif with 0 acked or scd_ssn didn't progress which is + * possible (i.e. first MPDU in the aggregation wasn't acked) + * Still it's important to update RS about sent vs. acked. + */ + if (!rs_update) { + tx_info->band = IEEE80211_IS_CHAN_2GHZ(sc->sc_ic.ic_bss->ni_chan) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ; + iwl_mvm_hwrate_to_tx_status(rate_n_flags, tx_info); + DPRINTFN(3, ("No reclaim. Update rs directly\n")); + iwl_mvm_rs_tx_status(sc, sc->sc_ic.ic_bss, tid, tx_info, false); + } } void ItlIwm:: @@ -1100,6 +1284,8 @@ iwm_rx_tx_ba_notif(struct iwm_softc *sc, struct iwm_rx_packet *pkt, struct iwm_r int qid; struct ieee80211_node *ni = ic->ic_bss; struct iwm_node *in = (struct iwm_node *)ni; + struct iwm_tx_ba *tid_data; + struct ieee80211_tx_info ba_info = {}; DPRINTFN(3, ("TID = %d, SeqCtl = %d, bitmap = 0x%llx, scd_flow = %d, scd_ssn = %d sent:%d, acked:%d\n", ba_notif->tid, le16_to_cpu(ba_notif->seq_ctl), @@ -1140,13 +1326,23 @@ iwm_rx_tx_ba_notif(struct iwm_softc *sc, struct iwm_rx_packet *pkt, struct iwm_r */ ssn = le16toh(ba_notif->scd_ssn); - if (SEQ_LT(ssn, ba->ba_winstart)) - return; + /* pack lq color from tid_data along the reduced txp */ + tid_data = &sc->sc_tx_ba[ba_notif->tid]; + + ba_info.flags = IEEE80211_TX_STAT_AMPDU; + ba_info.status.ampdu_ack_len = ba_notif->txed_2_done; + ba_info.status.ampdu_len = ba_notif->txed; + ba_info.status.tx_time = tid_data->tx_time; + ba_info.status.status_driver_data[0] = + (void *)(uintptr_t)ba_notif->reduced_txp; +// if (SEQ_LT(ssn, ba->ba_winstart)) +// return; + /* Skip rate control if our Tx rate is fixed. */ if (ic->ic_fixed_mcs == -1) iwm_ampdu_rate_control(sc, ni, ring, - ba->ba_winstart, ssn); + ba->ba_winstart, ssn, &ba_info, ba_notif->tid, tid_data->rate_n_flags); /* * SSN corresponds to the first (perhaps not yet transmitted) frame @@ -1190,15 +1386,15 @@ iwm_ampdu_tx_done(struct iwm_softc *sc, struct iwm_cmd_header *cmd_hdr, int i; /* - * Collect information about this A-MPDU. - */ + * Collect information about this A-MPDU. + */ for (i = 0; i < nframes; i++) { uint8_t qid = agg_status[i].qid; uint8_t idx = agg_status[i].idx; uint16_t txstatus = (le16toh(agg_status[i].status) & IWM_AGG_TX_STATE_STATUS_MSK); - if (status != IWM_TX_STATUS_SUCCESS && txdata->data_type == IEEE80211_FC0_TYPE_MGT) { + if (status != IWM_TX_STATUS_SUCCESS && ieee80211_is_mgmt(txdata->fc)) { iwm_toggle_tx_ant(sc, &sc->sc_mgmt_last_antenna_idx); } @@ -1252,7 +1448,7 @@ iwm_ampdu_tx_done(struct iwm_softc *sc, struct iwm_cmd_header *cmd_hdr, /* Report the final single-frame Tx attempt. */ iwm_ht_single_rate_control(sc, ni, rate, initial_rate, - failure_frame, txfail); + failure_frame, txfail); } if (txfail) { @@ -1270,104 +1466,208 @@ iwm_ampdu_tx_done(struct iwm_softc *sc, struct iwm_cmd_header *cmd_hdr, iwm_clear_oactive(sc, txq); } +#define IWL_MVM_TX_RES_GET_TID(_ra_tid) ((_ra_tid) & 0x0f) +#define TX_RES_INIT_RATE_INDEX_MSK 0x0f +#define TX_RES_RATE_TABLE_COLOR_POS 4 +#define TX_RES_RATE_TABLE_COLOR_MSK 0x70 +#define TX_RES_INV_RATE_INDEX_MSK 0x80 +#define TX_RES_RATE_TABLE_COL_GET(_f) (((_f) & TX_RES_RATE_TABLE_COLOR_MSK) >>\ + TX_RES_RATE_TABLE_COLOR_POS) + +static inline struct iwm_agg_tx_status * +iwl_mvm_get_agg_status(struct iwm_softc *sc, void *tx_resp) +{ + return (struct iwm_agg_tx_status *)(((struct iwm_tx_resp *)tx_resp)->status); +} + +static inline u32 iwl_mvm_get_scd_ssn(struct iwm_softc *sc, + struct iwm_tx_resp *tx_resp) +{ + return le32_to_cpup((__le32 *)iwl_mvm_get_agg_status(sc, tx_resp) + + tx_resp->frame_count) & 0xfff; +} + void ItlIwm:: iwm_rx_tx_cmd_single(struct iwm_softc *sc, struct iwm_tx_resp *tx_resp, - struct iwm_node *in, int txmcs, int txrate, int qid) + int qid, int idx) { struct ieee80211com *ic = &sc->sc_ic; + struct iwm_node *in = (struct iwm_node *)ic->ic_bss; struct ieee80211_node *ni = &in->in_ni; struct _ifnet *ifp = IC2IFP(ic); - int status = le16toh(tx_resp->status.status) & IWM_TX_STATUS_MSK; + u32 status = le16toh(iwl_mvm_get_agg_status(sc, tx_resp)->status); + u16 ssn = iwl_mvm_get_scd_ssn(sc, tx_resp); + ssn = le32toh(ssn) & 0xfff; int txfail; + int tid = IWL_MVM_TX_RES_GET_TID(tx_resp->ra_tid); + struct iwm_tx_data *txd; + struct iwm_tx_ring *ring = &sc->txq[qid]; + struct iwm_tx_ba *tid_data = &sc->sc_tx_ba[tid]; + u8 skb_freed = 0; + u8 lq_color; - KASSERT(tx_resp->frame_count == 1, ""); - - txfail = (status != IWM_TX_STATUS_SUCCESS && - status != IWM_TX_STATUS_DIRECT_DONE); - - /* - * Update rate control statistics. - * Only report frames which were actually queued with the currently - * selected Tx rate. Because Tx queues are relatively long we may - * encounter previously selected rates here during Tx bursts. - * Providing feedback based on such frames can lead to suboptimal - * Tx rate control decisions. - */ - if ((ni->ni_flags & IEEE80211_NODE_HT) == 0) { - if (txrate != ni->ni_txrate) { - if (++in->lq_rate_mismatch > 15) { - /* Try to sync firmware with the driver... */ - iwm_setrates(in, 1); - in->lq_rate_mismatch = 0; - } - } else { - in->lq_rate_mismatch = 0; - - in->in_amn.amn_txcnt++; - if (txfail) - in->in_amn.amn_retrycnt++; - if (tx_resp->failure_frame > 0) - in->in_amn.amn_retrycnt++; - } - } else if (ic->ic_fixed_mcs == -1 && ic->ic_state == IEEE80211_S_RUN && - (le32toh(tx_resp->initial_rate) & IWM_RATE_MCS_HT_MSK)) { - uint32_t fw_txmcs = le32toh(tx_resp->initial_rate) & - (IWM_RATE_HT_MCS_RATE_CODE_MSK | IWM_RATE_HT_MCS_NSS_MSK); - /* Ignore Tx reports which don't match our last LQ command. */ - if (fw_txmcs != ni->ni_txmcs) { - if (++in->lq_rate_mismatch > 15) { - /* Try to sync firmware with the driver... */ - iwm_setrates(in, 1); - in->lq_rate_mismatch = 0; - } - } else { - int mcs = fw_txmcs; - const struct ieee80211_ra_rate *rs = - ieee80211_ra_get_rateset(&in->in_rn, ic, ni, fw_txmcs); - unsigned int retries = 0, i; - int old_txmcs = ni->ni_txmcs; - int old_bw = in->in_rn.bw; - int old_nss = in->in_rn.nss; - int old_sgi = in->in_rn.sgi; - - in->lq_rate_mismatch = 0; - - for (i = 0; i < tx_resp->failure_frame; i++) { - if (mcs > rs->min_mcs) { - ieee80211_ra_add_stats_ht(&in->in_rn, - ic, ni, mcs, 1, 1); - mcs--; - } else - retries++; - } - - if (txfail && tx_resp->failure_frame == 0) { - ieee80211_ra_add_stats_ht(&in->in_rn, ic, ni, - fw_txmcs, 1, 1); - } else { - ieee80211_ra_add_stats_ht(&in->in_rn, ic, ni, - mcs, retries + 1, retries); + while (ring->tail != idx) { + txd = &ring->data[ring->tail]; + struct ieee80211_tx_info *info = &txd->info; + bool flushed = false; + if (txd->m != NULL) { + skb_freed++; + + memset(&info->status, 0, sizeof(info->status)); + + /* inform mac80211 about what happened with the frame */ + switch (status & IWM_TX_STATUS_MSK) { + case IWM_TX_STATUS_SUCCESS: + case IWM_TX_STATUS_DIRECT_DONE: + info->flags |= IEEE80211_TX_STAT_ACK; + break; + case IWM_TX_STATUS_FAIL_FIFO_FLUSHED: + case IWM_TX_STATUS_FAIL_DRAIN_FLOW: + flushed = true; + break; + case IWM_TX_STATUS_FAIL_DEST_PS: + /* the FW should have stopped the queue and not + * return this status + */ + WARN_ON(1); + info->flags |= IEEE80211_TX_STAT_TX_FILTERED; + break; + default: + break; } - - ieee80211_ra_choose(&in->in_rn, ic, ni); - + + if ((status & IWM_TX_STATUS_MSK) != IWM_TX_STATUS_SUCCESS && + ieee80211_is_mgmt(txd->fc)) + iwm_toggle_tx_ant(sc, &sc->sc_mgmt_last_antenna_idx); + + /* + * If we are freeing multiple frames, mark all the frames + * but the first one as acked, since they were acknowledged + * before + * */ + if (skb_freed > 1) + info->flags |= IEEE80211_TX_STAT_ACK; + + info->status.rates[0].count = tx_resp->failure_frame + 1; + iwl_mvm_hwrate_to_tx_status(le32_to_cpu(tx_resp->initial_rate), + info); + info->status.status_driver_data[1] = + (void *)(uintptr_t)le32_to_cpu(tx_resp->initial_rate); + + /* Single frame failure in an AMPDU queue => send BAR */ + if (info->flags & IEEE80211_TX_CTL_AMPDU && + !(info->flags & IEEE80211_TX_STAT_ACK) && + !(info->flags & IEEE80211_TX_STAT_TX_FILTERED) && !flushed) + info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; + info->flags &= ~IEEE80211_TX_CTL_AMPDU; + /* - * If RA has chosen a new TX rate we must update - * the firmware's LQ rate table. - * ni_txmcs may change again before the task runs so - * cache the chosen rate in the iwm_node structure. + * TODO: this is not accurate if we are freeing more than one + * packet. */ - if (ni->ni_txmcs != old_txmcs || in->in_rn.bw != old_bw || in->in_rn.sgi != old_sgi || in->in_rn.nss != old_nss) - iwm_setrates(in, 1); + info->status.tx_time = + le16_to_cpu(tx_resp->wireless_media_time); + BUILD_BUG_ON(ARRAY_SIZE(info->status.status_driver_data) < 1); + lq_color = TX_RES_RATE_TABLE_COL_GET(tx_resp->tlc_info); + info->status.status_driver_data[0] = + RS_DRV_DATA_PACK(lq_color, tx_resp->reduced_tpc); + + ieee80211_tx_status(sc, info, tid, txd->fc, ssn); + + iwm_reset_sched(sc, ring->qid, ring->tail, IWM_STATION_ID); + iwm_txd_done(sc, txd); + ring->queued--; } + ring->tail = (ring->tail + 1) % IWM_TX_RING_COUNT; } - - if (txfail) { - XYLog("%s %d OUTPUT_ERROR status=%d\n", __FUNCTION__, __LINE__, status); - ifp->netStat->outputErrors++; - } else { - DPRINTFN(2, ("%s %d succeed status=%d\n", __FUNCTION__, __LINE__, status)); - } + +// status = status & IWM_TX_STATUS_MSK; +// txfail = (status != IWM_TX_STATUS_SUCCESS && +// status != IWM_TX_STATUS_DIRECT_DONE); +// +// /* +// * Update rate control statistics. +// * Only report frames which were actually queued with the currently +// * selected Tx rate. Because Tx queues are relatively long we may +// * encounter previously selected rates here during Tx bursts. +// * Providing feedback based on such frames can lead to suboptimal +// * Tx rate control decisions. +// */ +// if ((ni->ni_flags & IEEE80211_NODE_HT) == 0) { +// if (ring->data[idx].txrate != ni->ni_txrate) { +// if (++in->lq_rate_mismatch > 15) { +// /* Try to sync firmware with the driver... */ +// iwm_setrates(in, 1); +// in->lq_rate_mismatch = 0; +// } +// } else { +// in->lq_rate_mismatch = 0; +// +// in->in_amn.amn_txcnt++; +// if (txfail) +// in->in_amn.amn_retrycnt++; +// if (tx_resp->failure_frame > 0) +// in->in_amn.amn_retrycnt++; +// } +// } else if (ic->ic_fixed_mcs == -1 && ic->ic_state == IEEE80211_S_RUN && +// (le32toh(tx_resp->initial_rate) & IWM_RATE_MCS_HT_MSK)) { +// uint32_t fw_txmcs = le32toh(tx_resp->initial_rate) & +// (IWM_RATE_HT_MCS_RATE_CODE_MSK | IWM_RATE_HT_MCS_NSS_MSK); +// /* Ignore Tx reports which don't match our last LQ command. */ +// if (fw_txmcs != ni->ni_txmcs) { +// if (++in->lq_rate_mismatch > 15) { +// /* Try to sync firmware with the driver... */ +// iwm_setrates(in, 1); +// in->lq_rate_mismatch = 0; +// } +// } else { +// int mcs = fw_txmcs; +// const struct ieee80211_ra_rate *rs = +// ieee80211_ra_get_rateset(&in->in_rn, ic, ni, fw_txmcs); +// unsigned int retries = 0, i; +// int old_txmcs = ni->ni_txmcs; +// int old_bw = in->in_rn.bw; +// int old_nss = in->in_rn.nss; +// int old_sgi = in->in_rn.sgi; +// +// in->lq_rate_mismatch = 0; +// +// for (i = 0; i < tx_resp->failure_frame; i++) { +// if (mcs > rs->min_mcs) { +// ieee80211_ra_add_stats_ht(&in->in_rn, +// ic, ni, mcs, 1, 1); +// mcs--; +// } else +// retries++; +// } +// +// if (txfail && tx_resp->failure_frame == 0) { +// ieee80211_ra_add_stats_ht(&in->in_rn, ic, ni, +// fw_txmcs, 1, 1); +// } else { +// ieee80211_ra_add_stats_ht(&in->in_rn, ic, ni, +// mcs, retries + 1, retries); +// } +// +// ieee80211_ra_choose(&in->in_rn, ic, ni); +// +// /* +// * If RA has chosen a new TX rate we must update +// * the firmware's LQ rate table. +// * ni_txmcs may change again before the task runs so +// * cache the chosen rate in the iwm_node structure. +// */ +// if (ni->ni_txmcs != old_txmcs || in->in_rn.bw != old_bw || in->in_rn.sgi != old_sgi || in->in_rn.nss != old_nss) +// iwm_setrates(in, 1); +// } +// } +// +// if (txfail) { +// XYLog("%s %d OUTPUT_ERROR status=%d\n", __FUNCTION__, __LINE__, status); +// ifp->netStat->outputErrors++; +// } else { +// DPRINTFN(2, ("%s %d succeed status=%d\n", __FUNCTION__, __LINE__, status)); +// } } void ItlIwm:: @@ -1407,8 +1707,9 @@ iwm_txd_done(struct iwm_softc *sc, struct iwm_tx_data *txd) txd->ampdu_txmcs = 0; txd->txmcs = 0; txd->txrate = 0; - txd->data_type = 0; + txd->fc = 0; txd->ampdu_nframes = 0; + memset(&txd->info, 0, sizeof(struct ieee80211_tx_info)); } void ItlIwm:: @@ -1429,6 +1730,13 @@ iwm_clear_oactive(struct iwm_softc *sc, struct iwm_tx_ring *ring) } } +#define TX_RES_INIT_RATE_INDEX_MSK 0x0f +#define TX_RES_RATE_TABLE_COLOR_POS 4 +#define TX_RES_RATE_TABLE_COLOR_MSK 0x70 +#define TX_RES_INV_RATE_INDEX_MSK 0x80 +#define TX_RES_RATE_TABLE_COL_GET(_f) (((_f) & TX_RES_RATE_TABLE_COLOR_MSK) >>\ + TX_RES_RATE_TABLE_COLOR_POS) + void ItlIwm:: iwm_rx_tx_cmd(struct iwm_softc *sc, struct iwm_rx_packet *pkt, struct iwm_rx_data *data) @@ -1441,6 +1749,7 @@ iwm_rx_tx_cmd(struct iwm_softc *sc, struct iwm_rx_packet *pkt, struct iwm_tx_resp *tx_resp = (struct iwm_tx_resp *)pkt->data; uint32_t ssn; uint32_t len = iwm_rx_packet_len(pkt); + struct iwm_tx_ba *tid_data; bus_dmamap_sync(sc->sc_dmat, data->map, 0, IWM_RBUF_SIZE, BUS_DMASYNC_POSTREAD); @@ -1455,12 +1764,13 @@ iwm_rx_tx_cmd(struct iwm_softc *sc, struct iwm_rx_packet *pkt, if (qid > IWM_LAST_AGG_TX_QUEUE) return; if (sizeof(*tx_resp) + sizeof(ssn) + - tx_resp->frame_count * sizeof(tx_resp->status) > len) + tx_resp->frame_count * sizeof(struct iwm_agg_tx_status) > len) return; - if (tx_resp->frame_count > 1) + if (tx_resp->frame_count > 1) { for (int i = 0; i < tx_resp->frame_count; i++) { - u16 fstatus = le16_to_cpu((&tx_resp->status)[i].status); + struct iwm_agg_tx_status *frame_status = iwl_mvm_get_agg_status(sc, tx_resp); + u16 fstatus = le16_to_cpu(frame_status[i].status); DPRINTFN(3, ("status %s (0x%04x), try-count (%d) qid (%d) seq (0x%x)\n", iwm_get_agg_tx_status(fstatus), @@ -1468,33 +1778,41 @@ iwm_rx_tx_cmd(struct iwm_softc *sc, struct iwm_rx_packet *pkt, (fstatus & IWM_AGG_TX_STATE_TRY_CNT_MSK) >> IWM_AGG_TX_STATE_TRY_CNT_POS, qid, - le16_to_cpu((&tx_resp->status)[i].idx))); - } - - txd = &ring->data[idx]; - if (txd->m == NULL) + le16_to_cpu(frame_status[i].idx))); + } + int tid = cmd_hdr->qid - IWM_FIRST_AGG_TX_QUEUE; + if (tid < 0) + return; + tid_data = &sc->sc_tx_ba[tid]; + tid_data->lq_color = TX_RES_RATE_TABLE_COL_GET(tx_resp->tlc_info); + tid_data->tx_time = le16toh(tx_resp->wireless_media_time); + tid_data->rate_n_flags = le32toh(tx_resp->initial_rate); return; + } DPRINTFN(2, ("%s idx=%d qid=%d txd->txmcs=%d txd->txrate=%d, frame_count=%d len=%d\n", __FUNCTION__, idx, qid, txd->txmcs, txd->txrate, ((struct iwm_tx_resp *)pkt->data)->frame_count, ((struct iwm_tx_resp *)pkt->data)->byte_cnt)); + + iwm_rx_tx_cmd_single(sc, tx_resp, qid, idx); + iwm_clear_oactive(sc, ring); - memcpy(&ssn, &tx_resp->status + tx_resp->frame_count, sizeof(ssn)); - ssn = le32toh(ssn) & 0xfff; - if (qid >= IWM_FIRST_AGG_TX_QUEUE) { - int status; - status = le16toh(tx_resp->status.status) & IWM_TX_STATUS_MSK; - iwm_ampdu_tx_done(sc, cmd_hdr, txd->in, ring, - le32toh(tx_resp->initial_rate), tx_resp->frame_count, - tx_resp->failure_frame, ssn, status, &tx_resp->status); - } else { - /* - * Even though this is not an agg queue, we must only free - * frames before the firmware's starting sequence number. - */ - iwm_rx_tx_cmd_single(sc, tx_resp, txd->in, txd->txmcs, - txd->txrate, qid); - iwm_ampdu_txq_advance(sc, ring, IWM_AGG_SSN_TO_TXQ_IDX(ssn)); - iwm_clear_oactive(sc, ring); - } +// memcpy(&ssn, &tx_resp->status + tx_resp->frame_count, sizeof(ssn)); +// ssn = le32toh(ssn) & 0xfff; +// if (qid >= IWM_FIRST_AGG_TX_QUEUE) { +// int status; +// status = le16toh(tx_resp->status.status) & IWM_TX_STATUS_MSK; +// iwm_ampdu_tx_done(sc, cmd_hdr, txd->in, ring, +// le32toh(tx_resp->initial_rate), tx_resp->frame_count, +// tx_resp->failure_frame, ssn, status, &tx_resp->status); +// } else { +// /* +// * Even though this is not an agg queue, we must only free +// * frames before the firmware's starting sequence number. +// */ +// iwm_rx_tx_cmd_single(sc, tx_resp, txd->in, txd->txmcs, +// txd->txrate, qid); +// iwm_ampdu_txq_advance(sc, ring, IWM_AGG_SSN_TO_TXQ_IDX(ssn)); +// iwm_clear_oactive(sc, ring); +// } } void ItlIwm:: @@ -1848,7 +2166,8 @@ iwm_tx(struct iwm_softc *sc, mbuf_t m, struct ieee80211_node *ni, int ac) data->txrate = ni->ni_txrate; data->totlen = totlen; data->ampdu_txmcs = ni->ni_txmcs; - data->data_type = type; + memcpy(&data->fc, &wh->i_fc[0], sizeof(uint16_t)); + data->info.band = IEEE80211_IS_CHAN_2GHZ(ni->ni_chan) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ; DPRINTFN(3, ("sending data: 嘤嘤嘤 qid=%d idx=%d len=%d nsegs=%d txflags=0x%08x rate_n_flags=0x%08x rateidx=%u txmcs=%d ni_txrate=%d\n", ring->qid, ring->cur, totlen, nsegs, le32toh(tx->tx_flags), @@ -1894,7 +2213,7 @@ iwm_tx(struct iwm_softc *sc, mbuf_t m, struct ieee80211_node *ni, int ac) /* Mark TX ring as full if we reach a certain threshold. */ if (++ring->queued > IWM_TX_RING_HIMARK) { -// XYLog("%s sc->qfullmsk is FULL ring->cur=%d ring->queued=%d\n", __FUNCTION__, ring->cur, ring->queued); + XYLog("%s qid=%d sc->qfullmsk is FULL ring->cur=%d ring->queued=%d\n", __FUNCTION__, ring->qid, ring->cur, ring->queued); sc->qfullmsk |= 1 << ring->qid; } @@ -2286,6 +2605,12 @@ iwm_auth(struct iwm_softc *sc) duration = IEEE80211_DUR_TU; iwm_protect_session(sc, in, duration, in->in_ni.ni_intval / 2); + rs_drv_alloc_sta(sc, &in->in_ni); + + iwl_mvm_rs_rate_init(sc, ic->ic_bss, + IEEE80211_IS_CHAN_2GHZ(ic->ic_bss->ni_chan) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ, + false); + return 0; rm_binding: @@ -2377,6 +2702,7 @@ iwm_deauth(struct iwm_softc *sc) &ic->ic_channels[1], 1, 1, 0); if (err) return err; + rs_drv_free_sta(sc, &in->in_ni); return 0; } @@ -2504,7 +2830,11 @@ iwm_run(struct iwm_softc *sc) /* Start at lowest available bit-rate, AMRR will raise. */ in->in_ni.ni_txrate = 0; in->in_ni.ni_txmcs = 0; - iwm_setrates(in, 0); +// iwm_setrates(in, 0); + + iwl_mvm_rs_rate_init(sc, ic->ic_bss, + IEEE80211_IS_CHAN_2GHZ(ic->ic_bss->ni_chan) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ, + true); timeout_add_msec(&sc->sc_calib_to, 500); iwm_led_enable(sc); @@ -4562,6 +4892,9 @@ iwm_preinit(struct iwm_softc *sc) ieee80211_media_init(ifp); + iwm_rs_free(sc); + iwm_rs_alloc(sc); + return 0; } @@ -4694,6 +5027,7 @@ iwm_attach(struct iwm_softc *sc, struct pci_attach_args *pa) sc->sc_nvm_max_section_size = 16384; sc->nvm_type = IWM_NVM; sc->support_ldpc = 0; + sc->non_shared_ant = IWM_ANT_A; break; case PCI_PRODUCT_INTEL_WL_3165_1: case PCI_PRODUCT_INTEL_WL_3165_2: @@ -4704,6 +5038,7 @@ iwm_attach(struct iwm_softc *sc, struct pci_attach_args *pa) sc->sc_nvm_max_section_size = 16384; sc->nvm_type = IWM_NVM; sc->support_ldpc = 0; + sc->non_shared_ant = IWM_ANT_A; break; case PCI_PRODUCT_INTEL_WL_3168_1: sc->sc_fwname = "iwm-3168-29"; @@ -4713,6 +5048,7 @@ iwm_attach(struct iwm_softc *sc, struct pci_attach_args *pa) sc->sc_nvm_max_section_size = 16384; sc->nvm_type = IWM_NVM_SDP; sc->support_ldpc = 0; + sc->non_shared_ant = IWM_ANT_A; break; case PCI_PRODUCT_INTEL_WL_7260_1: case PCI_PRODUCT_INTEL_WL_7260_2: @@ -4723,6 +5059,7 @@ iwm_attach(struct iwm_softc *sc, struct pci_attach_args *pa) sc->sc_nvm_max_section_size = 16384; sc->nvm_type = IWM_NVM; sc->support_ldpc = 0; + sc->non_shared_ant = IWM_ANT_A; break; case PCI_PRODUCT_INTEL_WL_7265_1: case PCI_PRODUCT_INTEL_WL_7265_2: @@ -4733,6 +5070,7 @@ iwm_attach(struct iwm_softc *sc, struct pci_attach_args *pa) sc->sc_nvm_max_section_size = 16384; sc->nvm_type = IWM_NVM; sc->support_ldpc = 1; + sc->non_shared_ant = IWM_ANT_A; break; case PCI_PRODUCT_INTEL_WL_8260_1: case PCI_PRODUCT_INTEL_WL_8260_2: @@ -4743,6 +5081,7 @@ iwm_attach(struct iwm_softc *sc, struct pci_attach_args *pa) sc->sc_nvm_max_section_size = 32768; sc->nvm_type = IWM_NVM_EXT; sc->support_ldpc = 1; + sc->non_shared_ant = IWM_ANT_A; break; case PCI_PRODUCT_INTEL_WL_8265_1: sc->sc_fwname = "iwm-8265-36"; @@ -4752,6 +5091,7 @@ iwm_attach(struct iwm_softc *sc, struct pci_attach_args *pa) sc->sc_nvm_max_section_size = 32768; sc->nvm_type = IWM_NVM_EXT; sc->support_ldpc = 1; + sc->non_shared_ant = IWM_ANT_A; break; case PCI_PRODUCT_INTEL_WL_9260_1: sc->sc_fwname = "iwm-9260-46"; @@ -4761,6 +5101,7 @@ iwm_attach(struct iwm_softc *sc, struct pci_attach_args *pa) sc->sc_nvm_max_section_size = 32768; sc->sc_mqrx_supported = 1; sc->support_ldpc = 1; + sc->non_shared_ant = IWM_ANT_B; break; case PCI_PRODUCT_INTEL_WL_9560_1: case PCI_PRODUCT_INTEL_WL_9560_2: @@ -4787,6 +5128,7 @@ iwm_attach(struct iwm_softc *sc, struct pci_attach_args *pa) sc->sc_integrated = 1; sc->support_ldpc = 1; sc->sc_xtal_latency = 650; + sc->non_shared_ant = IWM_ANT_B; break; default: XYLog("%s: unknown adapter type\n", DEVNAME(sc)); @@ -4931,6 +5273,9 @@ iwm_attach(struct iwm_softc *sc, struct pci_attach_args *pa) ic->ic_ampdu_params = (IEEE80211_AMPDU_PARAM_SS_4 | 0x3 /* 64k */); ic->ic_caps |= (IEEE80211_C_QOS | IEEE80211_C_TX_AMPDU | IEEE80211_C_AMSDU_IN_AMPDU); ic->ic_caps |= IEEE80211_C_SUPPORTS_VHT_EXT_NSS_BW; +#if 0 + ic->ic_caps |= IEEE80211_C_TX_AMPDU_SETUP_IN_RS; +#endif ic->ic_sup_rates[IEEE80211_MODE_11A] = ieee80211_std_rateset_11a; ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b; @@ -5179,6 +5524,7 @@ iwm_ba_task(void *arg) struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[tid]; int qid = IWM_FIRST_AGG_TX_QUEUE + tid; struct iwm_tx_ring *ring = &sc->txq[qid]; + struct iwm_tx_ba *tx_ba; uint16_t ssn = ba->ba_winstart; if (sc->ba_tx.start_tidmask & (1 << tid)) { uint8_t fifo = iwm_ac_to_tx_fifo[tid_to_mac80211_ac[tid]]; @@ -5208,6 +5554,12 @@ iwm_ba_task(void *arg) ba->ba_bitmap = 0; if (!that->iwm_sta_tx_agg(sc, ni, tid, 0, ssn, 1)) { ieee80211_addba_resp_accept(ic, ni, tid); + sc->lq_sta.rs_drv.lq.agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF; + + XYLog("Tx aggregation enabled on ra = %s tid = %d\n", + ether_sprintf(ni->ni_macaddr), tid); + + iwl_mvm_send_lq_cmd(sc, &sc->lq_sta.rs_drv.lq); } else { out: ieee80211_addba_resp_refuse(ic, ni, tid, @@ -5219,6 +5571,17 @@ iwm_ba_task(void *arg) that->iwm_sta_tx_agg(sc, ni, tid, 0, 0, 0); that->iwm_ampdu_txq_advance(sc, ring, ring->cur); that->iwm_clear_oactive(sc, ring); + /* In DQA-mode the queue isn't removed on agg termination */ + tx_ba = &sc->sc_tx_ba[tid]; + sc->agg_tid_disable |= (1 << tid); + tx_ba->wn = NULL; + tx_ba->lq_color = 0; + tx_ba->rate_n_flags = 0; + tx_ba->tpt_meas_start = 0; + tx_ba->tx_count = 0; + tx_ba->tx_count_last = 0; + tx_ba->tx_time = 0; + ba->ba_bitmap = 0; sc->ba_tx.stop_tidmask &= ~(1 << tid); } } diff --git a/itlwm/hal_iwm/rs.cpp b/itlwm/hal_iwm/rs.cpp new file mode 100644 index 000000000..5cdc54134 --- /dev/null +++ b/itlwm/hal_iwm/rs.cpp @@ -0,0 +1,3685 @@ +// +// rs.cpp +// itlwm +// +// Created by zxystd on 2021/8/27. +// Copyright © 2021 钟先耀. All rights reserved. +// + +#include "ItlIwm.hpp" + +#define IWL_RATE_MAX_WINDOW 62 /* # tx in history window */ + +/* Calculations of success ratio are done in fixed point where 12800 is 100%. + * Use this macro when dealing with thresholds consts set as a percentage + */ +#define RS_PERCENT(x) (128 * x) + +static u8 rs_ht_to_legacy[] = { + [IWL_RATE_MCS_0_INDEX] = IWL_RATE_6M_INDEX, + [IWL_RATE_MCS_1_INDEX] = IWL_RATE_9M_INDEX, + [IWL_RATE_MCS_2_INDEX] = IWL_RATE_12M_INDEX, + [IWL_RATE_MCS_3_INDEX] = IWL_RATE_18M_INDEX, + [IWL_RATE_MCS_4_INDEX] = IWL_RATE_24M_INDEX, + [IWL_RATE_MCS_5_INDEX] = IWL_RATE_36M_INDEX, + [IWL_RATE_MCS_6_INDEX] = IWL_RATE_48M_INDEX, + [IWL_RATE_MCS_7_INDEX] = IWL_RATE_54M_INDEX, + [IWL_RATE_MCS_8_INDEX] = IWL_RATE_54M_INDEX, + [IWL_RATE_MCS_9_INDEX] = IWL_RATE_54M_INDEX, +}; + +static const u8 ant_toggle_lookup[] = { + [ANT_NONE] = ANT_NONE, + [ANT_A] = ANT_B, + [ANT_B] = ANT_A, + [ANT_AB] = ANT_AB, +}; + +#define IWL_DECLARE_RATE_INFO(r, s, rp, rn) \ + [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \ + IWL_RATE_HT_SISO_MCS_##s##_PLCP, \ + IWL_RATE_HT_MIMO2_MCS_##s##_PLCP, \ + IWL_RATE_VHT_SISO_MCS_##s##_PLCP, \ + IWL_RATE_VHT_MIMO2_MCS_##s##_PLCP,\ + IWL_RATE_##rp##M_INDEX, \ + IWL_RATE_##rn##M_INDEX } + +#define IWL_DECLARE_MCS_RATE(s) \ + [IWL_RATE_MCS_##s##_INDEX] = { IWL_RATE_INVM_PLCP, \ + IWL_RATE_HT_SISO_MCS_##s##_PLCP, \ + IWL_RATE_HT_MIMO2_MCS_##s##_PLCP, \ + IWL_RATE_VHT_SISO_MCS_##s##_PLCP, \ + IWL_RATE_VHT_MIMO2_MCS_##s##_PLCP, \ + IWL_RATE_INVM_INDEX, \ + IWL_RATE_INVM_INDEX } + +/* + * Parameter order: + * rate, ht rate, prev rate, next rate + * + * If there isn't a valid next or previous rate then INV is used which + * maps to IWL_RATE_INVALID + * + */ +static const struct iwl_rs_rate_info iwl_rates[IWL_RATE_COUNT] = { + IWL_DECLARE_RATE_INFO(1, INV, INV, 2), /* 1mbps */ + IWL_DECLARE_RATE_INFO(2, INV, 1, 5), /* 2mbps */ + IWL_DECLARE_RATE_INFO(5, INV, 2, 11), /*5.5mbps */ + IWL_DECLARE_RATE_INFO(11, INV, 9, 12), /* 11mbps */ + IWL_DECLARE_RATE_INFO(6, 0, 5, 11), /* 6mbps ; MCS 0 */ + IWL_DECLARE_RATE_INFO(9, INV, 6, 11), /* 9mbps */ + IWL_DECLARE_RATE_INFO(12, 1, 11, 18), /* 12mbps ; MCS 1 */ + IWL_DECLARE_RATE_INFO(18, 2, 12, 24), /* 18mbps ; MCS 2 */ + IWL_DECLARE_RATE_INFO(24, 3, 18, 36), /* 24mbps ; MCS 3 */ + IWL_DECLARE_RATE_INFO(36, 4, 24, 48), /* 36mbps ; MCS 4 */ + IWL_DECLARE_RATE_INFO(48, 5, 36, 54), /* 48mbps ; MCS 5 */ + IWL_DECLARE_RATE_INFO(54, 6, 48, INV), /* 54mbps ; MCS 6 */ + IWL_DECLARE_MCS_RATE(7), /* MCS 7 */ + IWL_DECLARE_MCS_RATE(8), /* MCS 8 */ + IWL_DECLARE_MCS_RATE(9), /* MCS 9 */ +}; + +enum rs_action { + RS_ACTION_STAY = 0, + RS_ACTION_DOWNSCALE = -1, + RS_ACTION_UPSCALE = 1, +}; + +enum rs_column_mode { + RS_INVALID = 0, + RS_LEGACY, + RS_SISO, + RS_MIMO2, +}; + +#define MAX_NEXT_COLUMNS 7 +#define MAX_COLUMN_CHECKS 3 + +struct rs_tx_column; + +typedef bool (*allow_column_func_t) (struct iwm_softc *sc, + struct ieee80211_node *ni, + struct rs_rate *rate, + const struct rs_tx_column *next_col); + +struct rs_tx_column { + enum rs_column_mode mode; + u8 ant; + bool sgi; + enum rs_column next_columns[MAX_NEXT_COLUMNS]; + allow_column_func_t checks[MAX_COLUMN_CHECKS]; +}; + +static bool iwl_mvm_bt_coex_is_ant_avail(struct iwm_softc *sc, u8 ant) +{ + /* there is no other antenna, shared antenna is always available */ +// if (mvm->cfg->bt_shared_single_ant) +// return true; +// +// if (ant & mvm->cfg->non_shared_ant) +// return true; +// +// return le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) < +// BT_HIGH_TRAFFIC; + // TODO: IMP + return true; +} + +static bool rs_ant_allow(struct iwm_softc *sc, struct ieee80211_node *ni, + struct rs_rate *rate, + const struct rs_tx_column *next_col) +{ + return iwl_mvm_bt_coex_is_ant_avail(sc, next_col->ant); +} + +static bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwm_softc *sc, struct ieee80211_node *ni) +{ + //TODO: IMP + return true; +} + +static bool rs_mimo_allow(struct iwm_softc *sc, struct ieee80211_node *ni, + struct rs_rate *rate, + const struct rs_tx_column *next_col) +{ + ItlIwm *that = container_of(sc, ItlIwm, com); + + if (!ieee80211_node_supports_ht(ni)) + return false; + +// if (sta->smps_mode == IEEE80211_SMPS_STATIC) +// return false; + + if (num_of_ant(that->iwm_fw_valid_tx_ant(sc)) < 2) + return false; + + if (!iwl_mvm_bt_coex_is_mimo_allowed(sc, ni)) + return false; + + if (sc->sc_nvm.sku_cap_mimo_disable) + return false; + + return true; +} + +static bool rs_siso_allow(struct iwm_softc *sc, struct ieee80211_node *ni, + struct rs_rate *rate, + const struct rs_tx_column *next_col) +{ + if (!ieee80211_node_supports_ht(ni)) + return false; + + return true; +} + +static bool rs_sgi_allow(struct iwm_softc *sc, struct ieee80211_node *ni, + struct rs_rate *rate, + const struct rs_tx_column *next_col) +{ + if (is_ht20(rate) && (ieee80211_node_supports_ht_sgi20(ni))) + return true; + if (is_ht40(rate) && (ieee80211_node_supports_ht_sgi40(ni))) + return true; + if (is_ht80(rate) && (ieee80211_node_supports_vht_sgi80(ni))) + return true; + if (is_ht160(rate) && (ieee80211_node_supports_vht_sgi160(ni))) + return true; + + return false; +} + +static const struct rs_tx_column rs_tx_columns[] = { + [RS_COLUMN_LEGACY_ANT_A] = { + .mode = RS_LEGACY, + .ant = ANT_A, + .next_columns = { + RS_COLUMN_LEGACY_ANT_B, + RS_COLUMN_SISO_ANT_A, + RS_COLUMN_MIMO2, + RS_COLUMN_INVALID, + RS_COLUMN_INVALID, + RS_COLUMN_INVALID, + RS_COLUMN_INVALID, + }, + .checks = { + rs_ant_allow, + }, + }, + [RS_COLUMN_LEGACY_ANT_B] = { + .mode = RS_LEGACY, + .ant = ANT_B, + .next_columns = { + RS_COLUMN_LEGACY_ANT_A, + RS_COLUMN_SISO_ANT_B, + RS_COLUMN_MIMO2, + RS_COLUMN_INVALID, + RS_COLUMN_INVALID, + RS_COLUMN_INVALID, + RS_COLUMN_INVALID, + }, + .checks = { + rs_ant_allow, + }, + }, + [RS_COLUMN_SISO_ANT_A] = { + .mode = RS_SISO, + .ant = ANT_A, + .next_columns = { + RS_COLUMN_SISO_ANT_B, + RS_COLUMN_MIMO2, + RS_COLUMN_SISO_ANT_A_SGI, + RS_COLUMN_LEGACY_ANT_A, + RS_COLUMN_LEGACY_ANT_B, + RS_COLUMN_INVALID, + RS_COLUMN_INVALID, + }, + .checks = { + rs_siso_allow, + rs_ant_allow, + }, + }, + [RS_COLUMN_SISO_ANT_B] = { + .mode = RS_SISO, + .ant = ANT_B, + .next_columns = { + RS_COLUMN_SISO_ANT_A, + RS_COLUMN_MIMO2, + RS_COLUMN_SISO_ANT_B_SGI, + RS_COLUMN_LEGACY_ANT_A, + RS_COLUMN_LEGACY_ANT_B, + RS_COLUMN_INVALID, + RS_COLUMN_INVALID, + }, + .checks = { + rs_siso_allow, + rs_ant_allow, + }, + }, + [RS_COLUMN_SISO_ANT_A_SGI] = { + .mode = RS_SISO, + .ant = ANT_A, + .sgi = true, + .next_columns = { + RS_COLUMN_SISO_ANT_B_SGI, + RS_COLUMN_MIMO2_SGI, + RS_COLUMN_SISO_ANT_A, + RS_COLUMN_LEGACY_ANT_A, + RS_COLUMN_LEGACY_ANT_B, + RS_COLUMN_INVALID, + RS_COLUMN_INVALID, + }, + .checks = { + rs_siso_allow, + rs_ant_allow, + rs_sgi_allow, + }, + }, + [RS_COLUMN_SISO_ANT_B_SGI] = { + .mode = RS_SISO, + .ant = ANT_B, + .sgi = true, + .next_columns = { + RS_COLUMN_SISO_ANT_A_SGI, + RS_COLUMN_MIMO2_SGI, + RS_COLUMN_SISO_ANT_B, + RS_COLUMN_LEGACY_ANT_A, + RS_COLUMN_LEGACY_ANT_B, + RS_COLUMN_INVALID, + RS_COLUMN_INVALID, + }, + .checks = { + rs_siso_allow, + rs_ant_allow, + rs_sgi_allow, + }, + }, + [RS_COLUMN_MIMO2] = { + .mode = RS_MIMO2, + .ant = ANT_AB, + .next_columns = { + RS_COLUMN_SISO_ANT_A, + RS_COLUMN_MIMO2_SGI, + RS_COLUMN_LEGACY_ANT_A, + RS_COLUMN_LEGACY_ANT_B, + RS_COLUMN_INVALID, + RS_COLUMN_INVALID, + RS_COLUMN_INVALID, + }, + .checks = { + rs_mimo_allow, + }, + }, + [RS_COLUMN_MIMO2_SGI] = { + .mode = RS_MIMO2, + .ant = ANT_AB, + .sgi = true, + .next_columns = { + RS_COLUMN_SISO_ANT_A_SGI, + RS_COLUMN_MIMO2, + RS_COLUMN_LEGACY_ANT_A, + RS_COLUMN_LEGACY_ANT_B, + RS_COLUMN_INVALID, + RS_COLUMN_INVALID, + RS_COLUMN_INVALID, + }, + .checks = { + rs_mimo_allow, + rs_sgi_allow, + }, + }, +}; + +static inline u8 rs_extract_rate(u32 rate_n_flags) +{ + /* also works for HT because bits 7:6 are zero there */ + return (u8)(rate_n_flags & RATE_LEGACY_RATE_MSK); +} + +static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags) +{ + int idx = 0; + + if (rate_n_flags & RATE_MCS_HT_MSK) { + idx = rate_n_flags & RATE_HT_MCS_RATE_CODE_MSK; + idx += IWL_RATE_MCS_0_INDEX; + + /* skip 9M not supported in HT*/ + if (idx >= IWL_RATE_9M_INDEX) + idx += 1; + if ((idx >= IWL_FIRST_HT_RATE) && (idx <= IWL_LAST_HT_RATE)) + return idx; + } else if (rate_n_flags & RATE_MCS_VHT_MSK || + rate_n_flags & RATE_MCS_HE_MSK) { + idx = rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK; + idx += IWL_RATE_MCS_0_INDEX; + + /* skip 9M not supported in VHT*/ + if (idx >= IWL_RATE_9M_INDEX) + idx++; + if ((idx >= IWL_FIRST_VHT_RATE) && (idx <= IWL_LAST_VHT_RATE)) + return idx; + if ((rate_n_flags & RATE_MCS_HE_MSK) && + (idx <= IWL_LAST_HE_RATE)) + return idx; + } else { + /* legacy rate format, search for match in table */ + + u8 legacy_rate = rs_extract_rate(rate_n_flags); + for (idx = 0; idx < ARRAY_SIZE(iwl_rates); idx++) + if (iwl_rates[idx].plcp == legacy_rate) + return idx; + } + + return IWL_RATE_INVALID; +} + +static void rs_rate_scale_perform(struct iwm_softc *sc, + struct ieee80211_node *ni, + struct iwl_lq_sta *lq_sta, + int tid, bool ndp); +static void rs_fill_lq_cmd(struct iwm_softc *sc, + struct ieee80211_node *ni, + struct iwl_lq_sta *lq_sta, + const struct rs_rate *initial_rate); +static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search); + +/* + * The following tables contain the expected throughput metrics for all rates + * + * 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 60 MBits + * + * where invalid entries are zeros. + * + * CCK rates are only valid in legacy table and will only be used in G + * (2.4 GHz) band. + */ +static const u16 expected_tpt_legacy[IWL_RATE_COUNT] = { + 7, 13, 35, 58, 40, 57, 72, 98, 121, 154, 177, 186, 0, 0, 0 +}; + +/* Expected TpT tables. 4 indexes: + * 0 - NGI, 1 - SGI, 2 - AGG+NGI, 3 - AGG+SGI + */ +static const u16 expected_tpt_siso_20MHz[4][IWL_RATE_COUNT] = { + {0, 0, 0, 0, 42, 0, 76, 102, 124, 159, 183, 193, 202, 216, 0}, + {0, 0, 0, 0, 46, 0, 82, 110, 132, 168, 192, 202, 210, 225, 0}, + {0, 0, 0, 0, 49, 0, 97, 145, 192, 285, 375, 420, 464, 551, 0}, + {0, 0, 0, 0, 54, 0, 108, 160, 213, 315, 415, 465, 513, 608, 0}, +}; + +static const u16 expected_tpt_siso_40MHz[4][IWL_RATE_COUNT] = { + {0, 0, 0, 0, 77, 0, 127, 160, 184, 220, 242, 250, 257, 269, 275}, + {0, 0, 0, 0, 83, 0, 135, 169, 193, 229, 250, 257, 264, 275, 280}, + {0, 0, 0, 0, 101, 0, 199, 295, 389, 570, 744, 828, 911, 1070, 1173}, + {0, 0, 0, 0, 112, 0, 220, 326, 429, 629, 819, 912, 1000, 1173, 1284}, +}; + +static const u16 expected_tpt_siso_80MHz[4][IWL_RATE_COUNT] = { + {0, 0, 0, 0, 130, 0, 191, 223, 244, 273, 288, 294, 298, 305, 308}, + {0, 0, 0, 0, 138, 0, 200, 231, 251, 279, 293, 298, 302, 308, 312}, + {0, 0, 0, 0, 217, 0, 429, 634, 834, 1220, 1585, 1760, 1931, 2258, 2466}, + {0, 0, 0, 0, 241, 0, 475, 701, 921, 1343, 1741, 1931, 2117, 2468, 2691}, +}; + +static const u16 expected_tpt_siso_160MHz[4][IWL_RATE_COUNT] = { + {0, 0, 0, 0, 191, 0, 244, 288, 298, 308, 313, 318, 323, 328, 330}, + {0, 0, 0, 0, 200, 0, 251, 293, 302, 312, 317, 322, 327, 332, 334}, + {0, 0, 0, 0, 439, 0, 875, 1307, 1736, 2584, 3419, 3831, 4240, 5049, 5581}, + {0, 0, 0, 0, 488, 0, 972, 1451, 1925, 2864, 3785, 4240, 4691, 5581, 6165}, +}; + +static const u16 expected_tpt_mimo2_20MHz[4][IWL_RATE_COUNT] = { + {0, 0, 0, 0, 74, 0, 123, 155, 179, 213, 235, 243, 250, 261, 0}, + {0, 0, 0, 0, 81, 0, 131, 164, 187, 221, 242, 250, 256, 267, 0}, + {0, 0, 0, 0, 98, 0, 193, 286, 375, 550, 718, 799, 878, 1032, 0}, + {0, 0, 0, 0, 109, 0, 214, 316, 414, 607, 790, 879, 965, 1132, 0}, +}; + +static const u16 expected_tpt_mimo2_40MHz[4][IWL_RATE_COUNT] = { + {0, 0, 0, 0, 123, 0, 182, 214, 235, 264, 279, 285, 289, 296, 300}, + {0, 0, 0, 0, 131, 0, 191, 222, 242, 270, 284, 289, 293, 300, 303}, + {0, 0, 0, 0, 200, 0, 390, 571, 741, 1067, 1365, 1505, 1640, 1894, 2053}, + {0, 0, 0, 0, 221, 0, 430, 630, 816, 1169, 1490, 1641, 1784, 2053, 2221}, +}; + +static const u16 expected_tpt_mimo2_80MHz[4][IWL_RATE_COUNT] = { + {0, 0, 0, 0, 182, 0, 240, 264, 278, 299, 308, 311, 313, 317, 319}, + {0, 0, 0, 0, 190, 0, 247, 269, 282, 302, 310, 313, 315, 319, 320}, + {0, 0, 0, 0, 428, 0, 833, 1215, 1577, 2254, 2863, 3147, 3418, 3913, 4219}, + {0, 0, 0, 0, 474, 0, 920, 1338, 1732, 2464, 3116, 3418, 3705, 4225, 4545}, +}; + +static const u16 expected_tpt_mimo2_160MHz[4][IWL_RATE_COUNT] = { + {0, 0, 0, 0, 240, 0, 278, 308, 313, 319, 322, 324, 328, 330, 334}, + {0, 0, 0, 0, 247, 0, 282, 310, 315, 320, 323, 325, 329, 332, 338}, + {0, 0, 0, 0, 875, 0, 1735, 2582, 3414, 5043, 6619, 7389, 8147, 9629, 10592}, + {0, 0, 0, 0, 971, 0, 1925, 2861, 3779, 5574, 7304, 8147, 8976, 10592, 11640}, +}; + +/* mbps, mcs */ +static const struct iwl_rate_mcs_info iwl_rate_mcs[IWL_RATE_COUNT] = { + { "1", "BPSK DSSS"}, + { "2", "QPSK DSSS"}, + {"5.5", "BPSK CCK"}, + { "11", "QPSK CCK"}, + { "6", "BPSK 1/2"}, + { "9", "BPSK 1/2"}, + { "12", "QPSK 1/2"}, + { "18", "QPSK 3/4"}, + { "24", "16QAM 1/2"}, + { "36", "16QAM 3/4"}, + { "48", "64QAM 2/3"}, + { "54", "64QAM 3/4"}, + { "60", "64QAM 5/6"}, +}; + +#define MCS_INDEX_PER_STREAM (8) + +static const char *rs_pretty_ant(u8 ant) +{ + static const char * const ant_name[] = { + [ANT_NONE] = "None", + [ANT_A] = "A", + [ANT_B] = "B", + [ANT_AB] = "AB", + [ANT_C] = "C", + [ANT_AC] = "AC", + [ANT_BC] = "BC", + [ANT_ABC] = "ABC", + }; + + if (ant > ANT_ABC) + return "UNKNOWN"; + + return ant_name[ant]; +} + +static const char *rs_pretty_lq_type(enum iwl_table_type type) +{ + static const char * const lq_types[] = { + [LQ_NONE] = "NONE", + [LQ_LEGACY_A] = "LEGACY_A", + [LQ_LEGACY_G] = "LEGACY_G", + [LQ_HT_SISO] = "HT SISO", + [LQ_HT_MIMO2] = "HT MIMO", + [LQ_VHT_SISO] = "VHT SISO", + [LQ_VHT_MIMO2] = "VHT MIMO", + [LQ_HE_SISO] = "HE SISO", + [LQ_HE_MIMO2] = "HE MIMO", + }; + + if (type < LQ_NONE || type >= LQ_MAX) + return "UNKNOWN"; + + return lq_types[type]; +} + +static char *rs_pretty_rate(const struct rs_rate *rate) +{ + static char buf[40]; + static const char * const legacy_rates[] = { + [IWL_RATE_1M_INDEX] = "1M", + [IWL_RATE_2M_INDEX] = "2M", + [IWL_RATE_5M_INDEX] = "5.5M", + [IWL_RATE_11M_INDEX] = "11M", + [IWL_RATE_6M_INDEX] = "6M", + [IWL_RATE_9M_INDEX] = "9M", + [IWL_RATE_12M_INDEX] = "12M", + [IWL_RATE_18M_INDEX] = "18M", + [IWL_RATE_24M_INDEX] = "24M", + [IWL_RATE_36M_INDEX] = "36M", + [IWL_RATE_48M_INDEX] = "48M", + [IWL_RATE_54M_INDEX] = "54M", + }; + static const char *const ht_vht_rates[] = { + [IWL_RATE_MCS_0_INDEX] = "MCS0", + [IWL_RATE_MCS_1_INDEX] = "MCS1", + [IWL_RATE_MCS_2_INDEX] = "MCS2", + [IWL_RATE_MCS_3_INDEX] = "MCS3", + [IWL_RATE_MCS_4_INDEX] = "MCS4", + [IWL_RATE_MCS_5_INDEX] = "MCS5", + [IWL_RATE_MCS_6_INDEX] = "MCS6", + [IWL_RATE_MCS_7_INDEX] = "MCS7", + [IWL_RATE_MCS_8_INDEX] = "MCS8", + [IWL_RATE_MCS_9_INDEX] = "MCS9", + }; + const char *rate_str; + + if (is_type_legacy(rate->type) && (rate->index <= IWL_RATE_54M_INDEX)) + rate_str = legacy_rates[rate->index]; + else if ((is_type_ht(rate->type) || is_type_vht(rate->type)) && + (rate->index >= IWL_RATE_MCS_0_INDEX) && + (rate->index <= IWL_RATE_MCS_9_INDEX)) + rate_str = ht_vht_rates[rate->index]; + else + rate_str = "BAD_RATE"; + + snprintf(buf, sizeof(buf), "(%s|%s|%s)", rs_pretty_lq_type(rate->type), + rs_pretty_ant(rate->ant), rate_str); + return buf; +} + +static inline void rs_dump_rate(struct iwm_softc *sc, const struct rs_rate *rate, + const char *prefix) +{ + IWL_DEBUG_RATE(sc, + "%s: %s BW: %d SGI: %d LDPC: %d STBC: %d\n", + prefix, rs_pretty_rate(rate), rate->bw, + rate->sgi, rate->ldpc, rate->stbc); +} + +static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window) +{ + window->data = 0; + window->success_counter = 0; + window->success_ratio = IWL_INVALID_VALUE; + window->counter = 0; + window->average_tpt = IWL_INVALID_VALUE; +} + +static void rs_rate_scale_clear_tbl_windows(struct iwm_softc *sc, + struct iwl_scale_tbl_info *tbl) +{ + int i; + + IWL_DEBUG_RATE(sc, "Clearing up window stats\n"); + for (i = 0; i < IWL_RATE_COUNT; i++) + rs_rate_scale_clear_window(&tbl->win[i]); + + for (i = 0; i < ARRAY_SIZE(tbl->tpc_win); i++) + rs_rate_scale_clear_window(&tbl->tpc_win[i]); +} + +static inline u8 rs_is_valid_ant(u8 valid_antenna, u8 ant_type) +{ + return (ant_type & valid_antenna) == ant_type; +} + +extern int ieee80211_can_use_ampdu(struct ieee80211com *, + struct ieee80211_node *); + +static int rs_tl_turn_on_agg_for_tid(struct iwm_softc *sc, + struct iwl_lq_sta *lq_data, u8 tid, + struct ieee80211_node *ni) +{ + IWL_DEBUG_RATE(sc, "Starting Tx agg: STA: %s tid: %d\n", + ether_sprintf(ni->ni_macaddr), tid); + + /* start BA session until the peer sends del BA */ + if (!ieee80211_can_use_ampdu(&sc->sc_ic, ni)) + return -1; + ieee80211_node_trigger_addba_req(ni, tid); + return 0; +} + +static void rs_tl_turn_on_agg(struct iwm_softc *sc, + u8 tid, struct iwl_lq_sta *lq_sta, + struct ieee80211_node *ni) +{ +#if 0 + struct iwm_tx_ba *tid_data; + struct ieee80211_tx_ba *tx_ba; + + /* + * In AP mode, tid can be equal to IWL_MAX_TID_COUNT + * when the frame is not QoS + */ + if (WARN_ON_ONCE(tid > IWL_MAX_TID_COUNT)) { + IWL_ERR(mvm, "tid exceeds max TID count: %d/%d\n", + tid, IWL_MAX_TID_COUNT); + return; + } else if (tid == IWL_MAX_TID_COUNT) { + return; + } + + tx_ba = &sc->sc_ic.ic_bss->ni_tx_ba[tid]; + tid_data = &sc->sc_tx_ba[tid]; + if (sc->sc_ic.ic_state >= IEEE80211_S_RUN && + tx_ba->ba_state == IEEE80211_BA_INIT && + (lq_sta->tx_agg_tid_en & BIT(tid)) && + tid_data->tx_count_last >= IWL_MVM_RS_AGG_START_THRESHOLD) { + IWL_DEBUG_RATE(mvm, "try to aggregate tid %d\n", tid); + rs_tl_turn_on_agg_for_tid(sc, lq_sta, tid, ni); + } +#else + ; +#endif +} + +static inline int get_num_of_ant_from_rate(u32 rate_n_flags) +{ + return !!(rate_n_flags & RATE_MCS_ANT_A_MSK) + + !!(rate_n_flags & RATE_MCS_ANT_B_MSK) + + !!(rate_n_flags & RATE_MCS_ANT_C_MSK); +} + +/* + * Static function to get the expected throughput from an iwl_scale_tbl_info + * that wraps a NULL pointer check + */ +static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index) +{ + if (tbl->expected_tpt) + return tbl->expected_tpt[rs_index]; + return 0; +} + +/* + * rs_collect_tx_data - Update the success/failure sliding window + * + * We keep a sliding window of the last 62 packets transmitted + * at this rate. window->data contains the bitmask of successful + * packets. + */ +static int _rs_collect_tx_data(struct iwm_softc *sc, + struct iwl_scale_tbl_info *tbl, + int scale_index, int attempts, int successes, + struct iwl_rate_scale_data *window) +{ + static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1)); + s32 fail_count, tpt; + + /* Get expected throughput */ + tpt = get_expected_tpt(tbl, scale_index); + + /* + * Keep track of only the latest 62 tx frame attempts in this rate's + * history window; anything older isn't really relevant any more. + * If we have filled up the sliding window, drop the oldest attempt; + * if the oldest attempt (highest bit in bitmap) shows "success", + * subtract "1" from the success counter (this is the main reason + * we keep these bitmaps!). + */ + while (attempts > 0) { + if (window->counter >= IWL_RATE_MAX_WINDOW) { + /* remove earliest */ + window->counter = IWL_RATE_MAX_WINDOW - 1; + + if (window->data & mask) { + window->data &= ~mask; + window->success_counter--; + } + } + + /* Increment frames-attempted counter */ + window->counter++; + + /* Shift bitmap by one frame to throw away oldest history */ + window->data <<= 1; + + /* Mark the most recent #successes attempts as successful */ + if (successes > 0) { + window->success_counter++; + window->data |= 0x1; + successes--; + } + + attempts--; + } + + /* Calculate current success ratio, avoid divide-by-0! */ + if (window->counter > 0) + window->success_ratio = 128 * (100 * window->success_counter) + / window->counter; + else + window->success_ratio = IWL_INVALID_VALUE; + + fail_count = window->counter - window->success_counter; + + /* Calculate average throughput, if we have enough history. */ + if ((fail_count >= IWL_MVM_RS_RATE_MIN_FAILURE_TH) || + (window->success_counter >= IWL_MVM_RS_RATE_MIN_SUCCESS_TH)) + window->average_tpt = (window->success_ratio * tpt + 64) / 128; + else + window->average_tpt = IWL_INVALID_VALUE; + + return 0; +} + +static int rs_collect_tpc_data(struct iwm_softc *sc, + struct iwl_lq_sta *lq_sta, + struct iwl_scale_tbl_info *tbl, + int scale_index, int attempts, int successes, + u8 reduced_txp) +{ + struct iwl_rate_scale_data *window = NULL; + + if (WARN_ON_ONCE(reduced_txp > TPC_MAX_REDUCTION)) + return -EINVAL; + + window = &tbl->tpc_win[reduced_txp]; + return _rs_collect_tx_data(sc, tbl, scale_index, attempts, successes, + window); +} + +static void rs_update_tid_tpt_stats(struct iwm_softc *sc, + u8 tid, int successes) +{ + if (tid >= IWL_MAX_TID_COUNT) + return; + + struct iwm_tx_ba *tid_data = &sc->sc_tx_ba[tid]; + struct ieee80211_tx_ba *tx_ba = &sc->sc_ic.ic_bss->ni_tx_ba[tid]; + + /* + * Measure if there're enough successful transmits per second. + * These statistics are used only to decide if we can start a + * BA session, so it should be updated only when A-MPDU is + * off. + */ + if (tx_ba->ba_state != IEEE80211_BA_INIT) + return; + + if (time_is_before_jiffies(tid_data->tpt_meas_start + hz) || + (tid_data->tx_count >= IWL_MVM_RS_AGG_START_THRESHOLD)) { + tid_data->tx_count_last = tid_data->tx_count; + tid_data->tx_count = 0; + tid_data->tpt_meas_start = ticks; + } else { + tid_data->tx_count += successes; + } +} + +static int rs_collect_tlc_data(struct iwm_softc *sc, + u8 tid, + struct iwl_scale_tbl_info *tbl, + int scale_index, int attempts, int successes) +{ + struct iwl_rate_scale_data *window = NULL; + + if (scale_index < 0 || scale_index >= IWL_RATE_COUNT) + return -EINVAL; + + if (tbl->column != RS_COLUMN_INVALID) { + struct lq_sta_pers *pers = &sc->lq_sta.rs_drv.pers; + + pers->tx_stats[tbl->column][scale_index].total += attempts; + pers->tx_stats[tbl->column][scale_index].success += successes; + } + + rs_update_tid_tpt_stats(sc, tid, successes); + + /* Select window for current tx bit rate */ + window = &(tbl->win[scale_index]); + return _rs_collect_tx_data(sc, tbl, scale_index, attempts, successes, + window); +} + +/* Convert rs_rate object into ucode rate bitmask */ +static u32 ucode_rate_from_rs_rate(struct iwm_softc *sc, + struct rs_rate *rate) +{ + u32 ucode_rate = 0; + int index = rate->index; + + ucode_rate |= ((rate->ant << RATE_MCS_ANT_POS) & + RATE_MCS_ANT_ABC_MSK); + + if (is_legacy(rate)) { + ucode_rate |= iwl_rates[index].plcp; + if (index >= IWL_FIRST_CCK_RATE && index <= IWL_LAST_CCK_RATE) + ucode_rate |= RATE_MCS_CCK_MSK; + return ucode_rate; + } + + /* set RTS protection for all non legacy rates + * This helps with congested environments reducing the conflict cost to + * RTS retries only, instead of the entire BA packet. + */ + ucode_rate |= RATE_MCS_RTS_REQUIRED_MSK; + + if (is_ht(rate)) { + if (index < IWL_FIRST_HT_RATE || index > IWL_LAST_HT_RATE) { + IWL_ERR(mvm, "Invalid HT rate index %d\n", index); + index = IWL_LAST_HT_RATE; + } + ucode_rate |= RATE_MCS_HT_MSK; + + if (is_ht_siso(rate)) + ucode_rate |= iwl_rates[index].plcp_ht_siso; + else if (is_ht_mimo2(rate)) + ucode_rate |= iwl_rates[index].plcp_ht_mimo2; + else + WARN_ON_ONCE(1); + } else if (is_vht(rate)) { + if (index < IWL_FIRST_VHT_RATE || index > IWL_LAST_VHT_RATE) { + IWL_ERR(mvm, "Invalid VHT rate index %d\n", index); + index = IWL_LAST_VHT_RATE; + } + ucode_rate |= RATE_MCS_VHT_MSK; + if (is_vht_siso(rate)) + ucode_rate |= iwl_rates[index].plcp_vht_siso; + else if (is_vht_mimo2(rate)) + ucode_rate |= iwl_rates[index].plcp_vht_mimo2; + else + WARN_ON_ONCE(1); + + } else { + IWL_ERR(mvm, "Invalid rate->type %d\n", rate->type); + } + + if (is_siso(rate) && rate->stbc) { + /* To enable STBC we need to set both a flag and ANT_AB */ + ucode_rate |= RATE_MCS_ANT_AB_MSK; + ucode_rate |= RATE_MCS_STBC_MSK; + } + + ucode_rate |= rate->bw; + if (rate->sgi) + ucode_rate |= RATE_MCS_SGI_MSK; + if (rate->ldpc) + ucode_rate |= RATE_MCS_LDPC_MSK; + + return ucode_rate; +} + +/* Convert a ucode rate into an rs_rate object */ +static int rs_rate_from_ucode_rate(const u32 ucode_rate, + enum nl80211_band band, + struct rs_rate *rate) +{ + u32 ant_msk = ucode_rate & RATE_MCS_ANT_ABC_MSK; + u8 num_of_ant = get_num_of_ant_from_rate(ucode_rate); + u8 nss; + + memset(rate, 0, sizeof(*rate)); + rate->index = iwl_hwrate_to_plcp_idx(ucode_rate); + + if (rate->index == IWL_RATE_INVALID) + return -EINVAL; + + rate->ant = (ant_msk >> RATE_MCS_ANT_POS); + + /* Legacy */ + if (!(ucode_rate & RATE_MCS_HT_MSK) && + !(ucode_rate & RATE_MCS_VHT_MSK) && + !(ucode_rate & RATE_MCS_HE_MSK)) { + if (num_of_ant == 1) { + if (band == NL80211_BAND_5GHZ) + rate->type = LQ_LEGACY_A; + else + rate->type = LQ_LEGACY_G; + } + + return 0; + } + + /* HT, VHT or HE */ + if (ucode_rate & RATE_MCS_SGI_MSK) + rate->sgi = true; + if (ucode_rate & RATE_MCS_LDPC_MSK) + rate->ldpc = true; + if (ucode_rate & RATE_MCS_STBC_MSK) + rate->stbc = true; + if (ucode_rate & RATE_MCS_BF_MSK) + rate->bfer = true; + + rate->bw = ucode_rate & RATE_MCS_CHAN_WIDTH_MSK; + + if (ucode_rate & RATE_MCS_HT_MSK) { + nss = ((ucode_rate & RATE_HT_MCS_NSS_MSK) >> + RATE_HT_MCS_NSS_POS) + 1; + + if (nss == 1) { + rate->type = LQ_HT_SISO; + WARN_ON(!rate->stbc && !rate->bfer && num_of_ant != 1, + "stbc %d bfer %d", + rate->stbc, rate->bfer); + } else if (nss == 2) { + rate->type = LQ_HT_MIMO2; + WARN_ON_ONCE(num_of_ant != 2); + } else { + WARN_ON_ONCE(1); + } + } else if (ucode_rate & RATE_MCS_VHT_MSK) { + nss = ((ucode_rate & RATE_VHT_MCS_NSS_MSK) >> + RATE_VHT_MCS_NSS_POS) + 1; + + if (nss == 1) { + rate->type = LQ_VHT_SISO; + WARN_ON(!rate->stbc && !rate->bfer && num_of_ant != 1, + "stbc %d bfer %d", + rate->stbc, rate->bfer); + } else if (nss == 2) { + rate->type = LQ_VHT_MIMO2; + WARN_ON_ONCE(num_of_ant != 2); + } else { + WARN_ON_ONCE(1); + } + } else if (ucode_rate & RATE_MCS_HE_MSK) { + nss = ((ucode_rate & RATE_VHT_MCS_NSS_MSK) >> + RATE_VHT_MCS_NSS_POS) + 1; + + if (nss == 1) { + rate->type = LQ_HE_SISO; + WARN_ON(!rate->stbc && !rate->bfer && num_of_ant != 1, + "stbc %d bfer %d", rate->stbc, rate->bfer); + } else if (nss == 2) { + rate->type = LQ_HE_MIMO2; + WARN_ON_ONCE(num_of_ant != 2); + } else { + WARN_ON_ONCE(1); + } + } + + WARN_ON_ONCE(rate->bw == RATE_MCS_CHAN_WIDTH_80 && + !is_he(rate) && !is_vht(rate)); + + return 0; +} + +/* switch to another antenna/antennas and return 1 */ +/* if no other valid antenna found, return 0 */ +static int rs_toggle_antenna(u32 valid_ant, struct rs_rate *rate) +{ + u8 new_ant_type; + + if (!rate->ant || WARN_ON_ONCE(rate->ant & ANT_C)) + return 0; + + if (!rs_is_valid_ant(valid_ant, rate->ant)) + return 0; + + new_ant_type = ant_toggle_lookup[rate->ant]; + + while ((new_ant_type != rate->ant) && + !rs_is_valid_ant(valid_ant, new_ant_type)) + new_ant_type = ant_toggle_lookup[new_ant_type]; + + if (new_ant_type == rate->ant) + return 0; + + rate->ant = new_ant_type; + + return 1; +} + +static u16 rs_get_supported_rates(struct iwl_lq_sta *lq_sta, + struct rs_rate *rate) +{ + if (is_legacy(rate)) + return lq_sta->active_legacy_rate; + else if (is_siso(rate)) + return lq_sta->active_siso_rate; + else if (is_mimo2(rate)) + return lq_sta->active_mimo2_rate; + + WARN_ON_ONCE(1); + return 0; +} + +static u16 rs_get_adjacent_rate(struct iwm_softc *sc, u8 index, u16 rate_mask, + int rate_type) +{ + u8 high = IWL_RATE_INVALID; + u8 low = IWL_RATE_INVALID; + + /* 802.11A or ht walks to the next literal adjacent rate in + * the rate table */ + if (is_type_a_band(rate_type) || !is_type_legacy(rate_type)) { + int i; + u32 mask; + + /* Find the previous rate that is in the rate mask */ + i = index - 1; + if (i >= 0) + mask = BIT(i); + for (; i >= 0; i--, mask >>= 1) { + if (rate_mask & mask) { + low = i; + break; + } + } + + /* Find the next rate that is in the rate mask */ + i = index + 1; + for (mask = (1 << i); i < IWL_RATE_COUNT; i++, mask <<= 1) { + if (rate_mask & mask) { + high = i; + break; + } + } + + return (high << 8) | low; + } + + low = index; + while (low != IWL_RATE_INVALID) { + low = iwl_rates[low].prev_rs; + if (low == IWL_RATE_INVALID) + break; + if (rate_mask & (1 << low)) + break; + } + + high = index; + while (high != IWL_RATE_INVALID) { + high = iwl_rates[high].next_rs; + if (high == IWL_RATE_INVALID) + break; + if (rate_mask & (1 << high)) + break; + } + + return (high << 8) | low; +} + +static inline bool rs_rate_supported(struct iwl_lq_sta *lq_sta, + struct rs_rate *rate) +{ + return BIT(rate->index) & rs_get_supported_rates(lq_sta, rate); +} + +/* Get the next supported lower rate in the current column. + * Return true if bottom rate in the current column was reached + */ +static bool rs_get_lower_rate_in_column(struct iwl_lq_sta *lq_sta, + struct rs_rate *rate) +{ + u8 low; + u16 high_low; + u16 rate_mask; + struct iwm_softc *sc = lq_sta->pers.drv; + + rate_mask = rs_get_supported_rates(lq_sta, rate); + high_low = rs_get_adjacent_rate(sc, rate->index, rate_mask, + rate->type); + low = high_low & 0xff; + + /* Bottom rate of column reached */ + if (low == IWL_RATE_INVALID) + return true; + + rate->index = low; + return false; +} + +/* Get the next rate to use following a column downgrade */ +static void rs_get_lower_rate_down_column(struct iwl_lq_sta *lq_sta, + struct rs_rate *rate) +{ + struct iwm_softc *sc = lq_sta->pers.drv; + ItlIwm *that = container_of(sc, ItlIwm, com); + + if (is_legacy(rate)) { + /* No column to downgrade from Legacy */ + return; + } else if (is_siso(rate)) { + /* Downgrade to Legacy if we were in SISO */ + if (lq_sta->band == NL80211_BAND_5GHZ) + rate->type = LQ_LEGACY_A; + else + rate->type = LQ_LEGACY_G; + + rate->bw = RATE_MCS_CHAN_WIDTH_20; + + WARN_ON_ONCE(rate->index < IWL_RATE_MCS_0_INDEX || + rate->index > IWL_RATE_MCS_9_INDEX); + + rate->index = rs_ht_to_legacy[rate->index]; + rate->ldpc = false; + } else { + /* Downgrade to SISO with same MCS if in MIMO */ + rate->type = is_vht_mimo2(rate) ? + LQ_VHT_SISO : LQ_HT_SISO; + } + + if (num_of_ant(rate->ant) > 1) + rate->ant = first_antenna(that->iwm_fw_valid_tx_ant(sc)); + + /* Relevant in both switching to SISO or Legacy */ + rate->sgi = false; + + if (!rs_rate_supported(lq_sta, rate)) + rs_get_lower_rate_in_column(lq_sta, rate); +} + +/* Check if both rates share the same column */ +static inline bool rs_rate_column_match(struct rs_rate *a, + struct rs_rate *b) +{ + bool ant_match; + + if (a->stbc || a->bfer) + ant_match = (b->ant == ANT_A || b->ant == ANT_B); + else + ant_match = (a->ant == b->ant); + + return (a->type == b->type) && (a->bw == b->bw) && (a->sgi == b->sgi) + && ant_match; +} + +static inline enum rs_column rs_get_column_from_rate(struct rs_rate *rate) +{ + if (is_legacy(rate)) { + if (rate->ant == ANT_A) + return RS_COLUMN_LEGACY_ANT_A; + + if (rate->ant == ANT_B) + return RS_COLUMN_LEGACY_ANT_B; + + goto err; + } + + if (is_siso(rate)) { + if (rate->ant == ANT_A || rate->stbc || rate->bfer) + return rate->sgi ? RS_COLUMN_SISO_ANT_A_SGI : + RS_COLUMN_SISO_ANT_A; + + if (rate->ant == ANT_B) + return rate->sgi ? RS_COLUMN_SISO_ANT_B_SGI : + RS_COLUMN_SISO_ANT_B; + + goto err; + } + + if (is_mimo(rate)) + return rate->sgi ? RS_COLUMN_MIMO2_SGI : RS_COLUMN_MIMO2; + +err: + return RS_COLUMN_INVALID; +} + +/* + * mac80211 sends us Tx status + */ +void rs_drv_mac80211_tx_status(struct iwm_softc *sc, + struct ieee80211_node *sta, + struct ieee80211_tx_info *info, int tid, uint16_t fc, int ssn) +{ + if (!ieee80211_is_data(fc) || + info->flags & IEEE80211_TX_CTL_NO_ACK) + return; + + iwl_mvm_rs_tx_status(sc, sta, tid, info, + false); +} + +/* + * Begin a period of staying with a selected modulation mode. + * Set "stay_in_tbl" flag to prevent any mode switches. + * Set frame tx success limits according to legacy vs. high-throughput, + * and reset overall (spanning all rates) tx success history statistics. + * These control how long we stay using same modulation mode before + * searching for a new mode. + */ +static void rs_set_stay_in_table(struct iwm_softc *mvm, u8 is_legacy, + struct iwl_lq_sta *lq_sta) +{ + IWL_DEBUG_RATE(mvm, "Moving to RS_STATE_STAY_IN_COLUMN\n"); + lq_sta->rs_state = RS_STATE_STAY_IN_COLUMN; + if (is_legacy) { + lq_sta->table_count_limit = IWL_MVM_RS_LEGACY_TABLE_COUNT; + lq_sta->max_failure_limit = IWL_MVM_RS_LEGACY_FAILURE_LIMIT; + lq_sta->max_success_limit = IWL_MVM_RS_LEGACY_SUCCESS_LIMIT; + } else { + lq_sta->table_count_limit = IWL_MVM_RS_NON_LEGACY_TABLE_COUNT; + lq_sta->max_failure_limit = IWL_MVM_RS_NON_LEGACY_FAILURE_LIMIT; + lq_sta->max_success_limit = IWL_MVM_RS_NON_LEGACY_SUCCESS_LIMIT; + } + lq_sta->table_count = 0; + lq_sta->total_failed = 0; + lq_sta->total_success = 0; + lq_sta->flush_timer = ticks; + lq_sta->visited_columns = 0; +} + +static inline int rs_get_max_rate_from_mask(unsigned long rate_mask) +{ + if (rate_mask) + return find_last_bit(&rate_mask, BITS_PER_LONG); + return IWL_RATE_INVALID; +} + +static int rs_get_max_allowed_rate(struct iwl_lq_sta *lq_sta, + const struct rs_tx_column *column) +{ + switch (column->mode) { + case RS_LEGACY: + return lq_sta->max_legacy_rate_idx; + case RS_SISO: + return lq_sta->max_siso_rate_idx; + case RS_MIMO2: + return lq_sta->max_mimo2_rate_idx; + default: + WARN_ON_ONCE(1); + } + + return lq_sta->max_legacy_rate_idx; +} + +static const u16 *rs_get_expected_tpt_table(struct iwl_lq_sta *lq_sta, + const struct rs_tx_column *column, + u32 bw) +{ + /* Used to choose among HT tables */ + const u16 (*ht_tbl_pointer)[IWL_RATE_COUNT]; + + if (WARN_ON_ONCE(column->mode != RS_LEGACY && + column->mode != RS_SISO && + column->mode != RS_MIMO2)) + return expected_tpt_legacy; + + /* Legacy rates have only one table */ + if (column->mode == RS_LEGACY) + return expected_tpt_legacy; + + ht_tbl_pointer = expected_tpt_mimo2_20MHz; + /* Choose among many HT tables depending on number of streams + * (SISO/MIMO2), channel width (20/40/80), SGI, and aggregation + * status */ + if (column->mode == RS_SISO) { + switch (bw) { + case RATE_MCS_CHAN_WIDTH_20: + ht_tbl_pointer = expected_tpt_siso_20MHz; + break; + case RATE_MCS_CHAN_WIDTH_40: + ht_tbl_pointer = expected_tpt_siso_40MHz; + break; + case RATE_MCS_CHAN_WIDTH_80: + ht_tbl_pointer = expected_tpt_siso_80MHz; + break; + case RATE_MCS_CHAN_WIDTH_160: + ht_tbl_pointer = expected_tpt_siso_160MHz; + break; + default: + WARN_ON_ONCE(1); + } + } else if (column->mode == RS_MIMO2) { + switch (bw) { + case RATE_MCS_CHAN_WIDTH_20: + ht_tbl_pointer = expected_tpt_mimo2_20MHz; + break; + case RATE_MCS_CHAN_WIDTH_40: + ht_tbl_pointer = expected_tpt_mimo2_40MHz; + break; + case RATE_MCS_CHAN_WIDTH_80: + ht_tbl_pointer = expected_tpt_mimo2_80MHz; + break; + case RATE_MCS_CHAN_WIDTH_160: + ht_tbl_pointer = expected_tpt_mimo2_160MHz; + break; + default: + WARN_ON_ONCE(1); + } + } else { + WARN_ON_ONCE(1); + } + + if (!column->sgi && !lq_sta->is_agg) /* Normal */ + return ht_tbl_pointer[0]; + else if (column->sgi && !lq_sta->is_agg) /* SGI */ + return ht_tbl_pointer[1]; + else if (!column->sgi && lq_sta->is_agg) /* AGG */ + return ht_tbl_pointer[2]; + else /* AGG+SGI */ + return ht_tbl_pointer[3]; +} + +static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta, + struct iwl_scale_tbl_info *tbl) +{ + struct rs_rate *rate = &tbl->rate; + const struct rs_tx_column *column = &rs_tx_columns[tbl->column]; + + tbl->expected_tpt = rs_get_expected_tpt_table(lq_sta, column, rate->bw); +} + +/* rs uses two tables, one is active and the second is for searching better + * configuration. This function, according to the index of the currently + * active table returns the search table, which is located at the + * index complementary to 1 according to the active table (active = 1, + * search = 0 or active = 0, search = 1). + * Since lq_info is an arary of size 2, make sure index cannot be out of bounds. + */ +static inline u8 rs_search_tbl(u8 active_tbl) +{ + return (active_tbl ^ 1) & 1; +} + +static s32 rs_get_best_rate(struct iwm_softc *sc, + struct iwl_lq_sta *lq_sta, + struct iwl_scale_tbl_info *tbl, /* "search" */ + unsigned long rate_mask, s8 index) +{ + struct iwl_scale_tbl_info *active_tbl = + &(lq_sta->lq_info[lq_sta->active_tbl]); + s32 success_ratio = active_tbl->win[index].success_ratio; + u16 expected_current_tpt = active_tbl->expected_tpt[index]; + const u16 *tpt_tbl = tbl->expected_tpt; + u16 high_low; + u32 target_tpt; + int rate_idx; + + if (success_ratio >= RS_PERCENT(IWL_MVM_RS_SR_NO_DECREASE)) { + target_tpt = 100 * expected_current_tpt; + IWL_DEBUG_RATE(mvm, + "SR %d high. Find rate exceeding EXPECTED_CURRENT %d\n", + success_ratio, target_tpt); + } else { + target_tpt = lq_sta->last_tpt; + IWL_DEBUG_RATE(mvm, + "SR %d not that good. Find rate exceeding ACTUAL_TPT %d\n", + success_ratio, target_tpt); + } + + rate_idx = find_first_bit(&rate_mask, BITS_PER_LONG); + + while (rate_idx != IWL_RATE_INVALID) { + if (target_tpt < (100 * tpt_tbl[rate_idx])) + break; + + high_low = rs_get_adjacent_rate(sc, rate_idx, rate_mask, + tbl->rate.type); + + rate_idx = (high_low >> 8) & 0xff; + } + + IWL_DEBUG_RATE(mvm, "Best rate found %d target_tp %d expected_new %d\n", + rate_idx, target_tpt, + rate_idx != IWL_RATE_INVALID ? + 100 * tpt_tbl[rate_idx] : IWL_INVALID_VALUE); + + return rate_idx; +} + +static u32 rs_bw_from_sta_bw(struct ieee80211_node *ni) +{ + struct ieee80211_vht_cap vht_cap = { + .vht_cap_info = cpu_to_le32(ni->ni_vhtcaps), + .supp_mcs = ni->ni_vht_mcsinfo, + }; + + switch (ni->ni_chw) { + case IEEE80211_CHAN_WIDTH_160: + /* + * Don't use 160 MHz if VHT extended NSS support + * says we cannot use 2 streams, we don't want to + * deal with this. + * We only check MCS 0 - they will support that if + * we got here at all and we don't care which MCS, + * we want to determine a more global state. + */ + if (ieee80211_get_vht_max_nss(&vht_cap, + IEEE80211_VHT_CHANWIDTH_160MHZ, + 0, true, + ni->ni_rx_nss) < ni->ni_rx_nss) + return RATE_MCS_CHAN_WIDTH_80; + return RATE_MCS_CHAN_WIDTH_160; + case IEEE80211_CHAN_WIDTH_80: + return RATE_MCS_CHAN_WIDTH_80; + case IEEE80211_CHAN_WIDTH_40: + return RATE_MCS_CHAN_WIDTH_40; + case IEEE80211_CHAN_WIDTH_20: + default: + return RATE_MCS_CHAN_WIDTH_20; + } +} + +/* + * Check whether we should continue using same modulation mode, or + * begin search for a new mode, based on: + * 1) # tx successes or failures while using this mode + * 2) # times calling this function + * 3) elapsed time in this mode (not used, for now) + */ +static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search) +{ + struct iwl_scale_tbl_info *tbl; + int active_tbl; + int flush_interval_passed = 0; + struct iwm_softc *sc; + + sc = lq_sta->pers.drv; + active_tbl = lq_sta->active_tbl; + + tbl = &(lq_sta->lq_info[active_tbl]); + + /* If we've been disallowing search, see if we should now allow it */ + if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN) { + /* Elapsed time using current modulation mode */ + if (lq_sta->flush_timer) + flush_interval_passed = + time_after(ticks, + (unsigned long)(lq_sta->flush_timer + + (IWL_MVM_RS_STAY_IN_COLUMN_TIMEOUT * hz))); + + /* + * Check if we should allow search for new modulation mode. + * If many frames have failed or succeeded, or we've used + * this same modulation for a long time, allow search, and + * reset history stats that keep track of whether we should + * allow a new search. Also (below) reset all bitmaps and + * stats in active history. + */ + if (force_search || + (lq_sta->total_failed > lq_sta->max_failure_limit) || + (lq_sta->total_success > lq_sta->max_success_limit) || + ((!lq_sta->search_better_tbl) && + (lq_sta->flush_timer) && (flush_interval_passed))) { + IWL_DEBUG_RATE(mvm, + "LQ: stay is expired %d %d %d\n", + lq_sta->total_failed, + lq_sta->total_success, + flush_interval_passed); + + /* Allow search for new mode */ + lq_sta->rs_state = RS_STATE_SEARCH_CYCLE_STARTED; + IWL_DEBUG_RATE(mvm, + "Moving to RS_STATE_SEARCH_CYCLE_STARTED\n"); + lq_sta->total_failed = 0; + lq_sta->total_success = 0; + lq_sta->flush_timer = 0; + /* mark the current column as visited */ + lq_sta->visited_columns = BIT(tbl->column); + /* + * Else if we've used this modulation mode enough repetitions + * (regardless of elapsed time or success/failure), reset + * history bitmaps and rate-specific stats for all rates in + * active table. + */ + } else { + lq_sta->table_count++; + if (lq_sta->table_count >= + lq_sta->table_count_limit) { + lq_sta->table_count = 0; + + IWL_DEBUG_RATE(sc, + "LQ: stay in table clear win\n"); + rs_rate_scale_clear_tbl_windows(sc, tbl); + } + } + + /* If transitioning to allow "search", reset all history + * bitmaps and stats in active table (this will become the new + * "search" table). */ + if (lq_sta->rs_state == RS_STATE_SEARCH_CYCLE_STARTED) { + rs_rate_scale_clear_tbl_windows(sc, tbl); + } + } +} + +static void rs_set_amsdu_len(struct iwm_softc *sc, struct ieee80211_node *ni, + struct iwl_scale_tbl_info *tbl, + enum rs_action scale_action) +{ +// struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); +// int i; +// +// sta->max_amsdu_len = rs_fw_get_max_amsdu_len(sta); +// +// /* +// * In case TLC offload is not active amsdu_enabled is either 0xFFFF +// * or 0, since there is no per-TID alg. +// */ +// if ((!is_vht(&tbl->rate) && !is_ht(&tbl->rate)) || +// tbl->rate.index < IWL_RATE_MCS_5_INDEX || +// scale_action == RS_ACTION_DOWNSCALE) +// mvmsta->amsdu_enabled = 0; +// else +// mvmsta->amsdu_enabled = 0xFFFF; +// +// if (mvmsta->vif->bss_conf.he_support && +// !iwlwifi_mod_params.disable_11ax) +// mvmsta->max_amsdu_len = sta->max_amsdu_len; +// else +// mvmsta->max_amsdu_len = min_t(int, sta->max_amsdu_len, 8500); +// +// sta->max_rc_amsdu_len = mvmsta->max_amsdu_len; +// +// for (i = 0; i < IWL_MAX_TID_COUNT; i++) { +// if (mvmsta->amsdu_enabled) +// sta->max_tid_amsdu_len[i] = +// iwl_mvm_max_amsdu_size(mvm, sta, i); +// else +// /* +// * Not so elegant, but this will effectively +// * prevent AMSDU on this TID +// */ +// sta->max_tid_amsdu_len[i] = 1; +// } + // TODO: IMP +} + +/** + * iwl_mvm_send_lq_cmd() - Send link quality command + * @mvm: Driver data. + * @lq: Link quality command to send. + * + * The link quality command is sent as the last step of station creation. + * This is the special case in which init is set and we call a callback in + * this case to clear the state indicating that station creation is in + * progress. + */ +int iwl_mvm_send_lq_cmd(struct iwm_softc *sc, struct iwm_lq_cmd *lq) +{ + ItlIwm *that = container_of(sc, ItlIwm, com); + + struct iwm_host_cmd cmd = { + .id = IWM_LQ_CMD, + .len = { sizeof(struct iwm_lq_cmd), }, + .flags = IWM_CMD_ASYNC, + .data = { lq, }, + }; + + return that->iwm_send_cmd(sc, &cmd);; +} + +/* + * setup rate table in uCode + */ +static void rs_update_rate_tbl(struct iwm_softc *sc, + struct ieee80211_node *ni, + struct iwl_lq_sta *lq_sta, + struct iwl_scale_tbl_info *tbl) +{ + rs_fill_lq_cmd(sc, ni, lq_sta, &tbl->rate); + iwl_mvm_send_lq_cmd(sc, &lq_sta->lq); +} + +static bool rs_tweak_rate_tbl(struct iwm_softc *sc, + struct ieee80211_node *ni, + struct iwl_lq_sta *lq_sta, + struct iwl_scale_tbl_info *tbl, + enum rs_action scale_action) +{ + if (rs_bw_from_sta_bw(ni) != RATE_MCS_CHAN_WIDTH_80) + return false; + + if (!is_vht_siso(&tbl->rate)) + return false; + + if ((tbl->rate.bw == RATE_MCS_CHAN_WIDTH_80) && + (tbl->rate.index == IWL_RATE_MCS_0_INDEX) && + (scale_action == RS_ACTION_DOWNSCALE)) { + tbl->rate.bw = RATE_MCS_CHAN_WIDTH_20; + tbl->rate.index = IWL_RATE_MCS_4_INDEX; + IWL_DEBUG_RATE(sc, "Switch 80Mhz SISO MCS0 -> 20Mhz MCS4\n"); + goto tweaked; + } + + /* Go back to 80Mhz MCS1 only if we've established that 20Mhz MCS5 is + * sustainable, i.e. we're past the test window. We can't go back + * if MCS5 is just tested as this will happen always after switching + * to 20Mhz MCS4 because the rate stats are cleared. + */ + if ((tbl->rate.bw == RATE_MCS_CHAN_WIDTH_20) && + (((tbl->rate.index == IWL_RATE_MCS_5_INDEX) && + (scale_action == RS_ACTION_STAY)) || + ((tbl->rate.index > IWL_RATE_MCS_5_INDEX) && + (scale_action == RS_ACTION_UPSCALE)))) { + tbl->rate.bw = RATE_MCS_CHAN_WIDTH_80; + tbl->rate.index = IWL_RATE_MCS_1_INDEX; + IWL_DEBUG_RATE(sc, "Switch 20Mhz SISO MCS5 -> 80Mhz MCS1\n"); + goto tweaked; + } + + return false; + +tweaked: + rs_set_expected_tpt_table(lq_sta, tbl); + rs_rate_scale_clear_tbl_windows(sc, tbl); + return true; +} + +static enum rs_column rs_get_next_column(struct iwm_softc *sc, + struct iwl_lq_sta *lq_sta, + struct ieee80211_node *ni, + struct iwl_scale_tbl_info *tbl) +{ + int i, j, max_rate; + enum rs_column next_col_id; + const struct rs_tx_column *curr_col = &rs_tx_columns[tbl->column]; + const struct rs_tx_column *next_col; + allow_column_func_t allow_func; + ItlIwm *that = container_of(sc, ItlIwm, com); + u8 valid_ants = that->iwm_fw_valid_tx_ant(sc); + const u16 *expected_tpt_tbl; + u16 tpt, max_expected_tpt; + + for (i = 0; i < MAX_NEXT_COLUMNS; i++) { + next_col_id = curr_col->next_columns[i]; + + if (next_col_id == RS_COLUMN_INVALID) + continue; + + if (lq_sta->visited_columns & BIT(next_col_id)) { + IWL_DEBUG_RATE(sc, "Skip already visited column %d\n", + next_col_id); + continue; + } + + next_col = &rs_tx_columns[next_col_id]; + + if (!rs_is_valid_ant(valid_ants, next_col->ant)) { + IWL_DEBUG_RATE(sc, + "Skip column %d as ANT config isn't supported by chip. valid_ants 0x%x column ant 0x%x\n", + next_col_id, valid_ants, next_col->ant); + continue; + } + + for (j = 0; j < MAX_COLUMN_CHECKS; j++) { + allow_func = next_col->checks[j]; + if (allow_func && !allow_func(sc, ni, &tbl->rate, + next_col)) + break; + } + + if (j != MAX_COLUMN_CHECKS) { + IWL_DEBUG_RATE(sc, + "Skip column %d: not allowed (check %d failed)\n", + next_col_id, j); + + continue; + } + + tpt = lq_sta->last_tpt / 100; + expected_tpt_tbl = rs_get_expected_tpt_table(lq_sta, next_col, + rs_bw_from_sta_bw(ni)); + if (WARN_ON_ONCE(!expected_tpt_tbl)) + continue; + + max_rate = rs_get_max_allowed_rate(lq_sta, next_col); + if (max_rate == IWL_RATE_INVALID) { + IWL_DEBUG_RATE(sc, + "Skip column %d: no rate is allowed in this column\n", + next_col_id); + continue; + } + + max_expected_tpt = expected_tpt_tbl[max_rate]; + if (tpt >= max_expected_tpt) { + IWL_DEBUG_RATE(sc, + "Skip column %d: can't beat current TPT. Max expected %d current %d\n", + next_col_id, max_expected_tpt, tpt); + continue; + } + + IWL_DEBUG_RATE(sc, + "Found potential column %d. Max expected %d current %d\n", + next_col_id, max_expected_tpt, tpt); + break; + } + + if (i == MAX_NEXT_COLUMNS) + return RS_COLUMN_INVALID; + + return next_col_id; +} + +static int rs_switch_to_column(struct iwm_softc *sc, + struct iwl_lq_sta *lq_sta, + struct ieee80211_node *ni, + enum rs_column col_id) +{ + struct iwl_scale_tbl_info *tbl = &lq_sta->lq_info[lq_sta->active_tbl]; + struct iwl_scale_tbl_info *search_tbl = + &lq_sta->lq_info[rs_search_tbl(lq_sta->active_tbl)]; + struct rs_rate *rate = &search_tbl->rate; + const struct rs_tx_column *column = &rs_tx_columns[col_id]; + const struct rs_tx_column *curr_column = &rs_tx_columns[tbl->column]; + unsigned long rate_mask = 0; + u32 rate_idx = 0; + + memcpy(search_tbl, tbl, offsetof(struct iwl_scale_tbl_info, win)); + + rate->sgi = column->sgi; + rate->ant = column->ant; + + if (column->mode == RS_LEGACY) { + if (lq_sta->band == NL80211_BAND_5GHZ) + rate->type = LQ_LEGACY_A; + else + rate->type = LQ_LEGACY_G; + + rate->bw = RATE_MCS_CHAN_WIDTH_20; + rate->ldpc = false; + rate_mask = lq_sta->active_legacy_rate; + } else if (column->mode == RS_SISO) { + rate->type = lq_sta->is_vht ? LQ_VHT_SISO : LQ_HT_SISO; + rate_mask = lq_sta->active_siso_rate; + } else if (column->mode == RS_MIMO2) { + rate->type = lq_sta->is_vht ? LQ_VHT_MIMO2 : LQ_HT_MIMO2; + rate_mask = lq_sta->active_mimo2_rate; + } else { + WARN_ON(1, "Bad column mode"); + } + + if (column->mode != RS_LEGACY) { + rate->bw = rs_bw_from_sta_bw(ni); + rate->ldpc = lq_sta->ldpc; + } + + search_tbl->column = col_id; + rs_set_expected_tpt_table(lq_sta, search_tbl); + + lq_sta->visited_columns |= BIT(col_id); + + /* Get the best matching rate if we're changing modes. e.g. + * SISO->MIMO, LEGACY->SISO, MIMO->SISO + */ + if (curr_column->mode != column->mode) { + rate_idx = rs_get_best_rate(sc, lq_sta, search_tbl, + rate_mask, rate->index); + + if ((rate_idx == IWL_RATE_INVALID) || + !(BIT(rate_idx) & rate_mask)) { + IWL_DEBUG_RATE(sc, + "can not switch with index %d" + " rate mask %lx\n", + rate_idx, rate_mask); + + goto err; + } + + rate->index = rate_idx; + } + + IWL_DEBUG_RATE(sc, "Switched to column %d: Index %d\n", + col_id, rate->index); + + return 0; + +err: + rate->type = LQ_NONE; + return -1; +} + +static enum rs_action rs_get_rate_action(struct iwm_softc *sc, + struct iwl_scale_tbl_info *tbl, + s32 sr, int low, int high, + int current_tpt, + int low_tpt, int high_tpt) +{ + enum rs_action action = RS_ACTION_STAY; + + if ((sr <= RS_PERCENT(IWL_MVM_RS_SR_FORCE_DECREASE)) || + (current_tpt == 0)) { + IWL_DEBUG_RATE(mvm, + "Decrease rate because of low SR\n"); + return RS_ACTION_DOWNSCALE; + } + + if ((low_tpt == IWL_INVALID_VALUE) && + (high_tpt == IWL_INVALID_VALUE) && + (high != IWL_RATE_INVALID)) { + IWL_DEBUG_RATE(mvm, + "No data about high/low rates. Increase rate\n"); + return RS_ACTION_UPSCALE; + } + + if ((high_tpt == IWL_INVALID_VALUE) && + (high != IWL_RATE_INVALID) && + (low_tpt != IWL_INVALID_VALUE) && + (low_tpt < current_tpt)) { + IWL_DEBUG_RATE(mvm, + "No data about high rate and low rate is worse. Increase rate\n"); + return RS_ACTION_UPSCALE; + } + + if ((high_tpt != IWL_INVALID_VALUE) && + (high_tpt > current_tpt)) { + IWL_DEBUG_RATE(mvm, + "Higher rate is better. Increate rate\n"); + return RS_ACTION_UPSCALE; + } + + if ((low_tpt != IWL_INVALID_VALUE) && + (high_tpt != IWL_INVALID_VALUE) && + (low_tpt < current_tpt) && + (high_tpt < current_tpt)) { + IWL_DEBUG_RATE(mvm, + "Both high and low are worse. Maintain rate\n"); + return RS_ACTION_STAY; + } + + if ((low_tpt != IWL_INVALID_VALUE) && + (low_tpt > current_tpt)) { + IWL_DEBUG_RATE(mvm, + "Lower rate is better\n"); + action = RS_ACTION_DOWNSCALE; + goto out; + } + + if ((low_tpt == IWL_INVALID_VALUE) && + (low != IWL_RATE_INVALID)) { + IWL_DEBUG_RATE(mvm, + "No data about lower rate\n"); + action = RS_ACTION_DOWNSCALE; + goto out; + } + + IWL_DEBUG_RATE(mvm, "Maintain rate\n"); + +out: + if ((action == RS_ACTION_DOWNSCALE) && (low != IWL_RATE_INVALID)) { + if (sr >= RS_PERCENT(IWL_MVM_RS_SR_NO_DECREASE)) { + IWL_DEBUG_RATE(mvm, + "SR is above NO DECREASE. Avoid downscale\n"); + action = RS_ACTION_STAY; + } else if (current_tpt > (100 * tbl->expected_tpt[low])) { + IWL_DEBUG_RATE(mvm, + "Current TPT is higher than max expected in low rate. Avoid downscale\n"); + action = RS_ACTION_STAY; + } else { + IWL_DEBUG_RATE(mvm, "Decrease rate\n"); + } + } + + return action; +} + +static bool rs_stbc_allow(struct iwm_softc *sc, struct ieee80211_node *ni, + struct iwl_lq_sta *lq_sta) +{ + /* Our chip supports Tx STBC and the peer is an HT/VHT STA which + * supports STBC of at least 1*SS + */ + if (!lq_sta->stbc_capable) + return false; + + if (!iwl_mvm_bt_coex_is_mimo_allowed(sc, ni)) + return false; + + return true; +} + +static void rs_get_adjacent_txp(struct iwm_softc *mvm, int index, + int *weaker, int *stronger) +{ + *weaker = index + IWL_MVM_RS_TPC_TX_POWER_STEP; + if (*weaker > TPC_MAX_REDUCTION) + *weaker = TPC_INVALID; + + *stronger = index - IWL_MVM_RS_TPC_TX_POWER_STEP; + if (*stronger < 0) + *stronger = TPC_INVALID; +} + +static bool iwl_mvm_bt_coex_is_tpc_allowed(struct iwm_softc *mvm, + enum nl80211_band band) +{ +// u32 bt_activity = le32_to_cpu(mvm->last_bt_notif.bt_activity_grading); +// + if (band != NL80211_BAND_2GHZ) + return false; +// +// return bt_activity >= BT_LOW_TRAFFIC; + return false; +} + +static bool rs_tpc_allowed(struct iwm_softc *mvm, + struct rs_rate *rate, enum nl80211_band band) +{ + int index = rate->index; + bool cam = /*(iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM)*/ false; + bool sta_ps_disabled = /*(vif->type == NL80211_IFTYPE_STATION && + !vif->bss_conf.ps)*/ true; + + IWL_DEBUG_RATE(mvm, "cam: %d sta_ps_disabled %d\n", + cam, sta_ps_disabled); + /* + * allow tpc only if power management is enabled, or bt coex + * activity grade allows it and we are on 2.4Ghz. + */ + if ((cam || sta_ps_disabled) && + !iwl_mvm_bt_coex_is_tpc_allowed(mvm, band)) + return false; + + IWL_DEBUG_RATE(mvm, "check rate, table type: %d\n", rate->type); + if (is_legacy(rate)) + return index == IWL_RATE_54M_INDEX; + if (is_ht(rate)) + return index == IWL_RATE_MCS_7_INDEX; + if (is_vht(rate)) + return index == IWL_RATE_MCS_9_INDEX; + + WARN_ON_ONCE(1); + return false; +} + +enum tpc_action { + TPC_ACTION_STAY, + TPC_ACTION_DECREASE, + TPC_ACTION_INCREASE, + TPC_ACTION_NO_RESTIRCTION, +}; + +static enum tpc_action rs_get_tpc_action(struct iwm_softc *mvm, + s32 sr, int weak, int strong, + int current_tpt, + int weak_tpt, int strong_tpt) +{ + /* stay until we have valid tpt */ + if (current_tpt == IWL_INVALID_VALUE) { + IWL_DEBUG_RATE(mvm, "no current tpt. stay.\n"); + return TPC_ACTION_STAY; + } + + /* Too many failures, increase txp */ + if (sr <= RS_PERCENT(IWL_MVM_RS_TPC_SR_FORCE_INCREASE) || + current_tpt == 0) { + IWL_DEBUG_RATE(mvm, "increase txp because of weak SR\n"); + return TPC_ACTION_NO_RESTIRCTION; + } + + /* try decreasing first if applicable */ + if (sr >= RS_PERCENT(IWL_MVM_RS_TPC_SR_NO_INCREASE) && + weak != TPC_INVALID) { + if (weak_tpt == IWL_INVALID_VALUE && + (strong_tpt == IWL_INVALID_VALUE || + current_tpt >= strong_tpt)) { + IWL_DEBUG_RATE(mvm, + "no weak txp measurement. decrease txp\n"); + return TPC_ACTION_DECREASE; + } + + if (weak_tpt > current_tpt) { + IWL_DEBUG_RATE(mvm, + "lower txp has better tpt. decrease txp\n"); + return TPC_ACTION_DECREASE; + } + } + + /* next, increase if needed */ + if (sr < RS_PERCENT(IWL_MVM_RS_TPC_SR_NO_INCREASE) && + strong != TPC_INVALID) { + if (weak_tpt == IWL_INVALID_VALUE && + strong_tpt != IWL_INVALID_VALUE && + current_tpt < strong_tpt) { + IWL_DEBUG_RATE(mvm, + "higher txp has better tpt. increase txp\n"); + return TPC_ACTION_INCREASE; + } + + if (weak_tpt < current_tpt && + (strong_tpt == IWL_INVALID_VALUE || + strong_tpt > current_tpt)) { + IWL_DEBUG_RATE(mvm, + "lower txp has worse tpt. increase txp\n"); + return TPC_ACTION_INCREASE; + } + } + + IWL_DEBUG_RATE(mvm, "no need to increase or decrease txp - stay\n"); + return TPC_ACTION_STAY; +} + +static bool rs_tpc_perform(struct iwm_softc *mvm, + struct ieee80211_node *ni, + struct iwl_lq_sta *lq_sta, + struct iwl_scale_tbl_info *tbl) +{ + enum nl80211_band band; + struct iwl_rate_scale_data *window; + struct rs_rate *rate = &tbl->rate; + enum tpc_action action; + s32 sr; + u8 cur = lq_sta->lq.reduced_tpc; + int current_tpt; + int weak, strong; + int weak_tpt = IWL_INVALID_VALUE, strong_tpt = IWL_INVALID_VALUE; + + if (WARN_ON(!ni->ni_chan)) + band = NUM_NL80211_BANDS; + else + band = IEEE80211_IS_CHAN_2GHZ(ni->ni_chan) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ; + + if (!rs_tpc_allowed(mvm, rate, band)) { + IWL_DEBUG_RATE(mvm, + "tpc is not allowed. remove txp restrictions\n"); + lq_sta->lq.reduced_tpc = TPC_NO_REDUCTION; + return cur != TPC_NO_REDUCTION; + } + + rs_get_adjacent_txp(mvm, cur, &weak, &strong); + + /* Collect measured throughputs for current and adjacent rates */ + window = tbl->tpc_win; + sr = window[cur].success_ratio; + current_tpt = window[cur].average_tpt; + if (weak != TPC_INVALID) + weak_tpt = window[weak].average_tpt; + if (strong != TPC_INVALID) + strong_tpt = window[strong].average_tpt; + + IWL_DEBUG_RATE(mvm, + "(TPC: %d): cur_tpt %d SR %d weak %d strong %d weak_tpt %d strong_tpt %d\n", + cur, current_tpt, sr, weak, strong, + weak_tpt, strong_tpt); + + action = rs_get_tpc_action(mvm, sr, weak, strong, + current_tpt, weak_tpt, strong_tpt); + + /* override actions if we are on the edge */ + if (weak == TPC_INVALID && action == TPC_ACTION_DECREASE) { + IWL_DEBUG_RATE(mvm, "already in lowest txp, stay\n"); + action = TPC_ACTION_STAY; + } else if (strong == TPC_INVALID && + (action == TPC_ACTION_INCREASE || + action == TPC_ACTION_NO_RESTIRCTION)) { + IWL_DEBUG_RATE(mvm, "already in highest txp, stay\n"); + action = TPC_ACTION_STAY; + } + + switch (action) { + case TPC_ACTION_DECREASE: + lq_sta->lq.reduced_tpc = weak; + return true; + case TPC_ACTION_INCREASE: + lq_sta->lq.reduced_tpc = strong; + return true; + case TPC_ACTION_NO_RESTIRCTION: + lq_sta->lq.reduced_tpc = TPC_NO_REDUCTION; + return true; + case TPC_ACTION_STAY: + /* do nothing */ + break; + } + return false; +} + +/* + * Do rate scaling and search for new modulation mode. + */ +static void rs_rate_scale_perform(struct iwm_softc *mvm, + struct ieee80211_node *ni, + struct iwl_lq_sta *lq_sta, + int tid, bool ndp) +{ + int low = IWL_RATE_INVALID; + int high = IWL_RATE_INVALID; + int index; + struct iwl_rate_scale_data *window = NULL; + int current_tpt = IWL_INVALID_VALUE; + int low_tpt = IWL_INVALID_VALUE; + int high_tpt = IWL_INVALID_VALUE; + u32 fail_count; + enum rs_action scale_action = RS_ACTION_STAY; + u16 rate_mask; + u8 update_lq = 0; + struct iwl_scale_tbl_info *tbl, *tbl1; + u8 active_tbl = 0; + u8 done_search = 0; + u16 high_low; + s32 sr; + u8 prev_agg = lq_sta->is_agg; + struct rs_rate *rate; + + lq_sta->is_agg = (mvm->sc_tx_ba[EDCA_AC_BE].wn != NULL || + mvm->sc_tx_ba[EDCA_AC_BK].wn != NULL || + mvm->sc_tx_ba[EDCA_AC_VI].wn != NULL || + mvm->sc_tx_ba[EDCA_AC_VO].wn != NULL); + + /* + * Select rate-scale / modulation-mode table to work with in + * the rest of this function: "search" if searching for better + * modulation mode, or "active" if doing rate scaling within a mode. + */ + if (!lq_sta->search_better_tbl) + active_tbl = lq_sta->active_tbl; + else + active_tbl = rs_search_tbl(lq_sta->active_tbl); + + tbl = &(lq_sta->lq_info[active_tbl]); + rate = &tbl->rate; + + if (prev_agg != lq_sta->is_agg) { + IWL_DEBUG_RATE(mvm, + "Aggregation changed: prev %d current %d. Update expected TPT table\n", + prev_agg, lq_sta->is_agg); + rs_set_expected_tpt_table(lq_sta, tbl); + rs_rate_scale_clear_tbl_windows(mvm, tbl); + } + + /* current tx rate */ + index = rate->index; + + /* rates available for this association, and for modulation mode */ + rate_mask = rs_get_supported_rates(lq_sta, rate); + + if (!(BIT(index) & rate_mask)) { + IWL_ERR(mvm, "Current Rate is not valid\n"); + if (lq_sta->search_better_tbl) { + /* revert to active table if search table is not valid*/ + rate->type = LQ_NONE; + lq_sta->search_better_tbl = 0; + tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); + rs_update_rate_tbl(mvm, ni, lq_sta, tbl); + } + return; + } + + /* Get expected throughput table and history window for current rate */ + if (!tbl->expected_tpt) { + IWL_ERR(mvm, "tbl->expected_tpt is NULL\n"); + return; + } + + /* TODO: handle rate_idx_mask and rate_idx_mcs_mask */ + window = &(tbl->win[index]); + + /* + * If there is not enough history to calculate actual average + * throughput, keep analyzing results of more tx frames, without + * changing rate or mode (bypass most of the rest of this function). + * Set up new rate table in uCode only if old rate is not supported + * in current association (use new rate found above). + */ + fail_count = window->counter - window->success_counter; + if ((fail_count < IWL_MVM_RS_RATE_MIN_FAILURE_TH) && + (window->success_counter < IWL_MVM_RS_RATE_MIN_SUCCESS_TH)) { + IWL_DEBUG_RATE(mvm, + "%s: Test Window: succ %d total %d\n", + rs_pretty_rate(rate), + window->success_counter, window->counter); + + /* Can't calculate this yet; not enough history */ + window->average_tpt = IWL_INVALID_VALUE; + + /* Should we stay with this modulation mode, + * or search for a new one? */ + rs_stay_in_table(lq_sta, false); + + return; + } + + /* If we are searching for better modulation mode, check success. */ + if (lq_sta->search_better_tbl) { + /* If good success, continue using the "search" mode; + * no need to send new link quality command, since we're + * continuing to use the setup that we've been trying. */ + if (window->average_tpt > lq_sta->last_tpt) { + IWL_DEBUG_RATE(mvm, + "SWITCHING TO NEW TABLE SR: %d " + "cur-tpt %d old-tpt %d\n", + window->success_ratio, + window->average_tpt, + lq_sta->last_tpt); + + /* Swap tables; "search" becomes "active" */ + lq_sta->active_tbl = active_tbl; + current_tpt = window->average_tpt; + /* Else poor success; go back to mode in "active" table */ + } else { + IWL_DEBUG_RATE(mvm, + "GOING BACK TO THE OLD TABLE: SR %d " + "cur-tpt %d old-tpt %d\n", + window->success_ratio, + window->average_tpt, + lq_sta->last_tpt); + + /* Nullify "search" table */ + rate->type = LQ_NONE; + + /* Revert to "active" table */ + active_tbl = lq_sta->active_tbl; + tbl = &(lq_sta->lq_info[active_tbl]); + + /* Revert to "active" rate and throughput info */ + index = tbl->rate.index; + current_tpt = lq_sta->last_tpt; + + /* Need to set up a new rate table in uCode */ + update_lq = 1; + } + + /* Either way, we've made a decision; modulation mode + * search is done, allow rate adjustment next time. */ + lq_sta->search_better_tbl = 0; + done_search = 1; /* Don't switch modes below! */ + goto lq_update; + } + + /* (Else) not in search of better modulation mode, try for better + * starting rate, while staying in this mode. */ + high_low = rs_get_adjacent_rate(mvm, index, rate_mask, rate->type); + low = high_low & 0xff; + high = (high_low >> 8) & 0xff; + + /* TODO: handle rate_idx_mask and rate_idx_mcs_mask */ + + sr = window->success_ratio; + + /* Collect measured throughputs for current and adjacent rates */ + current_tpt = window->average_tpt; + if (low != IWL_RATE_INVALID) + low_tpt = tbl->win[low].average_tpt; + if (high != IWL_RATE_INVALID) + high_tpt = tbl->win[high].average_tpt; + + IWL_DEBUG_RATE(mvm, + "%s: cur_tpt %d SR %d low %d high %d low_tpt %d high_tpt %d\n", + rs_pretty_rate(rate), current_tpt, sr, + low, high, low_tpt, high_tpt); + + scale_action = rs_get_rate_action(mvm, tbl, sr, low, high, + current_tpt, low_tpt, high_tpt); + + /* Force a search in case BT doesn't like us being in MIMO */ + if (is_mimo(rate) && + !iwl_mvm_bt_coex_is_mimo_allowed(mvm, ni)) { + IWL_DEBUG_RATE(mvm, + "BT Coex forbids MIMO. Search for new config\n"); + rs_stay_in_table(lq_sta, true); + goto lq_update; + } + + switch (scale_action) { + case RS_ACTION_DOWNSCALE: + /* Decrease starting rate, update uCode's rate table */ + if (low != IWL_RATE_INVALID) { + update_lq = 1; + index = low; + } else { + IWL_DEBUG_RATE(mvm, + "At the bottom rate. Can't decrease\n"); + } + + break; + case RS_ACTION_UPSCALE: + /* Increase starting rate, update uCode's rate table */ + if (high != IWL_RATE_INVALID) { + update_lq = 1; + index = high; + } else { + IWL_DEBUG_RATE(mvm, + "At the top rate. Can't increase\n"); + } + + break; + case RS_ACTION_STAY: + /* No change */ + if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN) + update_lq = rs_tpc_perform(mvm, ni, lq_sta, tbl); + break; + default: + break; + } + +lq_update: + /* Replace uCode's rate table for the destination station. */ + if (update_lq) { + tbl->rate.index = index; + if (IWL_MVM_RS_80_20_FAR_RANGE_TWEAK) + rs_tweak_rate_tbl(mvm, ni, lq_sta, tbl, scale_action); + rs_set_amsdu_len(mvm, ni, tbl, scale_action); + rs_update_rate_tbl(mvm, ni, lq_sta, tbl); + } + + rs_stay_in_table(lq_sta, false); + + /* + * Search for new modulation mode if we're: + * 1) Not changing rates right now + * 2) Not just finishing up a search + * 3) Allowing a new search + */ + if (!update_lq && !done_search && + lq_sta->rs_state == RS_STATE_SEARCH_CYCLE_STARTED + && window->counter) { + enum rs_column next_column; + + /* Save current throughput to compare with "search" throughput*/ + lq_sta->last_tpt = current_tpt; + + IWL_DEBUG_RATE(mvm, + "Start Search: update_lq %d done_search %d rs_state %d win->counter %d\n", + update_lq, done_search, lq_sta->rs_state, + window->counter); + + next_column = rs_get_next_column(mvm, lq_sta, ni, tbl); + if (next_column != RS_COLUMN_INVALID) { + int ret = rs_switch_to_column(mvm, lq_sta, ni, + next_column); + if (!ret) + lq_sta->search_better_tbl = 1; + } else { + IWL_DEBUG_RATE(mvm, + "No more columns to explore in search cycle. Go to RS_STATE_SEARCH_CYCLE_ENDED\n"); + lq_sta->rs_state = RS_STATE_SEARCH_CYCLE_ENDED; + } + + /* If new "search" mode was selected, set up in uCode table */ + if (lq_sta->search_better_tbl) { + /* Access the "search" table, clear its history. */ + tbl = &lq_sta->lq_info[rs_search_tbl(lq_sta->active_tbl)]; + rs_rate_scale_clear_tbl_windows(mvm, tbl); + + /* Use new "search" start rate */ + index = tbl->rate.index; + + rs_dump_rate(mvm, &tbl->rate, + "Switch to SEARCH TABLE:"); + rs_update_rate_tbl(mvm, ni, lq_sta, tbl); + } else { + done_search = 1; + } + } + + if (!ndp) + rs_tl_turn_on_agg(mvm, tid, lq_sta, ni); + + if (done_search && lq_sta->rs_state == RS_STATE_SEARCH_CYCLE_ENDED) { + tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]); + rs_set_stay_in_table(mvm, is_legacy(&tbl1->rate), lq_sta); + } +} + +struct rs_init_rate_info { + s8 rssi; + u8 rate_idx; +}; + +static const struct rs_init_rate_info rs_optimal_rates_24ghz_legacy[] = { + { -60, IWL_RATE_54M_INDEX }, + { -64, IWL_RATE_48M_INDEX }, + { -68, IWL_RATE_36M_INDEX }, + { -80, IWL_RATE_24M_INDEX }, + { -84, IWL_RATE_18M_INDEX }, + { -85, IWL_RATE_12M_INDEX }, + { -86, IWL_RATE_11M_INDEX }, + { -88, IWL_RATE_5M_INDEX }, + { -90, IWL_RATE_2M_INDEX }, + { S8_MIN, IWL_RATE_1M_INDEX }, +}; + +static const struct rs_init_rate_info rs_optimal_rates_5ghz_legacy[] = { + { -60, IWL_RATE_54M_INDEX }, + { -64, IWL_RATE_48M_INDEX }, + { -72, IWL_RATE_36M_INDEX }, + { -80, IWL_RATE_24M_INDEX }, + { -84, IWL_RATE_18M_INDEX }, + { -85, IWL_RATE_12M_INDEX }, + { -87, IWL_RATE_9M_INDEX }, + { S8_MIN, IWL_RATE_6M_INDEX }, +}; + +static const struct rs_init_rate_info rs_optimal_rates_ht[] = { + { -60, IWL_RATE_MCS_7_INDEX }, + { -64, IWL_RATE_MCS_6_INDEX }, + { -68, IWL_RATE_MCS_5_INDEX }, + { -72, IWL_RATE_MCS_4_INDEX }, + { -80, IWL_RATE_MCS_3_INDEX }, + { -84, IWL_RATE_MCS_2_INDEX }, + { -85, IWL_RATE_MCS_1_INDEX }, + { S8_MIN, IWL_RATE_MCS_0_INDEX}, +}; + +/* MCS index 9 is not valid for 20MHz VHT channel width, + * but is ok for 40, 80 and 160MHz channels. + */ +static const struct rs_init_rate_info rs_optimal_rates_vht_20mhz[] = { + { -60, IWL_RATE_MCS_8_INDEX }, + { -64, IWL_RATE_MCS_7_INDEX }, + { -68, IWL_RATE_MCS_6_INDEX }, + { -72, IWL_RATE_MCS_5_INDEX }, + { -80, IWL_RATE_MCS_4_INDEX }, + { -84, IWL_RATE_MCS_3_INDEX }, + { -85, IWL_RATE_MCS_2_INDEX }, + { -87, IWL_RATE_MCS_1_INDEX }, + { S8_MIN, IWL_RATE_MCS_0_INDEX}, +}; + +static const struct rs_init_rate_info rs_optimal_rates_vht[] = { + { -60, IWL_RATE_MCS_9_INDEX }, + { -64, IWL_RATE_MCS_8_INDEX }, + { -68, IWL_RATE_MCS_7_INDEX }, + { -72, IWL_RATE_MCS_6_INDEX }, + { -80, IWL_RATE_MCS_5_INDEX }, + { -84, IWL_RATE_MCS_4_INDEX }, + { -85, IWL_RATE_MCS_3_INDEX }, + { -87, IWL_RATE_MCS_2_INDEX }, + { -88, IWL_RATE_MCS_1_INDEX }, + { S8_MIN, IWL_RATE_MCS_0_INDEX }, +}; + +#define IWL_RS_LOW_RSSI_THRESHOLD (-76) /* dBm */ + +/* Init the optimal rate based on STA caps + * This combined with rssi is used to report the last tx rate + * to userspace when we haven't transmitted enough frames. + */ +static void rs_init_optimal_rate(struct iwm_softc *mvm, + struct ieee80211_node *sta, + struct iwl_lq_sta *lq_sta) +{ + struct rs_rate *rate = &lq_sta->optimal_rate; + + if (lq_sta->max_mimo2_rate_idx != IWL_RATE_INVALID) + rate->type = lq_sta->is_vht ? LQ_VHT_MIMO2 : LQ_HT_MIMO2; + else if (lq_sta->max_siso_rate_idx != IWL_RATE_INVALID) + rate->type = lq_sta->is_vht ? LQ_VHT_SISO : LQ_HT_SISO; + else if (lq_sta->band == NL80211_BAND_5GHZ) + rate->type = LQ_LEGACY_A; + else + rate->type = LQ_LEGACY_G; + + rate->bw = rs_bw_from_sta_bw(sta); + rate->sgi = rs_sgi_allow(mvm, sta, rate, NULL); + + /* ANT/LDPC/STBC aren't relevant for the rate reported to userspace */ + + if (is_mimo(rate)) { + lq_sta->optimal_rate_mask = lq_sta->active_mimo2_rate; + } else if (is_siso(rate)) { + lq_sta->optimal_rate_mask = lq_sta->active_siso_rate; + } else { + lq_sta->optimal_rate_mask = lq_sta->active_legacy_rate; + + if (lq_sta->band == NL80211_BAND_5GHZ) { + lq_sta->optimal_rates = rs_optimal_rates_5ghz_legacy; + lq_sta->optimal_nentries = + ARRAY_SIZE(rs_optimal_rates_5ghz_legacy); + } else { + lq_sta->optimal_rates = rs_optimal_rates_24ghz_legacy; + lq_sta->optimal_nentries = + ARRAY_SIZE(rs_optimal_rates_24ghz_legacy); + } + } + + if (is_vht(rate)) { + if (rate->bw == RATE_MCS_CHAN_WIDTH_20) { + lq_sta->optimal_rates = rs_optimal_rates_vht_20mhz; + lq_sta->optimal_nentries = + ARRAY_SIZE(rs_optimal_rates_vht_20mhz); + } else { + lq_sta->optimal_rates = rs_optimal_rates_vht; + lq_sta->optimal_nentries = + ARRAY_SIZE(rs_optimal_rates_vht); + } + } else if (is_ht(rate)) { + lq_sta->optimal_rates = rs_optimal_rates_ht; + lq_sta->optimal_nentries = ARRAY_SIZE(rs_optimal_rates_ht); + } +} + +/* Compute the optimal rate index based on RSSI */ +static struct rs_rate *rs_get_optimal_rate(struct iwm_softc *mvm, + struct iwl_lq_sta *lq_sta) +{ + struct rs_rate *rate = &lq_sta->optimal_rate; + int i; + + rate->index = find_first_bit(&lq_sta->optimal_rate_mask, + BITS_PER_LONG); + + for (i = 0; i < lq_sta->optimal_nentries; i++) { + int rate_idx = lq_sta->optimal_rates[i].rate_idx; + + if ((lq_sta->pers.last_rssi >= lq_sta->optimal_rates[i].rssi) && + (BIT(rate_idx) & lq_sta->optimal_rate_mask)) { + rate->index = rate_idx; + break; + } + } + + return rate; +} + +/* Choose an initial legacy rate and antenna to use based on the RSSI + * of last Rx + */ +static void rs_get_initial_rate(struct iwm_softc *mvm, + struct ieee80211_node *sta, + struct iwl_lq_sta *lq_sta, + enum nl80211_band band, + struct rs_rate *rate) +{ + int i, nentries; + unsigned long active_rate; + s8 best_rssi = S8_MIN; + u8 best_ant = ANT_NONE; + ItlIwm *that = container_of(mvm, ItlIwm, com); + u8 valid_tx_ant = that->iwm_fw_valid_tx_ant(mvm); + const struct rs_init_rate_info *initial_rates; + + for (i = 0; i < ARRAY_SIZE(lq_sta->pers.chain_signal); i++) { + if (!(lq_sta->pers.chains & BIT(i))) + continue; + + if (lq_sta->pers.chain_signal[i] > best_rssi) { + best_rssi = lq_sta->pers.chain_signal[i]; + best_ant = BIT(i); + } + } + + IWL_DEBUG_RATE(mvm, "Best ANT: %s Best RSSI: %d\n", + rs_pretty_ant(best_ant), best_rssi); + + if (best_ant != ANT_A && best_ant != ANT_B) + rate->ant = first_antenna(valid_tx_ant); + else + rate->ant = best_ant; + + rate->sgi = false; + rate->ldpc = false; + rate->bw = RATE_MCS_CHAN_WIDTH_20; + + rate->index = find_first_bit(&lq_sta->active_legacy_rate, + BITS_PER_LONG); + + if (band == NL80211_BAND_5GHZ) { + rate->type = LQ_LEGACY_A; + initial_rates = rs_optimal_rates_5ghz_legacy; + nentries = ARRAY_SIZE(rs_optimal_rates_5ghz_legacy); + } else { + rate->type = LQ_LEGACY_G; + initial_rates = rs_optimal_rates_24ghz_legacy; + nentries = ARRAY_SIZE(rs_optimal_rates_24ghz_legacy); + } + + if (!IWL_MVM_RS_RSSI_BASED_INIT_RATE) + goto out; + + /* Start from a higher rate if the corresponding debug capability + * is enabled. The rate is chosen according to AP capabilities. + * In case of VHT/HT when the rssi is low fallback to the case of + * legacy rates. + */ + if (ieee80211_node_supports_vht(sta) && + best_rssi > IWL_RS_LOW_RSSI_THRESHOLD) { + /* + * In AP mode, when a new station associates, rs is initialized + * immediately upon association completion, before the phy + * context is updated with the association parameters, so the + * sta bandwidth might be wider than the phy context allows. + * To avoid this issue, always initialize rs with 20mhz + * bandwidth rate, and after authorization, when the phy context + * is already up-to-date, re-init rs with the correct bw. + */ + u32 bw = mvm->sc_ic.ic_state < IEEE80211_S_RUN ? + RATE_MCS_CHAN_WIDTH_20 : rs_bw_from_sta_bw(sta); + + switch (bw) { + case RATE_MCS_CHAN_WIDTH_40: + case RATE_MCS_CHAN_WIDTH_80: + case RATE_MCS_CHAN_WIDTH_160: + initial_rates = rs_optimal_rates_vht; + nentries = ARRAY_SIZE(rs_optimal_rates_vht); + break; + case RATE_MCS_CHAN_WIDTH_20: + initial_rates = rs_optimal_rates_vht_20mhz; + nentries = ARRAY_SIZE(rs_optimal_rates_vht_20mhz); + break; + default: + IWL_ERR(mvm, "Invalid BW %d\n", sta->ni_chw); + goto out; + } + + active_rate = lq_sta->active_siso_rate; + rate->type = LQ_VHT_SISO; + rate->bw = bw; + } else if (ieee80211_node_supports_ht(sta) && + best_rssi > IWL_RS_LOW_RSSI_THRESHOLD) { + initial_rates = rs_optimal_rates_ht; + nentries = ARRAY_SIZE(rs_optimal_rates_ht); + active_rate = lq_sta->active_siso_rate; + rate->type = LQ_HT_SISO; + } else { + active_rate = lq_sta->active_legacy_rate; + } + + for (i = 0; i < nentries; i++) { + int rate_idx = initial_rates[i].rate_idx; + + if ((best_rssi >= initial_rates[i].rssi) && + (BIT(rate_idx) & active_rate)) { + rate->index = rate_idx; + break; + } + } + +out: + rs_dump_rate(mvm, rate, "INITIAL"); +} + +/* Save info about RSSI of last Rx */ +void rs_update_last_rssi(struct iwm_softc *mvm, + struct ieee80211_rx_status *rx_status) +{ + struct iwl_lq_sta *lq_sta = &mvm->lq_sta.rs_drv; + int i; + + lq_sta->pers.chains = rx_status->chains; + lq_sta->pers.chain_signal[0] = rx_status->chain_signal[0]; + lq_sta->pers.chain_signal[1] = rx_status->chain_signal[1]; + lq_sta->pers.chain_signal[2] = rx_status->chain_signal[2]; + lq_sta->pers.last_rssi = S8_MIN; + + for (i = 0; i < ARRAY_SIZE(lq_sta->pers.chain_signal); i++) { + if (!(lq_sta->pers.chains & BIT(i))) + continue; + + if (lq_sta->pers.chain_signal[i] > lq_sta->pers.last_rssi) + lq_sta->pers.last_rssi = lq_sta->pers.chain_signal[i]; + } +} + +/* + * rs_initialize_lq - Initialize a station's hardware rate table + * + * The uCode's station table contains a table of fallback rates + * for automatic fallback during transmission. + * + * NOTE: This sets up a default set of values. These will be replaced later + * if the driver's iwl-agn-rs rate scaling algorithm is used, instead of + * rc80211_simple. + * + * NOTE: Run REPLY_ADD_STA command to set up station table entry, before + * calling this function (which runs REPLY_TX_LINK_QUALITY_CMD, + * which requires station table entry to exist). + */ +static void rs_initialize_lq(struct iwm_softc *mvm, + struct ieee80211_node *sta, + struct iwl_lq_sta *lq_sta, + enum nl80211_band band) +{ + struct iwl_scale_tbl_info *tbl; + struct rs_rate *rate; + u8 active_tbl = 0; + + if (!sta || !lq_sta) + return; + + if (!lq_sta->search_better_tbl) + active_tbl = lq_sta->active_tbl; + else + active_tbl = rs_search_tbl(lq_sta->active_tbl); + + tbl = &(lq_sta->lq_info[active_tbl]); + rate = &tbl->rate; + + rs_get_initial_rate(mvm, sta, lq_sta, band, rate); + rs_init_optimal_rate(mvm, sta, lq_sta); + + WARN_ON(rate->ant != ANT_A && rate->ant != ANT_B, + "ant: 0x%x, chains 0x%x, fw tx ant: 0x%x, nvm tx ant: 0x%x\n", + rate->ant, lq_sta->pers.chains, mvm->fw->valid_tx_ant, + mvm->nvm_data ? mvm->nvm_data->valid_tx_ant : ANT_INVALID); + + tbl->column = rs_get_column_from_rate(rate); + + rs_set_expected_tpt_table(lq_sta, tbl); + rs_fill_lq_cmd(mvm, sta, lq_sta, rate); + /* TODO restore station should remember the lq cmd */ + iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq); +} + +static void rs_drv_get_rate(struct iwm_softc *mvm, struct ieee80211_node *sta, + struct ieee80211_tx_rate *r) +{ + struct iwl_lq_sta *lq_sta; + struct rs_rate *optimal_rate; + u32 last_ucode_rate; + + if (sta) { + /* if vif isn't initialized mvm doesn't know about + * this station, so don't do anything with the it + */ + sta = NULL; + } + + lq_sta = &mvm->lq_sta.rs_drv; + iwl_mvm_hwrate_to_tx_rate(lq_sta->last_rate_n_flags, + IEEE80211_IS_CHAN_2GHZ(sta->ni_chan) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ, r); + + /* Report the optimal rate based on rssi and STA caps if we haven't + * converged yet (too little traffic) or exploring other modulations + */ + if (lq_sta->rs_state != RS_STATE_STAY_IN_COLUMN) { + optimal_rate = rs_get_optimal_rate(mvm, lq_sta); + last_ucode_rate = ucode_rate_from_rs_rate(mvm, + optimal_rate); + iwl_mvm_hwrate_to_tx_rate(last_ucode_rate, IEEE80211_IS_CHAN_2GHZ(sta->ni_chan) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ, + r); + } +} + +void *rs_drv_alloc_sta(iwm_softc *sc, struct ieee80211_node *ni) +{ + struct iwl_lq_sta *lq_sta = &sc->lq_sta.rs_drv; + + IWL_DEBUG_RATE(mvm, "create station rate scale window\n"); + + lq_sta->pers.drv = sc; + lq_sta->pers.chains = 0; + memset(lq_sta->pers.chain_signal, 0, sizeof(lq_sta->pers.chain_signal)); + lq_sta->pers.last_rssi = S8_MIN; + + return lq_sta; +} + +void rs_drv_free_sta(iwm_softc *sc, struct ieee80211_node *ni) +{} + +static int rs_vht_highest_rx_mcs_index(struct ieee80211_node *sta, + int nss) +{ + u16 rx_mcs = le16_to_cpu(sta->ni_ic->ic_bss->ni_vht_mcsinfo.rx_mcs_map) & + (0x3 << (2 * (nss - 1))); + rx_mcs >>= (2 * (nss - 1)); + + if (rx_mcs == IEEE80211_VHT_MCS_SUPPORT_0_7) + return IWL_RATE_MCS_7_INDEX; + else if (rx_mcs == IEEE80211_VHT_MCS_SUPPORT_0_8) + return IWL_RATE_MCS_8_INDEX; + else if (rx_mcs == IEEE80211_VHT_MCS_SUPPORT_0_9) + return IWL_RATE_MCS_9_INDEX; + + WARN_ON_ONCE(rx_mcs != IEEE80211_VHT_MCS_NOT_SUPPORTED); + return -1; +} + +static void rs_vht_set_enabled_rates(struct ieee80211_node *sta, + struct iwl_lq_sta *lq_sta) +{ + int i; + int highest_mcs = rs_vht_highest_rx_mcs_index(sta, 1); + + if (highest_mcs >= IWL_RATE_MCS_0_INDEX) { + for (i = IWL_RATE_MCS_0_INDEX; i <= highest_mcs; i++) { + if (i == IWL_RATE_9M_INDEX) + continue; + + /* VHT MCS9 isn't valid for 20Mhz for NSS=1,2 */ + if (i == IWL_RATE_MCS_9_INDEX && + sta->ni_chw == IEEE80211_CHAN_WIDTH_20) + continue; + + lq_sta->active_siso_rate |= BIT(i); + } + } + + if (sta->ni_rx_nss < 2) + return; + + highest_mcs = rs_vht_highest_rx_mcs_index(sta, 2); + if (highest_mcs >= IWL_RATE_MCS_0_INDEX) { + for (i = IWL_RATE_MCS_0_INDEX; i <= highest_mcs; i++) { + if (i == IWL_RATE_9M_INDEX) + continue; + + /* VHT MCS9 isn't valid for 20Mhz for NSS=1,2 */ + if (i == IWL_RATE_MCS_9_INDEX && + sta->ni_chw == IEEE80211_CHAN_WIDTH_20) + continue; + + lq_sta->active_mimo2_rate |= BIT(i); + } + } +} + +static void rs_ht_init(struct iwm_softc *mvm, + struct ieee80211_node *sta, + struct iwl_lq_sta *lq_sta) +{ + ItlIwm *that = container_of(mvm, ItlIwm, com); + /* active_siso_rate mask includes 9 MBits (bit 5), + * and CCK (bits 0-3), supp_rates[] does not; + * shift to convert format, force 9 MBits off. + */ + lq_sta->active_siso_rate = sta->ni_rxmcs[0] << 1; + lq_sta->active_siso_rate |= sta->ni_rxmcs[0] & 0x1; + lq_sta->active_siso_rate &= ~((u16)0x2); + lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE; + + lq_sta->active_mimo2_rate = sta->ni_rxmcs[1] << 1; + lq_sta->active_mimo2_rate |= sta->ni_rxmcs[1] & 0x1; + lq_sta->active_mimo2_rate &= ~((u16)0x2); + lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE; + + if ((sta->ni_htcaps & IEEE80211_HTCAP_LDPC)) + lq_sta->ldpc = true; + + if ((num_of_ant(that->iwm_fw_valid_tx_ant(mvm)) > 1) && + (sta->ni_htcaps & IEEE80211_HTCAP_RXSTBC_MASK)) + lq_sta->stbc_capable = true; + + lq_sta->is_vht = false; +} + +static void rs_vht_init(struct iwm_softc *mvm, + struct ieee80211_node *sta, + struct iwl_lq_sta *lq_sta) +{ + ItlIwm *that = container_of(mvm, ItlIwm, com); + rs_vht_set_enabled_rates(sta, lq_sta); + + if ((sta->ni_vhtcaps & IEEE80211_VHTCAP_RXLDPC)) + lq_sta->ldpc = true; + + if ((num_of_ant(that->iwm_fw_valid_tx_ant(mvm)) > 1) && + (sta->ni_vhtcaps & IEEE80211_VHTCAP_RXSTBC_MASK)) + lq_sta->stbc_capable = true; + + if (isset(mvm->sc_enabled_capa, IWM_UCODE_TLV_CAPA_BEAMFORMER) && + (num_of_ant(that->iwm_fw_valid_tx_ant(mvm)) > 1) && + (sta->ni_vhtcaps & IEEE80211_VHTCAP_SU_BEAMFORMEE_CAPABLE)) + lq_sta->bfer_capable = true; + + lq_sta->is_vht = true; +} + +static u8 iwl_mvm_bt_coex_get_single_ant_msk(struct iwm_softc *mvm, u8 enabled_ants) +{ + if (isset(&mvm->sc_enabled_capa, IWM_UCODE_TLV_CAPA_COEX_SCHEMA_2) && + (mvm->non_shared_ant & enabled_ants)) + return mvm->non_shared_ant; + + return first_antenna(enabled_ants); +} + +/** + * struct ieee80211_rate - bitrate definition + * + * This structure describes a bitrate that an 802.11 PHY can + * operate with. The two values @hw_value and @hw_value_short + * are only for driver use when pointers to this structure are + * passed around. + * + * @flags: rate-specific flags + * @bitrate: bitrate in units of 100 Kbps + * @hw_value: driver/hardware value for this rate + * @hw_value_short: driver/hardware value for this rate when + * short preamble is used + */ +struct ieee80211_rate { + u32 flags; + u16 bitrate; + u16 hw_value, hw_value_short; +}; + +/** + * enum ieee80211_rate_flags - rate flags + * + * Hardware/specification flags for rates. These are structured + * in a way that allows using the same bitrate structure for + * different bands/PHY modes. + * + * @IEEE80211_RATE_SHORT_PREAMBLE: Hardware can send with short + * preamble on this bitrate; only relevant in 2.4GHz band and + * with CCK rates. + * @IEEE80211_RATE_MANDATORY_A: This bitrate is a mandatory rate + * when used with 802.11a (on the 5 GHz band); filled by the + * core code when registering the wiphy. + * @IEEE80211_RATE_MANDATORY_B: This bitrate is a mandatory rate + * when used with 802.11b (on the 2.4 GHz band); filled by the + * core code when registering the wiphy. + * @IEEE80211_RATE_MANDATORY_G: This bitrate is a mandatory rate + * when used with 802.11g (on the 2.4 GHz band); filled by the + * core code when registering the wiphy. + * @IEEE80211_RATE_ERP_G: This is an ERP rate in 802.11g mode. + * @IEEE80211_RATE_SUPPORTS_5MHZ: Rate can be used in 5 MHz mode + * @IEEE80211_RATE_SUPPORTS_10MHZ: Rate can be used in 10 MHz mode + */ +enum ieee80211_rate_flags { + IEEE80211_RATE_SHORT_PREAMBLE = 1<<0, + IEEE80211_RATE_MANDATORY_A = 1<<1, + IEEE80211_RATE_MANDATORY_B = 1<<2, + IEEE80211_RATE_MANDATORY_G = 1<<3, + IEEE80211_RATE_ERP_G = 1<<4, + IEEE80211_RATE_SUPPORTS_5MHZ = 1<<5, + IEEE80211_RATE_SUPPORTS_10MHZ = 1<<6, +}; + +/* rate data (static) */ +static struct ieee80211_rate iwl_cfg80211_rates[] = { + { .bitrate = 1 * 10, .hw_value = 0, .hw_value_short = 0, }, + { .bitrate = 2 * 10, .hw_value = 1, .hw_value_short = 1, + .flags = IEEE80211_RATE_SHORT_PREAMBLE, }, + { .bitrate = (u16)(5.5 * 10), .hw_value = 2, .hw_value_short = 2, + .flags = IEEE80211_RATE_SHORT_PREAMBLE, }, + { .bitrate = 11 * 10, .hw_value = 3, .hw_value_short = 3, + .flags = IEEE80211_RATE_SHORT_PREAMBLE, }, + { .bitrate = 6 * 10, .hw_value = 4, .hw_value_short = 4, }, + { .bitrate = 9 * 10, .hw_value = 5, .hw_value_short = 5, }, + { .bitrate = 12 * 10, .hw_value = 6, .hw_value_short = 6, }, + { .bitrate = 18 * 10, .hw_value = 7, .hw_value_short = 7, }, + { .bitrate = 24 * 10, .hw_value = 8, .hw_value_short = 8, }, + { .bitrate = 36 * 10, .hw_value = 9, .hw_value_short = 9, }, + { .bitrate = 48 * 10, .hw_value = 10, .hw_value_short = 10, }, + { .bitrate = 54 * 10, .hw_value = 11, .hw_value_short = 11, }, +}; +#define RATES_24_OFFS 0 +#define N_RATES_24 ARRAY_SIZE(iwl_cfg80211_rates) +#define RATES_52_OFFS 4 +#define N_RATES_52 (N_RATES_24 - RATES_52_OFFS) + +/* + * Called after adding a new station to initialize rate scaling + */ +static void rs_drv_rate_init(struct iwm_softc *mvm, struct ieee80211_node *sta, + enum nl80211_band band) +{ + int i, j; + struct iwl_lq_sta *lq_sta = &mvm->lq_sta.rs_drv; + ItlIwm *that = container_of(mvm, ItlIwm, com); + uint8_t rate; + +// lockdep_assert_held(&mvmsta->lq_sta.rs_drv.pers.lock); + + /* clear all non-persistent lq data */ + memset(lq_sta, 0, offsetof(typeof(*lq_sta), pers)); + + lq_sta->lq.sta_id = IWM_STATION_ID; +#if 0 + mvm->amsdu_enabled = 0; + mvm->max_amsdu_len = sta->max_amsdu_len; +#endif + + for (j = 0; j < LQ_SIZE; j++) + rs_rate_scale_clear_tbl_windows(mvm, &lq_sta->lq_info[j]); + + lq_sta->flush_timer = 0; + lq_sta->last_tx = ticks; + + IWL_DEBUG_RATE(mvm, + "LQ: *** rate scale station global init for station %d ***\n", + IWM_STATION_ID); + /* TODO: what is a good starting rate for STA? About middle? Maybe not + * the lowest or the highest rate.. Could consider using RSSI from + * previous packets? Need to have IEEE 802.1X auth succeed immediately + * after assoc.. */ + + lq_sta->missed_rate_counter = IWL_MVM_RS_MISSED_RATE_MAX; + lq_sta->band = band; + /* + * active legacy rates as per supported rates bitmap + */ + lq_sta->active_legacy_rate = 0; + for (i = 0; i < sta->ni_rates.rs_nrates; i++) { + rate = sta->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL; + /* Map 802.11 rate to HW rate index. */ + for (j = 0; j <= (band == NL80211_BAND_2GHZ ? N_RATES_24 : N_RATES_52); j++) { + if (iwl_cfg80211_rates[j + (band == NL80211_BAND_2GHZ ? RATES_24_OFFS : RATES_52_OFFS)].bitrate / 5 == rate) + break; + } + lq_sta->active_legacy_rate |= BIT(iwl_cfg80211_rates[j + (band == NL80211_BAND_2GHZ ? RATES_24_OFFS : RATES_52_OFFS)].hw_value); + } + + /* TODO: should probably account for rx_highest for both HT/VHT */ + if ((sta->ni_flags & IEEE80211_NODE_VHT) == 0) + rs_ht_init(mvm, sta, lq_sta); + else + rs_vht_init(mvm, sta, lq_sta); + + lq_sta->max_legacy_rate_idx = + rs_get_max_rate_from_mask(lq_sta->active_legacy_rate); + lq_sta->max_siso_rate_idx = + rs_get_max_rate_from_mask(lq_sta->active_siso_rate); + lq_sta->max_mimo2_rate_idx = + rs_get_max_rate_from_mask(lq_sta->active_mimo2_rate); + + IWL_DEBUG_RATE(mvm, + "LEGACY=%lX SISO=%lX MIMO2=%lX VHT=%d LDPC=%d STBC=%d BFER=%d\n", + lq_sta->active_legacy_rate, + lq_sta->active_siso_rate, + lq_sta->active_mimo2_rate, + lq_sta->is_vht, lq_sta->ldpc, lq_sta->stbc_capable, + lq_sta->bfer_capable); + IWL_DEBUG_RATE(mvm, "MAX RATE: LEGACY=%d SISO=%d MIMO2=%d\n", + lq_sta->max_legacy_rate_idx, + lq_sta->max_siso_rate_idx, + lq_sta->max_mimo2_rate_idx); + + /* These values will be overridden later */ + lq_sta->lq.single_stream_ant_msk = + iwl_mvm_bt_coex_get_single_ant_msk(mvm, that->iwm_fw_valid_tx_ant(mvm)); + lq_sta->lq.dual_stream_ant_msk = ANT_AB; + + /* as default allow aggregation for all tids */ + lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID; + lq_sta->is_agg = 0; + rs_initialize_lq(mvm, sta, lq_sta, band); +} + +void rs_drv_rate_update(struct iwm_softc *mvm, + struct ieee80211_node *sta, + enum nl80211_band band, u32 changed) +{ + /* Stop any ongoing aggregations as rs starts off assuming no agg */ + ieee80211_stop_ampdu_tx(&mvm->sc_ic, sta, 0); + + iwl_mvm_rs_rate_init(mvm, sta, band, true); +} + +static void __iwl_mvm_rs_tx_status(struct iwm_softc *mvm, + struct ieee80211_node *sta, + int tid, struct ieee80211_tx_info *info, + bool ndp) +{ + int legacy_success; + int retries; + int i; + struct iwm_lq_cmd *table; + u32 lq_hwrate; + uint32_t last_rate; + struct rs_rate lq_rate, tx_resp_rate; + struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl; + u32 tlc_info = (u32)(uintptr_t)info->status.status_driver_data[0]; + u8 reduced_txp = tlc_info & RS_DRV_DATA_TXP_MSK; + u8 lq_color = RS_DRV_DATA_LQ_COLOR_GET(tlc_info); + u32 tx_resp_hwrate = (u32)(uintptr_t)info->status.status_driver_data[1]; + struct iwl_lq_sta *lq_sta = &mvm->lq_sta.rs_drv; + char pretty_rate[100]; + + if (!lq_sta->pers.drv) { + IWL_DEBUG_RATE(mvm, "Rate scaling not initialized yet.\n"); + return; + } + + /* This packet was aggregated but doesn't carry status info */ + if ((info->flags & IEEE80211_TX_CTL_AMPDU) && + !(info->flags & IEEE80211_TX_STAT_AMPDU)) + return; + + if (rs_rate_from_ucode_rate(tx_resp_hwrate, (enum nl80211_band)info->band, + &tx_resp_rate)) { + WARN_ON_ONCE(1); + return; + } + + if (time_after(ticks, + (unsigned long)(lq_sta->last_tx + + (IWL_MVM_RS_IDLE_TIMEOUT * hz)))) { + IWL_DEBUG_RATE(mvm, "Tx idle for too long. reinit rs\n"); + /* reach here only in case of driver RS, call directly + * the unlocked version + */ + rs_drv_rate_init(mvm, sta, (nl80211_band)info->band); + return; + } + lq_sta->last_tx = ticks; + + /* Ignore this Tx frame response if its initial rate doesn't match + * that of latest Link Quality command. There may be stragglers + * from a previous Link Quality command, but we're no longer interested + * in those; they're either from the "active" mode while we're trying + * to check "search" mode, or a prior "search" mode after we've moved + * to a new "search" mode (which might become the new "active" mode). + */ + table = &lq_sta->lq; + lq_hwrate = le32_to_cpu(table->rs_table[0]); + if (rs_rate_from_ucode_rate(lq_hwrate, (enum nl80211_band)info->band, &lq_rate)) { + WARN_ON_ONCE(1); + return; + } + + /* Here we actually compare this rate to the latest LQ command */ + if (lq_color != LQ_FLAG_COLOR_GET(table->flags)) { + IWL_DEBUG_RATE(mvm, + "tx resp color 0x%x does not match 0x%x\n", + lq_color, LQ_FLAG_COLOR_GET(table->flags)); + + /* Since rates mis-match, the last LQ command may have failed. + * After IWL_MISSED_RATE_MAX mis-matches, resync the uCode with + * ... driver. + */ + lq_sta->missed_rate_counter++; + if (lq_sta->missed_rate_counter > IWL_MVM_RS_MISSED_RATE_MAX) { + lq_sta->missed_rate_counter = 0; + IWL_DEBUG_RATE(mvm, + "Too many rates mismatch. Send sync LQ. rs_state %d\n", + lq_sta->rs_state); + iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq); + } + /* Regardless, ignore this status info for outdated rate */ + return; + } + + /* Rate did match, so reset the missed_rate_counter */ + lq_sta->missed_rate_counter = 0; + + if (!lq_sta->search_better_tbl) { + curr_tbl = &lq_sta->lq_info[lq_sta->active_tbl]; + other_tbl = &lq_sta->lq_info[rs_search_tbl(lq_sta->active_tbl)]; + } else { + curr_tbl = &lq_sta->lq_info[rs_search_tbl(lq_sta->active_tbl)]; + other_tbl = &lq_sta->lq_info[lq_sta->active_tbl]; + } + + if (WARN_ON_ONCE(!rs_rate_column_match(&lq_rate, &curr_tbl->rate))) { + IWL_DEBUG_RATE(mvm, + "Neither active nor search matches tx rate\n"); + tmp_tbl = &lq_sta->lq_info[lq_sta->active_tbl]; + rs_dump_rate(mvm, &tmp_tbl->rate, "ACTIVE"); + tmp_tbl = &lq_sta->lq_info[rs_search_tbl(lq_sta->active_tbl)]; + rs_dump_rate(mvm, &tmp_tbl->rate, "SEARCH"); + rs_dump_rate(mvm, &lq_rate, "ACTUAL"); + + /* no matching table found, let's by-pass the data collection + * and continue to perform rate scale to find the rate table + */ + rs_stay_in_table(lq_sta, true); + goto done; + } + + /* Updating the frame history depends on whether packets were + * aggregated. + * + * For aggregation, all packets were transmitted at the same rate, the + * first index into rate scale table. + */ + if (info->flags & IEEE80211_TX_STAT_AMPDU) { + rs_collect_tpc_data(mvm, lq_sta, curr_tbl, tx_resp_rate.index, + info->status.ampdu_len, + info->status.ampdu_ack_len, + reduced_txp); + + /* ampdu_ack_len = 0 marks no BA was received. For TLC, treat + * it as a single frame loss as we don't want the success ratio + * to dip too quickly because a BA wasn't received. + * For TPC, there's no need for this optimisation since we want + * to recover very quickly from a bad power reduction and, + * therefore we'd like the success ratio to get an immediate hit + * when failing to get a BA, so we'd switch back to a lower or + * zero power reduction. When FW transmits agg with a rate + * different from the initial rate, it will not use reduced txp + * and will send BA notification twice (one empty with reduced + * txp equal to the value from LQ and one with reduced txp 0). + * We need to update counters for each txp level accordingly. + */ + if (info->status.ampdu_ack_len == 0) + info->status.ampdu_len = 1; + + rs_collect_tlc_data(mvm, tid, curr_tbl, + tx_resp_rate.index, + info->status.ampdu_len, + info->status.ampdu_ack_len); + + /* Update success/fail counts if not searching for new mode */ + if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN) { + lq_sta->total_success += info->status.ampdu_ack_len; + lq_sta->total_failed += (info->status.ampdu_len - + info->status.ampdu_ack_len); + } + } else { + /* For legacy, update frame history with for each Tx retry. */ + retries = info->status.rates[0].count - 1; + /* HW doesn't send more than 15 retries */ + retries = min(retries, 15); + + /* The last transmission may have been successful */ + legacy_success = !!(info->flags & IEEE80211_TX_STAT_ACK); + /* Collect data for each rate used during failed TX attempts */ + for (i = 0; i <= retries; ++i) { + lq_hwrate = le32_to_cpu(table->rs_table[i]); + if (rs_rate_from_ucode_rate(lq_hwrate, (enum nl80211_band)info->band, + &lq_rate)) { + WARN_ON_ONCE(1); + return; + } + + /* Only collect stats if retried rate is in the same RS + * table as active/search. + */ + if (rs_rate_column_match(&lq_rate, &curr_tbl->rate)) + tmp_tbl = curr_tbl; + else if (rs_rate_column_match(&lq_rate, + &other_tbl->rate)) + tmp_tbl = other_tbl; + else + continue; + + rs_collect_tpc_data(mvm, lq_sta, tmp_tbl, + tx_resp_rate.index, 1, + i < retries ? 0 : legacy_success, + reduced_txp); + rs_collect_tlc_data(mvm, tid, tmp_tbl, + tx_resp_rate.index, 1, + i < retries ? 0 : legacy_success); + } + + /* Update success/fail counts if not searching for new mode */ + if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN) { + lq_sta->total_success += legacy_success; + lq_sta->total_failed += retries + (1 - legacy_success); + } + } + /* The last TX rate is cached in lq_sta; it's set in if/else above */ + last_rate = lq_sta->last_rate_n_flags; + lq_sta->last_rate_n_flags = lq_hwrate; + if (last_rate != lq_hwrate) { + rs_pretty_print_rate(pretty_rate, sizeof(pretty_rate), lq_sta->last_rate_n_flags); + XYLog("%s new rate: %s\n", __FUNCTION__, pretty_rate); + } + if ((lq_sta->last_rate_n_flags & RATE_MCS_VHT_MSK) || (lq_sta->last_rate_n_flags & RATE_MCS_HE_MSK)) { + sta->ni_txmcs = (lq_sta->last_rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK); + } else if (lq_sta->last_rate_n_flags & RATE_MCS_HT_MSK) { + sta->ni_txmcs = (lq_sta->last_rate_n_flags & + (RATE_HT_MCS_RATE_CODE_MSK | + RATE_HT_MCS_NSS_MSK)); + } else { + int index = iwl_mvm_legacy_rate_to_mac80211_idx(lq_sta->last_rate_n_flags, (enum nl80211_band)info->band); + if (index < 0 || index >= ieee80211_std_rateset_11g.rs_nrates) + goto done; + + sta->ni_txrate = ieee80211_std_rateset_11g.rs_rates[index] / 2; + } + IWL_DEBUG_RATE(mvm, "reduced txpower: %d\n", reduced_txp); +done: + /* See if there's a better rate or modulation mode to try. */ + if (/*sta->supp_rates[info->band]*/ true) + rs_rate_scale_perform(mvm, sta, lq_sta, tid, ndp); +} + +void iwl_mvm_rs_tx_status(struct iwm_softc *mvm, struct ieee80211_node *sta, + int tid, struct ieee80211_tx_info *info, bool ndp) +{ + /* If it's locked we are in middle of init flow + * just wait for next tx status to update the lq_sta data + */ + if (!IOSimpleLockTryLock(mvm->lq_sta.rs_drv.pers.lock)) + return; + + __iwl_mvm_rs_tx_status(mvm, sta, tid, info, ndp); + IOSimpleLockUnlock(mvm->lq_sta.rs_drv.pers.lock); +} + +static void rs_fill_rates_for_column(struct iwm_softc *mvm, + struct iwl_lq_sta *lq_sta, + struct rs_rate *rate, + __le32 *rs_table, int *rs_table_index, + int num_rates, int num_retries, + u8 valid_tx_ant, bool toggle_ant) +{ + int i, j; + __le32 ucode_rate; + bool bottom_reached = false; + int prev_rate_idx = rate->index; + int end = LINK_QUAL_MAX_RETRY_NUM; + int index = *rs_table_index; + + for (i = 0; i < num_rates && index < end; i++) { + for (j = 0; j < num_retries && index < end; j++, index++) { + ucode_rate = cpu_to_le32(ucode_rate_from_rs_rate(mvm, + rate)); + rs_table[index] = ucode_rate; + if (toggle_ant) + rs_toggle_antenna(valid_tx_ant, rate); + } + + prev_rate_idx = rate->index; + bottom_reached = rs_get_lower_rate_in_column(lq_sta, rate); + if (bottom_reached && !is_legacy(rate)) + break; + } + + if (!bottom_reached && !is_legacy(rate)) + rate->index = prev_rate_idx; + + *rs_table_index = index; +} + +/* Building the rate table is non trivial. When we're in MIMO2/VHT/80Mhz/SGI + * column the rate table should look like this: + * + * rate[0] 0x400F019 VHT | ANT: AB BW: 80Mhz MCS: 9 NSS: 2 SGI + * rate[1] 0x400F019 VHT | ANT: AB BW: 80Mhz MCS: 9 NSS: 2 SGI + * rate[2] 0x400F018 VHT | ANT: AB BW: 80Mhz MCS: 8 NSS: 2 SGI + * rate[3] 0x400F018 VHT | ANT: AB BW: 80Mhz MCS: 8 NSS: 2 SGI + * rate[4] 0x400F017 VHT | ANT: AB BW: 80Mhz MCS: 7 NSS: 2 SGI + * rate[5] 0x400F017 VHT | ANT: AB BW: 80Mhz MCS: 7 NSS: 2 SGI + * rate[6] 0x4005007 VHT | ANT: A BW: 80Mhz MCS: 7 NSS: 1 NGI + * rate[7] 0x4009006 VHT | ANT: B BW: 80Mhz MCS: 6 NSS: 1 NGI + * rate[8] 0x4005005 VHT | ANT: A BW: 80Mhz MCS: 5 NSS: 1 NGI + * rate[9] 0x800B Legacy | ANT: B Rate: 36 Mbps + * rate[10] 0x4009 Legacy | ANT: A Rate: 24 Mbps + * rate[11] 0x8007 Legacy | ANT: B Rate: 18 Mbps + * rate[12] 0x4005 Legacy | ANT: A Rate: 12 Mbps + * rate[13] 0x800F Legacy | ANT: B Rate: 9 Mbps + * rate[14] 0x400D Legacy | ANT: A Rate: 6 Mbps + * rate[15] 0x800D Legacy | ANT: B Rate: 6 Mbps + */ +static void rs_build_rates_table(struct iwm_softc *mvm, + struct ieee80211_node *sta, + struct iwl_lq_sta *lq_sta, + const struct rs_rate *initial_rate) +{ + struct rs_rate rate; + int num_rates, num_retries, index = 0; + u8 valid_tx_ant = 0; + struct iwm_lq_cmd *lq_cmd = &lq_sta->lq; + bool toggle_ant = false; + u32 color; + ItlIwm *that = container_of(mvm, ItlIwm, com); + + memcpy(&rate, initial_rate, sizeof(rate)); + + valid_tx_ant = that->iwm_fw_valid_tx_ant(mvm); + + /* TODO: remove old API when min FW API hits 14 */ + if (!isset(&mvm->sc_ucode_api, IWM_UCODE_TLV_API_LQ_SS_PARAMS) && + rs_stbc_allow(mvm, sta, lq_sta)) + rate.stbc = true; + + if (is_siso(&rate)) { + num_rates = IWL_MVM_RS_INITIAL_SISO_NUM_RATES; + num_retries = IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE; + } else if (is_mimo(&rate)) { + num_rates = IWL_MVM_RS_INITIAL_MIMO_NUM_RATES; + num_retries = IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE; + } else { + num_rates = IWL_MVM_RS_INITIAL_LEGACY_NUM_RATES; + num_retries = IWL_MVM_RS_INITIAL_LEGACY_RETRIES; + toggle_ant = true; + } + + rs_fill_rates_for_column(mvm, lq_sta, &rate, (__le32 *)lq_cmd->rs_table, &index, + num_rates, num_retries, valid_tx_ant, + toggle_ant); + + rs_get_lower_rate_down_column(lq_sta, &rate); + + if (is_siso(&rate)) { + num_rates = IWL_MVM_RS_SECONDARY_SISO_NUM_RATES; + num_retries = IWL_MVM_RS_SECONDARY_SISO_RETRIES; + lq_cmd->mimo_delim = index; + } else if (is_legacy(&rate)) { + num_rates = IWL_MVM_RS_SECONDARY_LEGACY_NUM_RATES; + num_retries = IWL_MVM_RS_SECONDARY_LEGACY_RETRIES; + } else { + WARN_ON_ONCE(1); + } + + toggle_ant = true; + + rs_fill_rates_for_column(mvm, lq_sta, &rate, (__le32 *)lq_cmd->rs_table, &index, + num_rates, num_retries, valid_tx_ant, + toggle_ant); + + rs_get_lower_rate_down_column(lq_sta, &rate); + + num_rates = IWL_MVM_RS_SECONDARY_LEGACY_NUM_RATES; + num_retries = IWL_MVM_RS_SECONDARY_LEGACY_RETRIES; + + rs_fill_rates_for_column(mvm, lq_sta, &rate, (__le32 *)lq_cmd->rs_table, &index, + num_rates, num_retries, valid_tx_ant, + toggle_ant); + + /* update the color of the LQ command (as a counter at bits 1-3) */ + color = LQ_FLAGS_COLOR_INC(LQ_FLAG_COLOR_GET(lq_cmd->flags)); + lq_cmd->flags = LQ_FLAG_COLOR_SET(lq_cmd->flags, color); +} + +//struct rs_bfer_active_iter_data { +// struct ieee80211_node *exclude_sta; +// struct ieee80211_node *bfer_mvmsta; +//}; +// +//static void rs_bfer_active_iter(void *_data, +// struct ieee80211_node *sta) +//{ +// struct rs_bfer_active_iter_data *data = (struct rs_bfer_active_iter_data *)_data; +// struct iwm_lq_cmd *lq_cmd = &sta->ni_ic->lq_sta.rs_drv.lq; +// u32 ss_params = le32_to_cpu(lq_cmd->ss_params); +// +// if (sta == data->exclude_sta) +// return; +// +// /* The current sta has BFER allowed */ +// if (ss_params & LQ_SS_BFER_ALLOWED) { +// WARN_ON_ONCE(data->bfer_mvmsta != NULL); +// +// data->bfer_mvmsta = mvmsta; +// } +//} +// +//static int rs_bfer_priority(struct ieee80211_node *sta) +//{ +// return 1; +//} +// +///* Returns >0 if sta1 has a higher BFER priority compared to sta2 */ +//static int rs_bfer_priority_cmp(struct ieee80211_node *sta1, +// struct ieee80211_node *sta2) +//{ +// int prio1 = rs_bfer_priority(sta1); +// int prio2 = rs_bfer_priority(sta2); +// +// if (prio1 > prio2) +// return 1; +// if (prio1 < prio2) +// return -1; +// return 0; +//} +// +//static inline void ieee80211_iterate_stations_atomic(struct iwm_softc *hw, +// void (*iterator)(void *data, +// struct ieee80211_node *sta), +// void *data) +//{ +// iterator(data, hw->sc_ic.ic_bss); +//} + +static void rs_set_lq_ss_params(struct iwm_softc *mvm, + struct ieee80211_node *sta, + struct iwl_lq_sta *lq_sta, + const struct rs_rate *initial_rate) +{ + struct iwm_lq_cmd *lq_cmd = &lq_sta->lq; +// struct rs_bfer_active_iter_data data = { +// .exclude_sta = sta, +// .bfer_mvmsta = NULL, +// }; + u32 ss_params = LQ_SS_PARAMS_VALID; + + if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta)) + goto out; + + if (lq_sta->stbc_capable) + ss_params |= LQ_SS_STBC_1SS_ALLOWED; + + if (!lq_sta->bfer_capable) + goto out; + +// ieee80211_iterate_stations_atomic(mvm, +// rs_bfer_active_iter, +// &data); +// bfer_mvmsta = data.bfer_mvmsta; +// +// /* This code is safe as it doesn't run concurrently for different +// * stations. This is guaranteed by the fact that calls to +// * ieee80211_tx_status wouldn't run concurrently for a single HW. +// */ +// if (!bfer_mvmsta) { +// IWL_DEBUG_RATE(mvm, "No sta with BFER allowed found. Allow\n"); +// +// ss_params |= LQ_SS_BFER_ALLOWED; +// goto out; +// } +// +// IWL_DEBUG_RATE(mvm, "Found existing sta %d with BFER activated\n", +// bfer_mvmsta->sta_id); +// +// /* Disallow BFER on another STA if active and we're a higher priority */ +// if (rs_bfer_priority_cmp(mvmsta, bfer_mvmsta) > 0) { +// struct iwm_lq_cmd *bfersta_lq_cmd = +// &bfer_mvmsta->lq_sta.rs_drv.lq; +// u32 bfersta_ss_params = le32_to_cpu(bfersta_lq_cmd->ss_params); +// +// bfersta_ss_params &= ~LQ_SS_BFER_ALLOWED; +// bfersta_lq_cmd->ss_params = cpu_to_le32(bfersta_ss_params); +// iwl_mvm_send_lq_cmd(mvm, bfersta_lq_cmd); +// +// ss_params |= LQ_SS_BFER_ALLOWED; +// IWL_DEBUG_RATE(mvm, +// "Lower priority BFER sta found (%d). Switch BFER\n", +// bfer_mvmsta->sta_id); +// } +out: + lq_cmd->ss_params = cpu_to_le32(ss_params); +} + +#define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) +#define LINK_QUAL_AGG_TIME_LIMIT_BT_ACT (1200) + +static u16 iwl_mvm_coex_agg_time_limit(struct iwm_softc *mvm, +struct ieee80211_node *sta) +{ +// if (mvm->last_bt_notif.ttc_status & BIT(phy_ctxt->id)) +// return LINK_QUAL_AGG_TIME_LIMIT_DEF; +// +// if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) < +// BT_HIGH_TRAFFIC) +// return LINK_QUAL_AGG_TIME_LIMIT_DEF; +// +// lut_type = iwl_get_coex_type(mvm, mvmsta->vif); +// +// if (lut_type == BT_COEX_LOOSE_LUT || lut_type == BT_COEX_INVALID_LUT) + return LINK_QUAL_AGG_TIME_LIMIT_DEF; + +// /* tight coex, high bt traffic, reduce AGG time limit */ +// return LINK_QUAL_AGG_TIME_LIMIT_BT_ACT; +} + +static void rs_fill_lq_cmd(struct iwm_softc *mvm, + struct ieee80211_node *sta, + struct iwl_lq_sta *lq_sta, + const struct rs_rate *initial_rate) +{ + struct iwm_lq_cmd *lq_cmd = &lq_sta->lq; + + lq_cmd->agg_disable_start_th = IWL_MVM_RS_AGG_DISABLE_START; + lq_cmd->agg_time_limit = + cpu_to_le16(IWL_MVM_RS_AGG_TIME_LIMIT); + + if (WARN_ON_ONCE(!sta || !initial_rate)) + return; + + rs_build_rates_table(mvm, sta, lq_sta, initial_rate); + + if (isset(&mvm->sc_ucode_api, IWM_UCODE_TLV_API_LQ_SS_PARAMS)) + rs_set_lq_ss_params(mvm, sta, lq_sta, initial_rate); + + if (!isset(&mvm->sc_enabled_capa, IWM_UCODE_TLV_CAPA_COEX_SCHEMA_2) && + num_of_ant(initial_rate->ant) == 1) + lq_cmd->single_stream_ant_msk = initial_rate->ant; + + lq_cmd->agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF; + +#if 0 + if (mvmsta->vif->p2p) + lq_cmd->flags |= LQ_FLAG_USE_RTS_MSK; +#endif + + lq_cmd->agg_time_limit = + cpu_to_le16(iwl_mvm_coex_agg_time_limit(mvm, sta)); +} + +int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate) +{ + + char *type, *bw; + u8 mcs = 0, nss = 0; + u8 ant = (rate & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS; + + if (!(rate & RATE_MCS_HT_MSK) && + !(rate & RATE_MCS_VHT_MSK) && + !(rate & RATE_MCS_HE_MSK)) { + int index = iwl_hwrate_to_plcp_idx(rate); + + return snprintf(buf, bufsz, "Legacy | ANT: %s Rate: %s Mbps", + rs_pretty_ant(ant), + index == IWL_RATE_INVALID ? "BAD" : + iwl_rate_mcs[index].mbps); + } + + if (rate & RATE_MCS_VHT_MSK) { + type = "VHT"; + mcs = rate & RATE_VHT_MCS_RATE_CODE_MSK; + nss = ((rate & RATE_VHT_MCS_NSS_MSK) + >> RATE_VHT_MCS_NSS_POS) + 1; + } else if (rate & RATE_MCS_HT_MSK) { + type = "HT"; + mcs = rate & RATE_HT_MCS_INDEX_MSK; + nss = ((rate & RATE_HT_MCS_NSS_MSK) + >> RATE_HT_MCS_NSS_POS) + 1; + } else if (rate & RATE_MCS_HE_MSK) { + type = "HE"; + mcs = rate & RATE_VHT_MCS_RATE_CODE_MSK; + nss = ((rate & RATE_VHT_MCS_NSS_MSK) + >> RATE_VHT_MCS_NSS_POS) + 1; + } else { + type = "Unknown"; /* shouldn't happen */ + } + + switch (rate & RATE_MCS_CHAN_WIDTH_MSK) { + case RATE_MCS_CHAN_WIDTH_20: + bw = "20Mhz"; + break; + case RATE_MCS_CHAN_WIDTH_40: + bw = "40Mhz"; + break; + case RATE_MCS_CHAN_WIDTH_80: + bw = "80Mhz"; + break; + case RATE_MCS_CHAN_WIDTH_160: + bw = "160Mhz"; + break; + default: + bw = "BAD BW"; + } + + return snprintf(buf, bufsz, + "0x%x: %s | ANT: %s BW: %s MCS: %d NSS: %d %s%s%s%s%s", + rate, type, rs_pretty_ant(ant), bw, mcs, nss, + (rate & RATE_MCS_SGI_MSK) ? "SGI " : "NGI ", + (rate & RATE_MCS_STBC_MSK) ? "STBC " : "", + (rate & RATE_MCS_LDPC_MSK) ? "LDPC " : "", + (rate & RATE_HE_DUAL_CARRIER_MODE_MSK) ? "DCM " : "", + (rate & RATE_MCS_BF_MSK) ? "BF " : ""); +} + +void iwl_mvm_rs_rate_init(struct iwm_softc *mvm, struct ieee80211_node *sta, + enum nl80211_band band, bool update) +{ + IOSimpleLockLock(mvm->lq_sta.rs_drv.pers.lock); + rs_drv_rate_init(mvm, sta, band); + IOSimpleLockUnlock(mvm->lq_sta.rs_drv.pers.lock); +} + +static int rs_drv_tx_protection(struct iwm_softc *mvm, + bool enable) +{ + struct iwm_lq_cmd *lq = &mvm->lq_sta.rs_drv.lq; + + if (enable) { + if (mvm->tx_protection == 0) + lq->flags |= LQ_FLAG_USE_RTS_MSK; + mvm->tx_protection++; + } else { + mvm->tx_protection--; + if (mvm->tx_protection == 0) + lq->flags &= ~LQ_FLAG_USE_RTS_MSK; + } + + return iwl_mvm_send_lq_cmd(mvm, lq); +} + +/** + * iwl_mvm_tx_protection - ask FW to enable RTS/CTS protection + * @mvm: The mvm component + * @mvmsta: The station + * @enable: Enable Tx protection? + */ +int iwl_mvm_tx_protection(struct iwm_softc *mvm, + bool enable) +{ + return rs_drv_tx_protection(mvm, enable); +} + +void +iwm_rs_alloc(struct iwm_softc *sc) +{ + sc->lq_sta.rs_drv.pers.lock = IOSimpleLockAlloc(); +} + +void iwm_rs_free(struct iwm_softc *sc) +{ + if (sc->lq_sta.rs_drv.pers.lock) { + IOSimpleLockFree(sc->lq_sta.rs_drv.pers.lock); + sc->lq_sta.rs_drv.pers.lock = NULL; + } +} diff --git a/itlwm/hal_iwm/rs.h b/itlwm/hal_iwm/rs.h new file mode 100644 index 000000000..0ad3a5f6b --- /dev/null +++ b/itlwm/hal_iwm/rs.h @@ -0,0 +1,1509 @@ +// +// rs.hpp +// itlwm +// +// Created by zxystd on 2021/8/27. +// Copyright © 2021 钟先耀. All rights reserved. +// + +#ifndef rs_hpp +#define rs_hpp + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#define IWL_DEBUG_RATE(sc, fmt, x...) +//#define IWL_DEBUG_RATE(sc, fmt, x...)\ +//do\ +//{\ +//XYLog("%s: " fmt, "RATE", ##x);\ +//}while(0) + +#define IWL_ERR(sc, fmt, x...)\ +do\ +{\ +XYLog("%s: " fmt, "ERR", ##x);\ +}while(0) + +/** + * enum nl80211_band - Frequency band + * @NL80211_BAND_2GHZ: 2.4 GHz ISM band + * @NL80211_BAND_5GHZ: around 5 GHz band (4.9 - 5.7 GHz) + * @NUM_NL80211_BANDS: number of bands, avoid using this in userspace + * since newer kernel versions may support more bands + */ +enum nl80211_band { + NL80211_BAND_2GHZ, + NL80211_BAND_5GHZ, + + NUM_NL80211_BANDS, +}; + +/** + * enum mac80211_tx_info_flags - flags to describe transmission information/status + * + * These flags are used with the @flags member of &ieee80211_tx_info. + * + * @IEEE80211_TX_CTL_REQ_TX_STATUS: require TX status callback for this frame. + * @IEEE80211_TX_CTL_ASSIGN_SEQ: The driver has to assign a sequence + * number to this frame, taking care of not overwriting the fragment + * number and increasing the sequence number only when the + * IEEE80211_TX_CTL_FIRST_FRAGMENT flag is set. mac80211 will properly + * assign sequence numbers to QoS-data frames but cannot do so correctly + * for non-QoS-data and management frames because beacons need them from + * that counter as well and mac80211 cannot guarantee proper sequencing. + * If this flag is set, the driver should instruct the hardware to + * assign a sequence number to the frame or assign one itself. Cf. IEEE + * 802.11-2007 7.1.3.4.1 paragraph 3. This flag will always be set for + * beacons and always be clear for frames without a sequence number field. + * @IEEE80211_TX_CTL_NO_ACK: tell the low level not to wait for an ack + * @IEEE80211_TX_CTL_CLEAR_PS_FILT: clear powersave filter for destination + * station + * @IEEE80211_TX_CTL_FIRST_FRAGMENT: this is a first fragment of the frame + * @IEEE80211_TX_CTL_SEND_AFTER_DTIM: send this frame after DTIM beacon + * @IEEE80211_TX_CTL_AMPDU: this frame should be sent as part of an A-MPDU + * @IEEE80211_TX_CTL_INJECTED: Frame was injected, internal to mac80211. + * @IEEE80211_TX_STAT_TX_FILTERED: The frame was not transmitted + * because the destination STA was in powersave mode. Note that to + * avoid race conditions, the filter must be set by the hardware or + * firmware upon receiving a frame that indicates that the station + * went to sleep (must be done on device to filter frames already on + * the queue) and may only be unset after mac80211 gives the OK for + * that by setting the IEEE80211_TX_CTL_CLEAR_PS_FILT (see above), + * since only then is it guaranteed that no more frames are in the + * hardware queue. + * @IEEE80211_TX_STAT_ACK: Frame was acknowledged + * @IEEE80211_TX_STAT_AMPDU: The frame was aggregated, so status + * is for the whole aggregation. + * @IEEE80211_TX_STAT_AMPDU_NO_BACK: no block ack was returned, + * so consider using block ack request (BAR). + * @IEEE80211_TX_CTL_RATE_CTRL_PROBE: internal to mac80211, can be + * set by rate control algorithms to indicate probe rate, will + * be cleared for fragmented frames (except on the last fragment) + * @IEEE80211_TX_INTFL_OFFCHAN_TX_OK: Internal to mac80211. Used to indicate + * that a frame can be transmitted while the queues are stopped for + * off-channel operation. + * @IEEE80211_TX_CTL_HW_80211_ENCAP: This frame uses hardware encapsulation + * (header conversion) + * @IEEE80211_TX_INTFL_RETRIED: completely internal to mac80211, + * used to indicate that a frame was already retried due to PS + * @IEEE80211_TX_INTFL_DONT_ENCRYPT: completely internal to mac80211, + * used to indicate frame should not be encrypted + * @IEEE80211_TX_CTL_NO_PS_BUFFER: This frame is a response to a poll + * frame (PS-Poll or uAPSD) or a non-bufferable MMPDU and must + * be sent although the station is in powersave mode. + * @IEEE80211_TX_CTL_MORE_FRAMES: More frames will be passed to the + * transmit function after the current frame, this can be used + * by drivers to kick the DMA queue only if unset or when the + * queue gets full. + * @IEEE80211_TX_INTFL_RETRANSMISSION: This frame is being retransmitted + * after TX status because the destination was asleep, it must not + * be modified again (no seqno assignment, crypto, etc.) + * @IEEE80211_TX_INTFL_MLME_CONN_TX: This frame was transmitted by the MLME + * code for connection establishment, this indicates that its status + * should kick the MLME state machine. + * @IEEE80211_TX_INTFL_NL80211_FRAME_TX: Frame was requested through nl80211 + * MLME command (internal to mac80211 to figure out whether to send TX + * status to user space) + * @IEEE80211_TX_CTL_LDPC: tells the driver to use LDPC for this frame + * @IEEE80211_TX_CTL_STBC: Enables Space-Time Block Coding (STBC) for this + * frame and selects the maximum number of streams that it can use. + * @IEEE80211_TX_CTL_TX_OFFCHAN: Marks this packet to be transmitted on + * the off-channel channel when a remain-on-channel offload is done + * in hardware -- normal packets still flow and are expected to be + * handled properly by the device. + * @IEEE80211_TX_INTFL_TKIP_MIC_FAILURE: Marks this packet to be used for TKIP + * testing. It will be sent out with incorrect Michael MIC key to allow + * TKIP countermeasures to be tested. + * @IEEE80211_TX_CTL_NO_CCK_RATE: This frame will be sent at non CCK rate. + * This flag is actually used for management frame especially for P2P + * frames not being sent at CCK rate in 2GHz band. + * @IEEE80211_TX_STATUS_EOSP: This packet marks the end of service period, + * when its status is reported the service period ends. For frames in + * an SP that mac80211 transmits, it is already set; for driver frames + * the driver may set this flag. It is also used to do the same for + * PS-Poll responses. + * @IEEE80211_TX_CTL_USE_MINRATE: This frame will be sent at lowest rate. + * This flag is used to send nullfunc frame at minimum rate when + * the nullfunc is used for connection monitoring purpose. + * @IEEE80211_TX_CTL_DONTFRAG: Don't fragment this packet even if it + * would be fragmented by size (this is optional, only used for + * monitor injection). + * @IEEE80211_TX_STAT_NOACK_TRANSMITTED: A frame that was marked with + * IEEE80211_TX_CTL_NO_ACK has been successfully transmitted without + * any errors (like issues specific to the driver/HW). + * This flag must not be set for frames that don't request no-ack + * behaviour with IEEE80211_TX_CTL_NO_ACK. + * + * Note: If you have to add new flags to the enumeration, then don't + * forget to update %IEEE80211_TX_TEMPORARY_FLAGS when necessary. + */ +enum mac80211_tx_info_flags { + IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0), + IEEE80211_TX_CTL_ASSIGN_SEQ = BIT(1), + IEEE80211_TX_CTL_NO_ACK = BIT(2), + IEEE80211_TX_CTL_CLEAR_PS_FILT = BIT(3), + IEEE80211_TX_CTL_FIRST_FRAGMENT = BIT(4), + IEEE80211_TX_CTL_SEND_AFTER_DTIM = BIT(5), + IEEE80211_TX_CTL_AMPDU = BIT(6), + IEEE80211_TX_CTL_INJECTED = BIT(7), + IEEE80211_TX_STAT_TX_FILTERED = BIT(8), + IEEE80211_TX_STAT_ACK = BIT(9), + IEEE80211_TX_STAT_AMPDU = BIT(10), + IEEE80211_TX_STAT_AMPDU_NO_BACK = BIT(11), + IEEE80211_TX_CTL_RATE_CTRL_PROBE = BIT(12), + IEEE80211_TX_INTFL_OFFCHAN_TX_OK = BIT(13), + IEEE80211_TX_CTL_HW_80211_ENCAP = BIT(14), + IEEE80211_TX_INTFL_RETRIED = BIT(15), + IEEE80211_TX_INTFL_DONT_ENCRYPT = BIT(16), + IEEE80211_TX_CTL_NO_PS_BUFFER = BIT(17), + IEEE80211_TX_CTL_MORE_FRAMES = BIT(18), + IEEE80211_TX_INTFL_RETRANSMISSION = BIT(19), + IEEE80211_TX_INTFL_MLME_CONN_TX = BIT(20), + IEEE80211_TX_INTFL_NL80211_FRAME_TX = BIT(21), + IEEE80211_TX_CTL_LDPC = BIT(22), + IEEE80211_TX_CTL_STBC = BIT(23) | BIT(24), + IEEE80211_TX_CTL_TX_OFFCHAN = BIT(25), + IEEE80211_TX_INTFL_TKIP_MIC_FAILURE = BIT(26), + IEEE80211_TX_CTL_NO_CCK_RATE = BIT(27), + IEEE80211_TX_STATUS_EOSP = BIT(28), + IEEE80211_TX_CTL_USE_MINRATE = BIT(29), + IEEE80211_TX_CTL_DONTFRAG = BIT(30), + IEEE80211_TX_STAT_NOACK_TRANSMITTED = BIT(31), +}; + +/** + * enum mac80211_rate_control_flags - per-rate flags set by the + * Rate Control algorithm. + * + * These flags are set by the Rate control algorithm for each rate during tx, + * in the @flags member of struct ieee80211_tx_rate. + * + * @IEEE80211_TX_RC_USE_RTS_CTS: Use RTS/CTS exchange for this rate. + * @IEEE80211_TX_RC_USE_CTS_PROTECT: CTS-to-self protection is required. + * This is set if the current BSS requires ERP protection. + * @IEEE80211_TX_RC_USE_SHORT_PREAMBLE: Use short preamble. + * @IEEE80211_TX_RC_MCS: HT rate. + * @IEEE80211_TX_RC_VHT_MCS: VHT MCS rate, in this case the idx field is split + * into a higher 4 bits (Nss) and lower 4 bits (MCS number) + * @IEEE80211_TX_RC_GREEN_FIELD: Indicates whether this rate should be used in + * Greenfield mode. + * @IEEE80211_TX_RC_40_MHZ_WIDTH: Indicates if the Channel Width should be 40 MHz. + * @IEEE80211_TX_RC_80_MHZ_WIDTH: Indicates 80 MHz transmission + * @IEEE80211_TX_RC_160_MHZ_WIDTH: Indicates 160 MHz transmission + * (80+80 isn't supported yet) + * @IEEE80211_TX_RC_DUP_DATA: The frame should be transmitted on both of the + * adjacent 20 MHz channels, if the current channel type is + * NL80211_CHAN_HT40MINUS or NL80211_CHAN_HT40PLUS. + * @IEEE80211_TX_RC_SHORT_GI: Short Guard interval should be used for this rate. + */ +enum mac80211_rate_control_flags { + IEEE80211_TX_RC_USE_RTS_CTS = BIT(0), + IEEE80211_TX_RC_USE_CTS_PROTECT = BIT(1), + IEEE80211_TX_RC_USE_SHORT_PREAMBLE = BIT(2), + + /* rate index is an HT/VHT MCS instead of an index */ + IEEE80211_TX_RC_MCS = BIT(3), + IEEE80211_TX_RC_GREEN_FIELD = BIT(4), + IEEE80211_TX_RC_40_MHZ_WIDTH = BIT(5), + IEEE80211_TX_RC_DUP_DATA = BIT(6), + IEEE80211_TX_RC_SHORT_GI = BIT(7), + IEEE80211_TX_RC_VHT_MCS = BIT(8), + IEEE80211_TX_RC_80_MHZ_WIDTH = BIT(9), + IEEE80211_TX_RC_160_MHZ_WIDTH = BIT(10), +}; + +/** + * struct ieee80211_rx_status - receive status + * + * The low-level driver should provide this information (the subset + * supported by hardware) to the 802.11 code with each received + * frame, in the skb's control buffer (cb). + * + * @mactime: value in microseconds of the 64-bit Time Synchronization Function + * (TSF) timer when the first data symbol (MPDU) arrived at the hardware. + * @boottime_ns: CLOCK_BOOTTIME timestamp the frame was received at, this is + * needed only for beacons and probe responses that update the scan cache. + * @device_timestamp: arbitrary timestamp for the device, mac80211 doesn't use + * it but can store it and pass it back to the driver for synchronisation + * @band: the active band when this frame was received + * @freq: frequency the radio was tuned to when receiving this frame, in MHz + * This field must be set for management frames, but isn't strictly needed + * for data (other) frames - for those it only affects radiotap reporting. + * @freq_offset: @freq has a positive offset of 500Khz. + * @signal: signal strength when receiving this frame, either in dBm, in dB or + * unspecified depending on the hardware capabilities flags + * @IEEE80211_HW_SIGNAL_* + * @chains: bitmask of receive chains for which separate signal strength + * values were filled. + * @chain_signal: per-chain signal strength, in dBm (unlike @signal, doesn't + * support dB or unspecified units) + * @antenna: antenna used + * @rate_idx: index of data rate into band's supported rates or MCS index if + * HT or VHT is used (%RX_FLAG_HT/%RX_FLAG_VHT) + * @nss: number of streams (VHT and HE only) + * @flag: %RX_FLAG_\* + * @encoding: &enum mac80211_rx_encoding + * @bw: &enum rate_info_bw + * @enc_flags: uses bits from &enum mac80211_rx_encoding_flags + * @he_ru: HE RU, from &enum nl80211_he_ru_alloc + * @he_gi: HE GI, from &enum nl80211_he_gi + * @he_dcm: HE DCM value + * @rx_flags: internal RX flags for mac80211 + * @ampdu_reference: A-MPDU reference number, must be a different value for + * each A-MPDU but the same for each subframe within one A-MPDU + * @ampdu_delimiter_crc: A-MPDU delimiter CRC + * @zero_length_psdu_type: radiotap type of the 0-length PSDU + */ +struct ieee80211_rx_status { +// u64 mactime; +// u64 boottime_ns; +// u32 device_timestamp; +// u32 ampdu_reference; +// u32 flag; +// u16 freq: 13, freq_offset: 1; +// u8 enc_flags; +// u8 encoding:2, bw:3, he_ru:3; +// u8 he_gi:2, he_dcm:1; +// u8 rate_idx; +// u8 nss; +// u8 rx_flags; +// u8 band; +// u8 antenna; + s8 signal; + u8 chains; + s8 chain_signal[4]; +// u8 ampdu_delimiter_crc; +// u8 zero_length_psdu_type; +}; + +/** + * struct ieee80211_tx_rate - rate selection/status + * + * @idx: rate index to attempt to send with + * @flags: rate control flags (&enum mac80211_rate_control_flags) + * @count: number of tries in this rate before going to the next rate + * + * A value of -1 for @idx indicates an invalid rate and, if used + * in an array of retry rates, that no more rates should be tried. + * + * When used for transmit status reporting, the driver should + * always report the rate along with the flags it used. + * + * &struct ieee80211_tx_info contains an array of these structs + * in the control information, and it will be filled by the rate + * control algorithm according to what should be sent. For example, + * if this array contains, in the format { , } the + * information:: + * + * { 3, 2 }, { 2, 2 }, { 1, 4 }, { -1, 0 }, { -1, 0 } + * + * then this means that the frame should be transmitted + * up to twice at rate 3, up to twice at rate 2, and up to four + * times at rate 1 if it doesn't get acknowledged. Say it gets + * acknowledged by the peer after the fifth attempt, the status + * information should then contain:: + * + * { 3, 2 }, { 2, 2 }, { 1, 1 }, { -1, 0 } ... + * + * since it was transmitted twice at rate 3, twice at rate 2 + * and once at rate 1 after which we received an acknowledgement. + */ +struct ieee80211_tx_rate { + s8 idx; + u16 count:5, + flags:11; +} __packed; + +struct ieee80211_tx_info { + /* common information */ + u32 flags; + u32 band:3, + ack_frame_id:13, + hw_queue:4, + tx_time_est:10; + /* 2 free bits */ + + union { + struct { + struct ieee80211_tx_rate rates[4]; + s32 ack_signal; + u8 ampdu_ack_len; + u8 ampdu_len; + u8 antenna; + u16 tx_time; + bool is_valid_ack_signal; + void *status_driver_data[19 / sizeof(void *)]; + } status; + }; +}; + +/** + * struct ieee80211_mcs_info - MCS information + * @rx_mask: RX mask + * @rx_highest: highest supported RX rate. If set represents + * the highest supported RX data rate in units of 1 Mbps. + * If this field is 0 this value should not be used to + * consider the highest RX data rate supported. + * @tx_params: TX parameters + */ +struct ieee80211_mcs_info { + u8 rx_mask[10]; + __le16 rx_highest; + u8 tx_params; + u8 reserved[3]; +} __packed; + +/** + * struct ieee80211_sta_ht_cap - STA's HT capabilities + * + * This structure describes most essential parameters needed + * to describe 802.11n HT capabilities for an STA. + * + * @ht_supported: is HT supported by the STA + * @cap: HT capabilities map as described in 802.11n spec + * @ampdu_factor: Maximum A-MPDU length factor + * @ampdu_density: Minimum A-MPDU spacing + * @mcs: Supported MCS rates + */ +struct ieee80211_sta_ht_cap { + u16 cap; /* use IEEE80211_HT_CAP_ */ + bool ht_supported; + u8 ampdu_factor; + u8 ampdu_density; + struct ieee80211_mcs_info mcs; +}; + +/** + * struct ieee80211_sta_vht_cap - STA's VHT capabilities + * + * This structure describes most essential parameters needed + * to describe 802.11ac VHT capabilities for an STA. + * + * @vht_supported: is VHT supported by the STA + * @cap: VHT capabilities map as described in 802.11ac spec + * @vht_mcs: Supported VHT MCS rates + */ +struct ieee80211_sta_vht_cap { + bool vht_supported; + u32 cap; /* use IEEE80211_VHT_CAP_ */ + struct ieee80211_vht_mcs_info vht_mcs; +}; + +/** + * struct ieee80211_vht_cap - VHT capabilities + * + * This structure is the "VHT capabilities element" as + * described in 802.11ac D3.0 8.4.2.160 + * @vht_cap_info: VHT capability info + * @supp_mcs: VHT MCS supported rates + */ +struct ieee80211_vht_cap { + __le32 vht_cap_info; + struct ieee80211_vht_mcs_info supp_mcs; +} __packed; + +static inline int ieee80211_get_vht_max_nss(struct ieee80211_vht_cap *cap, + int bw, + int mcs, bool ext_nss_bw_capable, + unsigned int max_vht_nss) +{ + u16 map = le16_to_cpu(cap->supp_mcs.rx_mcs_map); + int ext_nss_bw; + int supp_width; + int i, mcs_encoding; + + if (map == 0xffff) + return 0; + + if (WARN_ON(mcs > 9 || max_vht_nss > 8)) + return 0; + if (mcs <= 7) + mcs_encoding = 0; + else if (mcs == 8) + mcs_encoding = 1; + else + mcs_encoding = 2; + + if (!max_vht_nss) { + /* find max_vht_nss for the given MCS */ + for (i = 7; i >= 0; i--) { + int supp = (map >> (2 * i)) & 3; + + if (supp == 3) + continue; + + if (supp >= mcs_encoding) { + max_vht_nss = i + 1; + break; + } + } + } + + if (!(cap->supp_mcs.tx_mcs_map & + cpu_to_le16(IEEE80211_VHT_EXT_NSS_BW_CAPABLE))) + return max_vht_nss; + + ext_nss_bw = le32_get_bits(cap->vht_cap_info, + IEEE80211_VHTCAP_EXT_NSS_BW_MASK); + supp_width = le32_get_bits(cap->vht_cap_info, + IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_MASK); + + /* if not capable, treat ext_nss_bw as 0 */ + if (!ext_nss_bw_capable) + ext_nss_bw = 0; + + /* This is invalid */ + if (supp_width == 3) + return 0; + + /* This is an invalid combination so pretend nothing is supported */ + if (supp_width == 2 && (ext_nss_bw == 1 || ext_nss_bw == 2)) + return 0; + + /* + * Cover all the special cases according to IEEE 802.11-2016 + * Table 9-250. All other cases are either factor of 1 or not + * valid/supported. + */ + switch (bw) { + case IEEE80211_VHT_CHANWIDTH_USE_HT: + case IEEE80211_VHT_CHANWIDTH_80MHZ: + if ((supp_width == 1 || supp_width == 2) && + ext_nss_bw == 3) + return 2 * max_vht_nss; + break; + case IEEE80211_VHT_CHANWIDTH_160MHZ: + if (supp_width == 0 && + (ext_nss_bw == 1 || ext_nss_bw == 2)) + return max_vht_nss / 2; + if (supp_width == 0 && + ext_nss_bw == 3) + return (3 * max_vht_nss) / 4; + if (supp_width == 1 && + ext_nss_bw == 3) + return 2 * max_vht_nss; + break; + case IEEE80211_VHT_CHANWIDTH_80P80MHZ: + if (supp_width == 0 && ext_nss_bw == 1) + return 0; /* not possible */ + if (supp_width == 0 && + ext_nss_bw == 2) + return max_vht_nss / 2; + if (supp_width == 0 && + ext_nss_bw == 3) + return (3 * max_vht_nss) / 4; + if (supp_width == 1 && + ext_nss_bw == 0) + return 0; /* not possible */ + if (supp_width == 1 && + ext_nss_bw == 1) + return max_vht_nss / 2; + if (supp_width == 1 && + ext_nss_bw == 2) + return (3 * max_vht_nss) / 4; + break; + } + + /* not covered or invalid combination received */ + return max_vht_nss; +} + +#define IWL_MVM_UAPSD_NOAGG_BSSIDS_NUM 20 + +#define IWL_MVM_DEFAULT_PS_TX_DATA_TIMEOUT (100 * USEC_PER_MSEC) +#define IWL_MVM_DEFAULT_PS_RX_DATA_TIMEOUT (100 * USEC_PER_MSEC) +#define IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT (10 * USEC_PER_MSEC) +#define IWL_MVM_WOWLAN_PS_RX_DATA_TIMEOUT (10 * USEC_PER_MSEC) +#define IWL_MVM_SHORT_PS_TX_DATA_TIMEOUT (2 * 1024) /* defined in TU */ +#define IWL_MVM_SHORT_PS_RX_DATA_TIMEOUT (40 * 1024) /* defined in TU */ +#define IWL_MVM_P2P_LOWLATENCY_PS_ENABLE 0 +#define IWL_MVM_UAPSD_RX_DATA_TIMEOUT (50 * USEC_PER_MSEC) +#define IWL_MVM_UAPSD_TX_DATA_TIMEOUT (50 * USEC_PER_MSEC) +#define IWL_MVM_UAPSD_QUEUES (IEEE80211_WMM_IE_STA_QOSINFO_AC_VO |\ + IEEE80211_WMM_IE_STA_QOSINFO_AC_VI |\ + IEEE80211_WMM_IE_STA_QOSINFO_AC_BK |\ + IEEE80211_WMM_IE_STA_QOSINFO_AC_BE) +#define IWL_MVM_PS_HEAVY_TX_THLD_PACKETS 20 +#define IWL_MVM_PS_HEAVY_RX_THLD_PACKETS 8 +#define IWL_MVM_PS_SNOOZE_HEAVY_TX_THLD_PACKETS 30 +#define IWL_MVM_PS_SNOOZE_HEAVY_RX_THLD_PACKETS 20 +#define IWL_MVM_PS_HEAVY_TX_THLD_PERCENT 50 +#define IWL_MVM_PS_HEAVY_RX_THLD_PERCENT 50 +#define IWL_MVM_PS_SNOOZE_INTERVAL 25 +#define IWL_MVM_PS_SNOOZE_WINDOW 50 +#define IWL_MVM_WOWLAN_PS_SNOOZE_WINDOW 25 +#define IWL_MVM_LOWLAT_QUOTA_MIN_PERCENT 64 +#define IWL_MVM_BT_COEX_EN_RED_TXP_THRESH 62 +#define IWL_MVM_BT_COEX_DIS_RED_TXP_THRESH 65 +#define IWL_MVM_BT_COEX_SYNC2SCO 1 +#define IWL_MVM_BT_COEX_MPLUT 1 +#define IWL_MVM_BT_COEX_RRC 1 +#define IWL_MVM_BT_COEX_TTC 1 +#define IWL_MVM_BT_COEX_MPLUT_REG0 0x22002200 +#define IWL_MVM_BT_COEX_MPLUT_REG1 0x11118451 +#define IWL_MVM_BT_COEX_ANTENNA_COUPLING_THRS 30 +#define IWL_MVM_FW_MCAST_FILTER_PASS_ALL 0 +#define IWL_MVM_FW_BCAST_FILTER_PASS_ALL 0 +#define IWL_MVM_QUOTA_THRESHOLD 4 +#define IWL_MVM_RS_RSSI_BASED_INIT_RATE 0 +#define IWL_MVM_RS_80_20_FAR_RANGE_TWEAK 1 +#define IWL_MVM_TOF_IS_RESPONDER 0 +#define IWL_MVM_HW_CSUM_DISABLE 0 +#define IWL_MVM_PARSE_NVM 0 +#define IWL_MVM_ADWELL_ENABLE 1 +#define IWL_MVM_ADWELL_MAX_BUDGET 0 +#define IWL_MVM_TCM_LOAD_MEDIUM_THRESH 10 /* percentage */ +#define IWL_MVM_TCM_LOAD_HIGH_THRESH 50 /* percentage */ +#define IWL_MVM_TCM_LOWLAT_ENABLE_THRESH 100 /* packets/10 seconds */ +#define IWL_MVM_UAPSD_NONAGG_PERIOD 5000 /* msecs */ +#define IWL_MVM_UAPSD_NOAGG_LIST_LEN IWL_MVM_UAPSD_NOAGG_BSSIDS_NUM +#define IWL_MVM_NON_TRANSMITTING_AP 0 +#define IWL_MVM_RS_NUM_TRY_BEFORE_ANT_TOGGLE 1 +#define IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE 2 +#define IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE_TW 1 +#define IWL_MVM_RS_INITIAL_MIMO_NUM_RATES 3 +#define IWL_MVM_RS_INITIAL_SISO_NUM_RATES 3 +#define IWL_MVM_RS_INITIAL_LEGACY_NUM_RATES 2 +#define IWL_MVM_RS_INITIAL_LEGACY_RETRIES 2 +#define IWL_MVM_RS_SECONDARY_LEGACY_RETRIES 1 +#define IWL_MVM_RS_SECONDARY_LEGACY_NUM_RATES 16 +#define IWL_MVM_RS_SECONDARY_SISO_NUM_RATES 3 +#define IWL_MVM_RS_SECONDARY_SISO_RETRIES 1 +#define IWL_MVM_RS_RATE_MIN_FAILURE_TH 3 +#define IWL_MVM_RS_RATE_MIN_SUCCESS_TH 8 +#define IWL_MVM_RS_STAY_IN_COLUMN_TIMEOUT 5 /* Seconds */ +#define IWL_MVM_RS_IDLE_TIMEOUT 5 /* Seconds */ +#define IWL_MVM_RS_MISSED_RATE_MAX 15 +#define IWL_MVM_RS_LEGACY_FAILURE_LIMIT 160 +#define IWL_MVM_RS_LEGACY_SUCCESS_LIMIT 480 +#define IWL_MVM_RS_LEGACY_TABLE_COUNT 160 +#define IWL_MVM_RS_NON_LEGACY_FAILURE_LIMIT 400 +#define IWL_MVM_RS_NON_LEGACY_SUCCESS_LIMIT 4500 +#define IWL_MVM_RS_NON_LEGACY_TABLE_COUNT 1500 +#define IWL_MVM_RS_SR_FORCE_DECREASE 15 /* percent */ +#define IWL_MVM_RS_SR_NO_DECREASE 85 /* percent */ +#define IWL_MVM_RS_AGG_TIME_LIMIT 4000 /* 4 msecs. valid 100-8000 */ +#define IWL_MVM_RS_AGG_DISABLE_START 3 +#define IWL_MVM_RS_AGG_START_THRESHOLD 10 /* num frames per second */ +#define IWL_MVM_RS_TPC_SR_FORCE_INCREASE 75 /* percent */ +#define IWL_MVM_RS_TPC_SR_NO_INCREASE 85 /* percent */ +#define IWL_MVM_RS_TPC_TX_POWER_STEP 3 +#define IWL_MVM_ENABLE_EBS 1 +#define IWL_MVM_FTM_INITIATOR_ALGO IWL_TOF_ALGO_TYPE_MAX_LIKE +#define IWL_MVM_FTM_INITIATOR_DYNACK true +#define IWL_MVM_FTM_R2I_MAX_REP 7 +#define IWL_MVM_FTM_I2R_MAX_REP 7 +#define IWL_MVM_FTM_R2I_MAX_STS 1 +#define IWL_MVM_FTM_I2R_MAX_STS 1 +#define IWL_MVM_FTM_R2I_MAX_TOTAL_LTF 3 +#define IWL_MVM_FTM_I2R_MAX_TOTAL_LTF 3 +#define IWL_MVM_FTM_INITIATOR_SECURE_LTF false +#define IWL_MVM_FTM_RESP_NDP_SUPPORT true +#define IWL_MVM_FTM_RESP_LMR_FEEDBACK_SUPPORT true +#define IWL_MVM_D3_DEBUG false +#define IWL_MVM_USE_TWT true +#define IWL_MVM_AMPDU_CONSEC_DROPS_DELBA 10 +#define IWL_MVM_USE_NSSN_SYNC 0 +#define IWL_MVM_PHY_FILTER_CHAIN_A 0 +#define IWL_MVM_PHY_FILTER_CHAIN_B 0 +#define IWL_MVM_PHY_FILTER_CHAIN_C 0 +#define IWL_MVM_PHY_FILTER_CHAIN_D 0 +#define IWL_MVM_FTM_INITIATOR_ENABLE_SMOOTH false +#define IWL_MVM_FTM_INITIATOR_SMOOTH_ALPHA 40 +/* 20016 pSec is 6 meter RTT, meaning 3 meter range */ +#define IWL_MVM_FTM_INITIATOR_SMOOTH_UNDERSHOOT 20016 +#define IWL_MVM_FTM_INITIATOR_SMOOTH_OVERSHOOT 20016 +#define IWL_MVM_FTM_INITIATOR_SMOOTH_AGE_SEC 2 +#define IWL_MVM_DISABLE_AP_FILS false +#define IWL_MVM_6GHZ_PASSIVE_SCAN_TIMEOUT 3000 /* in seconds */ +#define IWL_MVM_6GHZ_PASSIVE_SCAN_ASSOC_TIMEOUT 60 /* in seconds */ + +#define IWL_MAX_TID_COUNT 8 +#define IWL_MGMT_TID 15 +#define IWL_FRAME_LIMIT 64 +#define IWL_MAX_RX_HW_QUEUES 16 +#define IWL_9000_MAX_RX_HW_QUEUES 6 + +/* Antenna presence definitions */ +#define ANT_NONE 0x0 +#define ANT_INVALID 0xff +#define ANT_A BIT(0) +#define ANT_B BIT(1) +#define ANT_C BIT(2) +#define ANT_AB (ANT_A | ANT_B) +#define ANT_AC (ANT_A | ANT_C) +#define ANT_BC (ANT_B | ANT_C) +#define ANT_ABC (ANT_A | ANT_B | ANT_C) +#define MAX_ANT_NUM 3 + +#define IWL_RATE_BIT_MSK(r) BIT(IWL_RATE_##r##M_INDEX) + +/* fw API values for legacy bit rates, both OFDM and CCK */ +enum { + IWL_RATE_6M_PLCP = 13, + IWL_RATE_9M_PLCP = 15, + IWL_RATE_12M_PLCP = 5, + IWL_RATE_18M_PLCP = 7, + IWL_RATE_24M_PLCP = 9, + IWL_RATE_36M_PLCP = 11, + IWL_RATE_48M_PLCP = 1, + IWL_RATE_54M_PLCP = 3, + IWL_RATE_1M_PLCP = 10, + IWL_RATE_2M_PLCP = 20, + IWL_RATE_5M_PLCP = 55, + IWL_RATE_11M_PLCP = 110, + IWL_RATE_INVM_PLCP = 0xff, +}; + +static inline u8 num_of_ant(u8 mask) +{ + return !!((mask) & ANT_A) + + !!((mask) & ANT_B) + + !!((mask) & ANT_C); +} + +/* + * Returns the first antenna as ANT_[ABC], as defined in iwl-config.h. + * The parameter should also be a combination of ANT_[ABC]. + */ +static inline u8 first_antenna(u8 mask) +{ + BUILD_BUG_ON(ANT_A != BIT(0)); /* using ffs is wrong if not */ + if (WARN_ON_ONCE(!mask)) /* ffs will return 0 if mask is zeroed */ + return BIT(0); + return BIT(ffs(mask) - 1); +} + +/* + * These serve as indexes into + * struct iwl_rate_info fw_rate_idx_to_plcp[IWL_RATE_COUNT]; + * TODO: avoid overlap between legacy and HT rates + */ +enum { + IWL_RATE_1M_INDEX = 0, + IWL_FIRST_CCK_RATE = IWL_RATE_1M_INDEX, + IWL_RATE_2M_INDEX, + IWL_RATE_5M_INDEX, + IWL_RATE_11M_INDEX, + IWL_LAST_CCK_RATE = IWL_RATE_11M_INDEX, + IWL_RATE_6M_INDEX, + IWL_FIRST_OFDM_RATE = IWL_RATE_6M_INDEX, + IWL_RATE_MCS_0_INDEX = IWL_RATE_6M_INDEX, + IWL_FIRST_HT_RATE = IWL_RATE_MCS_0_INDEX, + IWL_FIRST_VHT_RATE = IWL_RATE_MCS_0_INDEX, + IWL_RATE_9M_INDEX, + IWL_RATE_12M_INDEX, + IWL_RATE_MCS_1_INDEX = IWL_RATE_12M_INDEX, + IWL_RATE_18M_INDEX, + IWL_RATE_MCS_2_INDEX = IWL_RATE_18M_INDEX, + IWL_RATE_24M_INDEX, + IWL_RATE_MCS_3_INDEX = IWL_RATE_24M_INDEX, + IWL_RATE_36M_INDEX, + IWL_RATE_MCS_4_INDEX = IWL_RATE_36M_INDEX, + IWL_RATE_48M_INDEX, + IWL_RATE_MCS_5_INDEX = IWL_RATE_48M_INDEX, + IWL_RATE_54M_INDEX, + IWL_RATE_MCS_6_INDEX = IWL_RATE_54M_INDEX, + IWL_LAST_NON_HT_RATE = IWL_RATE_54M_INDEX, + IWL_RATE_60M_INDEX, + IWL_RATE_MCS_7_INDEX = IWL_RATE_60M_INDEX, + IWL_LAST_HT_RATE = IWL_RATE_MCS_7_INDEX, + IWL_RATE_MCS_8_INDEX, + IWL_RATE_MCS_9_INDEX, + IWL_LAST_VHT_RATE = IWL_RATE_MCS_9_INDEX, + IWL_RATE_MCS_10_INDEX, + IWL_RATE_MCS_11_INDEX, + IWL_LAST_HE_RATE = IWL_RATE_MCS_11_INDEX, + IWL_RATE_COUNT_LEGACY = IWL_LAST_NON_HT_RATE + 1, + IWL_RATE_COUNT = IWL_LAST_HE_RATE + 1, +}; + +/* + * rate_n_flags bit fields + * + * The 32-bit value has different layouts in the low 8 bites depending on the + * format. There are three formats, HT, VHT and legacy (11abg, with subformats + * for CCK and OFDM). + * + * High-throughput (HT) rate format + * bit 8 is 1, bit 26 is 0, bit 9 is 0 (OFDM) + * Very High-throughput (VHT) rate format + * bit 8 is 0, bit 26 is 1, bit 9 is 0 (OFDM) + * Legacy OFDM rate format for bits 7:0 + * bit 8 is 0, bit 26 is 0, bit 9 is 0 (OFDM) + * Legacy CCK rate format for bits 7:0: + * bit 8 is 0, bit 26 is 0, bit 9 is 1 (CCK) + */ + +/* Bit 8: (1) HT format, (0) legacy or VHT format */ +#define RATE_MCS_HT_POS 8 +#define RATE_MCS_HT_MSK (1 << RATE_MCS_HT_POS) + +/* Bit 9: (1) CCK, (0) OFDM. HT (bit 8) must be "0" for this bit to be valid */ +#define RATE_MCS_CCK_POS 9 +#define RATE_MCS_CCK_MSK (1 << RATE_MCS_CCK_POS) + +/* Bit 26: (1) VHT format, (0) legacy format in bits 8:0 */ +#define RATE_MCS_VHT_POS 26 +#define RATE_MCS_VHT_MSK (1 << RATE_MCS_VHT_POS) + + +/* + * High-throughput (HT) rate format for bits 7:0 + * + * 2-0: MCS rate base + * 0) 6 Mbps + * 1) 12 Mbps + * 2) 18 Mbps + * 3) 24 Mbps + * 4) 36 Mbps + * 5) 48 Mbps + * 6) 54 Mbps + * 7) 60 Mbps + * 4-3: 0) Single stream (SISO) + * 1) Dual stream (MIMO) + * 2) Triple stream (MIMO) + * 5: Value of 0x20 in bits 7:0 indicates 6 Mbps HT40 duplicate data + * (bits 7-6 are zero) + * + * Together the low 5 bits work out to the MCS index because we don't + * support MCSes above 15/23, and 0-7 have one stream, 8-15 have two + * streams and 16-23 have three streams. We could also support MCS 32 + * which is the duplicate 20 MHz MCS (bit 5 set, all others zero.) + */ +#define RATE_HT_MCS_RATE_CODE_MSK 0x7 +#define RATE_HT_MCS_NSS_POS 3 +#define RATE_HT_MCS_NSS_MSK (3 << RATE_HT_MCS_NSS_POS) + +/* Bit 10: (1) Use Green Field preamble */ +#define RATE_HT_MCS_GF_POS 10 +#define RATE_HT_MCS_GF_MSK (1 << RATE_HT_MCS_GF_POS) + +#define RATE_HT_MCS_INDEX_MSK 0x3f + +/* + * Very High-throughput (VHT) rate format for bits 7:0 + * + * 3-0: VHT MCS (0-9) + * 5-4: number of streams - 1: + * 0) Single stream (SISO) + * 1) Dual stream (MIMO) + * 2) Triple stream (MIMO) + */ + +/* Bit 4-5: (0) SISO, (1) MIMO2 (2) MIMO3 */ +#define RATE_VHT_MCS_RATE_CODE_MSK 0xf +#define RATE_VHT_MCS_NSS_POS 4 +#define RATE_VHT_MCS_NSS_MSK (3 << RATE_VHT_MCS_NSS_POS) + +/* + * Legacy OFDM rate format for bits 7:0 + * + * 3-0: 0xD) 6 Mbps + * 0xF) 9 Mbps + * 0x5) 12 Mbps + * 0x7) 18 Mbps + * 0x9) 24 Mbps + * 0xB) 36 Mbps + * 0x1) 48 Mbps + * 0x3) 54 Mbps + * (bits 7-4 are 0) + * + * Legacy CCK rate format for bits 7:0: + * bit 8 is 0, bit 26 is 0, bit 9 is 1 (CCK): + * + * 6-0: 10) 1 Mbps + * 20) 2 Mbps + * 55) 5.5 Mbps + * 110) 11 Mbps + * (bit 7 is 0) + */ +#define RATE_LEGACY_RATE_MSK 0xff + +/* Bit 10 - OFDM HE */ +#define RATE_MCS_HE_POS 10 +#define RATE_MCS_HE_MSK BIT(RATE_MCS_HE_POS) + +/* + * Bit 11-12: (0) 20MHz, (1) 40MHz, (2) 80MHz, (3) 160MHz + * 0 and 1 are valid for HT and VHT, 2 and 3 only for VHT + */ +#define RATE_MCS_CHAN_WIDTH_POS 11 +#define RATE_MCS_CHAN_WIDTH_MSK (3 << RATE_MCS_CHAN_WIDTH_POS) +#define RATE_MCS_CHAN_WIDTH_20 (0 << RATE_MCS_CHAN_WIDTH_POS) +#define RATE_MCS_CHAN_WIDTH_40 (1 << RATE_MCS_CHAN_WIDTH_POS) +#define RATE_MCS_CHAN_WIDTH_80 (2 << RATE_MCS_CHAN_WIDTH_POS) +#define RATE_MCS_CHAN_WIDTH_160 (3 << RATE_MCS_CHAN_WIDTH_POS) + +/* Bit 13: (1) Short guard interval (0.4 usec), (0) normal GI (0.8 usec) */ +#define RATE_MCS_SGI_POS 13 +#define RATE_MCS_SGI_MSK (1 << RATE_MCS_SGI_POS) + +/* Bit 14-16: Antenna selection (1) Ant A, (2) Ant B, (4) Ant C */ +#define RATE_MCS_ANT_POS 14 +#define RATE_MCS_ANT_A_MSK (1 << RATE_MCS_ANT_POS) +#define RATE_MCS_ANT_B_MSK (2 << RATE_MCS_ANT_POS) +#define RATE_MCS_ANT_C_MSK (4 << RATE_MCS_ANT_POS) +#define RATE_MCS_ANT_AB_MSK (RATE_MCS_ANT_A_MSK | \ + RATE_MCS_ANT_B_MSK) +#define RATE_MCS_ANT_ABC_MSK (RATE_MCS_ANT_AB_MSK | \ + RATE_MCS_ANT_C_MSK) +#define RATE_MCS_ANT_MSK RATE_MCS_ANT_ABC_MSK + +/* Bit 17: (0) SS, (1) SS*2 */ +#define RATE_MCS_STBC_POS 17 +#define RATE_MCS_STBC_MSK BIT(RATE_MCS_STBC_POS) + +/* Bit 18: OFDM-HE dual carrier mode */ +#define RATE_HE_DUAL_CARRIER_MODE 18 +#define RATE_HE_DUAL_CARRIER_MODE_MSK BIT(RATE_HE_DUAL_CARRIER_MODE) + +/* Bit 19: (0) Beamforming is off, (1) Beamforming is on */ +#define RATE_MCS_BF_POS 19 +#define RATE_MCS_BF_MSK (1 << RATE_MCS_BF_POS) + +/* + * Bit 20-21: HE LTF type and guard interval + * HE (ext) SU: + * 0 1xLTF+0.8us + * 1 2xLTF+0.8us + * 2 2xLTF+1.6us + * 3 & SGI (bit 13) clear 4xLTF+3.2us + * 3 & SGI (bit 13) set 4xLTF+0.8us + * HE MU: + * 0 4xLTF+0.8us + * 1 2xLTF+0.8us + * 2 2xLTF+1.6us + * 3 4xLTF+3.2us + * HE TRIG: + * 0 1xLTF+1.6us + * 1 2xLTF+1.6us + * 2 4xLTF+3.2us + * 3 (does not occur) + */ +#define RATE_MCS_HE_GI_LTF_POS 20 +#define RATE_MCS_HE_GI_LTF_MSK (3 << RATE_MCS_HE_GI_LTF_POS) + +/* Bit 22-23: HE type. (0) SU, (1) SU_EXT, (2) MU, (3) trigger based */ +#define RATE_MCS_HE_TYPE_POS 22 +#define RATE_MCS_HE_TYPE_SU (0 << RATE_MCS_HE_TYPE_POS) +#define RATE_MCS_HE_TYPE_EXT_SU (1 << RATE_MCS_HE_TYPE_POS) +#define RATE_MCS_HE_TYPE_MU (2 << RATE_MCS_HE_TYPE_POS) +#define RATE_MCS_HE_TYPE_TRIG (3 << RATE_MCS_HE_TYPE_POS) +#define RATE_MCS_HE_TYPE_MSK (3 << RATE_MCS_HE_TYPE_POS) + +/* Bit 24-25: (0) 20MHz (no dup), (1) 2x20MHz, (2) 4x20MHz, 3 8x20MHz */ +#define RATE_MCS_DUP_POS 24 +#define RATE_MCS_DUP_MSK (3 << RATE_MCS_DUP_POS) + +/* Bit 27: (1) LDPC enabled, (0) LDPC disabled */ +#define RATE_MCS_LDPC_POS 27 +#define RATE_MCS_LDPC_MSK (1 << RATE_MCS_LDPC_POS) + +/* Bit 28: (1) 106-tone RX (8 MHz RU), (0) normal bandwidth */ +#define RATE_MCS_HE_106T_POS 28 +#define RATE_MCS_HE_106T_MSK (1 << RATE_MCS_HE_106T_POS) + +/* Bit 30-31: (1) RTS, (2) CTS */ +#define RATE_MCS_RTS_REQUIRED_POS (30) +#define RATE_MCS_RTS_REQUIRED_MSK (0x1 << RATE_MCS_RTS_REQUIRED_POS) + +#define RATE_MCS_CTS_REQUIRED_POS (31) +#define RATE_MCS_CTS_REQUIRED_MSK (0x1 << RATE_MCS_CTS_REQUIRED_POS) + +/* Link Quality definitions */ + +/* # entries in rate scale table to support Tx retries */ +#define LQ_MAX_RETRY_NUM 16 + +/* Link quality command flags bit fields */ + +/* Bit 0: (0) Don't use RTS (1) Use RTS */ +#define LQ_FLAG_USE_RTS_POS 0 +#define LQ_FLAG_USE_RTS_MSK (1 << LQ_FLAG_USE_RTS_POS) + +/* Bit 1-3: LQ command color. Used to match responses to LQ commands */ +#define LQ_FLAG_COLOR_POS 1 +#define LQ_FLAG_COLOR_MSK (7 << LQ_FLAG_COLOR_POS) +#define LQ_FLAG_COLOR_GET(_f) (((_f) & LQ_FLAG_COLOR_MSK) >>\ + LQ_FLAG_COLOR_POS) +#define LQ_FLAGS_COLOR_INC(_c) ((((_c) + 1) << LQ_FLAG_COLOR_POS) &\ + LQ_FLAG_COLOR_MSK) +#define LQ_FLAG_COLOR_SET(_f, _c) ((_c) | ((_f) & ~LQ_FLAG_COLOR_MSK)) + +/* Bit 4-5: Tx RTS BW Signalling + * (0) No RTS BW signalling + * (1) Static BW signalling + * (2) Dynamic BW signalling + */ +#define LQ_FLAG_RTS_BW_SIG_POS 4 +#define LQ_FLAG_RTS_BW_SIG_NONE (0 << LQ_FLAG_RTS_BW_SIG_POS) +#define LQ_FLAG_RTS_BW_SIG_STATIC (1 << LQ_FLAG_RTS_BW_SIG_POS) +#define LQ_FLAG_RTS_BW_SIG_DYNAMIC (2 << LQ_FLAG_RTS_BW_SIG_POS) + +/* Bit 6: (0) No dynamic BW selection (1) Allow dynamic BW selection + * Dyanmic BW selection allows Tx with narrower BW then requested in rates + */ +#define LQ_FLAG_DYNAMIC_BW_POS 6 +#define LQ_FLAG_DYNAMIC_BW_MSK (1 << LQ_FLAG_DYNAMIC_BW_POS) + +/* Single Stream Tx Parameters (lq_cmd->ss_params) + * Flags to control a smart FW decision about whether BFER/STBC/SISO will be + * used for single stream Tx. + */ + +/* Bit 0-1: Max STBC streams allowed. Can be 0-3. + * (0) - No STBC allowed + * (1) - 2x1 STBC allowed (HT/VHT) + * (2) - 4x2 STBC allowed (HT/VHT) + * (3) - 3x2 STBC allowed (HT only) + * All our chips are at most 2 antennas so only (1) is valid for now. + */ +#define LQ_SS_STBC_ALLOWED_POS 0 +#define LQ_SS_STBC_ALLOWED_MSK (3 << LQ_SS_STBC_ALLOWED_MSK) + +/* 2x1 STBC is allowed */ +#define LQ_SS_STBC_1SS_ALLOWED (1 << LQ_SS_STBC_ALLOWED_POS) + +/* Bit 2: Beamformer (VHT only) is allowed */ +#define LQ_SS_BFER_ALLOWED_POS 2 +#define LQ_SS_BFER_ALLOWED (1 << LQ_SS_BFER_ALLOWED_POS) + +/* Bit 3: Force BFER or STBC for testing + * If this is set: + * If BFER is allowed then force the ucode to choose BFER else + * If STBC is allowed then force the ucode to choose STBC over SISO + */ +#define LQ_SS_FORCE_POS 3 +#define LQ_SS_FORCE (1 << LQ_SS_FORCE_POS) + +/* Bit 31: ss_params field is valid. Used for FW backward compatibility + * with other drivers which don't support the ss_params API yet + */ +#define LQ_SS_PARAMS_VALID_POS 31 +#define LQ_SS_PARAMS_VALID (1 << LQ_SS_PARAMS_VALID_POS) + +struct iwl_rs_rate_info { + u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */ + u8 plcp_ht_siso; /* uCode API: IWL_RATE_SISO_6M_PLCP, etc. */ + u8 plcp_ht_mimo2; /* uCode API: IWL_RATE_MIMO2_6M_PLCP, etc. */ + u8 plcp_vht_siso; + u8 plcp_vht_mimo2; + u8 prev_rs; /* previous rate used in rs algo */ + u8 next_rs; /* next rate used in rs algo */ +}; + +#define IWL_RATE_60M_PLCP 3 + +enum { + IWL_RATE_INVM_INDEX = IWL_RATE_COUNT, + IWL_RATE_INVALID = IWL_RATE_COUNT, +}; + +#define LINK_QUAL_MAX_RETRY_NUM 16 + +enum { + IWL_RATE_6M_INDEX_TABLE = 0, + IWL_RATE_9M_INDEX_TABLE, + IWL_RATE_12M_INDEX_TABLE, + IWL_RATE_18M_INDEX_TABLE, + IWL_RATE_24M_INDEX_TABLE, + IWL_RATE_36M_INDEX_TABLE, + IWL_RATE_48M_INDEX_TABLE, + IWL_RATE_54M_INDEX_TABLE, + IWL_RATE_1M_INDEX_TABLE, + IWL_RATE_2M_INDEX_TABLE, + IWL_RATE_5M_INDEX_TABLE, + IWL_RATE_11M_INDEX_TABLE, + IWL_RATE_INVM_INDEX_TABLE = IWL_RATE_INVM_INDEX - 1, +}; + +/* #define vs. enum to keep from defaulting to 'large integer' */ +#define IWL_RATE_6M_MASK (1 << IWL_RATE_6M_INDEX) +#define IWL_RATE_9M_MASK (1 << IWL_RATE_9M_INDEX) +#define IWL_RATE_12M_MASK (1 << IWL_RATE_12M_INDEX) +#define IWL_RATE_18M_MASK (1 << IWL_RATE_18M_INDEX) +#define IWL_RATE_24M_MASK (1 << IWL_RATE_24M_INDEX) +#define IWL_RATE_36M_MASK (1 << IWL_RATE_36M_INDEX) +#define IWL_RATE_48M_MASK (1 << IWL_RATE_48M_INDEX) +#define IWL_RATE_54M_MASK (1 << IWL_RATE_54M_INDEX) +#define IWL_RATE_60M_MASK (1 << IWL_RATE_60M_INDEX) +#define IWL_RATE_1M_MASK (1 << IWL_RATE_1M_INDEX) +#define IWL_RATE_2M_MASK (1 << IWL_RATE_2M_INDEX) +#define IWL_RATE_5M_MASK (1 << IWL_RATE_5M_INDEX) +#define IWL_RATE_11M_MASK (1 << IWL_RATE_11M_INDEX) + + +/* uCode API values for HT/VHT bit rates */ +enum { + IWL_RATE_HT_SISO_MCS_0_PLCP = 0, + IWL_RATE_HT_SISO_MCS_1_PLCP = 1, + IWL_RATE_HT_SISO_MCS_2_PLCP = 2, + IWL_RATE_HT_SISO_MCS_3_PLCP = 3, + IWL_RATE_HT_SISO_MCS_4_PLCP = 4, + IWL_RATE_HT_SISO_MCS_5_PLCP = 5, + IWL_RATE_HT_SISO_MCS_6_PLCP = 6, + IWL_RATE_HT_SISO_MCS_7_PLCP = 7, + IWL_RATE_HT_MIMO2_MCS_0_PLCP = 0x8, + IWL_RATE_HT_MIMO2_MCS_1_PLCP = 0x9, + IWL_RATE_HT_MIMO2_MCS_2_PLCP = 0xA, + IWL_RATE_HT_MIMO2_MCS_3_PLCP = 0xB, + IWL_RATE_HT_MIMO2_MCS_4_PLCP = 0xC, + IWL_RATE_HT_MIMO2_MCS_5_PLCP = 0xD, + IWL_RATE_HT_MIMO2_MCS_6_PLCP = 0xE, + IWL_RATE_HT_MIMO2_MCS_7_PLCP = 0xF, + IWL_RATE_VHT_SISO_MCS_0_PLCP = 0, + IWL_RATE_VHT_SISO_MCS_1_PLCP = 1, + IWL_RATE_VHT_SISO_MCS_2_PLCP = 2, + IWL_RATE_VHT_SISO_MCS_3_PLCP = 3, + IWL_RATE_VHT_SISO_MCS_4_PLCP = 4, + IWL_RATE_VHT_SISO_MCS_5_PLCP = 5, + IWL_RATE_VHT_SISO_MCS_6_PLCP = 6, + IWL_RATE_VHT_SISO_MCS_7_PLCP = 7, + IWL_RATE_VHT_SISO_MCS_8_PLCP = 8, + IWL_RATE_VHT_SISO_MCS_9_PLCP = 9, + IWL_RATE_VHT_MIMO2_MCS_0_PLCP = 0x10, + IWL_RATE_VHT_MIMO2_MCS_1_PLCP = 0x11, + IWL_RATE_VHT_MIMO2_MCS_2_PLCP = 0x12, + IWL_RATE_VHT_MIMO2_MCS_3_PLCP = 0x13, + IWL_RATE_VHT_MIMO2_MCS_4_PLCP = 0x14, + IWL_RATE_VHT_MIMO2_MCS_5_PLCP = 0x15, + IWL_RATE_VHT_MIMO2_MCS_6_PLCP = 0x16, + IWL_RATE_VHT_MIMO2_MCS_7_PLCP = 0x17, + IWL_RATE_VHT_MIMO2_MCS_8_PLCP = 0x18, + IWL_RATE_VHT_MIMO2_MCS_9_PLCP = 0x19, + IWL_RATE_HT_SISO_MCS_INV_PLCP, + IWL_RATE_HT_MIMO2_MCS_INV_PLCP = IWL_RATE_HT_SISO_MCS_INV_PLCP, + IWL_RATE_VHT_SISO_MCS_INV_PLCP = IWL_RATE_HT_SISO_MCS_INV_PLCP, + IWL_RATE_VHT_MIMO2_MCS_INV_PLCP = IWL_RATE_HT_SISO_MCS_INV_PLCP, + IWL_RATE_HT_SISO_MCS_8_PLCP = IWL_RATE_HT_SISO_MCS_INV_PLCP, + IWL_RATE_HT_SISO_MCS_9_PLCP = IWL_RATE_HT_SISO_MCS_INV_PLCP, + IWL_RATE_HT_MIMO2_MCS_8_PLCP = IWL_RATE_HT_SISO_MCS_INV_PLCP, + IWL_RATE_HT_MIMO2_MCS_9_PLCP = IWL_RATE_HT_SISO_MCS_INV_PLCP, +}; + +#define IWL_RATES_MASK ((1 << IWL_RATE_COUNT) - 1) + +#define IWL_INVALID_VALUE 0xff + +#define TPC_MAX_REDUCTION 15 +#define TPC_NO_REDUCTION 0 +#define TPC_INVALID 0xff + +#define LINK_QUAL_AGG_FRAME_LIMIT_DEF (63) +#define LINK_QUAL_AGG_FRAME_LIMIT_MAX (63) +/* + * FIXME - various places in firmware API still use u8, + * e.g. LQ command and SCD config command. + * This should be 256 instead. + */ +#define LINK_QUAL_AGG_FRAME_LIMIT_GEN2_DEF (255) +#define LINK_QUAL_AGG_FRAME_LIMIT_GEN2_MAX (255) +#define LINK_QUAL_AGG_FRAME_LIMIT_MIN (0) + +#define LQ_SIZE 2 /* 2 mode tables: "Active" and "Search" */ + +/* load per tid defines for A-MPDU activation */ +#define IWL_AGG_TPT_THREHOLD 0 +#define IWL_AGG_ALL_TID 0xff + +enum iwl_table_type { + LQ_NONE, + LQ_LEGACY_G, /* legacy types */ + LQ_LEGACY_A, + LQ_HT_SISO, /* HT types */ + LQ_HT_MIMO2, + LQ_VHT_SISO, /* VHT types */ + LQ_VHT_MIMO2, + LQ_HE_SISO, /* HE types */ + LQ_HE_MIMO2, + LQ_MAX, +}; + +struct rs_rate { + int index; + enum iwl_table_type type; + u8 ant; + u32 bw; + bool sgi; + bool ldpc; + bool stbc; + bool bfer; +}; + +#define is_type_legacy(type) (((type) == LQ_LEGACY_G) || \ + ((type) == LQ_LEGACY_A)) +#define is_type_ht_siso(type) ((type) == LQ_HT_SISO) +#define is_type_ht_mimo2(type) ((type) == LQ_HT_MIMO2) +#define is_type_vht_siso(type) ((type) == LQ_VHT_SISO) +#define is_type_vht_mimo2(type) ((type) == LQ_VHT_MIMO2) +#define is_type_he_siso(type) ((type) == LQ_HE_SISO) +#define is_type_he_mimo2(type) ((type) == LQ_HE_MIMO2) +#define is_type_siso(type) (is_type_ht_siso(type) || is_type_vht_siso(type) || \ + is_type_he_siso(type)) +#define is_type_mimo2(type) (is_type_ht_mimo2(type) || \ + is_type_vht_mimo2(type) || is_type_he_mimo2(type)) +#define is_type_mimo(type) (is_type_mimo2(type)) +#define is_type_ht(type) (is_type_ht_siso(type) || is_type_ht_mimo2(type)) +#define is_type_vht(type) (is_type_vht_siso(type) || is_type_vht_mimo2(type)) +#define is_type_he(type) (is_type_he_siso(type) || is_type_he_mimo2(type)) +#define is_type_a_band(type) ((type) == LQ_LEGACY_A) +#define is_type_g_band(type) ((type) == LQ_LEGACY_G) + +#define is_legacy(rate) is_type_legacy((rate)->type) +#define is_ht_siso(rate) is_type_ht_siso((rate)->type) +#define is_ht_mimo2(rate) is_type_ht_mimo2((rate)->type) +#define is_vht_siso(rate) is_type_vht_siso((rate)->type) +#define is_vht_mimo2(rate) is_type_vht_mimo2((rate)->type) +#define is_siso(rate) is_type_siso((rate)->type) +#define is_mimo2(rate) is_type_mimo2((rate)->type) +#define is_mimo(rate) is_type_mimo((rate)->type) +#define is_ht(rate) is_type_ht((rate)->type) +#define is_vht(rate) is_type_vht((rate)->type) +#define is_he(rate) is_type_he((rate)->type) +#define is_a_band(rate) is_type_a_band((rate)->type) +#define is_g_band(rate) is_type_g_band((rate)->type) + +#define is_ht20(rate) ((rate)->bw == RATE_MCS_CHAN_WIDTH_20) +#define is_ht40(rate) ((rate)->bw == RATE_MCS_CHAN_WIDTH_40) +#define is_ht80(rate) ((rate)->bw == RATE_MCS_CHAN_WIDTH_80) +#define is_ht160(rate) ((rate)->bw == RATE_MCS_CHAN_WIDTH_160) + +#define IWL_MAX_MCS_DISPLAY_SIZE 12 + +struct iwl_rate_mcs_info { + char mbps[IWL_MAX_MCS_DISPLAY_SIZE]; + char mcs[IWL_MAX_MCS_DISPLAY_SIZE]; +}; + +/** + * struct iwl_lq_sta_rs_fw - rate and related statistics for RS in FW + * @last_rate_n_flags: last rate reported by FW + * @sta_id: the id of the station +#ifdef CONFIG_MAC80211_DEBUGFS + * @dbg_fixed_rate: for debug, use fixed rate if not 0 + * @dbg_agg_frame_count_lim: for debug, max number of frames in A-MPDU +#endif + * @chains: bitmask of chains reported in %chain_signal + * @chain_signal: per chain signal strength + * @last_rssi: last rssi reported + * @drv: pointer back to the driver data + */ + +struct iwl_lq_sta_rs_fw { + /* last tx rate_n_flags */ + u32 last_rate_n_flags; + + /* persistent fields - initialized only once - keep last! */ + struct lq_sta_pers_rs_fw { + u32 sta_id; + u8 chains; + s8 chain_signal[4]; + s8 last_rssi; + struct iwm_softc *drv; + } pers; +}; + +/** + * struct iwl_rate_scale_data -- tx success history for one rate + */ +struct iwl_rate_scale_data { + u64 data; /* bitmap of successful frames */ + s32 success_counter; /* number of frames successful */ + s32 success_ratio; /* per-cent * 128 */ + s32 counter; /* number of frames attempted */ + s32 average_tpt; /* success ratio * expected throughput */ +}; + +/* Possible Tx columns + * Tx Column = a combo of legacy/siso/mimo x antenna x SGI + */ +enum rs_column { + RS_COLUMN_LEGACY_ANT_A = 0, + RS_COLUMN_LEGACY_ANT_B, + RS_COLUMN_SISO_ANT_A, + RS_COLUMN_SISO_ANT_B, + RS_COLUMN_SISO_ANT_A_SGI, + RS_COLUMN_SISO_ANT_B_SGI, + RS_COLUMN_MIMO2, + RS_COLUMN_MIMO2_SGI, + + RS_COLUMN_LAST = RS_COLUMN_MIMO2_SGI, + RS_COLUMN_COUNT = RS_COLUMN_LAST + 1, + RS_COLUMN_INVALID, +}; + +enum rs_ss_force_opt { + RS_SS_FORCE_NONE = 0, + RS_SS_FORCE_STBC, + RS_SS_FORCE_BFER, + RS_SS_FORCE_SISO, +}; + +/* Packet stats per rate */ +struct rs_rate_stats { + u64 success; + u64 total; +}; + +/** + * struct iwl_scale_tbl_info -- tx params and success history for all rates + * + * There are two of these in struct iwl_lq_sta, + * one for "active", and one for "search". + */ +struct iwl_scale_tbl_info { + struct rs_rate rate; + enum rs_column column; + const u16 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */ + struct iwl_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */ + /* per txpower-reduction history */ + struct iwl_rate_scale_data tpc_win[TPC_MAX_REDUCTION + 1]; +}; + +enum { + RS_STATE_SEARCH_CYCLE_STARTED, + RS_STATE_SEARCH_CYCLE_ENDED, + RS_STATE_STAY_IN_COLUMN, +}; + +struct lq_sta_pers { + u8 chains; + s8 chain_signal[4]; + s8 last_rssi; + struct rs_rate_stats tx_stats[RS_COLUMN_COUNT][IWL_RATE_COUNT]; + struct iwm_softc *drv; + IOSimpleLock *lock; /* for races in reinit/update table */ +}; + +/** + * struct iwl_lq_sta -- driver's rate scaling private structure + * + * Pointer to this gets passed back and forth between driver and mac80211. + */ +struct iwl_lq_sta { + u8 active_tbl; /* index of active table, range 0-1 */ + u8 rs_state; /* RS_STATE_* */ + u8 search_better_tbl; /* 1: currently trying alternate mode */ + s32 last_tpt; + + /* The following determine when to search for a new mode */ + u32 table_count_limit; + u32 max_failure_limit; /* # failed frames before new search */ + u32 max_success_limit; /* # successful frames before new search */ + u32 table_count; + u32 total_failed; /* total failed frames, any/all rates */ + u32 total_success; /* total successful frames, any/all rates */ + u64 flush_timer; /* time staying in mode before new search */ + + u32 visited_columns; /* Bitmask marking which Tx columns were + * explored during a search cycle + */ + u64 last_tx; + bool is_vht; + bool ldpc; /* LDPC Rx is supported by the STA */ + bool stbc_capable; /* Tx STBC is supported by chip and Rx by STA */ + bool bfer_capable; /* Remote supports beamformee and we BFer */ + + enum nl80211_band band; + + /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */ + unsigned long active_legacy_rate; + unsigned long active_siso_rate; + unsigned long active_mimo2_rate; + + /* Highest rate per Tx mode */ + u8 max_legacy_rate_idx; + u8 max_siso_rate_idx; + u8 max_mimo2_rate_idx; + + /* Optimal rate based on RSSI and STA caps. + * Used only to reflect link speed to userspace. + */ + struct rs_rate optimal_rate; + unsigned long optimal_rate_mask; + const struct rs_init_rate_info *optimal_rates; + int optimal_nentries; + + u8 missed_rate_counter; + + struct iwm_lq_cmd lq; + struct iwl_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */ + u8 tx_agg_tid_en; + + /* last tx rate_n_flags */ + u32 last_rate_n_flags; + /* packets destined for this STA are aggregated */ + u8 is_agg; + + /* tx power reduce for this sta */ + int tpc_reduce; + + /* persistent fields - initialized only once - keep last! */ + struct lq_sta_pers pers; +}; + +/* ieee80211_tx_info's status_driver_data[0] is packed with lq color and txp + * Note, it's iwlmvm <-> mac80211 interface. + * bits 0-7: reduced tx power + * bits 8-10: LQ command's color + */ +#define RS_DRV_DATA_TXP_MSK 0xff +#define RS_DRV_DATA_LQ_COLOR_POS 8 +#define RS_DRV_DATA_LQ_COLOR_MSK (7 << RS_DRV_DATA_LQ_COLOR_POS) +#define RS_DRV_DATA_LQ_COLOR_GET(_f) (((_f) & RS_DRV_DATA_LQ_COLOR_MSK) >>\ + RS_DRV_DATA_LQ_COLOR_POS) +#define RS_DRV_DATA_PACK(_c, _p) ((void *)(uintptr_t)\ + (((uintptr_t)_p) |\ + ((_c) << RS_DRV_DATA_LQ_COLOR_POS))) + +#define IWL_DECLARE_RATE_INFO(r) \ + [IWL_RATE_##r##M_INDEX] = IWL_RATE_##r##M_PLCP + +/* + * Translate from fw_rate_index (IWL_RATE_XXM_INDEX) to PLCP + */ +static const u8 fw_rate_idx_to_plcp[IWL_RATE_COUNT] = { + IWL_DECLARE_RATE_INFO(1), + IWL_DECLARE_RATE_INFO(2), + IWL_DECLARE_RATE_INFO(5), + IWL_DECLARE_RATE_INFO(11), + IWL_DECLARE_RATE_INFO(6), + IWL_DECLARE_RATE_INFO(9), + IWL_DECLARE_RATE_INFO(12), + IWL_DECLARE_RATE_INFO(18), + IWL_DECLARE_RATE_INFO(24), + IWL_DECLARE_RATE_INFO(36), + IWL_DECLARE_RATE_INFO(48), + IWL_DECLARE_RATE_INFO(54), +}; + +#undef IWL_DECLARE_RATE_INFO + +static inline int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags, + enum nl80211_band band) +{ + int rate = rate_n_flags & RATE_LEGACY_RATE_MSK; + int idx; + int band_offset = 0; + + /* Legacy rate format, search for match in table */ + if (band != NL80211_BAND_2GHZ) + band_offset = IWL_FIRST_OFDM_RATE; + for (idx = band_offset; idx < IWL_RATE_COUNT_LEGACY; idx++) + if (fw_rate_idx_to_plcp[idx] == rate) + return idx - band_offset; + + return -1; +} + +static inline u8 iwl_mvm_mac80211_idx_to_hwrate(int rate_idx) +{ + /* Get PLCP rate for tx_cmd->rate_n_flags */ + return fw_rate_idx_to_plcp[rate_idx]; +} + +static inline void ieee80211_rate_set_vht(struct ieee80211_tx_rate *rate, + u8 mcs, u8 nss) +{ + WARN_ON(mcs & ~0xF); + WARN_ON((nss - 1) & ~0x7); + rate->idx = ((nss - 1) << 4) | mcs; +} + +static inline void iwl_mvm_hwrate_to_tx_rate(u32 rate_n_flags, + enum nl80211_band band, + struct ieee80211_tx_rate *r) +{ + if (rate_n_flags & RATE_HT_MCS_GF_MSK) + r->flags |= IEEE80211_TX_RC_GREEN_FIELD; + switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) { + case RATE_MCS_CHAN_WIDTH_20: + break; + case RATE_MCS_CHAN_WIDTH_40: + r->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; + break; + case RATE_MCS_CHAN_WIDTH_80: + r->flags |= IEEE80211_TX_RC_80_MHZ_WIDTH; + break; + case RATE_MCS_CHAN_WIDTH_160: + r->flags |= IEEE80211_TX_RC_160_MHZ_WIDTH; + break; + } + if (rate_n_flags & RATE_MCS_SGI_MSK) + r->flags |= IEEE80211_TX_RC_SHORT_GI; + if (rate_n_flags & RATE_MCS_HT_MSK) { + r->flags |= IEEE80211_TX_RC_MCS; + r->idx = rate_n_flags & RATE_HT_MCS_INDEX_MSK; + } else if (rate_n_flags & RATE_MCS_VHT_MSK) { + ieee80211_rate_set_vht( + r, rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK, + ((rate_n_flags & RATE_VHT_MCS_NSS_MSK) >> + RATE_VHT_MCS_NSS_POS) + 1); + r->flags |= IEEE80211_TX_RC_VHT_MCS; + } else { + r->idx = iwl_mvm_legacy_rate_to_mac80211_idx(rate_n_flags, + band); + } +} + +/* + * translate ucode response to mac80211 tx status control values + */ +static inline void iwl_mvm_hwrate_to_tx_status(u32 rate_n_flags, + struct ieee80211_tx_info *info) +{ + struct ieee80211_tx_rate *r = &info->status.rates[0]; + + info->status.antenna = + ((rate_n_flags & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS); + iwl_mvm_hwrate_to_tx_rate(rate_n_flags, (enum nl80211_band)info->band, r); +} + +int iwl_mvm_send_lq_cmd(struct iwm_softc *sc, struct iwm_lq_cmd *lq); + +/* Initialize station's rate scaling information after adding station */ +void iwl_mvm_rs_rate_init(struct iwm_softc *mvm, struct ieee80211_node *sta, + enum nl80211_band band, bool init); + +/* Notify RS about Tx status */ +void iwl_mvm_rs_tx_status(struct iwm_softc *mvm, struct ieee80211_node *sta, + int tid, struct ieee80211_tx_info *info, bool ndp); + +void rs_drv_mac80211_tx_status(struct iwm_softc *sc, + struct ieee80211_node *sta, + struct ieee80211_tx_info *info, int tid, uint16_t fc, int ssn); + +void rs_update_last_rssi(struct iwm_softc *mvm, + struct ieee80211_rx_status *rx_status); + +int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate); + +void rs_drv_rate_update(struct iwm_softc *mvm, + struct ieee80211_node *sta, + enum nl80211_band band, u32 changed); + +void *rs_drv_alloc_sta(iwm_softc *sc, struct ieee80211_node *ni); + +void rs_drv_free_sta(iwm_softc *sc, struct ieee80211_node *ni); + +void iwm_rs_alloc(struct iwm_softc *sc); + +void iwm_rs_free(struct iwm_softc *sc); + +#endif /* rs_hpp */ diff --git a/itlwm/hal_iwm/rx.cpp b/itlwm/hal_iwm/rx.cpp index 775771511..2b3e1c7e1 100644 --- a/itlwm/hal_iwm/rx.cpp +++ b/itlwm/hal_iwm/rx.cpp @@ -354,6 +354,7 @@ iwm_rx_mpdu(struct iwm_softc *sc, mbuf_t m, void *pktdata, { struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_rxinfo rxi; + struct ieee80211_rx_status rx_status; struct iwm_rx_phy_info *phy_info; struct iwm_rx_mpdu_res_start *rx_res; int device_timestamp; @@ -363,6 +364,7 @@ iwm_rx_mpdu(struct iwm_softc *sc, mbuf_t m, void *pktdata, int rssi, chanidx, rate_n_flags; memset(&rxi, 0, sizeof(rxi)); + memset(&rx_status, 0, sizeof(struct ieee80211_rx_status)); phy_info = &sc->sc_last_phy_info; rx_res = (struct iwm_rx_mpdu_res_start *)pktdata; @@ -415,7 +417,8 @@ iwm_rx_mpdu(struct iwm_softc *sc, mbuf_t m, void *pktdata, phy_flags = letoh16(phy_info->phy_flags); rate_n_flags = le32toh(phy_info->rate_n_flags); - rssi = iwm_get_signal_strength(sc, phy_info); + rssi = iwm_get_signal_strength(sc, &rx_status, phy_info); + rs_update_last_rssi(sc, &rx_status); rssi = (0 - IWM_MIN_DBM) + rssi; /* normalize */ rssi = MIN(rssi, ic->ic_max_rssi); /* clip to max. 100% */ @@ -823,6 +826,7 @@ iwm_rx_mpdu_mq(struct iwm_softc *sc, mbuf_t m, void *pktdata, { struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_rxinfo rxi; + struct ieee80211_rx_status rx_status; struct iwm_rx_mpdu_desc *desc; uint32_t len, hdrlen, rate_n_flags, device_timestamp; int rssi; @@ -830,6 +834,7 @@ iwm_rx_mpdu_mq(struct iwm_softc *sc, mbuf_t m, void *pktdata, uint16_t phy_info; memset(&rxi, 0, sizeof(rxi)); + memset(&rx_status, 0, sizeof(struct ieee80211_rx_status)); desc = (struct iwm_rx_mpdu_desc *)pktdata; @@ -950,7 +955,8 @@ iwm_rx_mpdu_mq(struct iwm_softc *sc, mbuf_t m, void *pktdata, chanidx = desc->v1.channel; device_timestamp = desc->v1.gp2_on_air_rise; - rssi = iwm_rxmq_get_signal_strength(sc, desc); + rssi = iwm_rxmq_get_signal_strength(sc, &rx_status, rate_n_flags, desc); + rs_update_last_rssi(sc, &rx_status); rssi = (0 - IWM_MIN_DBM) + rssi; /* normalize */ rssi = MIN(rssi, ic->ic_max_rssi); /* clip to max. 100% */ From 3b8ac82b68185e1c56c236a9b862e947a50231c3 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Mon, 28 Mar 2022 01:16:41 +0800 Subject: [PATCH 018/114] rs now we run. --- itlwm/hal_iwm/ItlIwm.hpp | 1 - itlwm/hal_iwm/mac80211.cpp | 180 +++---------------------------------- 2 files changed, 14 insertions(+), 167 deletions(-) diff --git a/itlwm/hal_iwm/ItlIwm.hpp b/itlwm/hal_iwm/ItlIwm.hpp index 976cf6e4f..448ea3feb 100644 --- a/itlwm/hal_iwm/ItlIwm.hpp +++ b/itlwm/hal_iwm/ItlIwm.hpp @@ -292,7 +292,6 @@ class ItlIwm : public ItlHalService, ItlDriverInfo, ItlDriverController { struct ieee80211_frame *, struct iwm_tx_cmd *); void iwm_txd_done(struct iwm_softc *, struct iwm_tx_data *); void iwm_ampdu_txq_advance(struct iwm_softc *, struct iwm_tx_ring *, int); - void iwm_tx_reclaim(struct iwm_softc *, struct ieee80211_tx_info *tx_info, int, int, int, uint32_t, bool); void iwm_clear_oactive(struct iwm_softc *, struct iwm_tx_ring *); void iwm_ra_choose(struct iwm_softc *, struct ieee80211_node *); int iwm_tx(struct iwm_softc *, mbuf_t, struct ieee80211_node *, int); diff --git a/itlwm/hal_iwm/mac80211.cpp b/itlwm/hal_iwm/mac80211.cpp index 461720989..9952a3de0 100644 --- a/itlwm/hal_iwm/mac80211.cpp +++ b/itlwm/hal_iwm/mac80211.cpp @@ -1040,25 +1040,6 @@ static int ieee80211_tx_get_rates(struct iwm_softc *sc, return i - 1; } -static void __ieee80211_tx_status(struct iwm_softc *sc, - struct ieee80211_tx_info *info, - int rates_idx, int retry_count, int tid, uint16_t fc, int ssn) -{ - bool acked; - bool noack_success; - - acked = !!(info->flags & IEEE80211_TX_STAT_ACK); - noack_success = !!(info->flags & - IEEE80211_TX_STAT_NOACK_TRANSMITTED); - - if ((info->flags & IEEE80211_TX_STAT_AMPDU_NO_BACK) && - (ieee80211_is_data_qos(fc))) { - - ieee80211_tx_compressed_bar(&sc->sc_ic, sc->sc_ic.ic_bss, tid, ssn); - XYLog("%s sending bar ssn=%d tid=%d\n", __FUNCTION__, ssn, tid); - } -} - void ieee80211_tx_status(struct iwm_softc *sc, struct ieee80211_tx_info *info, int tid, uint16_t fc, int ssn) { int rates_idx, retry_count; @@ -1069,9 +1050,6 @@ void ieee80211_tx_status(struct iwm_softc *sc, struct ieee80211_tx_info *info, i rates_idx = ieee80211_tx_get_rates(sc, info, &retry_count); rs_drv_mac80211_tx_status(sc, sc->sc_ic.ic_bss, info, tid, fc, ssn); - - if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP)) - __ieee80211_tx_status(sc, info, rates_idx, retry_count, tid, fc, ssn); } void ItlIwm:: @@ -1093,74 +1071,6 @@ iwm_ampdu_txq_advance(struct iwm_softc *sc, struct iwm_tx_ring *ring, int idx) } } -void ItlIwm:: -iwm_tx_reclaim(struct iwm_softc *sc, struct ieee80211_tx_info *tx_info, int tid, int qid, int ssn, uint32_t rate, bool is_flush) -{ - XYLog("%s ssn %d\n", __FUNCTION__, ssn); - struct iwm_tx_data *txd; - int idx = IWM_AGG_SSN_TO_TXQ_IDX(ssn); - struct iwm_tx_ring *ring = &sc->txq[qid]; - struct iwm_tx_ba *tid_data = &sc->sc_tx_ba[tid]; - int freed = 0; - bool rs_update = false; - - /* pack lq color from tid_data along the reduced txp */ - tx_info->status.status_driver_data[0] = - RS_DRV_DATA_PACK(tid_data->lq_color, - tx_info->status.status_driver_data[0]); - tx_info->status.status_driver_data[1] = (void *)(uintptr_t)rate; - while (ring->tail != idx) { - txd = &ring->data[ring->tail]; - struct ieee80211_tx_info *info = &txd->info; - if (txd->m != NULL) { - rs_update = true; - iwm_reset_sched(sc, ring->qid, ring->tail, IWM_STATION_ID); - - memset(&info->status, 0, sizeof(info->status)); - /* Packet was transmitted successfully, failures come as single - * frames because before failing a frame the firmware transmits - * it without aggregation at least once. - */ - if (!is_flush) - info->flags |= IEEE80211_TX_STAT_ACK; - - if (!is_flush) { - if (ieee80211_is_data_qos(txd->fc)) - freed++; - else - WARN_ON_ONCE(tid != IWL_MAX_TID_COUNT); - } - - /* this is the first skb we deliver in this batch */ - /* put the rate scaling data there */ - if (freed == 1) { - info->flags |= IEEE80211_TX_STAT_AMPDU; - memcpy(&info->status, &tx_info->status, - sizeof(tx_info->status)); - iwl_mvm_hwrate_to_tx_status(rate, info); - } - - ieee80211_tx_status(sc, info, tid, txd->fc, ssn); - - iwm_txd_done(sc, txd); - ring->queued--; - } - ring->tail = (ring->tail + 1) % IWM_TX_RING_COUNT; - XYLog("%s tail %d\n", __FUNCTION__, ring->tail); - } - - /* We got a BA notif with 0 acked or scd_ssn didn't progress which is - * possible (i.e. first MPDU in the aggregation wasn't acked) - * Still it's important to update RS about sent vs. acked. - */ - if (!is_flush && !rs_update) { - tx_info->band = IEEE80211_IS_CHAN_2GHZ(sc->sc_ic.ic_bss->ni_chan) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ; - iwl_mvm_hwrate_to_tx_status(rate, tx_info); - XYLog("No reclaim. Update rs directly\n"); - iwl_mvm_rs_tx_status(sc, sc->sc_ic.ic_bss, tid, tx_info, false); - } -} - void ItlIwm:: iwm_ampdu_rate_control(struct iwm_softc *sc, struct ieee80211_node *ni, struct iwm_tx_ring *ring, uint16_t seq, uint16_t ssn, struct ieee80211_tx_info *tx_info, int tid, uint32_t rate_n_flags) @@ -1336,8 +1246,8 @@ iwm_rx_tx_ba_notif(struct iwm_softc *sc, struct iwm_rx_packet *pkt, struct iwm_r ba_info.status.status_driver_data[0] = (void *)(uintptr_t)ba_notif->reduced_txp; -// if (SEQ_LT(ssn, ba->ba_winstart)) -// return; + if (SEQ_LT(ssn, ba->ba_winstart)) + return; /* Skip rate control if our Tx rate is fixed. */ if (ic->ic_fixed_mcs == -1) @@ -1383,35 +1293,6 @@ iwm_ampdu_tx_done(struct iwm_softc *sc, struct iwm_cmd_header *cmd_hdr, return; if (nframes > 1) { - int i; - - /* - * Collect information about this A-MPDU. - */ - for (i = 0; i < nframes; i++) { - uint8_t qid = agg_status[i].qid; - uint8_t idx = agg_status[i].idx; - uint16_t txstatus = (le16toh(agg_status[i].status) & - IWM_AGG_TX_STATE_STATUS_MSK); - - if (status != IWM_TX_STATUS_SUCCESS && ieee80211_is_mgmt(txdata->fc)) { - iwm_toggle_tx_ant(sc, &sc->sc_mgmt_last_antenna_idx); - } - - if (txstatus != IWM_AGG_TX_STATE_TRANSMITTED) - continue; - - if (qid != cmd_hdr->qid) - continue; - - txdata = &txq->data[idx]; - if (txdata->m == NULL) - continue; - - /* The Tx rate was the same for all subframes. */ - txdata->ampdu_txmcs = rate; - txdata->ampdu_nframes = nframes; - } return; } @@ -1429,28 +1310,6 @@ iwm_ampdu_tx_done(struct iwm_softc *sc, struct iwm_cmd_header *cmd_hdr, "bitmap=0x%llx\n", __func__, status, cmd_hdr->qid, txq->queued, cmd_hdr->idx, ssn, ba->ba_bitmap)); - /* - * Skip rate control if our Tx rate is fixed. - * Don't report frames to MiRA which were sent at a different - * Tx rate than ni->ni_txmcs. - */ - if (ic->ic_fixed_mcs == -1) { - if (txdata->ampdu_nframes > 1) { - /* - * This frame was once part of an A-MPDU. - * Report one failed A-MPDU Tx attempt. - * The firmware might have made several such - * attempts but we don't keep track of this. - */ - ieee80211_ra_add_stats_ht(&in->in_rn, ic, ni, - txdata->ampdu_txmcs, 1, 1); - } - - /* Report the final single-frame Tx attempt. */ - iwm_ht_single_rate_control(sc, ni, rate, initial_rate, - failure_frame, txfail); - } - if (txfail) { ieee80211_tx_compressed_bar(ic, ni, tid, ssn); XYLog("%s sending bar ssn=%d tid=%d\n", __FUNCTION__, ssn, tid); @@ -1462,8 +1321,6 @@ iwm_ampdu_tx_done(struct iwm_softc *sc, struct iwm_cmd_header *cmd_hdr, * frames before its BA window so mark them all as done. */ ieee80211_output_ba_move_window(ic, ni, tid, ssn); - iwm_ampdu_txq_advance(sc, txq, IWM_AGG_SSN_TO_TXQ_IDX(ssn)); - iwm_clear_oactive(sc, txq); } #define IWL_MVM_TX_RES_GET_TID(_ra_tid) ((_ra_tid) & 0x0f) @@ -1792,27 +1649,18 @@ iwm_rx_tx_cmd(struct iwm_softc *sc, struct iwm_rx_packet *pkt, DPRINTFN(2, ("%s idx=%d qid=%d txd->txmcs=%d txd->txrate=%d, frame_count=%d len=%d\n", __FUNCTION__, idx, qid, txd->txmcs, txd->txrate, ((struct iwm_tx_resp *)pkt->data)->frame_count, ((struct iwm_tx_resp *)pkt->data)->byte_cnt)); - iwm_rx_tx_cmd_single(sc, tx_resp, qid, idx); + ssn = iwm_get_scd_ssn(tx_resp); + iwm_rx_tx_cmd_single(sc, tx_resp, qid, IWM_AGG_SSN_TO_TXQ_IDX(ssn)); + if (qid >= IWM_FIRST_AGG_TX_QUEUE) { + int status; + + status = le16toh(iwl_mvm_get_agg_status(sc, tx_resp)->status) & IWM_TX_STATUS_MSK; + iwm_ampdu_tx_done(sc, cmd_hdr, txd->in, ring, + le32toh(tx_resp->initial_rate), tx_resp->frame_count, + tx_resp->failure_frame, ssn, status, iwl_mvm_get_agg_status(sc, tx_resp)); + } + iwm_clear_oactive(sc, ring); - -// memcpy(&ssn, &tx_resp->status + tx_resp->frame_count, sizeof(ssn)); -// ssn = le32toh(ssn) & 0xfff; -// if (qid >= IWM_FIRST_AGG_TX_QUEUE) { -// int status; -// status = le16toh(tx_resp->status.status) & IWM_TX_STATUS_MSK; -// iwm_ampdu_tx_done(sc, cmd_hdr, txd->in, ring, -// le32toh(tx_resp->initial_rate), tx_resp->frame_count, -// tx_resp->failure_frame, ssn, status, &tx_resp->status); -// } else { -// /* -// * Even though this is not an agg queue, we must only free -// * frames before the firmware's starting sequence number. -// */ -// iwm_rx_tx_cmd_single(sc, tx_resp, txd->in, txd->txmcs, -// txd->txrate, qid); -// iwm_ampdu_txq_advance(sc, ring, IWM_AGG_SSN_TO_TXQ_IDX(ssn)); -// iwm_clear_oactive(sc, ring); -// } } void ItlIwm:: @@ -2213,7 +2061,7 @@ iwm_tx(struct iwm_softc *sc, mbuf_t m, struct ieee80211_node *ni, int ac) /* Mark TX ring as full if we reach a certain threshold. */ if (++ring->queued > IWM_TX_RING_HIMARK) { - XYLog("%s qid=%d sc->qfullmsk is FULL ring->cur=%d ring->queued=%d\n", __FUNCTION__, ring->qid, ring->cur, ring->queued); +// XYLog("%s qid=%d sc->qfullmsk is FULL ring->cur=%d ring->queued=%d\n", __FUNCTION__, ring->qid, ring->cur, ring->queued); sc->qfullmsk |= 1 << ring->qid; } From 18d5fb8a7615e742fc05a46f89be3fdbf9afb4fc Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Mon, 28 Mar 2022 14:44:07 +0800 Subject: [PATCH 019/114] Clean. --- itlwm/hal_iwm/ItlIwm.hpp | 6 +- itlwm/hal_iwm/coex.cpp | 64 ++++++++- itlwm/hal_iwm/mac80211.cpp | 5 +- itlwm/hal_iwm/rs.cpp | 259 ++++++++++++++++--------------------- itlwm/hal_iwm/rs.h | 9 +- 5 files changed, 184 insertions(+), 159 deletions(-) diff --git a/itlwm/hal_iwm/ItlIwm.hpp b/itlwm/hal_iwm/ItlIwm.hpp index 448ea3feb..ef0d4737d 100644 --- a/itlwm/hal_iwm/ItlIwm.hpp +++ b/itlwm/hal_iwm/ItlIwm.hpp @@ -93,8 +93,11 @@ class ItlIwm : public ItlHalService, ItlDriverInfo, ItlDriverController { struct iwm_scan_channel_cfg_umac *chan, int n_ssids, int bgscan); //coex - uint16_t iwm_coex_agg_time_limit(struct iwm_softc *); + uint16_t iwm_coex_agg_time_limit(struct iwm_softc *, struct ieee80211_node *); uint8_t iwm_coex_tx_prio(struct iwm_softc *, struct ieee80211_frame *, uint8_t); + static bool iwm_coex_is_ant_avail(struct iwm_softc *, u8); + static bool iwm_coex_is_mimo_allowed(struct iwm_softc *, struct ieee80211_node *); + static bool iwm_coex_is_tpc_allowed(struct iwm_softc *, bool); uint8_t iwm_lookup_cmd_ver(struct iwm_softc *, uint8_t, uint8_t); int iwm_is_mimo_ht_plcp(uint8_t); @@ -206,6 +209,7 @@ class ItlIwm : public ItlHalService, ItlDriverInfo, ItlDriverController { uint8_t); static void iwm_rx_ba_session_expired(void *); static void iwm_reorder_timer_expired(void *); + static uint8_t iwm_num_of_ant(uint8_t mask); int iwm_sta_rx_agg(struct iwm_softc *, struct ieee80211_node *, uint8_t, uint16_t, uint16_t, int, int); static int iwm_ampdu_tx_start(struct ieee80211com *, struct ieee80211_node *, diff --git a/itlwm/hal_iwm/coex.cpp b/itlwm/hal_iwm/coex.cpp index d70b69f8c..16d7e0e4f 100644 --- a/itlwm/hal_iwm/coex.cpp +++ b/itlwm/hal_iwm/coex.cpp @@ -23,7 +23,7 @@ #define LINK_QUAL_AGG_TIME_LIMIT_BT_ACT (1200) uint16_t ItlIwm:: -iwm_coex_agg_time_limit(struct iwm_softc *sc) +iwm_coex_agg_time_limit(struct iwm_softc *sc, struct ieee80211_node *ni) { return LINK_QUAL_AGG_TIME_LIMIT_DEF; } @@ -69,3 +69,65 @@ iwm_coex_tx_prio(struct iwm_softc *sc, struct ieee80211_frame *wh, uint8_t ac) return 0; } + +bool ItlIwm:: +iwm_coex_is_ant_avail(struct iwm_softc *sc, u8 ant) +{ +#if 0 + /* there is no other antenna, shared antenna is always available */ + if (mvm->cfg->bt_shared_single_ant) + return true; +#endif + + if (ant & sc->non_shared_ant) + return true; + +#ifdef notyet_coex + return le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) < + BT_HIGH_TRAFFIC; +#else + return true; +#endif +} + +bool ItlIwm:: +iwm_coex_is_mimo_allowed(struct iwm_softc *sc, struct ieee80211_node *ni) +{ +#ifdef notyet_coex + struct iwm_node *in = (struct iwm_node *)ni; + struct iwm_phy_ctxt *phy_ctxt = in->in_phyctxt; + enum iwl_bt_coex_lut_type lut_type; + + if (sc->last_bt_notif.ttc_status & BIT(phy_ctxt->id)) + return true; + + if (le32_to_cpu(sc->last_bt_notif.bt_activity_grading) < + BT_HIGH_TRAFFIC) + return true; + + /* + * In Tight / TxTxDis, BT can't Rx while we Tx, so use both antennas + * since BT is already killed. + * In Loose, BT can Rx while we Tx, so forbid MIMO to let BT Rx while + * we Tx. + * When we are in 5GHz, we'll get BT_COEX_INVALID_LUT allowing MIMO. + */ + lut_type = iwl_get_coex_type(mvm, mvmsta->vif); + return lut_type != BT_COEX_LOOSE_LUT; +#else + return true; +#endif +} + +bool ItlIwm:: +iwm_coex_is_tpc_allowed(struct iwm_softc *mvm, bool is5G) +{ + if (is5G) + return false; + +#ifdef notyet_coex + return le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) >= BT_LOW_TRAFFIC; +#else + return true; +#endif +} diff --git a/itlwm/hal_iwm/mac80211.cpp b/itlwm/hal_iwm/mac80211.cpp index 9952a3de0..f04872ebe 100644 --- a/itlwm/hal_iwm/mac80211.cpp +++ b/itlwm/hal_iwm/mac80211.cpp @@ -438,7 +438,8 @@ iwm_reorder_timer_expired(void *arg) splx(s); } -static inline uint8_t iwm_num_of_ant(uint8_t mask) +uint8_t ItlIwm:: +iwm_num_of_ant(uint8_t mask) { return !!((mask) & IWM_ANT_A) + !!((mask) & IWM_ANT_B) + @@ -3088,7 +3089,7 @@ iwm_setrates(struct iwm_node *in, int async) lqcmd.single_stream_ant_msk = IWM_ANT_A; lqcmd.dual_stream_ant_msk = IWM_ANT_AB; - lqcmd.agg_time_limit = htole16(iwm_coex_agg_time_limit(sc)); + lqcmd.agg_time_limit = htole16(iwm_coex_agg_time_limit(sc, ni)); lqcmd.agg_disable_start_th = 3; lqcmd.agg_frame_cnt_limit = 0x3f; diff --git a/itlwm/hal_iwm/rs.cpp b/itlwm/hal_iwm/rs.cpp index 5cdc54134..37cf83921 100644 --- a/itlwm/hal_iwm/rs.cpp +++ b/itlwm/hal_iwm/rs.cpp @@ -110,32 +110,16 @@ struct rs_tx_column { allow_column_func_t checks[MAX_COLUMN_CHECKS]; }; -static bool iwl_mvm_bt_coex_is_ant_avail(struct iwm_softc *sc, u8 ant) -{ - /* there is no other antenna, shared antenna is always available */ -// if (mvm->cfg->bt_shared_single_ant) -// return true; -// -// if (ant & mvm->cfg->non_shared_ant) -// return true; -// -// return le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) < -// BT_HIGH_TRAFFIC; - // TODO: IMP - return true; -} - static bool rs_ant_allow(struct iwm_softc *sc, struct ieee80211_node *ni, struct rs_rate *rate, const struct rs_tx_column *next_col) { - return iwl_mvm_bt_coex_is_ant_avail(sc, next_col->ant); + return ItlIwm::iwm_coex_is_ant_avail(sc, next_col->ant); } static bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwm_softc *sc, struct ieee80211_node *ni) { - //TODO: IMP - return true; + return ItlIwm::iwm_coex_is_mimo_allowed(sc, ni); } static bool rs_mimo_allow(struct iwm_softc *sc, struct ieee80211_node *ni, @@ -150,7 +134,7 @@ static bool rs_mimo_allow(struct iwm_softc *sc, struct ieee80211_node *ni, // if (sta->smps_mode == IEEE80211_SMPS_STATIC) // return false; - if (num_of_ant(that->iwm_fw_valid_tx_ant(sc)) < 2) + if (that->iwm_num_of_ant(that->iwm_fw_valid_tx_ant(sc)) < 2) return false; if (!iwl_mvm_bt_coex_is_mimo_allowed(sc, ni)) @@ -632,7 +616,7 @@ static void rs_tl_turn_on_agg(struct iwm_softc *sc, return; } - tx_ba = &sc->sc_ic.ic_bss->ni_tx_ba[tid]; + tx_ba = &ni->ni_tx_ba[tid]; tid_data = &sc->sc_tx_ba[tid]; if (sc->sc_ic.ic_state >= IEEE80211_S_RUN && tx_ba->ba_state == IEEE80211_BA_INIT && @@ -759,7 +743,6 @@ static void rs_update_tid_tpt_stats(struct iwm_softc *sc, return; struct iwm_tx_ba *tid_data = &sc->sc_tx_ba[tid]; - struct ieee80211_tx_ba *tx_ba = &sc->sc_ic.ic_bss->ni_tx_ba[tid]; /* * Measure if there're enough successful transmits per second. @@ -767,7 +750,7 @@ static void rs_update_tid_tpt_stats(struct iwm_softc *sc, * BA session, so it should be updated only when A-MPDU is * off. */ - if (tx_ba->ba_state != IEEE80211_BA_INIT) + if (tid_data->wn != NULL) return; if (time_is_before_jiffies(tid_data->tpt_meas_start + hz) || @@ -1124,7 +1107,7 @@ static void rs_get_lower_rate_down_column(struct iwl_lq_sta *lq_sta, LQ_VHT_SISO : LQ_HT_SISO; } - if (num_of_ant(rate->ant) > 1) + if (that->iwm_num_of_ant(rate->ant) > 1) rate->ant = first_antenna(that->iwm_fw_valid_tx_ant(sc)); /* Relevant in both switching to SISO or Legacy */ @@ -1899,13 +1882,7 @@ static void rs_get_adjacent_txp(struct iwm_softc *mvm, int index, static bool iwl_mvm_bt_coex_is_tpc_allowed(struct iwm_softc *mvm, enum nl80211_band band) { -// u32 bt_activity = le32_to_cpu(mvm->last_bt_notif.bt_activity_grading); -// - if (band != NL80211_BAND_2GHZ) - return false; -// -// return bt_activity >= BT_LOW_TRAFFIC; - return false; + return ItlIwm::iwm_coex_is_tpc_allowed(mvm, band == NL80211_BAND_5GHZ); } static bool rs_tpc_allowed(struct iwm_softc *mvm, @@ -2756,7 +2733,7 @@ void rs_drv_free_sta(iwm_softc *sc, struct ieee80211_node *ni) static int rs_vht_highest_rx_mcs_index(struct ieee80211_node *sta, int nss) { - u16 rx_mcs = le16_to_cpu(sta->ni_ic->ic_bss->ni_vht_mcsinfo.rx_mcs_map) & + u16 rx_mcs = le16_to_cpu(sta->ni_vht_mcsinfo.rx_mcs_map) & (0x3 << (2 * (nss - 1))); rx_mcs >>= (2 * (nss - 1)); @@ -2832,7 +2809,7 @@ static void rs_ht_init(struct iwm_softc *mvm, if ((sta->ni_htcaps & IEEE80211_HTCAP_LDPC)) lq_sta->ldpc = true; - if ((num_of_ant(that->iwm_fw_valid_tx_ant(mvm)) > 1) && + if ((that->iwm_num_of_ant(that->iwm_fw_valid_tx_ant(mvm)) > 1) && (sta->ni_htcaps & IEEE80211_HTCAP_RXSTBC_MASK)) lq_sta->stbc_capable = true; @@ -2849,12 +2826,12 @@ static void rs_vht_init(struct iwm_softc *mvm, if ((sta->ni_vhtcaps & IEEE80211_VHTCAP_RXLDPC)) lq_sta->ldpc = true; - if ((num_of_ant(that->iwm_fw_valid_tx_ant(mvm)) > 1) && + if ((that->iwm_num_of_ant(that->iwm_fw_valid_tx_ant(mvm)) > 1) && (sta->ni_vhtcaps & IEEE80211_VHTCAP_RXSTBC_MASK)) lq_sta->stbc_capable = true; if (isset(mvm->sc_enabled_capa, IWM_UCODE_TLV_CAPA_BEAMFORMER) && - (num_of_ant(that->iwm_fw_valid_tx_ant(mvm)) > 1) && + (that->iwm_num_of_ant(that->iwm_fw_valid_tx_ant(mvm)) > 1) && (sta->ni_vhtcaps & IEEE80211_VHTCAP_SU_BEAMFORMEE_CAPABLE)) lq_sta->bfer_capable = true; @@ -3011,14 +2988,13 @@ static void rs_drv_rate_init(struct iwm_softc *mvm, struct ieee80211_node *sta, lq_sta->max_mimo2_rate_idx = rs_get_max_rate_from_mask(lq_sta->active_mimo2_rate); - IWL_DEBUG_RATE(mvm, - "LEGACY=%lX SISO=%lX MIMO2=%lX VHT=%d LDPC=%d STBC=%d BFER=%d\n", + XYLog("LEGACY=%lX SISO=%lX MIMO2=%lX VHT=%d LDPC=%d STBC=%d BFER=%d\n", lq_sta->active_legacy_rate, lq_sta->active_siso_rate, lq_sta->active_mimo2_rate, lq_sta->is_vht, lq_sta->ldpc, lq_sta->stbc_capable, lq_sta->bfer_capable); - IWL_DEBUG_RATE(mvm, "MAX RATE: LEGACY=%d SISO=%d MIMO2=%d\n", + XYLog("MAX RATE: LEGACY=%d SISO=%d MIMO2=%d\n", lq_sta->max_legacy_rate_idx, lq_sta->max_siso_rate_idx, lq_sta->max_mimo2_rate_idx); @@ -3403,55 +3379,58 @@ static void rs_build_rates_table(struct iwm_softc *mvm, lq_cmd->flags = LQ_FLAG_COLOR_SET(lq_cmd->flags, color); } -//struct rs_bfer_active_iter_data { -// struct ieee80211_node *exclude_sta; -// struct ieee80211_node *bfer_mvmsta; -//}; -// -//static void rs_bfer_active_iter(void *_data, -// struct ieee80211_node *sta) -//{ -// struct rs_bfer_active_iter_data *data = (struct rs_bfer_active_iter_data *)_data; -// struct iwm_lq_cmd *lq_cmd = &sta->ni_ic->lq_sta.rs_drv.lq; -// u32 ss_params = le32_to_cpu(lq_cmd->ss_params); -// -// if (sta == data->exclude_sta) -// return; -// -// /* The current sta has BFER allowed */ -// if (ss_params & LQ_SS_BFER_ALLOWED) { -// WARN_ON_ONCE(data->bfer_mvmsta != NULL); -// -// data->bfer_mvmsta = mvmsta; -// } -//} -// -//static int rs_bfer_priority(struct ieee80211_node *sta) -//{ -// return 1; -//} -// -///* Returns >0 if sta1 has a higher BFER priority compared to sta2 */ -//static int rs_bfer_priority_cmp(struct ieee80211_node *sta1, -// struct ieee80211_node *sta2) -//{ -// int prio1 = rs_bfer_priority(sta1); -// int prio2 = rs_bfer_priority(sta2); -// -// if (prio1 > prio2) -// return 1; -// if (prio1 < prio2) -// return -1; -// return 0; -//} -// -//static inline void ieee80211_iterate_stations_atomic(struct iwm_softc *hw, -// void (*iterator)(void *data, -// struct ieee80211_node *sta), -// void *data) -//{ -// iterator(data, hw->sc_ic.ic_bss); -//} +#if 0 +struct rs_bfer_active_iter_data { + struct ieee80211_node *exclude_sta; + struct ieee80211_node *bfer_mvmsta; +}; + +static void rs_bfer_active_iter(void *_data, + struct ieee80211_node *sta) +{ + struct rs_bfer_active_iter_data *data = (struct rs_bfer_active_iter_data *)_data; + struct iwm_lq_cmd *lq_cmd = &sta->ni_ic->lq_sta.rs_drv.lq; + u32 ss_params = le32_to_cpu(lq_cmd->ss_params); + + if (sta == data->exclude_sta) + return; + + /* The current sta has BFER allowed */ + if (ss_params & LQ_SS_BFER_ALLOWED) { + WARN_ON_ONCE(data->bfer_mvmsta != NULL); + + data->bfer_mvmsta = mvmsta; + } +} + +static int rs_bfer_priority(struct ieee80211_node *sta) +{ + return 1; +} + +/* Returns >0 if sta1 has a higher BFER priority compared to sta2 */ +static int rs_bfer_priority_cmp(struct ieee80211_node *sta1, + struct ieee80211_node *sta2) +{ + int prio1 = rs_bfer_priority(sta1); + int prio2 = rs_bfer_priority(sta2); + + if (prio1 > prio2) + return 1; + if (prio1 < prio2) + return -1; + return 0; +} + +static inline void ieee80211_iterate_stations_atomic(struct iwm_softc *hw, + void (*iterator)(void *data, + struct ieee80211_node *sta), + void *data) +{ + iterator(data, hw->sc_ic.ic_bss); +} + +#endif static void rs_set_lq_ss_params(struct iwm_softc *mvm, struct ieee80211_node *sta, @@ -3459,10 +3438,12 @@ static void rs_set_lq_ss_params(struct iwm_softc *mvm, const struct rs_rate *initial_rate) { struct iwm_lq_cmd *lq_cmd = &lq_sta->lq; -// struct rs_bfer_active_iter_data data = { -// .exclude_sta = sta, -// .bfer_mvmsta = NULL, -// }; +#if 0 + struct rs_bfer_active_iter_data data = { + .exclude_sta = sta, + .bfer_mvmsta = NULL, + }; +#endif u32 ss_params = LQ_SS_PARAMS_VALID; if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta)) @@ -3471,67 +3452,50 @@ static void rs_set_lq_ss_params(struct iwm_softc *mvm, if (lq_sta->stbc_capable) ss_params |= LQ_SS_STBC_1SS_ALLOWED; +#if 0 if (!lq_sta->bfer_capable) goto out; -// ieee80211_iterate_stations_atomic(mvm, -// rs_bfer_active_iter, -// &data); -// bfer_mvmsta = data.bfer_mvmsta; -// -// /* This code is safe as it doesn't run concurrently for different -// * stations. This is guaranteed by the fact that calls to -// * ieee80211_tx_status wouldn't run concurrently for a single HW. -// */ -// if (!bfer_mvmsta) { -// IWL_DEBUG_RATE(mvm, "No sta with BFER allowed found. Allow\n"); -// -// ss_params |= LQ_SS_BFER_ALLOWED; -// goto out; -// } -// -// IWL_DEBUG_RATE(mvm, "Found existing sta %d with BFER activated\n", -// bfer_mvmsta->sta_id); -// -// /* Disallow BFER on another STA if active and we're a higher priority */ -// if (rs_bfer_priority_cmp(mvmsta, bfer_mvmsta) > 0) { -// struct iwm_lq_cmd *bfersta_lq_cmd = -// &bfer_mvmsta->lq_sta.rs_drv.lq; -// u32 bfersta_ss_params = le32_to_cpu(bfersta_lq_cmd->ss_params); -// -// bfersta_ss_params &= ~LQ_SS_BFER_ALLOWED; -// bfersta_lq_cmd->ss_params = cpu_to_le32(bfersta_ss_params); -// iwl_mvm_send_lq_cmd(mvm, bfersta_lq_cmd); -// -// ss_params |= LQ_SS_BFER_ALLOWED; -// IWL_DEBUG_RATE(mvm, -// "Lower priority BFER sta found (%d). Switch BFER\n", -// bfer_mvmsta->sta_id); -// } -out: - lq_cmd->ss_params = cpu_to_le32(ss_params); -} + ieee80211_iterate_stations_atomic(mvm, + rs_bfer_active_iter, + &data); + bfer_mvmsta = data.bfer_mvmsta; -#define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) -#define LINK_QUAL_AGG_TIME_LIMIT_BT_ACT (1200) + /* This code is safe as it doesn't run concurrently for different + * stations. This is guaranteed by the fact that calls to + * ieee80211_tx_status wouldn't run concurrently for a single HW. + */ + if (!bfer_mvmsta) { + IWL_DEBUG_RATE(mvm, "No sta with BFER allowed found. Allow\n"); -static u16 iwl_mvm_coex_agg_time_limit(struct iwm_softc *mvm, -struct ieee80211_node *sta) -{ -// if (mvm->last_bt_notif.ttc_status & BIT(phy_ctxt->id)) -// return LINK_QUAL_AGG_TIME_LIMIT_DEF; -// -// if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) < -// BT_HIGH_TRAFFIC) -// return LINK_QUAL_AGG_TIME_LIMIT_DEF; -// -// lut_type = iwl_get_coex_type(mvm, mvmsta->vif); -// -// if (lut_type == BT_COEX_LOOSE_LUT || lut_type == BT_COEX_INVALID_LUT) - return LINK_QUAL_AGG_TIME_LIMIT_DEF; + ss_params |= LQ_SS_BFER_ALLOWED; + goto out; + } -// /* tight coex, high bt traffic, reduce AGG time limit */ -// return LINK_QUAL_AGG_TIME_LIMIT_BT_ACT; + IWL_DEBUG_RATE(mvm, "Found existing sta %d with BFER activated\n", + bfer_mvmsta->sta_id); + + /* Disallow BFER on another STA if active and we're a higher priority */ + if (rs_bfer_priority_cmp(mvmsta, bfer_mvmsta) > 0) { + struct iwm_lq_cmd *bfersta_lq_cmd = + &bfer_mvmsta->lq_sta.rs_drv.lq; + u32 bfersta_ss_params = le32_to_cpu(bfersta_lq_cmd->ss_params); + + bfersta_ss_params &= ~LQ_SS_BFER_ALLOWED; + bfersta_lq_cmd->ss_params = cpu_to_le32(bfersta_ss_params); + iwl_mvm_send_lq_cmd(mvm, bfersta_lq_cmd); + + ss_params |= LQ_SS_BFER_ALLOWED; + IWL_DEBUG_RATE(mvm, + "Lower priority BFER sta found (%d). Switch BFER\n", + bfer_mvmsta->sta_id); + } +#else + if (lq_sta->bfer_capable) + ss_params |= LQ_SS_BFER_ALLOWED; +#endif +out: + lq_cmd->ss_params = cpu_to_le32(ss_params); } static void rs_fill_lq_cmd(struct iwm_softc *mvm, @@ -3540,6 +3504,7 @@ static void rs_fill_lq_cmd(struct iwm_softc *mvm, const struct rs_rate *initial_rate) { struct iwm_lq_cmd *lq_cmd = &lq_sta->lq; + ItlIwm *that = container_of(mvm, ItlIwm, com); lq_cmd->agg_disable_start_th = IWL_MVM_RS_AGG_DISABLE_START; lq_cmd->agg_time_limit = @@ -3554,7 +3519,7 @@ static void rs_fill_lq_cmd(struct iwm_softc *mvm, rs_set_lq_ss_params(mvm, sta, lq_sta, initial_rate); if (!isset(&mvm->sc_enabled_capa, IWM_UCODE_TLV_CAPA_COEX_SCHEMA_2) && - num_of_ant(initial_rate->ant) == 1) + that->iwm_num_of_ant(initial_rate->ant) == 1) lq_cmd->single_stream_ant_msk = initial_rate->ant; lq_cmd->agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF; @@ -3565,7 +3530,7 @@ static void rs_fill_lq_cmd(struct iwm_softc *mvm, #endif lq_cmd->agg_time_limit = - cpu_to_le16(iwl_mvm_coex_agg_time_limit(mvm, sta)); + cpu_to_le16(that->iwm_coex_agg_time_limit(mvm, sta)); } int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate) diff --git a/itlwm/hal_iwm/rs.h b/itlwm/hal_iwm/rs.h index 0ad3a5f6b..ebf3027e1 100644 --- a/itlwm/hal_iwm/rs.h +++ b/itlwm/hal_iwm/rs.h @@ -36,7 +36,7 @@ #define IWL_ERR(sc, fmt, x...)\ do\ {\ -XYLog("%s: " fmt, "ERR", ##x);\ +XYLog("RS %s: " fmt, "ERR", ##x);\ }while(0) /** @@ -670,13 +670,6 @@ enum { IWL_RATE_INVM_PLCP = 0xff, }; -static inline u8 num_of_ant(u8 mask) -{ - return !!((mask) & ANT_A) + - !!((mask) & ANT_B) + - !!((mask) & ANT_C); -} - /* * Returns the first antenna as ANT_[ABC], as defined in iwl-config.h. * The parameter should also be a combination of ANT_[ABC]. From 377b4223330d2f661e9100d02f262f139c1756f7 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Mon, 28 Mar 2022 14:57:36 +0800 Subject: [PATCH 020/114] Clean unused. --- itlwm/hal_iwm/ItlIwm.hpp | 3 - itlwm/hal_iwm/mac80211.cpp | 164 ++----------------------------------- 2 files changed, 5 insertions(+), 162 deletions(-) diff --git a/itlwm/hal_iwm/ItlIwm.hpp b/itlwm/hal_iwm/ItlIwm.hpp index ef0d4737d..a9b943037 100644 --- a/itlwm/hal_iwm/ItlIwm.hpp +++ b/itlwm/hal_iwm/ItlIwm.hpp @@ -266,8 +266,6 @@ class ItlIwm : public ItlHalService, ItlDriverInfo, ItlDriverController { void iwm_rx_tx_cmd(struct iwm_softc *, struct iwm_rx_packet *, struct iwm_rx_data *); void iwm_ampdu_rate_control(struct iwm_softc *, struct ieee80211_node *, struct iwm_tx_ring *, uint16_t, uint16_t, struct ieee80211_tx_info *, int, uint32_t); - void iwm_ht_single_rate_control(struct iwm_softc *, struct ieee80211_node *, - uint8_t, uint8_t, uint8_t, int); void iwm_rx_mpdu_mq(struct iwm_softc *sc, mbuf_t m, void *pktdata, size_t maxlen, struct mbuf_list *ml); void iwm_rx_bmiss(struct iwm_softc *, struct iwm_rx_packet *, @@ -297,7 +295,6 @@ class ItlIwm : public ItlHalService, ItlDriverInfo, ItlDriverController { void iwm_txd_done(struct iwm_softc *, struct iwm_tx_data *); void iwm_ampdu_txq_advance(struct iwm_softc *, struct iwm_tx_ring *, int); void iwm_clear_oactive(struct iwm_softc *, struct iwm_tx_ring *); - void iwm_ra_choose(struct iwm_softc *, struct ieee80211_node *); int iwm_tx(struct iwm_softc *, mbuf_t, struct ieee80211_node *, int); int iwm_flush_tx_path(struct iwm_softc *, int); void iwm_led_enable(struct iwm_softc *); diff --git a/itlwm/hal_iwm/mac80211.cpp b/itlwm/hal_iwm/mac80211.cpp index f04872ebe..79c5e16ab 100644 --- a/itlwm/hal_iwm/mac80211.cpp +++ b/itlwm/hal_iwm/mac80211.cpp @@ -1043,6 +1043,7 @@ static int ieee80211_tx_get_rates(struct iwm_softc *sc, void ieee80211_tx_status(struct iwm_softc *sc, struct ieee80211_tx_info *info, int tid, uint16_t fc, int ssn) { + struct _ifnet *ifp = &sc->sc_ic.ic_ac.ac_if; int rates_idx, retry_count; if (!info) @@ -1051,6 +1052,10 @@ void ieee80211_tx_status(struct iwm_softc *sc, struct ieee80211_tx_info *info, i rates_idx = ieee80211_tx_get_rates(sc, info, &retry_count); rs_drv_mac80211_tx_status(sc, sc->sc_ic.ic_bss, info, tid, fc, ssn); + if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) && + (info->flags & IEEE80211_TX_STAT_AMPDU_NO_BACK) && + (ieee80211_is_data_qos(fc))) + ifp->netStat->outputErrors++; } void ItlIwm:: @@ -1076,8 +1081,6 @@ void ItlIwm:: iwm_ampdu_rate_control(struct iwm_softc *sc, struct ieee80211_node *ni, struct iwm_tx_ring *ring, uint16_t seq, uint16_t ssn, struct ieee80211_tx_info *tx_info, int tid, uint32_t rate_n_flags) { - struct ieee80211com *ic = &sc->sc_ic; - struct iwm_node *wn = (struct iwm_node *)ni; int idx, end_idx; struct iwm_tx_ba *tid_data = &sc->sc_tx_ba[tid]; int freed = 0; @@ -1139,51 +1142,6 @@ iwm_ampdu_rate_control(struct iwm_softc *sc, struct ieee80211_node *ni, } } -void ItlIwm:: -iwm_ht_single_rate_control(struct iwm_softc *sc, struct ieee80211_node *ni, - uint8_t rate, uint8_t rflags, uint8_t ackfailcnt, int txfail) -{ - struct ieee80211com *ic = (struct ieee80211com *)&sc->sc_ic; - struct iwm_node *wn = (struct iwm_node *)ni; - int mcs = rate; - const struct ieee80211_ra_rate *rs; - unsigned int retries = 0, i; - - /* - * Ignore Tx reports which don't match our last LQ command. - */ - if (rate != ni->ni_txmcs) { - if (++wn->lq_rate_mismatch > 15) { - /* Try to sync firmware with driver. */ - iwm_setrates(wn, 1); - wn->lq_rate_mismatch = 0; - } - return; - } - - wn->lq_rate_mismatch = 0; - - rs = ieee80211_ra_get_rateset(&wn->in_rn, ic, ni, rate); - /* - * Firmware has attempted rates in this rate set in sequence. - * Retries at a basic rate are counted against the minimum MCS. - */ - for (i = 0; i < ackfailcnt; i++) { - if (mcs > rs->min_mcs) { - ieee80211_ra_add_stats_ht(&wn->in_rn, ic, ni, mcs, 1, 1); - mcs--; - } else - retries++; - } - - if (txfail && ackfailcnt == 0) - ieee80211_ra_add_stats_ht(&wn->in_rn, ic, ni, mcs, 1, 1); - else - ieee80211_ra_add_stats_ht(&wn->in_rn, ic, ni, mcs, retries + 1, retries); - - iwm_ra_choose(sc, ni); -} - void ItlIwm:: iwm_rx_tx_ba_notif(struct iwm_softc *sc, struct iwm_rx_packet *pkt, struct iwm_rx_data *data) { @@ -1349,18 +1307,11 @@ void ItlIwm:: iwm_rx_tx_cmd_single(struct iwm_softc *sc, struct iwm_tx_resp *tx_resp, int qid, int idx) { - struct ieee80211com *ic = &sc->sc_ic; - struct iwm_node *in = (struct iwm_node *)ic->ic_bss; - struct ieee80211_node *ni = &in->in_ni; - struct _ifnet *ifp = IC2IFP(ic); u32 status = le16toh(iwl_mvm_get_agg_status(sc, tx_resp)->status); u16 ssn = iwl_mvm_get_scd_ssn(sc, tx_resp); - ssn = le32toh(ssn) & 0xfff; - int txfail; int tid = IWL_MVM_TX_RES_GET_TID(tx_resp->ra_tid); struct iwm_tx_data *txd; struct iwm_tx_ring *ring = &sc->txq[qid]; - struct iwm_tx_ba *tid_data = &sc->sc_tx_ba[tid]; u8 skb_freed = 0; u8 lq_color; @@ -1438,111 +1389,6 @@ iwm_rx_tx_cmd_single(struct iwm_softc *sc, struct iwm_tx_resp *tx_resp, } ring->tail = (ring->tail + 1) % IWM_TX_RING_COUNT; } - -// status = status & IWM_TX_STATUS_MSK; -// txfail = (status != IWM_TX_STATUS_SUCCESS && -// status != IWM_TX_STATUS_DIRECT_DONE); -// -// /* -// * Update rate control statistics. -// * Only report frames which were actually queued with the currently -// * selected Tx rate. Because Tx queues are relatively long we may -// * encounter previously selected rates here during Tx bursts. -// * Providing feedback based on such frames can lead to suboptimal -// * Tx rate control decisions. -// */ -// if ((ni->ni_flags & IEEE80211_NODE_HT) == 0) { -// if (ring->data[idx].txrate != ni->ni_txrate) { -// if (++in->lq_rate_mismatch > 15) { -// /* Try to sync firmware with the driver... */ -// iwm_setrates(in, 1); -// in->lq_rate_mismatch = 0; -// } -// } else { -// in->lq_rate_mismatch = 0; -// -// in->in_amn.amn_txcnt++; -// if (txfail) -// in->in_amn.amn_retrycnt++; -// if (tx_resp->failure_frame > 0) -// in->in_amn.amn_retrycnt++; -// } -// } else if (ic->ic_fixed_mcs == -1 && ic->ic_state == IEEE80211_S_RUN && -// (le32toh(tx_resp->initial_rate) & IWM_RATE_MCS_HT_MSK)) { -// uint32_t fw_txmcs = le32toh(tx_resp->initial_rate) & -// (IWM_RATE_HT_MCS_RATE_CODE_MSK | IWM_RATE_HT_MCS_NSS_MSK); -// /* Ignore Tx reports which don't match our last LQ command. */ -// if (fw_txmcs != ni->ni_txmcs) { -// if (++in->lq_rate_mismatch > 15) { -// /* Try to sync firmware with the driver... */ -// iwm_setrates(in, 1); -// in->lq_rate_mismatch = 0; -// } -// } else { -// int mcs = fw_txmcs; -// const struct ieee80211_ra_rate *rs = -// ieee80211_ra_get_rateset(&in->in_rn, ic, ni, fw_txmcs); -// unsigned int retries = 0, i; -// int old_txmcs = ni->ni_txmcs; -// int old_bw = in->in_rn.bw; -// int old_nss = in->in_rn.nss; -// int old_sgi = in->in_rn.sgi; -// -// in->lq_rate_mismatch = 0; -// -// for (i = 0; i < tx_resp->failure_frame; i++) { -// if (mcs > rs->min_mcs) { -// ieee80211_ra_add_stats_ht(&in->in_rn, -// ic, ni, mcs, 1, 1); -// mcs--; -// } else -// retries++; -// } -// -// if (txfail && tx_resp->failure_frame == 0) { -// ieee80211_ra_add_stats_ht(&in->in_rn, ic, ni, -// fw_txmcs, 1, 1); -// } else { -// ieee80211_ra_add_stats_ht(&in->in_rn, ic, ni, -// mcs, retries + 1, retries); -// } -// -// ieee80211_ra_choose(&in->in_rn, ic, ni); -// -// /* -// * If RA has chosen a new TX rate we must update -// * the firmware's LQ rate table. -// * ni_txmcs may change again before the task runs so -// * cache the chosen rate in the iwm_node structure. -// */ -// if (ni->ni_txmcs != old_txmcs || in->in_rn.bw != old_bw || in->in_rn.sgi != old_sgi || in->in_rn.nss != old_nss) -// iwm_setrates(in, 1); -// } -// } -// -// if (txfail) { -// XYLog("%s %d OUTPUT_ERROR status=%d\n", __FUNCTION__, __LINE__, status); -// ifp->netStat->outputErrors++; -// } else { -// DPRINTFN(2, ("%s %d succeed status=%d\n", __FUNCTION__, __LINE__, status)); -// } -} - -void ItlIwm:: -iwm_ra_choose(struct iwm_softc *sc, struct ieee80211_node *ni) -{ - struct ieee80211com *ic = &sc->sc_ic; - struct iwm_node *in = (struct iwm_node *)ni; - int old_txmcs = ni->ni_txmcs; - int old_bw = in->in_rn.bw; - int old_nss = in->in_rn.nss; - int old_sgi = in->in_rn.sgi; - - ieee80211_ra_choose(&in->in_rn, ic, ni); - - /* Update firmware's LQ retry table if RA has chosen a new MCS. */ - if (ni->ni_txmcs != old_txmcs || in->in_rn.bw != old_bw || in->in_rn.sgi != old_sgi || in->in_rn.nss != old_nss) - iwm_setrates(in, 1); } void ItlIwm:: From c646cde97c84882ecf288076ad5d2ba9bac0dc33 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Tue, 29 Mar 2022 01:24:33 +0800 Subject: [PATCH 021/114] Clean old iwm rate definition. --- itlwm/hal_iwm/ItlIwm.hpp | 12 +- itlwm/hal_iwm/coex.cpp | 13 +- itlwm/hal_iwm/fw.cpp | 37 ++--- itlwm/hal_iwm/if_iwmreg.h | 275 ---------------------------------- itlwm/hal_iwm/if_iwmvar.h | 2 +- itlwm/hal_iwm/itlhdr.h | 86 ----------- itlwm/hal_iwm/mac80211.cpp | 293 +++++-------------------------------- itlwm/hal_iwm/rs.cpp | 2 +- itlwm/hal_iwm/rs.h | 5 +- itlwm/hal_iwm/scan.cpp | 52 +++---- 10 files changed, 92 insertions(+), 685 deletions(-) diff --git a/itlwm/hal_iwm/ItlIwm.hpp b/itlwm/hal_iwm/ItlIwm.hpp index a9b943037..d6576d44b 100644 --- a/itlwm/hal_iwm/ItlIwm.hpp +++ b/itlwm/hal_iwm/ItlIwm.hpp @@ -84,9 +84,11 @@ class ItlIwm : public ItlHalService, ItlDriverInfo, ItlDriverController { int iwm_send_bt_init_conf(struct iwm_softc *); //fw - uint8_t iwm_fw_valid_tx_ant(struct iwm_softc *sc); - uint8_t iwm_fw_valid_rx_ant(struct iwm_softc *sc); + static uint8_t iwm_fw_valid_tx_ant(struct iwm_softc *sc); + static uint8_t iwm_fw_valid_rx_ant(struct iwm_softc *sc); void iwm_toggle_tx_ant(struct iwm_softc *sc, uint8_t *ant); + uint32_t iwm_get_tx_ant(struct iwm_softc *sc, struct ieee80211_node *ni, + int type, struct ieee80211_frame *wh); //scan uint8_t iwm_umac_scan_fill_channels(struct iwm_softc *sc, @@ -98,11 +100,9 @@ class ItlIwm : public ItlHalService, ItlDriverInfo, ItlDriverController { static bool iwm_coex_is_ant_avail(struct iwm_softc *, u8); static bool iwm_coex_is_mimo_allowed(struct iwm_softc *, struct ieee80211_node *); static bool iwm_coex_is_tpc_allowed(struct iwm_softc *, bool); + static bool iwm_coex_is_shared_ant_avail(struct iwm_softc *); uint8_t iwm_lookup_cmd_ver(struct iwm_softc *, uint8_t, uint8_t); - int iwm_is_mimo_ht_plcp(uint8_t); - int iwm_is_mimo_vht_plcp(uint8_t); - int iwm_is_mimo_mcs(int); int iwm_store_cscheme(struct iwm_softc *, uint8_t *, size_t); int iwm_firmware_store_section(struct iwm_softc *, enum iwm_ucode_type, uint8_t *, size_t); @@ -332,7 +332,6 @@ class ItlIwm : public ItlHalService, ItlDriverInfo, ItlDriverController { int iwm_umac_scan(struct iwm_softc *, int); void iwm_mcc_update(struct iwm_softc *, struct iwm_mcc_chub_notif *); uint8_t iwm_ridx2rate(struct ieee80211_rateset *, int); - int iwm_rval2ridx(int); void iwm_ack_rates(struct iwm_softc *, struct iwm_node *, int *, int *); void iwm_mac_ctxt_cmd_common(struct iwm_softc *, struct iwm_node *, struct iwm_mac_ctx_cmd *, uint32_t); @@ -363,7 +362,6 @@ class ItlIwm : public ItlHalService, ItlDriverInfo, ItlDriverController { static void iwm_delete_key(struct ieee80211com *, struct ieee80211_node *, struct ieee80211_key *); static void iwm_calib_timeout(void *); - void iwm_setrates(struct iwm_node *, int); int iwm_media_change(struct _ifnet *); static void iwm_newstate_task(void *); static int iwm_newstate(struct ieee80211com *, enum ieee80211_state, int); diff --git a/itlwm/hal_iwm/coex.cpp b/itlwm/hal_iwm/coex.cpp index 16d7e0e4f..6857dcc12 100644 --- a/itlwm/hal_iwm/coex.cpp +++ b/itlwm/hal_iwm/coex.cpp @@ -128,6 +128,17 @@ iwm_coex_is_tpc_allowed(struct iwm_softc *mvm, bool is5G) #ifdef notyet_coex return le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) >= BT_LOW_TRAFFIC; #else - return true; + return false; +#endif +} + +bool ItlIwm:: +iwm_coex_is_shared_ant_avail(struct iwm_softc *mvm) +{ +#ifdef notyet_coex + return le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) < BT_HIGH_TRAFFIC; +#else + return mvm->sc_device_family == IWM_DEVICE_FAMILY_9000 && + (iwm_fw_valid_tx_ant(mvm) & IWM_ANT_B); #endif } diff --git a/itlwm/hal_iwm/fw.cpp b/itlwm/hal_iwm/fw.cpp index 5afa852ce..141a5a222 100644 --- a/itlwm/hal_iwm/fw.cpp +++ b/itlwm/hal_iwm/fw.cpp @@ -120,6 +120,7 @@ */ #include "ItlIwm.hpp" +#include "rs.h" #include uint8_t ItlIwm:: @@ -137,28 +138,6 @@ iwm_lookup_cmd_ver(struct iwm_softc *sc, uint8_t grp, uint8_t cmd) return IWM_FW_CMD_VER_UNKNOWN; } -int ItlIwm:: -iwm_is_mimo_ht_plcp(uint8_t ht_plcp) -{ - return (ht_plcp != IWM_RATE_HT_SISO_MCS_INV_PLCP && - (ht_plcp & IWM_RATE_HT_MCS_NSS_MSK)); -} - -int ItlIwm:: -iwm_is_mimo_vht_plcp(uint8_t ht_plcp) -{ - return (ht_plcp != IWM_RATE_VHT_SISO_MCS_INV_PLCP && - (ht_plcp & IWM_RATE_VHT_MCS_NSS_MSK)); -} - -int ItlIwm:: -iwm_is_mimo_mcs(int mcs) -{ - int ridx = iwm_mcs2ridx[mcs]; - return iwm_is_mimo_ht_plcp(iwm_rates[ridx].ht_plcp); - -} - int ItlIwm:: iwm_store_cscheme(struct iwm_softc *sc, uint8_t *data, size_t dlen) { @@ -746,6 +725,20 @@ iwm_fw_valid_rx_ant(struct iwm_softc *sc) return rx_ant; } +uint32_t ItlIwm:: +iwm_get_tx_ant(struct iwm_softc *sc, struct ieee80211_node *ni, + int type, struct ieee80211_frame *wh) +{ + if (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan) && + !ItlIwm::iwm_coex_is_shared_ant_avail(sc)) + return sc->non_shared_ant << RATE_MCS_ANT_POS; + + if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && type == IEEE80211_FC0_TYPE_DATA) + return ((1 << sc->sc_tx_ant) << RATE_MCS_ANT_POS); + + return ((1 << sc->sc_mgmt_last_antenna_idx) << RATE_MCS_ANT_POS); +} + void ItlIwm:: iwm_toggle_tx_ant(struct iwm_softc *sc, uint8_t *ant) { diff --git a/itlwm/hal_iwm/if_iwmreg.h b/itlwm/hal_iwm/if_iwmreg.h index 44ebf1842..cdddd973c 100644 --- a/itlwm/hal_iwm/if_iwmreg.h +++ b/itlwm/hal_iwm/if_iwmreg.h @@ -4399,232 +4399,6 @@ struct iwm_beacon_filter_cmd { .bf_escape_timer = htole32(IWM_BF_ESCAPE_TIMER_DEFAULT), \ .ba_escape_timer = htole32(IWM_BA_ESCAPE_TIMER_DEFAULT) -/* uCode API values for HT/VHT bit rates */ -#define IWM_RATE_HT_SISO_MCS_0_PLCP 0 -#define IWM_RATE_HT_SISO_MCS_1_PLCP 1 -#define IWM_RATE_HT_SISO_MCS_2_PLCP 2 -#define IWM_RATE_HT_SISO_MCS_3_PLCP 3 -#define IWM_RATE_HT_SISO_MCS_4_PLCP 4 -#define IWM_RATE_HT_SISO_MCS_5_PLCP 5 -#define IWM_RATE_HT_SISO_MCS_6_PLCP 6 -#define IWM_RATE_HT_SISO_MCS_7_PLCP 7 -#define IWM_RATE_HT_MIMO2_MCS_8_PLCP 0x8 -#define IWM_RATE_HT_MIMO2_MCS_9_PLCP 0x9 -#define IWM_RATE_HT_MIMO2_MCS_10_PLCP 0xA -#define IWM_RATE_HT_MIMO2_MCS_11_PLCP 0xB -#define IWM_RATE_HT_MIMO2_MCS_12_PLCP 0xC -#define IWM_RATE_HT_MIMO2_MCS_13_PLCP 0xD -#define IWM_RATE_HT_MIMO2_MCS_14_PLCP 0xE -#define IWM_RATE_HT_MIMO2_MCS_15_PLCP 0xF -#define IWM_RATE_VHT_SISO_MCS_0_PLCP 0 -#define IWM_RATE_VHT_SISO_MCS_1_PLCP 1 -#define IWM_RATE_VHT_SISO_MCS_2_PLCP 2 -#define IWM_RATE_VHT_SISO_MCS_3_PLCP 3 -#define IWM_RATE_VHT_SISO_MCS_4_PLCP 4 -#define IWM_RATE_VHT_SISO_MCS_5_PLCP 5 -#define IWM_RATE_VHT_SISO_MCS_6_PLCP 6 -#define IWM_RATE_VHT_SISO_MCS_7_PLCP 7 -#define IWM_RATE_VHT_SISO_MCS_8_PLCP 8 -#define IWM_RATE_VHT_SISO_MCS_9_PLCP 9 -#define IWM_RATE_VHT_MIMO2_MCS_0_PLCP 0x10 -#define IWM_RATE_VHT_MIMO2_MCS_1_PLCP 0x11 -#define IWM_RATE_VHT_MIMO2_MCS_2_PLCP 0x12 -#define IWM_RATE_VHT_MIMO2_MCS_3_PLCP 0x13 -#define IWM_RATE_VHT_MIMO2_MCS_4_PLCP 0x14 -#define IWM_RATE_VHT_MIMO2_MCS_5_PLCP 0x15 -#define IWM_RATE_VHT_MIMO2_MCS_6_PLCP 0x16 -#define IWM_RATE_VHT_MIMO2_MCS_7_PLCP 0x17 -#define IWM_RATE_VHT_MIMO2_MCS_8_PLCP 0x18 -#define IWM_RATE_VHT_MIMO2_MCS_9_PLCP 0x19 -#define IWM_RATE_HT_SISO_MCS_INV_PLCP 0x1A -#define IWM_RATE_HT_MIMO2_MCS_INV_PLCP IWM_RATE_HT_SISO_MCS_INV_PLCP -#define IWM_RATE_VHT_SISO_MCS_INV_PLCP IWM_RATE_HT_SISO_MCS_INV_PLCP -#define IWM_RATE_VHT_MIMO2_MCS_INV_PLCP IWM_RATE_HT_SISO_MCS_INV_PLCP -#define IWM_RATE_HT_SISO_MCS_8_PLCP IWM_RATE_HT_SISO_MCS_INV_PLCP -#define IWM_RATE_HT_SISO_MCS_9_PLCP IWM_RATE_HT_SISO_MCS_INV_PLCP - -/* - * These serve as indexes into struct iwm_rate iwm_rates[IWM_RIDX_MAX]. - */ -enum { - IWM_RATE_1M_INDEX = 0, - IWM_FIRST_CCK_RATE = IWM_RATE_1M_INDEX, - IWM_RATE_2M_INDEX, - IWM_RATE_5M_INDEX, - IWM_RATE_11M_INDEX, - IWM_LAST_CCK_RATE = IWM_RATE_11M_INDEX, - IWM_RATE_6M_INDEX, - IWM_FIRST_OFDM_RATE = IWM_RATE_6M_INDEX, - IWM_RATE_MCS_0_INDEX = IWM_RATE_6M_INDEX, - IWM_FIRST_HT_RATE = IWM_RATE_MCS_0_INDEX, - IWM_FIRST_VHT_RATE = IWM_RATE_MCS_0_INDEX, - IWM_RATE_9M_INDEX, - IWM_RATE_12M_INDEX, - IWM_RATE_MCS_1_INDEX = IWM_RATE_12M_INDEX, - IWM_RATE_MCS_8_INDEX, - IWM_FIRST_HT_MIMO2_RATE = IWM_RATE_MCS_8_INDEX, - IWM_RATE_18M_INDEX, - IWM_RATE_MCS_2_INDEX = IWM_RATE_18M_INDEX, - IWM_RATE_24M_INDEX, - IWM_RATE_MCS_3_INDEX = IWM_RATE_24M_INDEX, - IWM_RATE_MCS_9_INDEX, - IWM_RATE_36M_INDEX, - IWM_RATE_MCS_4_INDEX = IWM_RATE_36M_INDEX, - IWM_RATE_MCS_10_INDEX, - IWM_RATE_48M_INDEX, - IWM_RATE_MCS_5_INDEX = IWM_RATE_48M_INDEX, - IWM_RATE_MCS_11_INDEX, - IWM_RATE_54M_INDEX, - IWM_RATE_MCS_6_INDEX = IWM_RATE_54M_INDEX, - IWM_LAST_NON_HT_RATE = IWM_RATE_54M_INDEX, - IWM_RATE_MCS_7_INDEX, - IWM_LAST_HT_SISO_RATE = IWM_RATE_MCS_7_INDEX, - IWM_RATE_MCS_12_INDEX, - IWM_RATE_MCS_13_INDEX, - IWM_RATE_MCS_14_INDEX, - IWM_RATE_MCS_15_INDEX, - IWM_LAST_VHT_SISO_RATE = IWM_RATE_MCS_13_INDEX, - IWM_LAST_HT_RATE = IWM_RATE_MCS_15_INDEX, - IWM_LAST_VHT_RATE = IWM_RATE_MCS_15_INDEX + 3, - IWM_RATE_COUNT_LEGACY = IWM_LAST_NON_HT_RATE + 1, - IWM_RATE_COUNT = IWM_LAST_VHT_RATE + 1, -}; - -#define IWM_RATE_BIT_MSK(r) (1 << (IWM_RATE_##r##M_INDEX)) - -/* fw API values for legacy bit rates, both OFDM and CCK */ -#define IWM_RATE_6M_PLCP 13 -#define IWM_RATE_9M_PLCP 15 -#define IWM_RATE_12M_PLCP 5 -#define IWM_RATE_18M_PLCP 7 -#define IWM_RATE_24M_PLCP 9 -#define IWM_RATE_36M_PLCP 11 -#define IWM_RATE_48M_PLCP 1 -#define IWM_RATE_54M_PLCP 3 -#define IWM_RATE_1M_PLCP 10 -#define IWM_RATE_2M_PLCP 20 -#define IWM_RATE_5M_PLCP 55 -#define IWM_RATE_11M_PLCP 110 -#define IWM_RATE_INVM_PLCP 0xff - -/* - * rate_n_flags bit fields - * - * The 32-bit value has different layouts in the low 8 bites depending on the - * format. There are three formats, HT, VHT and legacy (11abg, with subformats - * for CCK and OFDM). - * - * High-throughput (HT) rate format - * bit 8 is 1, bit 26 is 0, bit 9 is 0 (OFDM) - * Very High-throughput (VHT) rate format - * bit 8 is 0, bit 26 is 1, bit 9 is 0 (OFDM) - * Legacy OFDM rate format for bits 7:0 - * bit 8 is 0, bit 26 is 0, bit 9 is 0 (OFDM) - * Legacy CCK rate format for bits 7:0: - * bit 8 is 0, bit 26 is 0, bit 9 is 1 (CCK) - */ - -/* Bit 8: (1) HT format, (0) legacy or VHT format */ -#define IWM_RATE_MCS_HT_POS 8 -#define IWM_RATE_MCS_HT_MSK (1 << IWM_RATE_MCS_HT_POS) - -/* Bit 9: (1) CCK, (0) OFDM. HT (bit 8) must be "0" for this bit to be valid */ -#define IWM_RATE_MCS_CCK_POS 9 -#define IWM_RATE_MCS_CCK_MSK (1 << IWM_RATE_MCS_CCK_POS) - -/* Bit 26: (1) VHT format, (0) legacy format in bits 8:0 */ -#define IWM_RATE_MCS_VHT_POS 26 -#define IWM_RATE_MCS_VHT_MSK (1 << IWM_RATE_MCS_VHT_POS) - - -/* - * High-throughput (HT) rate format for bits 7:0 - * - * 2-0: MCS rate base - * 0) 6 Mbps - * 1) 12 Mbps - * 2) 18 Mbps - * 3) 24 Mbps - * 4) 36 Mbps - * 5) 48 Mbps - * 6) 54 Mbps - * 7) 60 Mbps - * 4-3: 0) Single stream (SISO) - * 1) Dual stream (MIMO) - * 2) Triple stream (MIMO) - * 5: Value of 0x20 in bits 7:0 indicates 6 Mbps HT40 duplicate data - * (bits 7-6 are zero) - * - * Together the low 5 bits work out to the MCS index because we don't - * support MCSes above 15/23, and 0-7 have one stream, 8-15 have two - * streams and 16-23 have three streams. We could also support MCS 32 - * which is the duplicate 20 MHz MCS (bit 5 set, all others zero.) - */ -#define IWM_RATE_HT_MCS_RATE_CODE_MSK 0x7 -#define IWM_RATE_HT_MCS_NSS_POS 3 -#define IWM_RATE_HT_MCS_NSS_MSK (3 << IWM_RATE_HT_MCS_NSS_POS) - -/* Bit 10: (1) Use Green Field preamble */ -#define IWM_RATE_HT_MCS_GF_POS 10 -#define IWM_RATE_HT_MCS_GF_MSK (1 << IWM_RATE_HT_MCS_GF_POS) - -#define IWM_RATE_HT_MCS_INDEX_MSK 0x3f - -/* - * Very High-throughput (VHT) rate format for bits 7:0 - * - * 3-0: VHT MCS (0-9) - * 5-4: number of streams - 1: - * 0) Single stream (SISO) - * 1) Dual stream (MIMO) - * 2) Triple stream (MIMO) - */ - -/* Bit 4-5: (0) SISO, (1) MIMO2 (2) MIMO3 */ -#define IWM_RATE_VHT_MCS_RATE_CODE_MSK 0xf -#define IWM_RATE_VHT_MCS_NSS_POS 4 -#define IWM_RATE_VHT_MCS_NSS_MSK (3 << IWM_RATE_VHT_MCS_NSS_POS) - -/* - * Legacy OFDM rate format for bits 7:0 - * - * 3-0: 0xD) 6 Mbps - * 0xF) 9 Mbps - * 0x5) 12 Mbps - * 0x7) 18 Mbps - * 0x9) 24 Mbps - * 0xB) 36 Mbps - * 0x1) 48 Mbps - * 0x3) 54 Mbps - * (bits 7-4 are 0) - * - * Legacy CCK rate format for bits 7:0: - * bit 8 is 0, bit 26 is 0, bit 9 is 1 (CCK): - * - * 6-0: 10) 1 Mbps - * 20) 2 Mbps - * 55) 5.5 Mbps - * 110) 11 Mbps - * (bit 7 is 0) - */ -#define IWM_RATE_LEGACY_RATE_MSK 0xff - - -/* - * Bit 11-12: (0) 20MHz, (1) 40MHz, (2) 80MHz, (3) 160MHz - * 0 and 1 are valid for HT and VHT, 2 and 3 only for VHT - */ -#define IWM_RATE_MCS_CHAN_WIDTH_POS 11 -#define IWM_RATE_MCS_CHAN_WIDTH_MSK (3 << IWM_RATE_MCS_CHAN_WIDTH_POS) -#define IWM_RATE_MCS_CHAN_WIDTH_20 (0 << IWM_RATE_MCS_CHAN_WIDTH_POS) -#define IWM_RATE_MCS_CHAN_WIDTH_40 (1 << IWM_RATE_MCS_CHAN_WIDTH_POS) -#define IWM_RATE_MCS_CHAN_WIDTH_80 (2 << IWM_RATE_MCS_CHAN_WIDTH_POS) -#define IWM_RATE_MCS_CHAN_WIDTH_160 (3 << IWM_RATE_MCS_CHAN_WIDTH_POS) - -/* Bit 13: (1) Short guard interval (0.4 usec), (0) normal GI (0.8 usec) */ -#define IWM_RATE_MCS_SGI_POS 13 -#define IWM_RATE_MCS_SGI_MSK (1 << IWM_RATE_MCS_SGI_POS) - /* Bit 14-16: Antenna selection (1) Ant A, (2) Ant B, (4) Ant C */ #define IWM_RATE_MCS_ANT_POS 14 #define IWM_RATE_MCS_ANT_A_MSK (1 << IWM_RATE_MCS_ANT_POS) @@ -4637,58 +4411,9 @@ enum { #define IWM_RATE_MCS_ANT_MSK IWM_RATE_MCS_ANT_ABC_MSK #define IWM_RATE_MCS_ANT_NUM 3 -/* Bit 17-18: (0) SS, (1) SS*2 */ -#define IWM_RATE_MCS_STBC_POS 17 -#define IWM_RATE_MCS_STBC_MSK (1 << IWM_RATE_MCS_STBC_POS) - -/* Bit 19: (0) Beamforming is off, (1) Beamforming is on */ -#define IWM_RATE_MCS_BF_POS 19 -#define IWM_RATE_MCS_BF_MSK (1 << IWM_RATE_MCS_BF_POS) - -/* Bit 20: (0) ZLF is off, (1) ZLF is on */ -#define IWM_RATE_MCS_ZLF_POS 20 -#define IWM_RATE_MCS_ZLF_MSK (1 << IWM_RATE_MCS_ZLF_POS) - -/* Bit 24-25: (0) 20MHz (no dup), (1) 2x20MHz, (2) 4x20MHz, 3 8x20MHz */ -#define IWM_RATE_MCS_DUP_POS 24 -#define IWM_RATE_MCS_DUP_MSK (3 << IWM_RATE_MCS_DUP_POS) - -/* Bit 27: (1) LDPC enabled, (0) LDPC disabled */ -#define IWM_RATE_MCS_LDPC_POS 27 -#define IWM_RATE_MCS_LDPC_MSK (1 << IWM_RATE_MCS_LDPC_POS) - - -/* Link Quality definitions */ - /* # entries in rate scale table to support Tx retries */ #define IWM_LQ_MAX_RETRY_NUM 16 -/* Link quality command flags bit fields */ - -/* Bit 0: (0) Don't use RTS (1) Use RTS */ -#define IWM_LQ_FLAG_USE_RTS_POS 0 -#define IWM_LQ_FLAG_USE_RTS_MSK (1 << IWM_LQ_FLAG_USE_RTS_POS) - -/* Bit 1-3: LQ command color. Used to match responses to LQ commands */ -#define IWM_LQ_FLAG_COLOR_POS 1 -#define IWM_LQ_FLAG_COLOR_MSK (7 << IWM_LQ_FLAG_COLOR_POS) - -/* Bit 4-5: Tx RTS BW Signalling - * (0) No RTS BW signalling - * (1) Static BW signalling - * (2) Dynamic BW signalling - */ -#define IWM_LQ_FLAG_RTS_BW_SIG_POS 4 -#define IWM_LQ_FLAG_RTS_BW_SIG_NONE (0 << IWM_LQ_FLAG_RTS_BW_SIG_POS) -#define IWM_LQ_FLAG_RTS_BW_SIG_STATIC (1 << IWM_LQ_FLAG_RTS_BW_SIG_POS) -#define IWM_LQ_FLAG_RTS_BW_SIG_DYNAMIC (2 << IWM_LQ_FLAG_RTS_BW_SIG_POS) - -/* Bit 6: (0) No dynamic BW selection (1) Allow dynamic BW selection - * Dyanmic BW selection allows Tx with narrower BW then requested in rates - */ -#define IWM_LQ_FLAG_DYNAMIC_BW_POS 6 -#define IWM_LQ_FLAG_DYNAMIC_BW_MSK (1 << IWM_LQ_FLAG_DYNAMIC_BW_POS) - /* Antenna flags. */ #define IWM_ANT_A (1 << 0) #define IWM_ANT_B (1 << 1) diff --git a/itlwm/hal_iwm/if_iwmvar.h b/itlwm/hal_iwm/if_iwmvar.h index 3d48b00fa..8624e10ec 100644 --- a/itlwm/hal_iwm/if_iwmvar.h +++ b/itlwm/hal_iwm/if_iwmvar.h @@ -551,6 +551,7 @@ struct iwm_softc { int cmdqid; uint8_t sc_mgmt_last_antenna_idx; + uint8_t sc_tx_ant; int sc_sf_state; @@ -713,7 +714,6 @@ struct iwm_node { uint16_t in_color; struct ieee80211_amrr_node in_amn; - struct ieee80211_ra_node in_rn; int lq_rate_mismatch; uint32_t next_ampdu_id; diff --git a/itlwm/hal_iwm/itlhdr.h b/itlwm/hal_iwm/itlhdr.h index f6af6e578..d8092946b 100644 --- a/itlwm/hal_iwm/itlhdr.h +++ b/itlwm/hal_iwm/itlhdr.h @@ -181,92 +181,6 @@ const uint8_t iwm_nvm_channels_8000[] = { #define IWM_FIRST_2GHZ_HT_MINUS 5 #define IWM_LAST_2GHZ_HT_PLUS 9 -const struct iwm_rate { - uint16_t rate; - uint8_t plcp; - uint8_t ht_plcp; - uint8_t vht_plcp; -} iwm_rates[] = { - /* Legacy */ /* HT */ - { 2, IWM_RATE_1M_PLCP, IWM_RATE_HT_SISO_MCS_INV_PLCP, IWM_RATE_VHT_SISO_MCS_INV_PLCP }, - { 4, IWM_RATE_2M_PLCP, IWM_RATE_HT_SISO_MCS_INV_PLCP, IWM_RATE_VHT_SISO_MCS_INV_PLCP }, - { 11, IWM_RATE_5M_PLCP, IWM_RATE_HT_SISO_MCS_INV_PLCP, IWM_RATE_VHT_SISO_MCS_INV_PLCP }, - { 22, IWM_RATE_11M_PLCP, IWM_RATE_HT_SISO_MCS_INV_PLCP, IWM_RATE_VHT_SISO_MCS_INV_PLCP }, - { 12, IWM_RATE_6M_PLCP, IWM_RATE_HT_SISO_MCS_0_PLCP, IWM_RATE_VHT_SISO_MCS_0_PLCP }, - { 18, IWM_RATE_9M_PLCP, IWM_RATE_HT_SISO_MCS_INV_PLCP, IWM_RATE_VHT_SISO_MCS_INV_PLCP }, - { 24, IWM_RATE_12M_PLCP, IWM_RATE_HT_SISO_MCS_1_PLCP, IWM_RATE_VHT_SISO_MCS_1_PLCP }, - { 26, IWM_RATE_12M_PLCP, IWM_RATE_HT_MIMO2_MCS_8_PLCP, IWM_RATE_VHT_MIMO2_MCS_0_PLCP }, - { 36, IWM_RATE_18M_PLCP, IWM_RATE_HT_SISO_MCS_2_PLCP, IWM_RATE_VHT_SISO_MCS_2_PLCP }, - { 48, IWM_RATE_24M_PLCP, IWM_RATE_HT_SISO_MCS_3_PLCP, IWM_RATE_VHT_SISO_MCS_3_PLCP }, - { 52, IWM_RATE_24M_PLCP, IWM_RATE_HT_MIMO2_MCS_9_PLCP, IWM_RATE_VHT_MIMO2_MCS_1_PLCP }, - { 72, IWM_RATE_36M_PLCP, IWM_RATE_HT_SISO_MCS_4_PLCP, IWM_RATE_VHT_SISO_MCS_4_PLCP }, - { 78, IWM_RATE_36M_PLCP, IWM_RATE_HT_MIMO2_MCS_10_PLCP, IWM_RATE_VHT_MIMO2_MCS_2_PLCP }, - { 96, IWM_RATE_48M_PLCP, IWM_RATE_HT_SISO_MCS_5_PLCP, IWM_RATE_VHT_SISO_MCS_5_PLCP }, - { 104, IWM_RATE_48M_PLCP, IWM_RATE_HT_MIMO2_MCS_11_PLCP, IWM_RATE_VHT_MIMO2_MCS_3_PLCP }, - { 108, IWM_RATE_54M_PLCP, IWM_RATE_HT_SISO_MCS_6_PLCP, IWM_RATE_VHT_SISO_MCS_6_PLCP }, - { 128, IWM_RATE_54M_PLCP, IWM_RATE_HT_SISO_MCS_7_PLCP, IWM_RATE_VHT_SISO_MCS_7_PLCP }, - { 156, IWM_RATE_54M_PLCP, IWM_RATE_HT_MIMO2_MCS_12_PLCP, IWM_RATE_VHT_SISO_MCS_8_PLCP }, - { 208, IWM_RATE_54M_PLCP, IWM_RATE_HT_MIMO2_MCS_13_PLCP, IWM_RATE_VHT_SISO_MCS_9_PLCP }, - { 234, IWM_RATE_54M_PLCP, IWM_RATE_HT_MIMO2_MCS_14_PLCP, IWM_RATE_VHT_MIMO2_MCS_4_PLCP }, - { 260, IWM_RATE_54M_PLCP, IWM_RATE_HT_MIMO2_MCS_15_PLCP, IWM_RATE_VHT_MIMO2_MCS_5_PLCP }, - { 312, IWM_RATE_54M_PLCP, IWM_RATE_HT_SISO_MCS_INV_PLCP, IWM_RATE_VHT_MIMO2_MCS_6_PLCP }, - { 360, IWM_RATE_54M_PLCP, IWM_RATE_HT_SISO_MCS_INV_PLCP, IWM_RATE_VHT_MIMO2_MCS_7_PLCP }, - { 720, IWM_RATE_54M_PLCP, IWM_RATE_HT_SISO_MCS_INV_PLCP, IWM_RATE_VHT_MIMO2_MCS_8_PLCP }, - { 780, IWM_RATE_54M_PLCP, IWM_RATE_HT_SISO_MCS_INV_PLCP, IWM_RATE_VHT_MIMO2_MCS_9_PLCP }, -}; -#define IWM_RIDX_CCK 0 -#define IWM_RIDX_OFDM 4 -#define IWM_RIDX_MAX (nitems(iwm_rates)-1) -#define IWM_RIDX_IS_CCK(_i_) ((_i_) < IWM_RIDX_OFDM) -#define IWM_RIDX_IS_OFDM(_i_) ((_i_) >= IWM_RIDX_OFDM) -#define IWM_RVAL_IS_OFDM(_i_) ((_i_) >= 12 && (_i_) != 22) - -/* Convert an MCS index into an iwm_rates[] index. */ -const int iwm_mcs2ridx[] = { - IWM_RATE_MCS_0_INDEX, - IWM_RATE_MCS_1_INDEX, - IWM_RATE_MCS_2_INDEX, - IWM_RATE_MCS_3_INDEX, - IWM_RATE_MCS_4_INDEX, - IWM_RATE_MCS_5_INDEX, - IWM_RATE_MCS_6_INDEX, - IWM_RATE_MCS_7_INDEX, - IWM_RATE_MCS_8_INDEX, - IWM_RATE_MCS_9_INDEX, - IWM_RATE_MCS_10_INDEX, - IWM_RATE_MCS_11_INDEX, - IWM_RATE_MCS_12_INDEX, - IWM_RATE_MCS_13_INDEX, - IWM_RATE_MCS_14_INDEX, - IWM_RATE_MCS_15_INDEX, -}; - -const int iwm_vht_siso_mcs2ridx[] = { - IWM_RATE_MCS_0_INDEX, - IWM_RATE_MCS_1_INDEX, - IWM_RATE_MCS_2_INDEX, - IWM_RATE_MCS_3_INDEX, - IWM_RATE_MCS_4_INDEX, - IWM_RATE_MCS_5_INDEX, - IWM_RATE_MCS_6_INDEX, - IWM_RATE_MCS_7_INDEX, - IWM_RATE_MCS_12_INDEX, - IWM_RATE_MCS_13_INDEX, -}; - -const int iwm_vht_mimo_mcs2ridx[] = { - IWM_RATE_MCS_8_INDEX, - IWM_RATE_MCS_9_INDEX, - IWM_RATE_MCS_10_INDEX, - IWM_RATE_MCS_11_INDEX, - IWM_RATE_MCS_14_INDEX, - IWM_RATE_MCS_15_INDEX, - IWM_RATE_MCS_15_INDEX+1, - IWM_RATE_MCS_15_INDEX+2, - IWM_RATE_MCS_15_INDEX+3, - IWM_RATE_MCS_15_INDEX+4, -}; - struct iwm_nvm_section { uint16_t length; uint8_t *data; diff --git a/itlwm/hal_iwm/mac80211.cpp b/itlwm/hal_iwm/mac80211.cpp index 79c5e16ab..965a62c2e 100644 --- a/itlwm/hal_iwm/mac80211.cpp +++ b/itlwm/hal_iwm/mac80211.cpp @@ -1236,15 +1236,6 @@ iwm_ampdu_tx_done(struct iwm_softc *sc, struct iwm_cmd_header *cmd_hdr, int txfail = (status != IWM_TX_STATUS_SUCCESS && status != IWM_TX_STATUS_DIRECT_DONE); struct ieee80211_tx_ba *ba; - int rate = 0; - if (initial_rate & IWM_RATE_MCS_VHT_MSK) { - rate = (initial_rate & - IWM_RATE_VHT_MCS_RATE_CODE_MSK); - } else if (initial_rate & IWM_RATE_MCS_HT_MSK) { - rate = (initial_rate & - (IWM_RATE_HT_MCS_RATE_CODE_MSK | - IWM_RATE_HT_MCS_NSS_MSK)); - } sc->sc_tx_timer = 0; @@ -1348,6 +1339,11 @@ iwm_rx_tx_cmd_single(struct iwm_softc *sc, struct iwm_tx_resp *tx_resp, if ((status & IWM_TX_STATUS_MSK) != IWM_TX_STATUS_SUCCESS && ieee80211_is_mgmt(txd->fc)) iwm_toggle_tx_ant(sc, &sc->sc_mgmt_last_antenna_idx); + + if ((status & IWM_TX_STATUS_MSK) != IWM_TX_STATUS_SUCCESS && + sc->sc_ic.ic_state <= IEEE80211_S_RUN) + iwm_toggle_tx_ant(sc, &sc->sc_tx_ant); + /* * If we are freeing multiple frames, mark all the frames @@ -1554,77 +1550,51 @@ iwm_tx_fill_cmd(struct iwm_softc *sc, struct iwm_node *in, { struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_node *ni = &in->in_ni; - const struct iwm_rate *rinfo; + const struct iwm_rate *rinfo = NULL; int type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; int subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; int ridx, rate_flags; + int min_ridx = (IEEE80211_IS_CHAN_5GHZ(ni->ni_chan)) ? + IWL_FIRST_OFDM_RATE : IWL_FIRST_CCK_RATE; + int i; + + int min_rate = ieee80211_min_basic_rate(ic); + for (i = 0; i < ieee80211_std_rateset_11g.rs_nrates; i++) { + if (ieee80211_std_rateset_11g.rs_rates[i] == min_rate) { + min_ridx = i; + break; + } + } + ridx = min_ridx; tx->rts_retry_limit = IWM_RTS_DFAULT_RETRY_LIMIT; - if (type == IEEE80211_FC0_TYPE_CTL && subtype == IEEE80211_FC0_SUBTYPE_BAR) { + if (type == IEEE80211_FC0_TYPE_CTL && subtype == IEEE80211_FC0_SUBTYPE_BAR) tx->data_retry_limit = IWM_BAR_DFAULT_RETRY_LIMIT; - } else { + else tx->data_retry_limit = IWM_DEFAULT_TX_RETRY; - } /* * for data packets, rate info comes from the table inside the fw. This * table is controlled by LINK_QUALITY commands */ if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && type == IEEE80211_FC0_TYPE_DATA) { - int i; tx->initial_rate_index = 0; tx->tx_flags |= cpu_to_le32(IWM_TX_CMD_FLG_STA_RATE); - if (ni->ni_flags & IEEE80211_NODE_VHT) { - ridx = (in->in_rn.nss > 1 ? iwm_vht_mimo_mcs2ridx[ni->ni_txmcs] : iwm_vht_siso_mcs2ridx[ni->ni_txmcs]); - return &iwm_rates[ridx]; - } else if (ni->ni_flags & IEEE80211_NODE_HT) { - ridx = iwm_mcs2ridx[ni->ni_txmcs]; - return &iwm_rates[ridx]; - } - ridx = (IEEE80211_IS_CHAN_5GHZ(ni->ni_chan)) ? - IWM_RIDX_OFDM : IWM_RIDX_CCK; - for (i = 0; i < ni->ni_rates.rs_nrates; i++) { - if (iwm_rates[i].rate == (ni->ni_txrate & - IEEE80211_RATE_VAL)) { - ridx = i; - break; - } - } - return &iwm_rates[ridx]; - } else if (type == IEEE80211_FC0_TYPE_CTL && subtype == IEEE80211_FC0_SUBTYPE_BAR) { + return rinfo; + } else if (type == IEEE80211_FC0_TYPE_CTL && subtype == IEEE80211_FC0_SUBTYPE_BAR) tx->tx_flags |= htole32(IWM_TX_CMD_FLG_ACK | IWM_TX_CMD_FLG_BAR); - } - - ridx = (IEEE80211_IS_CHAN_5GHZ(ni->ni_chan)) ? - IWM_RIDX_OFDM : IWM_RIDX_CCK; - for (int i = 0; i < ni->ni_rates.rs_nrates; i++) { - if (iwm_rates[i].rate == (ni->ni_txrate & - IEEE80211_RATE_VAL)) { - ridx = i; - break; - } - } - if (ni->ni_flags & IEEE80211_NODE_VHT) { - ridx = (in->in_rn.nss > 1 ? iwm_vht_mimo_mcs2ridx[ni->ni_txmcs] : iwm_vht_siso_mcs2ridx[ni->ni_txmcs]); - } else if (ni->ni_flags & IEEE80211_NODE_HT) { - ridx = iwm_mcs2ridx[ni->ni_txmcs]; - } - if (ic->ic_fixed_mcs != -1) { + + if (ic->ic_fixed_mcs != -1) ridx = sc->sc_fixed_ridx; - } - rinfo = &iwm_rates[ridx]; - if (iwm_is_mimo_ht_plcp(rinfo->ht_plcp) || iwm_is_mimo_vht_plcp(rinfo->vht_plcp)) - rate_flags = IWM_RATE_MCS_ANT_AB_MSK; - else if (sc->sc_device_family == IWM_DEVICE_FAMILY_9000 && - (iwm_fw_valid_tx_ant(sc) & IWM_ANT_B)) - rate_flags = IWM_RATE_MCS_ANT_B_MSK; - else - rate_flags = IWM_RATE_MCS_ANT_A_MSK; - if (IWM_RIDX_IS_CCK(ridx)) - rate_flags |= IWM_RATE_MCS_CCK_MSK; - tx->rate_n_flags = htole32(rate_flags | rinfo->plcp); + XYLog("%s ridx=%d\n", __FUNCTION__, ridx); + + rate_flags = iwm_get_tx_ant(sc, ni, type, wh); + /* Set CCK flag as needed */ + if ((ridx >= IWL_FIRST_CCK_RATE) && (ridx <= IWL_LAST_CCK_RATE)) + rate_flags |= RATE_MCS_CCK_MSK; + tx->rate_n_flags = htole32(rate_flags | iwl_mvm_mac80211_idx_to_hwrate(ridx)); return rinfo; } @@ -2287,6 +2257,8 @@ iwm_auth(struct iwm_softc *sc) goto rm_binding; } + iwm_toggle_tx_ant(sc, &sc->sc_tx_ant); + if (ic->ic_opmode == IEEE80211_M_MONITOR) return 0; @@ -2515,7 +2487,6 @@ iwm_run(struct iwm_softc *sc) } ieee80211_amrr_node_init(&sc->sc_amrr, &in->in_amn); - ieee80211_ra_node_init(ic, &in->in_rn, &in->in_ni); if (ic->ic_opmode == IEEE80211_M_MONITOR) { iwm_led_blink_start(sc); @@ -2525,7 +2496,6 @@ iwm_run(struct iwm_softc *sc) /* Start at lowest available bit-rate, AMRR will raise. */ in->in_ni.ni_txrate = 0; in->in_ni.ni_txmcs = 0; -// iwm_setrates(in, 0); iwl_mvm_rs_rate_init(sc, ic->ic_bss, IEEE80211_IS_CHAN_2GHZ(ic->ic_bss->ni_chan) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ, @@ -2760,7 +2730,7 @@ iwm_calib_timeout(void *arg) */ if (ni->ni_txrate != old_txrate) { XYLog("iwm_calib_timeout in->ni_txrate=%d\n", in->in_ni.ni_txrate); - that->iwm_setrates(in, 1); + iwl_mvm_send_lq_cmd(sc, &sc->lq_sta.rs_drv.lq); } } @@ -2769,180 +2739,6 @@ iwm_calib_timeout(void *arg) timeout_add_msec(&sc->sc_calib_to, 500); } -void ItlIwm:: -iwm_setrates(struct iwm_node *in, int async) -{ - struct ieee80211_node *ni = &in->in_ni; - struct ieee80211com *ic = ni->ni_ic; - struct iwm_softc *sc = (struct iwm_softc *)IC2IFP(ic)->if_softc; - struct iwm_lq_cmd lqcmd; - struct ieee80211_rateset *rs = &ni->ni_rates; - const struct ieee80211_ra_rate *ra_rate = ieee80211_ra_get_rateset(&in->in_rn, ic, ni, ni->ni_txmcs); - int i, ridx, ridx_min, ridx_max, j, sgi_ok = 0, mimo, tab = 0, is_40mhz = 0, is_80mhz = 0, is_160mhz = 0, ldpc = 0; - struct iwm_host_cmd cmd = { - .id = IWM_LQ_CMD, - .len = { sizeof(lqcmd), }, - }; - - cmd.flags = async ? IWM_CMD_ASYNC : 0; - - memset(&lqcmd, 0, sizeof(lqcmd)); - lqcmd.sta_id = IWM_STATION_ID; - - if (ic->ic_flags & IEEE80211_F_USEPROT) - lqcmd.flags |= IWM_LQ_FLAG_USE_RTS_MSK; - - if (ni->ni_chw == IEEE80211_CHAN_WIDTH_80P80 || ni->ni_chw == IEEE80211_CHAN_WIDTH_160) { - is_160mhz = 1; - } else if (ni->ni_chw == IEEE80211_CHAN_WIDTH_80) { - is_80mhz = 1; - } else if (ni->ni_chw == IEEE80211_CHAN_WIDTH_40) { - is_40mhz = 1; - } - - sgi_ok = ra_rate->sgi; - - if (ni->ni_flags & IEEE80211_NODE_VHT) { - if ((ni->ni_vhtcaps & IEEE80211_VHTCAP_RXLDPC) && (ic->ic_vhtcaps & IEEE80211_VHTCAP_RXLDPC)) - ldpc = 1; - } else if (ni->ni_flags & IEEE80211_NODE_HT) { - if ((ni->ni_htcaps & IEEE80211_HTCAP_LDPC) && (ic->ic_htcaps & IEEE80211_HTCAP_LDPC)) - ldpc = 1; - } - - /* - * Fill the LQ rate selection table with legacy and/or HT rates - * in descending order, i.e. with the node's current TX rate first. - * In cases where throughput of an HT rate corresponds to a legacy - * rate it makes no sense to add both. We rely on the fact that - * iwm_rates is laid out such that equivalent HT/legacy rates share - * the same IWM_RATE_*_INDEX value. Also, rates not applicable to - * legacy/HT are assumed to be marked with an 'invalid' PLCP value. - */ - j = 0; - ridx_min = iwm_rval2ridx(ieee80211_min_basic_rate(ic)); - mimo = ra_rate->nss > 1; - ridx_max = (mimo ? IWM_RIDX_MAX : ((ni->ni_flags & IEEE80211_NODE_VHT) ? IWM_LAST_VHT_SISO_RATE : IWM_LAST_HT_SISO_RATE)); - for (ridx = ridx_max; ridx >= ridx_min; ridx--) { - uint8_t plcp = iwm_rates[ridx].plcp; - uint8_t ht_plcp = iwm_rates[ridx].ht_plcp; - uint8_t vht_plcp = iwm_rates[ridx].vht_plcp; - - if (j >= nitems(lqcmd.rs_table)) - break; - tab = 0; - if (ni->ni_flags & IEEE80211_NODE_VHT) { - if (vht_plcp == IWM_RATE_VHT_SISO_MCS_INV_PLCP || vht_plcp == IWM_RATE_VHT_MIMO2_MCS_INV_PLCP) - continue; - if ((mimo && !iwm_is_mimo_vht_plcp(vht_plcp)) || - (!mimo && iwm_is_mimo_vht_plcp(vht_plcp))) - continue; - for (i = ni->ni_txmcs; i >= 0; i--) { - if ((in->in_rn.valid_rates & (1 << i)) == 0) - continue; - if (ridx == (mimo ? iwm_vht_mimo_mcs2ridx[i] : iwm_vht_siso_mcs2ridx[i])) { - tab = vht_plcp; - tab |= IWM_RATE_MCS_VHT_MSK; - if (is_40mhz) - tab |= IWM_RATE_MCS_CHAN_WIDTH_40; - if (is_80mhz) - tab |= IWM_RATE_MCS_CHAN_WIDTH_80; - if (is_160mhz) - tab |= IWM_RATE_MCS_CHAN_WIDTH_160; - if (sgi_ok) - tab |= IWM_RATE_MCS_SGI_MSK; - if (ldpc) - tab |= IWM_RATE_MCS_LDPC_MSK; - break; - } - } - } else if (ni->ni_flags & IEEE80211_NODE_HT) { - if (ht_plcp == IWM_RATE_HT_SISO_MCS_INV_PLCP) - continue; - /* Do not mix SISO and MIMO HT rates. */ - if ((mimo && !iwm_is_mimo_ht_plcp(ht_plcp)) || - (!mimo && iwm_is_mimo_ht_plcp(ht_plcp))) - continue; - for (i = ni->ni_txmcs; i >= 0; i--) { - if (isclr(ni->ni_rxmcs, i)) - continue; - if (ridx == iwm_mcs2ridx[i]) { - tab = ht_plcp; - tab |= IWM_RATE_MCS_HT_MSK; - if (sgi_ok) - tab |= IWM_RATE_MCS_SGI_MSK; - /* TODO: If we enable 40mhz Tx rate in 2.4ghz band, the data will all sent fail */ - if (is_40mhz && IEEE80211_IS_CHAN_5GHZ(ni->ni_chan)) - tab |= IWM_RATE_MCS_CHAN_WIDTH_40; - if (ldpc) - tab |= IWM_RATE_MCS_LDPC_MSK; - break; - } - } - } else if (plcp != IWM_RATE_INVM_PLCP) { - for (i = ni->ni_txmcs; i >= 0; i--) { - if (iwm_rates[ridx].rate == (rs->rs_rates[i] & - IEEE80211_RATE_VAL)) { - tab = plcp; - break; - } - } - } - - if (tab == 0) - continue; - - if (ni->ni_flags & IEEE80211_NODE_VHT) { - if (iwm_is_mimo_vht_plcp(vht_plcp)) - tab |= IWM_RATE_MCS_ANT_AB_MSK; - else if (sc->sc_device_family == IWM_DEVICE_FAMILY_9000 && - (iwm_fw_valid_tx_ant(sc) & IWM_ANT_B)) - tab |= IWM_RATE_MCS_ANT_B_MSK; - else - tab |= IWM_RATE_MCS_ANT_A_MSK; - } else if (iwm_is_mimo_ht_plcp(ht_plcp)) - tab |= IWM_RATE_MCS_ANT_AB_MSK; - else if (sc->sc_device_family == IWM_DEVICE_FAMILY_9000 && - (iwm_fw_valid_tx_ant(sc) & IWM_ANT_B)) - tab |= IWM_RATE_MCS_ANT_B_MSK; - else - tab |= IWM_RATE_MCS_ANT_A_MSK; - - if (IWM_RIDX_IS_CCK(ridx)) - tab |= IWM_RATE_MCS_CCK_MSK; - lqcmd.rs_table[j++] = htole32(tab); - } - - lqcmd.mimo_delim = (mimo ? j : 0); - - /* Fill the rest with the lowest possible rate */ - while (j < nitems(lqcmd.rs_table)) { - tab = iwm_rates[ridx_min].plcp; - if (IWM_RIDX_IS_CCK(ridx_min)) - tab |= IWM_RATE_MCS_CCK_MSK; - if (sc->sc_device_family == IWM_DEVICE_FAMILY_9000 && - (iwm_fw_valid_tx_ant(sc) & IWM_ANT_B)) - tab |= IWM_RATE_MCS_ANT_B_MSK; - else - tab |= IWM_RATE_MCS_ANT_A_MSK; - lqcmd.rs_table[j++] = htole32(tab); - } - - if (sc->sc_device_family == IWM_DEVICE_FAMILY_9000 && - (iwm_fw_valid_tx_ant(sc) & IWM_ANT_B)) - lqcmd.single_stream_ant_msk = IWM_ANT_B; - else - lqcmd.single_stream_ant_msk = IWM_ANT_A; - lqcmd.dual_stream_ant_msk = IWM_ANT_AB; - - lqcmd.agg_time_limit = htole16(iwm_coex_agg_time_limit(sc, ni)); - lqcmd.agg_disable_start_th = 3; - lqcmd.agg_frame_cnt_limit = 0x3f; - - cmd.data[0] = &lqcmd; - iwm_send_cmd(sc, &cmd); -} - /* Allow multicast from our BSSID. */ int ItlIwm:: iwm_allow_mcast(struct iwm_softc *sc) @@ -3133,18 +2929,6 @@ int ItlIwm::iwm_media_change(struct _ifnet *ifp) if (err != ENETRESET) return err; - if (ic->ic_fixed_mcs != -1) - sc->sc_fixed_ridx = iwm_mcs2ridx[ic->ic_fixed_mcs]; - else if (ic->ic_fixed_rate != -1) { - rate = ic->ic_sup_rates[ic->ic_curmode]. - rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL; - /* Map 802.11 rate to HW rate index. */ - for (ridx = 0; ridx <= IWM_RIDX_MAX; ridx++) - if (iwm_rates[ridx].rate == rate) - break; - sc->sc_fixed_ridx = ridx; - } - if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING)) { iwm_stop(ifp); @@ -5171,12 +4955,9 @@ iwm_chan_ctxt_task(void *arg) splx(s); return; } - - if (in->in_rn.bw != in->in_ni.ni_chw) { - ieee80211_ra_node_init(ic, &in->in_rn, &in->in_ni); - ieee80211_ra_choose(&in->in_rn, ic, &in->in_ni); - } - that->iwm_setrates((struct iwm_node *)ic->ic_bss, 0); + + rs_drv_rate_update(sc, &in->in_ni, IEEE80211_IS_CHAN_2GHZ(in->in_ni.ni_chan) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ, true); + iwl_mvm_send_lq_cmd(sc, &sc->lq_sta.rs_drv.lq); // refcnt_rele_wake(&sc->task_refs); splx(s); diff --git a/itlwm/hal_iwm/rs.cpp b/itlwm/hal_iwm/rs.cpp index 37cf83921..c28029571 100644 --- a/itlwm/hal_iwm/rs.cpp +++ b/itlwm/hal_iwm/rs.cpp @@ -61,7 +61,7 @@ static const u8 ant_toggle_lookup[] = { * maps to IWL_RATE_INVALID * */ -static const struct iwl_rs_rate_info iwl_rates[IWL_RATE_COUNT] = { +struct iwl_rs_rate_info iwl_rates[IWL_RATE_COUNT] = { IWL_DECLARE_RATE_INFO(1, INV, INV, 2), /* 1mbps */ IWL_DECLARE_RATE_INFO(2, INV, 1, 5), /* 2mbps */ IWL_DECLARE_RATE_INFO(5, INV, 2, 11), /*5.5mbps */ diff --git a/itlwm/hal_iwm/rs.h b/itlwm/hal_iwm/rs.h index ebf3027e1..66c945b99 100644 --- a/itlwm/hal_iwm/rs.h +++ b/itlwm/hal_iwm/rs.h @@ -921,9 +921,6 @@ enum { /* Link Quality definitions */ -/* # entries in rate scale table to support Tx retries */ -#define LQ_MAX_RETRY_NUM 16 - /* Link quality command flags bit fields */ /* Bit 0: (0) Don't use RTS (1) Use RTS */ @@ -1001,6 +998,8 @@ struct iwl_rs_rate_info { u8 next_rs; /* next rate used in rs algo */ }; +extern struct iwl_rs_rate_info iwl_rates[IWL_RATE_COUNT]; + #define IWL_RATE_60M_PLCP 3 enum { diff --git a/itlwm/hal_iwm/scan.cpp b/itlwm/hal_iwm/scan.cpp index 7342aaff0..78e85ddf2 100644 --- a/itlwm/hal_iwm/scan.cpp +++ b/itlwm/hal_iwm/scan.cpp @@ -120,6 +120,7 @@ */ #include "ItlIwm.hpp" +#include "rs.h" uint16_t ItlIwm:: iwm_scan_rx_chain(struct iwm_softc *sc) @@ -152,10 +153,10 @@ iwm_scan_rate_n_flags(struct iwm_softc *sc, int flags, int no_cck) tx_ant = (1 << sc->sc_scan_last_antenna) << IWM_RATE_MCS_ANT_POS; if ((flags & IEEE80211_CHAN_2GHZ) && !no_cck) - return htole32(IWM_RATE_1M_PLCP | IWM_RATE_MCS_CCK_MSK | + return htole32(IWL_RATE_1M_PLCP | RATE_MCS_CCK_MSK | tx_ant); else - return htole32(IWM_RATE_6M_PLCP | tx_ant); + return htole32(IWL_RATE_6M_PLCP | tx_ant); } uint8_t ItlIwm:: @@ -763,28 +764,13 @@ iwm_ridx2rate(struct ieee80211_rateset *rs, int ridx) for (i = 0; i < rs->rs_nrates; i++) { rval = (rs->rs_rates[i] & IEEE80211_RATE_VAL); - if (rval == iwm_rates[ridx].rate) + if (rval == ieee80211_std_rateset_11g.rs_rates[ridx]) return rs->rs_rates[i]; } return 0; } -int ItlIwm:: -iwm_rval2ridx(int rval) -{ - int ridx; - - for (ridx = 0; ridx < nitems(iwm_rates); ridx++) { - if (iwm_rates[ridx].plcp == IWM_RATE_INVM_PLCP) - continue; - if (rval == iwm_rates[ridx].rate) - break; - } - - return ridx; -} - void ItlIwm:: iwm_ack_rates(struct iwm_softc *sc, struct iwm_node *in, int *cck_rates, int *ofdm_rates) @@ -799,7 +785,7 @@ iwm_ack_rates(struct iwm_softc *sc, struct iwm_node *in, int *cck_rates, if (ni->ni_chan == IEEE80211_CHAN_ANYC || IEEE80211_IS_CHAN_2GHZ(ni->ni_chan)) { - for (i = IWM_FIRST_CCK_RATE; i < IWM_FIRST_OFDM_RATE; i++) { + for (i = IWL_FIRST_CCK_RATE; i < IWL_FIRST_OFDM_RATE; i++) { if ((iwm_ridx2rate(rs, i) & IEEE80211_RATE_BASIC) == 0) continue; cck |= (1 << i); @@ -807,10 +793,10 @@ iwm_ack_rates(struct iwm_softc *sc, struct iwm_node *in, int *cck_rates, lowest_present_cck = i; } } - for (i = IWM_FIRST_OFDM_RATE; i <= IWM_LAST_NON_HT_RATE; i++) { + for (i = IWL_FIRST_OFDM_RATE; i <= IWL_LAST_NON_HT_RATE; i++) { if ((iwm_ridx2rate(rs, i) & IEEE80211_RATE_BASIC) == 0) continue; - ofdm |= (1 << (i - IWM_FIRST_OFDM_RATE)); + ofdm |= (1 << (i - IWL_FIRST_OFDM_RATE)); if (lowest_present_ofdm == -1 || lowest_present_ofdm > i) lowest_present_ofdm = i; } @@ -838,12 +824,12 @@ iwm_ack_rates(struct iwm_softc *sc, struct iwm_node *in, int *cck_rates, * lower than all of the basic rates to these bitmaps. */ - if (IWM_RATE_24M_INDEX < lowest_present_ofdm) - ofdm |= IWM_RATE_BIT_MSK(24) >> IWM_FIRST_OFDM_RATE; - if (IWM_RATE_12M_INDEX < lowest_present_ofdm) - ofdm |= IWM_RATE_BIT_MSK(12) >> IWM_FIRST_OFDM_RATE; + if (IWL_RATE_24M_INDEX < lowest_present_ofdm) + ofdm |= IWL_RATE_BIT_MSK(24) >> IWL_FIRST_OFDM_RATE; + if (IWL_RATE_12M_INDEX < lowest_present_ofdm) + ofdm |= IWL_RATE_BIT_MSK(12) >> IWL_FIRST_OFDM_RATE; /* 6M already there or needed so always add */ - ofdm |= IWM_RATE_BIT_MSK(6) >> IWM_FIRST_OFDM_RATE; + ofdm |= IWL_RATE_BIT_MSK(6) >> IWL_FIRST_OFDM_RATE; /* * CCK is a bit more complex with DSSS vs. HR/DSSS vs. ERP. @@ -858,14 +844,14 @@ iwm_ack_rates(struct iwm_softc *sc, struct iwm_node *in, int *cck_rates, * As a consequence, it's not as complicated as it sounds, just add * any lower rates to the ACK rate bitmap. */ - if (IWM_RATE_11M_INDEX < lowest_present_cck) - cck |= IWM_RATE_BIT_MSK(11) >> IWM_FIRST_CCK_RATE; - if (IWM_RATE_5M_INDEX < lowest_present_cck) - cck |= IWM_RATE_BIT_MSK(5) >> IWM_FIRST_CCK_RATE; - if (IWM_RATE_2M_INDEX < lowest_present_cck) - cck |= IWM_RATE_BIT_MSK(2) >> IWM_FIRST_CCK_RATE; + if (IWL_RATE_11M_INDEX < lowest_present_cck) + cck |= IWL_RATE_BIT_MSK(11) >> IWL_FIRST_CCK_RATE; + if (IWL_RATE_5M_INDEX < lowest_present_cck) + cck |= IWL_RATE_BIT_MSK(5) >> IWL_FIRST_CCK_RATE; + if (IWL_RATE_2M_INDEX < lowest_present_cck) + cck |= IWL_RATE_BIT_MSK(2) >> IWL_FIRST_CCK_RATE; /* 1M already there or needed so always add */ - cck |= IWM_RATE_BIT_MSK(1) >> IWM_FIRST_CCK_RATE; + cck |= IWL_RATE_BIT_MSK(1) >> IWL_FIRST_CCK_RATE; *cck_rates = cck; *ofdm_rates = ofdm; From 9621c0f627376e666c1c40000145406732f1e562 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Tue, 29 Mar 2022 18:31:49 +0800 Subject: [PATCH 022/114] Adapt PLCP index. --- itlwm/hal_iwm/ItlIwm.hpp | 2 +- itlwm/hal_iwm/mac80211.cpp | 43 +++++++++++++++++++++++++++++--------- itlwm/hal_iwm/rs.h | 25 ++++++++++++++++++++++ 3 files changed, 59 insertions(+), 11 deletions(-) diff --git a/itlwm/hal_iwm/ItlIwm.hpp b/itlwm/hal_iwm/ItlIwm.hpp index d6576d44b..082a6d883 100644 --- a/itlwm/hal_iwm/ItlIwm.hpp +++ b/itlwm/hal_iwm/ItlIwm.hpp @@ -290,7 +290,7 @@ class ItlIwm : public ItlHalService, ItlDriverInfo, ItlDriverController { void iwm_cmd_done(struct iwm_softc *, int, int, int); void iwm_update_sched(struct iwm_softc *, int, int, uint8_t, uint16_t); void iwm_reset_sched(struct iwm_softc *, int, int, uint8_t); - const struct iwm_rate *iwm_tx_fill_cmd(struct iwm_softc *, struct iwm_node *, + const struct iwl_rs_rate_info *iwm_tx_fill_cmd(struct iwm_softc *, struct iwm_node *, struct ieee80211_frame *, struct iwm_tx_cmd *); void iwm_txd_done(struct iwm_softc *, struct iwm_tx_data *); void iwm_ampdu_txq_advance(struct iwm_softc *, struct iwm_tx_ring *, int); diff --git a/itlwm/hal_iwm/mac80211.cpp b/itlwm/hal_iwm/mac80211.cpp index 965a62c2e..e1360f13e 100644 --- a/itlwm/hal_iwm/mac80211.cpp +++ b/itlwm/hal_iwm/mac80211.cpp @@ -1544,13 +1544,12 @@ iwm_rx_bmiss(struct iwm_softc *sc, struct iwm_rx_packet *pkt, * unfilled for data frames (firmware takes care of that). * Return the selected TX rate. */ -const struct iwm_rate * ItlIwm:: +const struct iwl_rs_rate_info *ItlIwm:: iwm_tx_fill_cmd(struct iwm_softc *sc, struct iwm_node *in, struct ieee80211_frame *wh, struct iwm_tx_cmd *tx) { struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_node *ni = &in->in_ni; - const struct iwm_rate *rinfo = NULL; int type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; int subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; int ridx, rate_flags; @@ -1578,25 +1577,33 @@ iwm_tx_fill_cmd(struct iwm_softc *sc, struct iwm_node *in, * for data packets, rate info comes from the table inside the fw. This * table is controlled by LINK_QUALITY commands */ - if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && type == IEEE80211_FC0_TYPE_DATA) { + if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && + type == IEEE80211_FC0_TYPE_DATA) { tx->initial_rate_index = 0; tx->tx_flags |= cpu_to_le32(IWM_TX_CMD_FLG_STA_RATE); - return rinfo; - } else if (type == IEEE80211_FC0_TYPE_CTL && subtype == IEEE80211_FC0_SUBTYPE_BAR) + return &iwl_rates[ridx]; + } else if (type == IEEE80211_FC0_TYPE_CTL && + subtype == IEEE80211_FC0_SUBTYPE_BAR) tx->tx_flags |= htole32(IWM_TX_CMD_FLG_ACK | IWM_TX_CMD_FLG_BAR); - if (ic->ic_fixed_mcs != -1) + if (ic->ic_fixed_mcs != -1 || + ic->ic_fixed_rate != -1) ridx = sc->sc_fixed_ridx; - - XYLog("%s ridx=%d\n", __FUNCTION__, ridx); + else { + if (ni->ni_flags & IEEE80211_NODE_VHT) + ridx = iwm_vht_mcs2ridx[ni->ni_txmcs]; + else if (ni->ni_flags & IEEE80211_NODE_HT) + ridx = iwm_ht_mcs2ridx[ni->ni_txmcs % 8]; + } rate_flags = iwm_get_tx_ant(sc, ni, type, wh); + XYLog("%s ridx=%d ant=%d\n", __FUNCTION__, ridx, (rate_flags >> RATE_MCS_ANT_POS)); /* Set CCK flag as needed */ if ((ridx >= IWL_FIRST_CCK_RATE) && (ridx <= IWL_LAST_CCK_RATE)) rate_flags |= RATE_MCS_CCK_MSK; tx->rate_n_flags = htole32(rate_flags | iwl_mvm_mac80211_idx_to_hwrate(ridx)); - return rinfo; + return &iwl_rates[ridx]; } #define TB0_SIZE 20 @@ -1612,7 +1619,7 @@ iwm_tx(struct iwm_softc *sc, mbuf_t m, struct ieee80211_node *ni, int ac) struct iwm_tx_cmd *tx; struct ieee80211_frame *wh; struct ieee80211_key *k = NULL; - const struct iwm_rate *rinfo; + const struct iwl_rs_rate_info *rinfo; uint8_t *ivp; uint32_t flags; u_int hdrlen; @@ -2922,6 +2929,7 @@ int ItlIwm::iwm_media_change(struct _ifnet *ifp) XYLog("%s\n", __FUNCTION__); struct iwm_softc *sc = (struct iwm_softc*)ifp->if_softc; struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211_node *ni = ic->ic_bss; uint8_t rate, ridx; int err; @@ -2929,6 +2937,21 @@ int ItlIwm::iwm_media_change(struct _ifnet *ifp) if (err != ENETRESET) return err; + if (ic->ic_fixed_mcs != -1) { + if (ni->ni_flags & IEEE80211_NODE_VHT) + sc->sc_fixed_ridx = iwm_vht_mcs2ridx[ic->ic_fixed_mcs]; + else if (ni->ni_flags & IEEE80211_NODE_HT) + sc->sc_fixed_ridx = iwm_ht_mcs2ridx[ic->ic_fixed_mcs % 8]; + } else if (ic->ic_fixed_rate != -1) { + rate = ic->ic_sup_rates[ic->ic_curmode]. + rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL; + /* Map 802.11 rate to HW rate index. */ + for (ridx = 0; ridx <= ieee80211_std_rateset_11g.rs_nrates; ridx++) + if (ieee80211_std_rateset_11g.rs_rates[ridx] == rate) + break; + sc->sc_fixed_ridx = ridx; + } + if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING)) { iwm_stop(ifp); diff --git a/itlwm/hal_iwm/rs.h b/itlwm/hal_iwm/rs.h index 66c945b99..914f628e1 100644 --- a/itlwm/hal_iwm/rs.h +++ b/itlwm/hal_iwm/rs.h @@ -1387,6 +1387,31 @@ static const u8 fw_rate_idx_to_plcp[IWL_RATE_COUNT] = { #undef IWL_DECLARE_RATE_INFO +/* Convert an MCS index into an iwm_rates[] index. */ +const int iwm_ht_mcs2ridx[] = { + IWL_RATE_MCS_0_INDEX, + IWL_RATE_MCS_1_INDEX, + IWL_RATE_MCS_2_INDEX, + IWL_RATE_MCS_3_INDEX, + IWL_RATE_MCS_4_INDEX, + IWL_RATE_MCS_5_INDEX, + IWL_RATE_MCS_6_INDEX, + IWL_RATE_MCS_7_INDEX, +}; + +const int iwm_vht_mcs2ridx[] = { + IWL_RATE_MCS_0_INDEX, + IWL_RATE_MCS_1_INDEX, + IWL_RATE_MCS_2_INDEX, + IWL_RATE_MCS_3_INDEX, + IWL_RATE_MCS_4_INDEX, + IWL_RATE_MCS_5_INDEX, + IWL_RATE_MCS_6_INDEX, + IWL_RATE_MCS_7_INDEX, + IWL_RATE_MCS_8_INDEX, + IWL_RATE_MCS_9_INDEX, +}; + static inline int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags, enum nl80211_band band) { From 487e911706d902e63cced0dcfcf682944b16337c Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Wed, 30 Mar 2022 00:26:50 +0800 Subject: [PATCH 023/114] add ride limitation. --- itlwm/hal_iwm/mac80211.cpp | 6 ++++-- itlwm/hal_iwm/rs.h | 36 ++++++++++++++++++------------------ 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/itlwm/hal_iwm/mac80211.cpp b/itlwm/hal_iwm/mac80211.cpp index e1360f13e..51ec37c49 100644 --- a/itlwm/hal_iwm/mac80211.cpp +++ b/itlwm/hal_iwm/mac80211.cpp @@ -1552,7 +1552,7 @@ iwm_tx_fill_cmd(struct iwm_softc *sc, struct iwm_node *in, struct ieee80211_node *ni = &in->in_ni; int type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; int subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; - int ridx, rate_flags; + int ridx = -1, rate_flags; int min_ridx = (IEEE80211_IS_CHAN_5GHZ(ni->ni_chan)) ? IWL_FIRST_OFDM_RATE : IWL_FIRST_CCK_RATE; int i; @@ -1565,7 +1565,6 @@ iwm_tx_fill_cmd(struct iwm_softc *sc, struct iwm_node *in, } } - ridx = min_ridx; tx->rts_retry_limit = IWM_RTS_DFAULT_RETRY_LIMIT; if (type == IEEE80211_FC0_TYPE_CTL && subtype == IEEE80211_FC0_SUBTYPE_BAR) @@ -1596,6 +1595,9 @@ iwm_tx_fill_cmd(struct iwm_softc *sc, struct iwm_node *in, ridx = iwm_ht_mcs2ridx[ni->ni_txmcs % 8]; } + if (ridx == -1 || ridx >= IWL_RATE_COUNT_LEGACY) + ridx = min_ridx; + rate_flags = iwm_get_tx_ant(sc, ni, type, wh); XYLog("%s ridx=%d ant=%d\n", __FUNCTION__, ridx, (rate_flags >> RATE_MCS_ANT_POS)); /* Set CCK flag as needed */ diff --git a/itlwm/hal_iwm/rs.h b/itlwm/hal_iwm/rs.h index 914f628e1..0c5743ddd 100644 --- a/itlwm/hal_iwm/rs.h +++ b/itlwm/hal_iwm/rs.h @@ -1389,27 +1389,27 @@ static const u8 fw_rate_idx_to_plcp[IWL_RATE_COUNT] = { /* Convert an MCS index into an iwm_rates[] index. */ const int iwm_ht_mcs2ridx[] = { - IWL_RATE_MCS_0_INDEX, - IWL_RATE_MCS_1_INDEX, - IWL_RATE_MCS_2_INDEX, - IWL_RATE_MCS_3_INDEX, - IWL_RATE_MCS_4_INDEX, - IWL_RATE_MCS_5_INDEX, - IWL_RATE_MCS_6_INDEX, - IWL_RATE_MCS_7_INDEX, + IWL_RATE_6M_INDEX, + IWL_RATE_12M_INDEX, + IWL_RATE_18M_INDEX, + IWL_RATE_24M_INDEX, + IWL_RATE_36M_INDEX, + IWL_RATE_48M_INDEX, + IWL_RATE_54M_INDEX, + IWL_RATE_54M_INDEX, }; const int iwm_vht_mcs2ridx[] = { - IWL_RATE_MCS_0_INDEX, - IWL_RATE_MCS_1_INDEX, - IWL_RATE_MCS_2_INDEX, - IWL_RATE_MCS_3_INDEX, - IWL_RATE_MCS_4_INDEX, - IWL_RATE_MCS_5_INDEX, - IWL_RATE_MCS_6_INDEX, - IWL_RATE_MCS_7_INDEX, - IWL_RATE_MCS_8_INDEX, - IWL_RATE_MCS_9_INDEX, + IWL_RATE_6M_INDEX, + IWL_RATE_12M_INDEX, + IWL_RATE_18M_INDEX, + IWL_RATE_24M_INDEX, + IWL_RATE_36M_INDEX, + IWL_RATE_48M_INDEX, + IWL_RATE_54M_INDEX, + IWL_RATE_54M_INDEX, + IWL_RATE_54M_INDEX, + IWL_RATE_54M_INDEX, }; static inline int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags, From 2d9632f9d11aa44315fc1645f4b36c1c0d594344 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Thu, 31 Mar 2022 19:41:32 +0800 Subject: [PATCH 024/114] collapse --- itlwm/hal_iwm/mac80211.cpp | 8 ++-- itlwm/hal_iwm/rs.cpp | 82 +++++++++++++++++++------------------- itlwm/hal_iwm/rs.h | 13 +----- 3 files changed, 47 insertions(+), 56 deletions(-) diff --git a/itlwm/hal_iwm/mac80211.cpp b/itlwm/hal_iwm/mac80211.cpp index 51ec37c49..70818d8bf 100644 --- a/itlwm/hal_iwm/mac80211.cpp +++ b/itlwm/hal_iwm/mac80211.cpp @@ -1590,9 +1590,9 @@ iwm_tx_fill_cmd(struct iwm_softc *sc, struct iwm_node *in, ridx = sc->sc_fixed_ridx; else { if (ni->ni_flags & IEEE80211_NODE_VHT) - ridx = iwm_vht_mcs2ridx[ni->ni_txmcs]; + ridx = iwm_mcs2ridx[ni->ni_txmcs]; else if (ni->ni_flags & IEEE80211_NODE_HT) - ridx = iwm_ht_mcs2ridx[ni->ni_txmcs % 8]; + ridx = iwm_mcs2ridx[ni->ni_txmcs % 8]; } if (ridx == -1 || ridx >= IWL_RATE_COUNT_LEGACY) @@ -2941,9 +2941,9 @@ int ItlIwm::iwm_media_change(struct _ifnet *ifp) if (ic->ic_fixed_mcs != -1) { if (ni->ni_flags & IEEE80211_NODE_VHT) - sc->sc_fixed_ridx = iwm_vht_mcs2ridx[ic->ic_fixed_mcs]; + sc->sc_fixed_ridx = iwm_mcs2ridx[ic->ic_fixed_mcs]; else if (ni->ni_flags & IEEE80211_NODE_HT) - sc->sc_fixed_ridx = iwm_ht_mcs2ridx[ic->ic_fixed_mcs % 8]; + sc->sc_fixed_ridx = iwm_mcs2ridx[ic->ic_fixed_mcs % 8]; } else if (ic->ic_fixed_rate != -1) { rate = ic->ic_sup_rates[ic->ic_curmode]. rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL; diff --git a/itlwm/hal_iwm/rs.cpp b/itlwm/hal_iwm/rs.cpp index c28029571..dcdb373f5 100644 --- a/itlwm/hal_iwm/rs.cpp +++ b/itlwm/hal_iwm/rs.cpp @@ -1486,42 +1486,43 @@ static void rs_set_amsdu_len(struct iwm_softc *sc, struct ieee80211_node *ni, struct iwl_scale_tbl_info *tbl, enum rs_action scale_action) { -// struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); -// int i; -// -// sta->max_amsdu_len = rs_fw_get_max_amsdu_len(sta); -// -// /* -// * In case TLC offload is not active amsdu_enabled is either 0xFFFF -// * or 0, since there is no per-TID alg. -// */ -// if ((!is_vht(&tbl->rate) && !is_ht(&tbl->rate)) || -// tbl->rate.index < IWL_RATE_MCS_5_INDEX || -// scale_action == RS_ACTION_DOWNSCALE) -// mvmsta->amsdu_enabled = 0; -// else -// mvmsta->amsdu_enabled = 0xFFFF; -// -// if (mvmsta->vif->bss_conf.he_support && -// !iwlwifi_mod_params.disable_11ax) -// mvmsta->max_amsdu_len = sta->max_amsdu_len; -// else -// mvmsta->max_amsdu_len = min_t(int, sta->max_amsdu_len, 8500); -// -// sta->max_rc_amsdu_len = mvmsta->max_amsdu_len; -// -// for (i = 0; i < IWL_MAX_TID_COUNT; i++) { -// if (mvmsta->amsdu_enabled) -// sta->max_tid_amsdu_len[i] = -// iwl_mvm_max_amsdu_size(mvm, sta, i); -// else -// /* -// * Not so elegant, but this will effectively -// * prevent AMSDU on this TID -// */ -// sta->max_tid_amsdu_len[i] = 1; -// } - // TODO: IMP +#if 0 + struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); + int i; + + sta->max_amsdu_len = rs_fw_get_max_amsdu_len(sta); + + /* + * In case TLC offload is not active amsdu_enabled is either 0xFFFF + * or 0, since there is no per-TID alg. + */ + if ((!is_vht(&tbl->rate) && !is_ht(&tbl->rate)) || + tbl->rate.index < IWL_RATE_MCS_5_INDEX || + scale_action == RS_ACTION_DOWNSCALE) + mvmsta->amsdu_enabled = 0; + else + mvmsta->amsdu_enabled = 0xFFFF; + + if (mvmsta->vif->bss_conf.he_support && + !iwlwifi_mod_params.disable_11ax) + mvmsta->max_amsdu_len = sta->max_amsdu_len; + else + mvmsta->max_amsdu_len = min_t(int, sta->max_amsdu_len, 8500); + + sta->max_rc_amsdu_len = mvmsta->max_amsdu_len; + + for (i = 0; i < IWL_MAX_TID_COUNT; i++) { + if (mvmsta->amsdu_enabled) + sta->max_tid_amsdu_len[i] = + iwl_mvm_max_amsdu_size(mvm, sta, i); + else + /* + * Not so elegant, but this will effectively + * prevent AMSDU on this TID + */ + sta->max_tid_amsdu_len[i] = 1; + } +#endif } /** @@ -2102,8 +2103,7 @@ static void rs_rate_scale_perform(struct iwm_softc *mvm, rate = &tbl->rate; if (prev_agg != lq_sta->is_agg) { - IWL_DEBUG_RATE(mvm, - "Aggregation changed: prev %d current %d. Update expected TPT table\n", + XYLog("Aggregation changed: prev %d current %d. Update expected TPT table\n", prev_agg, lq_sta->is_agg); rs_set_expected_tpt_table(lq_sta, tbl); rs_rate_scale_clear_tbl_windows(mvm, tbl); @@ -2806,7 +2806,8 @@ static void rs_ht_init(struct iwm_softc *mvm, lq_sta->active_mimo2_rate &= ~((u16)0x2); lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE; - if ((sta->ni_htcaps & IEEE80211_HTCAP_LDPC)) + if ((sta->ni_htcaps & IEEE80211_HTCAP_LDPC) && + mvm->support_ldpc) lq_sta->ldpc = true; if ((that->iwm_num_of_ant(that->iwm_fw_valid_tx_ant(mvm)) > 1) && @@ -2823,7 +2824,8 @@ static void rs_vht_init(struct iwm_softc *mvm, ItlIwm *that = container_of(mvm, ItlIwm, com); rs_vht_set_enabled_rates(sta, lq_sta); - if ((sta->ni_vhtcaps & IEEE80211_VHTCAP_RXLDPC)) + if ((sta->ni_vhtcaps & IEEE80211_VHTCAP_RXLDPC) && + mvm->support_ldpc) lq_sta->ldpc = true; if ((that->iwm_num_of_ant(that->iwm_fw_valid_tx_ant(mvm)) > 1) && diff --git a/itlwm/hal_iwm/rs.h b/itlwm/hal_iwm/rs.h index 0c5743ddd..19e032a9a 100644 --- a/itlwm/hal_iwm/rs.h +++ b/itlwm/hal_iwm/rs.h @@ -1388,19 +1388,9 @@ static const u8 fw_rate_idx_to_plcp[IWL_RATE_COUNT] = { #undef IWL_DECLARE_RATE_INFO /* Convert an MCS index into an iwm_rates[] index. */ -const int iwm_ht_mcs2ridx[] = { +const int iwm_mcs2ridx[] = { IWL_RATE_6M_INDEX, IWL_RATE_12M_INDEX, - IWL_RATE_18M_INDEX, - IWL_RATE_24M_INDEX, - IWL_RATE_36M_INDEX, - IWL_RATE_48M_INDEX, - IWL_RATE_54M_INDEX, - IWL_RATE_54M_INDEX, -}; - -const int iwm_vht_mcs2ridx[] = { - IWL_RATE_6M_INDEX, IWL_RATE_12M_INDEX, IWL_RATE_18M_INDEX, IWL_RATE_24M_INDEX, @@ -1409,7 +1399,6 @@ const int iwm_vht_mcs2ridx[] = { IWL_RATE_54M_INDEX, IWL_RATE_54M_INDEX, IWL_RATE_54M_INDEX, - IWL_RATE_54M_INDEX, }; static inline int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags, From e663f035755c388b4ac41e887d1146341a491819 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Fri, 1 Apr 2022 01:05:06 +0800 Subject: [PATCH 025/114] Fix agg condition --- itlwm/hal_iwm/rs.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/itlwm/hal_iwm/rs.cpp b/itlwm/hal_iwm/rs.cpp index dcdb373f5..bff2713e3 100644 --- a/itlwm/hal_iwm/rs.cpp +++ b/itlwm/hal_iwm/rs.cpp @@ -2083,11 +2083,15 @@ static void rs_rate_scale_perform(struct iwm_softc *mvm, s32 sr; u8 prev_agg = lq_sta->is_agg; struct rs_rate *rate; - - lq_sta->is_agg = (mvm->sc_tx_ba[EDCA_AC_BE].wn != NULL || - mvm->sc_tx_ba[EDCA_AC_BK].wn != NULL || - mvm->sc_tx_ba[EDCA_AC_VI].wn != NULL || - mvm->sc_tx_ba[EDCA_AC_VO].wn != NULL); + int i; + + lq_sta->is_agg = false; + for (i = 0; i <= IWM_MAX_TID_COUNT; i++) { + if (mvm->sc_tx_ba[i].wn != NULL) { + lq_sta->is_agg = true; + break; + } + } /* * Select rate-scale / modulation-mode table to work with in From ec5ab4a582df2a2628d640b4bc29cb0b9f1736b4 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Fri, 1 Apr 2022 01:05:30 +0800 Subject: [PATCH 026/114] Enable Tx agg for RS. --- itlwm/hal_iwm/mac80211.cpp | 2 +- itlwm/hal_iwm/rs.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/itlwm/hal_iwm/mac80211.cpp b/itlwm/hal_iwm/mac80211.cpp index 70818d8bf..2f0bc4fca 100644 --- a/itlwm/hal_iwm/mac80211.cpp +++ b/itlwm/hal_iwm/mac80211.cpp @@ -4777,7 +4777,7 @@ iwm_attach(struct iwm_softc *sc, struct pci_attach_args *pa) ic->ic_ampdu_params = (IEEE80211_AMPDU_PARAM_SS_4 | 0x3 /* 64k */); ic->ic_caps |= (IEEE80211_C_QOS | IEEE80211_C_TX_AMPDU | IEEE80211_C_AMSDU_IN_AMPDU); ic->ic_caps |= IEEE80211_C_SUPPORTS_VHT_EXT_NSS_BW; -#if 0 +#if 1 ic->ic_caps |= IEEE80211_C_TX_AMPDU_SETUP_IN_RS; #endif diff --git a/itlwm/hal_iwm/rs.cpp b/itlwm/hal_iwm/rs.cpp index bff2713e3..4508c093d 100644 --- a/itlwm/hal_iwm/rs.cpp +++ b/itlwm/hal_iwm/rs.cpp @@ -600,7 +600,7 @@ static void rs_tl_turn_on_agg(struct iwm_softc *sc, u8 tid, struct iwl_lq_sta *lq_sta, struct ieee80211_node *ni) { -#if 0 +#if 1 struct iwm_tx_ba *tid_data; struct ieee80211_tx_ba *tx_ba; @@ -622,7 +622,7 @@ static void rs_tl_turn_on_agg(struct iwm_softc *sc, tx_ba->ba_state == IEEE80211_BA_INIT && (lq_sta->tx_agg_tid_en & BIT(tid)) && tid_data->tx_count_last >= IWL_MVM_RS_AGG_START_THRESHOLD) { - IWL_DEBUG_RATE(mvm, "try to aggregate tid %d\n", tid); + XYLog("RS: try to aggregate tid %d\n", tid); rs_tl_turn_on_agg_for_tid(sc, lq_sta, tid, ni); } #else From 6748fea6e6bf6d03ef0a081fb4d9228ed7aaea5a Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Fri, 1 Apr 2022 08:00:50 +0800 Subject: [PATCH 027/114] Add legacy rate --- itlwm/hal_iwm/mac80211.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/itlwm/hal_iwm/mac80211.cpp b/itlwm/hal_iwm/mac80211.cpp index 2f0bc4fca..6d0fa1db2 100644 --- a/itlwm/hal_iwm/mac80211.cpp +++ b/itlwm/hal_iwm/mac80211.cpp @@ -1593,6 +1593,14 @@ iwm_tx_fill_cmd(struct iwm_softc *sc, struct iwm_node *in, ridx = iwm_mcs2ridx[ni->ni_txmcs]; else if (ni->ni_flags & IEEE80211_NODE_HT) ridx = iwm_mcs2ridx[ni->ni_txmcs % 8]; + else { + for (i = 0; i < ieee80211_std_rateset_11g.rs_nrates; i++) { + if (ieee80211_std_rateset_11g.rs_rates[i] == ni->ni_txrate) { + ridx = i; + break; + } + } + } } if (ridx == -1 || ridx >= IWL_RATE_COUNT_LEGACY) From 71807fa301f0516034c51548001c3a4f25fcc7e3 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Wed, 24 Aug 2022 23:21:29 +0800 Subject: [PATCH 028/114] disable tid correctly --- itlwm/hal_iwm/mac80211.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/itlwm/hal_iwm/mac80211.cpp b/itlwm/hal_iwm/mac80211.cpp index 6d0fa1db2..3163ce994 100644 --- a/itlwm/hal_iwm/mac80211.cpp +++ b/itlwm/hal_iwm/mac80211.cpp @@ -5077,12 +5077,12 @@ iwm_ba_task(void *arg) that->iwm_nic_unlock(sc); sc->ba_tx.start_tidmask &= ~(1 << tid); } else if (sc->ba_tx.stop_tidmask & (1 << tid)) { + sc->agg_tid_disable |= (1 << tid); that->iwm_sta_tx_agg(sc, ni, tid, 0, 0, 0); that->iwm_ampdu_txq_advance(sc, ring, ring->cur); that->iwm_clear_oactive(sc, ring); /* In DQA-mode the queue isn't removed on agg termination */ tx_ba = &sc->sc_tx_ba[tid]; - sc->agg_tid_disable |= (1 << tid); tx_ba->wn = NULL; tx_ba->lq_color = 0; tx_ba->rate_n_flags = 0; From 326c4332da495fac5cf0deb4601930df28c3ad75 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Wed, 24 Aug 2022 23:22:59 +0800 Subject: [PATCH 029/114] Don't enable TX Aggregation queue again if it was already enabled before, only happens on one of the aggregation queue disable and enable again. --- itlwm/hal_iwm/tx.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/itlwm/hal_iwm/tx.cpp b/itlwm/hal_iwm/tx.cpp index 02c85454b..2ed600e61 100644 --- a/itlwm/hal_iwm/tx.cpp +++ b/itlwm/hal_iwm/tx.cpp @@ -295,6 +295,10 @@ iwm_enable_txq(struct iwm_softc *sc, int sta_id, int qid, int fifo, int ssn, int struct iwm_tx_ring *ring = &sc->txq[qid]; bool scd_bug = false; + if (agg && + (sc->agg_queue_mask & (1 << qid))) + return 0; + iwm_nic_assert_locked(sc); /* From 77c39672abfa256549da46f7194e9afdc98038ef Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Wed, 24 Aug 2022 23:30:28 +0800 Subject: [PATCH 030/114] Silent aggregate trying log. --- itlwm/hal_iwm/rs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/itlwm/hal_iwm/rs.cpp b/itlwm/hal_iwm/rs.cpp index 4508c093d..6d8eb10cc 100644 --- a/itlwm/hal_iwm/rs.cpp +++ b/itlwm/hal_iwm/rs.cpp @@ -622,7 +622,7 @@ static void rs_tl_turn_on_agg(struct iwm_softc *sc, tx_ba->ba_state == IEEE80211_BA_INIT && (lq_sta->tx_agg_tid_en & BIT(tid)) && tid_data->tx_count_last >= IWL_MVM_RS_AGG_START_THRESHOLD) { - XYLog("RS: try to aggregate tid %d\n", tid); + IWL_DEBUG_RATE("RS: try to aggregate tid %d\n", tid); rs_tl_turn_on_agg_for_tid(sc, lq_sta, tid, ni); } #else From 5d957efa0a9178ca130f1fdfc909b6f1c92eb498 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Mon, 29 Aug 2022 23:49:19 +0800 Subject: [PATCH 031/114] Missing ifq.cpp compiled in Ventura --- itlwm.xcodeproj/project.pbxproj | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/itlwm.xcodeproj/project.pbxproj b/itlwm.xcodeproj/project.pbxproj index cd40795da..df5f13275 100644 --- a/itlwm.xcodeproj/project.pbxproj +++ b/itlwm.xcodeproj/project.pbxproj @@ -317,13 +317,6 @@ 5088ECBF252884AF0068A63D /* libkmod.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5088ECBC252884870068A63D /* libkmod.a */; }; 5088ECC0252884C10068A63D /* libkmod.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5088ECBC252884870068A63D /* libkmod.a */; }; 5088ECC1252884D70068A63D /* libkmod.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5088ECBC252884870068A63D /* libkmod.a */; }; - A5FA2AE428A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; - A5FA2AE528A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; - A5FA2AE628A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; - A5FA2AE728A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; - A5FA2AE828A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; - A5FA2AE928A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; - A5FA2AEA28A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; A5DD111526D93B5F00BA01EF /* rs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5DD111326D93B5F00BA01EF /* rs.cpp */; }; A5DD111626D93B5F00BA01EF /* rs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5DD111326D93B5F00BA01EF /* rs.cpp */; }; A5DD111726D93B5F00BA01EF /* rs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5DD111326D93B5F00BA01EF /* rs.cpp */; }; @@ -336,6 +329,13 @@ A5DD111E26D93B5F00BA01EF /* rs.h in Headers */ = {isa = PBXBuildFile; fileRef = A5DD111426D93B5F00BA01EF /* rs.h */; }; A5DD111F26D93B5F00BA01EF /* rs.h in Headers */ = {isa = PBXBuildFile; fileRef = A5DD111426D93B5F00BA01EF /* rs.h */; }; A5DD112026D93B5F00BA01EF /* rs.h in Headers */ = {isa = PBXBuildFile; fileRef = A5DD111426D93B5F00BA01EF /* rs.h */; }; + A5FA2AE428A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; + A5FA2AE528A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; + A5FA2AE628A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; + A5FA2AE728A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; + A5FA2AE828A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; + A5FA2AE928A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; + A5FA2AEA28A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; F800DD9B24FBEBF000789320 /* ItlDriverController.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F800DD9A24FBEBF000789320 /* ItlDriverController.hpp */; }; F8294FE424FCBF5100239253 /* FwBinary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5076FA7F24CC71E40011B2BB /* FwBinary.cpp */; }; F837C91D2724577F00B2C499 /* coex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F837C91C2724577F00B2C499 /* coex.cpp */; }; @@ -344,6 +344,7 @@ F837C9202724577F00B2C499 /* coex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F837C91C2724577F00B2C499 /* coex.cpp */; }; F837C9212724577F00B2C499 /* coex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F837C91C2724577F00B2C499 /* coex.cpp */; }; F837C9222724577F00B2C499 /* coex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F837C91C2724577F00B2C499 /* coex.cpp */; }; + F8876A4E28B71F5400A21E42 /* rs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5DD111326D93B5F00BA01EF /* rs.cpp */; }; F88CB91424FBE9130060B1A5 /* ItlDriverInfo.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F88CB91324FBE9130060B1A5 /* ItlDriverInfo.hpp */; }; F88D2B3D2414E64000BBE700 /* sha1-pbkdf2.c in Sources */ = {isa = PBXBuildFile; fileRef = F88D2B3B2414E64000BBE700 /* sha1-pbkdf2.c */; }; F897ECBA266EFF93005EE8F7 /* debug.h in Headers */ = {isa = PBXBuildFile; fileRef = F89B6C2225027609000F77FF /* debug.h */; }; @@ -840,9 +841,9 @@ A5213EBC27A0C3ED00D7EAB1 /* iwm-8000C-36 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "iwm-8000C-36"; sourceTree = ""; }; A5213EBD27A0C3ED00D7EAB1 /* iwm-9260-46 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "iwm-9260-46"; sourceTree = ""; }; A5213EBE27A0C3ED00D7EAB1 /* iwm-8265-36 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "iwm-8265-36"; sourceTree = ""; }; - A5FA2AE328A797B200847103 /* _ifq.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = _ifq.cpp; sourceTree = ""; }; A5DD111326D93B5F00BA01EF /* rs.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = rs.cpp; sourceTree = ""; }; A5DD111426D93B5F00BA01EF /* rs.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = rs.h; sourceTree = ""; }; + A5FA2AE328A797B200847103 /* _ifq.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = _ifq.cpp; sourceTree = ""; }; F800DD9A24FBEBF000789320 /* ItlDriverController.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ItlDriverController.hpp; sourceTree = ""; }; F837C91C2724577F00B2C499 /* coex.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = coex.cpp; sourceTree = ""; }; F837C9252724732B00B2C499 /* iwlwifi-so-a0-gf-a0.pnvm */ = {isa = PBXFileReference; lastKnownFileType = file; path = "iwlwifi-so-a0-gf-a0.pnvm"; sourceTree = ""; }; @@ -2357,6 +2358,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F8876A4E28B71F5400A21E42 /* rs.cpp in Sources */, F8AE650A285471560085B4CF /* _mbuf.cpp in Sources */, F8AE650B285471560085B4CF /* ieee80211_ra.c in Sources */, F8AE650C285471560085B4CF /* _task.cpp in Sources */, From ddf3b31574f6a3cb9e813150c4a9c95a56622138 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Fri, 9 Jun 2023 18:30:27 +0800 Subject: [PATCH 032/114] partial new 80211 headers. --- include/Airport/Apple80211.h | 5 + include/Airport/IO80211Controller.h | 129 +++++++++++++ include/Airport/IO80211Interface.h | 4 + include/Airport/IO80211SkywalkInterface.h | 180 ++++++++++++++++++- include/Airport/IO80211VirtualInterface.h | 20 +++ include/Airport/IO80211WorkQueue.h | 34 ++++ include/Airport/IOSkywalkEthernetInterface.h | 5 +- include/Airport/IOSkywalkInterface.h | 19 ++ include/Airport/IOSkywalkNetworkInterface.h | 21 +++ 9 files changed, 412 insertions(+), 5 deletions(-) create mode 100644 include/Airport/IO80211WorkQueue.h create mode 100644 include/Airport/IOSkywalkInterface.h create mode 100644 include/Airport/IOSkywalkNetworkInterface.h diff --git a/include/Airport/Apple80211.h b/include/Airport/Apple80211.h index 42b27c538..b68de2f87 100644 --- a/include/Airport/Apple80211.h +++ b/include/Airport/Apple80211.h @@ -9,8 +9,13 @@ #ifndef Apple80211_h #define Apple80211_h +#if __IO80211_TARGET >= __MAC_14_0 +#define IO80211FAMILY_V2 +#endif + #include "apple_private_spi.h" #include "debug.h" +#include "IO80211WorkQueue.h" #include "IO80211WorkLoop.h" #include "IO80211Controller.h" #include "IO80211Interface.h" diff --git a/include/Airport/IO80211Controller.h b/include/Airport/IO80211Controller.h index 2527e847c..8744be139 100644 --- a/include/Airport/IO80211Controller.h +++ b/include/Airport/IO80211Controller.h @@ -30,6 +30,7 @@ #include "apple80211_ioctl.h" #include "IO80211SkywalkInterface.h" #include "IO80211WorkLoop.h" +#include "IO80211WorkQueue.h" #define AUTH_TIMEOUT 15 // seconds @@ -131,6 +132,133 @@ typedef IOReturn (*IOCTL_FUNC)(IO80211Controller*, IO80211Interface*, IO80211Vir extern IOCTL_FUNC gGetHandlerTable[]; extern IOCTL_FUNC gSetHandlerTable[]; +#ifdef IO80211FAMILY_V2 + +class IO80211InterfaceAVCAdvisory; + +class IO80211Controller : public IOEthernetController { + OSDeclareAbstractStructors(IO80211Controller) + +public: + + virtual void free() APPLE_KEXT_OVERRIDE; + virtual bool init(OSDictionary *) APPLE_KEXT_OVERRIDE; + virtual IOReturn configureReport(IOReportChannelList *,UInt,void *,void *) APPLE_KEXT_OVERRIDE; + virtual IOReturn updateReport(IOReportChannelList *,UInt,void *,void *) APPLE_KEXT_OVERRIDE; + virtual bool start(IOService *) APPLE_KEXT_OVERRIDE; + virtual void stop(IOService *) APPLE_KEXT_OVERRIDE; + virtual IOWorkLoop* getWorkLoop(void) const APPLE_KEXT_OVERRIDE; + virtual const char* stringFromReturn(int) APPLE_KEXT_OVERRIDE; + virtual int errnoFromReturn(int) APPLE_KEXT_OVERRIDE; + virtual int getFeatures(); + virtual const char* newVendorString(); + virtual const char* newModelString(); + virtual bool createWorkLoop() APPLE_KEXT_OVERRIDE; + virtual IOReturn getHardwareAddress(IOEthernetAddress *) APPLE_KEXT_OVERRIDE; + virtual IOReturn setHardwareAddress(const IOEthernetAddress * addrP) APPLE_KEXT_OVERRIDE; + virtual IOReturn setMulticastMode(bool active) APPLE_KEXT_OVERRIDE; + virtual IOReturn setPromiscuousMode(bool active) APPLE_KEXT_OVERRIDE; + virtual bool isCommandProhibited(int) = 0; + virtual bool createWorkQueue(); + virtual IO80211WorkQueue *getWorkQueue(); + virtual void requestPacketTx(void*, UInt); + virtual IOCommandGate *getIO80211CommandGate(); + virtual IOReturn getHardwareAddressForInterface(IOEthernetAddress *); + virtual bool useAppleRSNSupplicant(IO80211VirtualInterface *); + virtual IO80211SkywalkInterface* getPrimarySkywalkInterface(void); + virtual int bpfOutputPacket(OSObject *,UInt,mbuf_t m); + virtual SInt32 monitorModeSetEnabled(bool, UInt); + virtual SInt32 apple80211_ioctl(IO80211SkywalkInterface *,unsigned long,void *, bool, bool); + virtual SInt32 apple80211VirtualRequest(UInt,int,IO80211VirtualInterface *,void *); + virtual SInt32 apple80211SkywalkRequest(UInt,int,IO80211SkywalkInterface *,void *); + virtual SInt32 apple80211SkywalkRequest(UInt,int,IO80211SkywalkInterface *,void *,void *); + + virtual SInt32 handleCardSpecific(IO80211SkywalkInterface *,unsigned long,void *,bool) = 0; + + virtual UInt32 hardwareOutputQueueDepth(); + virtual SInt32 performCountryCodeOperation(IO80211CountryCodeOp); + + virtual void dataLinkLayerAttachComplete(); + virtual SInt32 enableFeature(IO80211FeatureCode, void*) = 0; + + virtual IOReturn getDRIVER_VERSION(IO80211SkywalkInterface *,apple80211_version_data *) = 0; + virtual IOReturn getHARDWARE_VERSION(IO80211SkywalkInterface *,apple80211_version_data *) = 0; + virtual IOReturn getCARD_CAPABILITIES(IO80211SkywalkInterface *,apple80211_capability_data *) = 0; + virtual IOReturn getPOWER(IO80211SkywalkInterface *,apple80211_power_data *) = 0; + virtual IOReturn setPOWER(IO80211SkywalkInterface *,apple80211_power_data *) = 0; + virtual IOReturn getCOUNTRY_CODE(IO80211SkywalkInterface *,apple80211_country_code_data *) = 0; + virtual IOReturn setCOUNTRY_CODE(IO80211SkywalkInterface *,apple80211_country_code_data *) = 0; + virtual IOReturn setGET_DEBUG_INFO(IO80211SkywalkInterface *,apple80211_debug_command *) = 0; + + virtual SInt32 setVirtualHardwareAddress(IO80211VirtualInterface *,ether_addr *); + virtual SInt32 enableVirtualInterface(IO80211VirtualInterface *); + virtual SInt32 disableVirtualInterface(IO80211VirtualInterface *); + virtual bool requiresExplicitMBufRelease(); + virtual bool flowIdSupported() { + return false; + } + virtual IO80211FlowQueueLegacy* requestFlowQueue(FlowIdMetadata const*); + virtual void releaseFlowQueue(IO80211FlowQueue *); + virtual void getLogPipes(CCPipe**, CCPipe**, CCPipe**) {}; + virtual void enableFeatureForLoggingFlags(unsigned long long) {}; + virtual IOReturn requestQueueSizeAndTimeout(unsigned short *, unsigned short *) { return kIOReturnIOError; }; + virtual IOReturn enablePacketTimestamping(void) { + return kIOReturnUnsupported; + } + virtual IOReturn disablePacketTimestamping(void) { + return kIOReturnUnsupported; + } + + virtual UInt getPacketTSCounter(); + virtual UInt64 getDriverTextLog(); + + virtual UInt32 selfDiagnosticsReport(int,char const*,UInt); + + virtual UInt64 getFaultReporterFromDriver(); + + virtual UInt32 getDataQueueDepth(OSObject *); + virtual bool isAssociatedToMovingNetwork(void) { return false; } + virtual bool wasDynSARInFailSafeMode(void) { return false; } + virtual void updateAdvisoryScoresIfNeed(void); + virtual UInt64 getAVCAdvisoryInfo(IO80211InterfaceAVCAdvisory *); + virtual SInt32 apple80211_ioctl_get(IO80211SkywalkInterface *,void *, bool, bool); + virtual SInt32 apple80211_ioctl_set(IO80211SkywalkInterface *,void *, bool, bool); + virtual bool attachInterface(OSObject *,IOService *); + virtual SInt32 apple80211_ioctl_get(IO80211VirtualInterface *,void *,bool,bool); + virtual SInt32 apple80211_ioctl_set(IO80211VirtualInterface *,void *,bool,bool); + virtual void detachInterface(OSObject *,bool); + virtual IO80211VirtualInterface* createVirtualInterface(ether_addr *,UInt); + virtual bool attachVirtualInterface(IO80211VirtualInterface **,ether_addr *,UInt,bool); + virtual bool detachVirtualInterface(IO80211VirtualInterface *,bool); + virtual IOReturn enable(IO80211SkywalkInterface *); + virtual IOReturn disable(IO80211SkywalkInterface *); + + OSMetaClassDeclareReservedUnused( IO80211Controller, 0); + OSMetaClassDeclareReservedUnused( IO80211Controller, 1); + OSMetaClassDeclareReservedUnused( IO80211Controller, 2); + OSMetaClassDeclareReservedUnused( IO80211Controller, 3); + OSMetaClassDeclareReservedUnused( IO80211Controller, 4); + OSMetaClassDeclareReservedUnused( IO80211Controller, 5); + OSMetaClassDeclareReservedUnused( IO80211Controller, 6); + OSMetaClassDeclareReservedUnused( IO80211Controller, 7); + OSMetaClassDeclareReservedUnused( IO80211Controller, 8); + OSMetaClassDeclareReservedUnused( IO80211Controller, 9); + OSMetaClassDeclareReservedUnused( IO80211Controller, 10); + OSMetaClassDeclareReservedUnused( IO80211Controller, 11); + OSMetaClassDeclareReservedUnused( IO80211Controller, 12); + OSMetaClassDeclareReservedUnused( IO80211Controller, 13); + OSMetaClassDeclareReservedUnused( IO80211Controller, 14); + OSMetaClassDeclareReservedUnused( IO80211Controller, 15); + + virtual void postMessage(UInt,void *,unsigned long,UInt,void *); + virtual IOReturn setMulticastList(ether_addr const*, UInt); + +protected: + uint8_t filler[0x128]; +}; + +#else + class IO80211Controller : public IOEthernetController { OSDeclareAbstractStructors(IO80211Controller) @@ -363,6 +491,7 @@ class IO80211Controller : public IOEthernetController { protected: uint8_t filler[0x500]; }; +#endif // 0x215: 1 byte, length of channel sequence, should be 16 // 0x21c: channel sequence, should contain 16 elements of length 12, possibly apple80211_channel (but why 16?) diff --git a/include/Airport/IO80211Interface.h b/include/Airport/IO80211Interface.h index 0c7f3fad6..a8e56425b 100644 --- a/include/Airport/IO80211Interface.h +++ b/include/Airport/IO80211Interface.h @@ -22,6 +22,8 @@ #include #include +#ifndef IO80211FAMILY_V2 + enum IO80211LinkState { kIO80211NetworkLinkUndefined, // Starting link state when an interface is created @@ -288,6 +290,8 @@ class IO80211Interface : public IOEthernetInterface u_int8_t dat[0x500]; }; +#endif + #endif /* defined(KERNEL) && defined(__cplusplus) */ #endif /* ! _IO80211INTERFACE_H */ diff --git a/include/Airport/IO80211SkywalkInterface.h b/include/Airport/IO80211SkywalkInterface.h index 82dc191ef..93109d715 100644 --- a/include/Airport/IO80211SkywalkInterface.h +++ b/include/Airport/IO80211SkywalkInterface.h @@ -10,18 +10,192 @@ #define _IO80211SKYWALK_H #include -#include +#include "IOSkywalkEthernetInterface.h" // This is necessary, because even the latest Xcode does not support properly targeting 11.0. #ifndef __IO80211_TARGET #error "Please define __IO80211_TARGET to the requested version" #endif -class IO80211SkywalkInterface : IOSkywalkEthernetInterface { +#ifdef IO80211FAMILY_V2 + +class TxSubmissionDequeueStats; +class TxCompletionEnqueueStats; +class IO80211NetworkPacket; +class PacketSkywalkScratch; +typedef UInt64 IO80211FlowQueueHash; +class IO80211Peer; +class CCPipe; +class IO80211APIUserClient; +struct apple80211_wme_ac; +struct apple80211_interface_availability; +struct apple80211_cca_report; +struct apple80211_stat_report; +struct apple80211_chip_counters_tx; +struct apple80211_chip_counters_rx; +struct apple80211_chip_error_counters_tx; +struct apple80211_ManagementInformationBasedot11_counters; +struct apple80211_lteCoex_report; +struct apple80211_frame_counters; +struct userPrintCtx; +struct apple80211_lqm_summary; +enum IO80211LinkState +{ + kIO80211NetworkLinkUndefined, // Starting link state when an interface is created + kIO80211NetworkLinkDown, // Interface not capable of transmitting packets + kIO80211NetworkLinkUp, // Interface capable of transmitting packets +}; +typedef enum IO80211LinkState IO80211LinkState; + +struct TxPacketRequest { + uint16_t unk1; // 0 + uint16_t t; // 2 + uint16_t mU; // 4 + uint16_t mM; // 6 + uint16_t pkt_cnt; + uint16_t unk2; + uint16_t unk3; + uint16_t unk4; + uint32_t pad; + mbuf_t bufs[8]; // 18 + uint32_t reqTx; +}; + +static_assert(sizeof(struct TxPacketRequest) == 0x60, "TxPacketRequest size error"); + +class IO80211SkywalkInterface : public IOSkywalkEthernetInterface { OSDeclareAbstractStructors(IO80211SkywalkInterface) public: - + + virtual bool init() APPLE_KEXT_OVERRIDE; + virtual void free() APPLE_KEXT_OVERRIDE; + virtual IOReturn configureReport(IOReportChannelList *,UInt,void *,void *) APPLE_KEXT_OVERRIDE; + virtual IOReturn updateReport(IOReportChannelList *,UInt,void *,void *) APPLE_KEXT_OVERRIDE; + virtual bool start(IOService *) APPLE_KEXT_OVERRIDE; + virtual void stop(IOService *) APPLE_KEXT_OVERRIDE; + virtual IOReturn newUserClient( task_t owningTask, void * securityID, + UInt32 type, OSDictionary * properties, + LIBKERN_RETURNS_RETAINED IOUserClient ** handler ) APPLE_KEXT_OVERRIDE; + virtual const char * stringFromReturn( IOReturn rtn ) APPLE_KEXT_OVERRIDE; + virtual int errnoFromReturn( IOReturn rtn ) APPLE_KEXT_OVERRIDE; + virtual IOReturn setPowerState( + unsigned long powerStateOrdinal, + IOService * whatDevice ) APPLE_KEXT_OVERRIDE; + virtual unsigned long maxCapabilityForDomainState( IOPMPowerFlags domainState ) APPLE_KEXT_OVERRIDE; + virtual unsigned long initialPowerStateForDomainState( IOPMPowerFlags domainState ) APPLE_KEXT_OVERRIDE; + virtual bool enable(UInt); + virtual bool disable(UInt); + virtual SInt32 initBSDInterfaceParameters(ifnet_init_eparams *,sockaddr_dl **); + virtual SInt32 prepareBSDInterface(ifnet_t, UInt); + virtual SInt32 processBSDCommand(ifnet_t, UInt, void *); + virtual SInt32 setInterfaceEnable(bool); + virtual SInt32 setRunningState(bool); + virtual IOReturn handleChosenMedia(UInt); + virtual IOReturn getSupportedMediaArray(UInt *,UInt *); + virtual UInt32 getFeatureFlags(void); + virtual const char *classNameOverride(void); + virtual IOReturn setPromiscuousModeEnable(bool, UInt); + virtual void *createPeerManager(void); + virtual void postMessage(UInt,void *,unsigned long,bool); + virtual IOReturn reportDataPathEvents(UInt,void *,unsigned long,bool); + virtual IOReturn recordOutputPackets(TxSubmissionDequeueStats *,TxSubmissionDequeueStats *); + virtual IOReturn recordOutputPacket(apple80211_wme_ac,int,int); + virtual void logTxPacket(IO80211NetworkPacket *,PacketSkywalkScratch *,apple80211_wme_ac,bool); + virtual void logTxCompletionPacket(IO80211NetworkPacket *,PacketSkywalkScratch *,unsigned char *,apple80211_wme_ac,int,UInt,bool); + virtual IOReturn recordCompletionPackets(TxCompletionEnqueueStats *,TxCompletionEnqueueStats *); + virtual IOReturn inputPacket(IO80211NetworkPacket *,packet_info_tag *,ether_header *,bool *); + virtual void logSkywalkTxReqPacket(IO80211NetworkPacket *,PacketSkywalkScratch *,unsigned char *,apple80211_wme_ac,bool); + virtual SInt64 pendingPackets(unsigned char); + virtual SInt64 packetSpace(unsigned char); + virtual bool isChipInterfaceReady(void); + virtual bool isDebounceOnGoing(void); + virtual bool setLinkState(IO80211LinkState,UInt,bool debounceTimeout = 30,UInt code = 0); + virtual IO80211LinkState linkState(void); + virtual void setScanningState(UInt,bool,apple80211_scan_data *,int); + virtual void setDataPathState(bool); + virtual void *getScanManager(void); + virtual void updateLinkParameters(apple80211_interface_availability *); + virtual void updateInterfaceCoexRiskPct(unsigned long long); + virtual void setLQM(unsigned long long); + virtual void updateLinkStatus(void); + virtual void updateLinkStatusGated(void); + virtual void setInterfaceExtendedCCA(apple80211_channel,apple80211_cca_report *); + virtual void setInterfaceCCA(apple80211_channel,int); + virtual void setInterfaceNF(apple80211_channel,long long); + virtual void setInterfaceOFDMDesense(apple80211_channel,long long); + virtual void removePacketQueue(IO80211FlowQueueHash *); + virtual void setDebugFlags(unsigned long long,UInt); + virtual SInt64 debugFlags(void); + virtual void setInterfaceChipCounters(apple80211_stat_report *,apple80211_chip_counters_tx *,apple80211_chip_error_counters_tx *,apple80211_chip_counters_rx *); + virtual void setInterfaceMIBdot11(apple80211_stat_report *,apple80211_ManagementInformationBasedot11_counters *); + virtual void setFrameStats(apple80211_stat_report *,apple80211_frame_counters *); + virtual SInt64 getWmeTxCounters(unsigned long long *); + virtual void setEnabledBySystem(bool); + virtual bool enabledBySystem(void); + virtual bool willRoam(ether_addr *,UInt); + virtual void setPeerManagerLogFlag(UInt,UInt,UInt); + virtual void setWoWEnabled(bool); + virtual bool wowEnabled(void); + virtual void printDataPath(userPrintCtx *); + virtual bool findOrCreateFlowQueue(IO80211FlowQueueHash); + virtual UInt64 findOrCreateFlowQueueWithCache(IO80211FlowQueueHash,bool *); + virtual UInt64 findExistingFlowQueue(IO80211FlowQueueHash); + virtual void removePacketQueue(IO80211FlowQueueHash const*); + virtual void flushPacketQueues(void); + virtual void cachePeer(ether_addr *,UInt *); + virtual bool shouldLog(unsigned long long); + virtual void vlogDebug(unsigned long long,char const*,va_list); + virtual void vlogDebugBPF(unsigned long long,char const*,va_list); + virtual UInt64 createLinkQualityMonitor(IO80211Peer *,IOService *); + virtual void releaseLinkQualityMonitor(IO80211Peer *); + virtual void *getP2PSkywalkPeerMgr(void); + virtual bool isCommandProhibited(int); + virtual void setNotificationProperty(OSSymbol const*,OSObject const*); + virtual void *getWorkerMatchingDict(OSString *); + virtual bool init(IOService *); + virtual bool isInterfaceEnabled(void); + virtual ether_addr *getSelfMacAddr(void); + virtual void setSelfMacAddr(ether_addr *); + virtual void *getPacketPool(OSString *); + virtual void *getLogger(void); + virtual IOReturn handleSIOCSIFADDR(void); + virtual IOReturn debugHandler(apple80211_debug_command *); + virtual void statsDump(void); + virtual void powerOnNotification(void); + virtual void powerOffNotification(void); + virtual UInt64 getTxQueueDepth(void); + virtual UInt64 getRxQueueCapacity(void); + virtual void updateRxCounter(unsigned long long); + virtual void *getMultiCastQueue(void); + virtual void *getCurrentBssid(void); + virtual int getAssocState(void); + virtual void notifyQueueState(apple80211_wme_ac,unsigned short); + virtual int getTxHeadroom(void); + virtual void *getRxCompQueue(void); + virtual void *getTxCompQueue(void); + virtual void *getTxSubQueue(apple80211_wme_ac); + virtual void *getTxPacketPool(void); + virtual void *getRxPacketPool(void); + virtual void enableDatapath(void); + virtual void disableDatapath(void); + virtual int getNumTxQueues(void); + virtual void *getLQMSummary(apple80211_lqm_summary *); + virtual int getEventPipeSize(void); + virtual UInt64 createEventPipe(IO80211APIUserClient *); + virtual void destroyEventPipe(IO80211APIUserClient *); + virtual void postMessageIOUC(char const*,UInt,void *,unsigned long); + virtual bool isIOUCPipeOpened(void); + virtual void *getRingMD(IO80211APIUserClient *,unsigned long long); + +public: + char _data[0x118]; }; +#else + +class IO80211SkywalkInterface; + +#endif + #endif /* _IO80211SKYWALK_H */ diff --git a/include/Airport/IO80211VirtualInterface.h b/include/Airport/IO80211VirtualInterface.h index 1a364d317..c64306cfd 100644 --- a/include/Airport/IO80211VirtualInterface.h +++ b/include/Airport/IO80211VirtualInterface.h @@ -1,7 +1,19 @@ #ifndef IO80211VirtualInterface_h #define IO80211VirtualInterface_h +#include +#include + +// This is necessary, because even the latest Xcode does not support properly targeting 11.0. +#ifndef __IO80211_TARGET +#error "Please define __IO80211_TARGET to the requested version" +#endif + +#ifndef IO80211FAMILY_V2 #include "IO80211Interface.h" +#else +#include "IO80211SkywalkInterface.h" +#endif #include "apple_private_spi.h" typedef UInt64 IO80211FlowQueueHash; @@ -17,6 +29,14 @@ struct apple80211_awdl_statistics; struct apple80211_lowlatency_peer_statistics_evevt; struct apple80211_p2p_airplay_statistics; struct apple80211_awdl_sidecar_statistics; +struct apple80211_pmk_cache_data; +struct apple80211_interface_availability; +struct packet_info_tx; +struct userPrintCtx; +struct apple80211_chip_counters_tx; +struct apple80211_chip_error_counters_tx; +struct apple80211_chip_counters_rx; +struct apple80211_ManagementInformationBasedot11_counters; class IO80211VirtualInterface : public IOService { OSDeclareDefaultStructors(IO80211VirtualInterface) diff --git a/include/Airport/IO80211WorkQueue.h b/include/Airport/IO80211WorkQueue.h new file mode 100644 index 000000000..f85faa743 --- /dev/null +++ b/include/Airport/IO80211WorkQueue.h @@ -0,0 +1,34 @@ + +#ifndef _IO80211WORKQUEUE_H +#define _IO80211WORKQUEUE_H + +#include +#include + +// This is necessary, because even the latest Xcode does not support properly targeting 11.0. +#ifndef __IO80211_TARGET +#error "Please define __IO80211_TARGET to the requested version" +#endif + +class IO80211WorkQueue : public IOWorkLoop +{ + OSDeclareDefaultStructors( IO80211WorkQueue ) + +public: + + virtual IOThread getThread() const APPLE_KEXT_OVERRIDE; + virtual void enableAllInterrupts() const APPLE_KEXT_OVERRIDE; + virtual void disableAllInterrupts() const APPLE_KEXT_OVERRIDE; + virtual IOReturn runAction(Action action, OSObject *target, + void *arg0 = NULL, void *arg1 = NULL, + void *arg2 = NULL, void *arg3 = NULL) APPLE_KEXT_OVERRIDE; + virtual int commandSleep(void *,unsigned long long); + virtual void commandWakeup(void *); + + static IO80211WorkQueue * workQueue(); + +public: + uint8_t filter[0x50]; +}; + +#endif diff --git a/include/Airport/IOSkywalkEthernetInterface.h b/include/Airport/IOSkywalkEthernetInterface.h index 0caa92b07..47ce6376a 100644 --- a/include/Airport/IOSkywalkEthernetInterface.h +++ b/include/Airport/IOSkywalkEthernetInterface.h @@ -1,12 +1,13 @@ #ifndef IOSkywalkEthernetInterface_h #define IOSkywalkEthernetInterface_h -#include +#include "IOSkywalkNetworkInterface.h" -class IOSkywalkEthernetInterface : public IOEthernetController { +class IOSkywalkEthernetInterface : public IOSkywalkNetworkInterface { OSDeclareAbstractStructors( IOSkywalkEthernetInterface ) public: + virtual void free() APPLE_KEXT_OVERRIDE; }; diff --git a/include/Airport/IOSkywalkInterface.h b/include/Airport/IOSkywalkInterface.h new file mode 100644 index 000000000..36464744a --- /dev/null +++ b/include/Airport/IOSkywalkInterface.h @@ -0,0 +1,19 @@ +// +// IOSkywalkInterface.h +// itlwm +// +// Created by qcwap on 2023/6/7. +// Copyright © 2023 钟先耀. All rights reserved. +// + +#ifndef IOSkywalkInterface_h +#define IOSkywalkInterface_h + + +class IOSkywalkInterface : public IOService { + OSDeclareAbstractStructors(IOSkywalkInterface) + + +}; + +#endif /* IOSkywalkInterface_h */ diff --git a/include/Airport/IOSkywalkNetworkInterface.h b/include/Airport/IOSkywalkNetworkInterface.h new file mode 100644 index 000000000..735148f16 --- /dev/null +++ b/include/Airport/IOSkywalkNetworkInterface.h @@ -0,0 +1,21 @@ +// +// IOSkywalkNetworkInterface.h +// itlwm +// +// Created by qcwap on 2023/6/7. +// Copyright © 2023 钟先耀. All rights reserved. +// + +#ifndef IOSkywalkNetworkInterface_h +#define IOSkywalkNetworkInterface_h + +#include "IOSkywalkInterface.h" + +class IOSkywalkNetworkInterface : public IOSkywalkInterface { + OSDeclareAbstractStructors( IOSkywalkNetworkInterface ) + +public: + +}; + +#endif /* IOSkywalkNetworkInterface_h */ From e7394f1e14e5a9e7717aaa65971772034fbf5946 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Fri, 9 Jun 2023 22:48:16 +0800 Subject: [PATCH 033/114] RS: only use 20MHz channel width TX rate on 2GHz channel due to the stability. --- itlwm/hal_iwm/rs.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/itlwm/hal_iwm/rs.cpp b/itlwm/hal_iwm/rs.cpp index 6d8eb10cc..f756336bf 100644 --- a/itlwm/hal_iwm/rs.cpp +++ b/itlwm/hal_iwm/rs.cpp @@ -1372,6 +1372,10 @@ static u32 rs_bw_from_sta_bw(struct ieee80211_node *ni) .vht_cap_info = cpu_to_le32(ni->ni_vhtcaps), .supp_mcs = ni->ni_vht_mcsinfo, }; + + if (ni->ni_chw == IEEE80211_CHAN_WIDTH_40 && + IEEE80211_IS_CHAN_2GHZ(ni->ni_chan)) + return RATE_MCS_CHAN_WIDTH_20; switch (ni->ni_chw) { case IEEE80211_CHAN_WIDTH_160: From 4e00dc0ba48062dd1bf598326a0ca73411feb10e Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Sat, 10 Jun 2023 00:51:14 +0800 Subject: [PATCH 034/114] Add reversed IOSkywalkFamily headers. --- include/Airport/IO80211SkywalkInterface.h | 22 ++--- include/Airport/IOSkywalkEthernetInterface.h | 37 +++++++- include/Airport/IOSkywalkInterface.h | 30 +++++++ include/Airport/IOSkywalkNetworkInterface.h | 93 ++++++++++++++++++++ 4 files changed, 170 insertions(+), 12 deletions(-) diff --git a/include/Airport/IO80211SkywalkInterface.h b/include/Airport/IO80211SkywalkInterface.h index 93109d715..ad48963c2 100644 --- a/include/Airport/IO80211SkywalkInterface.h +++ b/include/Airport/IO80211SkywalkInterface.h @@ -84,17 +84,17 @@ class IO80211SkywalkInterface : public IOSkywalkEthernetInterface { IOService * whatDevice ) APPLE_KEXT_OVERRIDE; virtual unsigned long maxCapabilityForDomainState( IOPMPowerFlags domainState ) APPLE_KEXT_OVERRIDE; virtual unsigned long initialPowerStateForDomainState( IOPMPowerFlags domainState ) APPLE_KEXT_OVERRIDE; - virtual bool enable(UInt); - virtual bool disable(UInt); - virtual SInt32 initBSDInterfaceParameters(ifnet_init_eparams *,sockaddr_dl **); - virtual SInt32 prepareBSDInterface(ifnet_t, UInt); - virtual SInt32 processBSDCommand(ifnet_t, UInt, void *); - virtual SInt32 setInterfaceEnable(bool); - virtual SInt32 setRunningState(bool); - virtual IOReturn handleChosenMedia(UInt); - virtual IOReturn getSupportedMediaArray(UInt *,UInt *); - virtual UInt32 getFeatureFlags(void); - virtual const char *classNameOverride(void); + virtual IOReturn enable(UInt) APPLE_KEXT_OVERRIDE; + virtual IOReturn disable(UInt) APPLE_KEXT_OVERRIDE; + virtual SInt32 initBSDInterfaceParameters(ifnet_init_eparams *,sockaddr_dl **) APPLE_KEXT_OVERRIDE; + virtual bool prepareBSDInterface(ifnet_t, UInt) APPLE_KEXT_OVERRIDE; + virtual IOReturn processBSDCommand(ifnet_t, UInt, void *) APPLE_KEXT_OVERRIDE; + virtual SInt32 setInterfaceEnable(bool) APPLE_KEXT_OVERRIDE; + virtual SInt32 setRunningState(bool) APPLE_KEXT_OVERRIDE; + virtual IOReturn handleChosenMedia(UInt) APPLE_KEXT_OVERRIDE; + virtual void *getSupportedMediaArray(UInt *,UInt *) APPLE_KEXT_OVERRIDE; + virtual UInt32 getFeatureFlags(void) APPLE_KEXT_OVERRIDE; + virtual const char *classNameOverride(void) APPLE_KEXT_OVERRIDE; virtual IOReturn setPromiscuousModeEnable(bool, UInt); virtual void *createPeerManager(void); virtual void postMessage(UInt,void *,unsigned long,bool); diff --git a/include/Airport/IOSkywalkEthernetInterface.h b/include/Airport/IOSkywalkEthernetInterface.h index 47ce6376a..bd0757ee9 100644 --- a/include/Airport/IOSkywalkEthernetInterface.h +++ b/include/Airport/IOSkywalkEthernetInterface.h @@ -8,7 +8,42 @@ class IOSkywalkEthernetInterface : public IOSkywalkNetworkInterface { public: virtual void free() APPLE_KEXT_OVERRIDE; - + virtual bool init(OSDictionary *) APPLE_KEXT_OVERRIDE; + virtual bool willTerminate( IOService * provider, IOOptionBits options ) APPLE_KEXT_OVERRIDE; + virtual bool didTerminate( IOService * provider, IOOptionBits options, bool * defer ) APPLE_KEXT_OVERRIDE; + virtual void stop( IOService * provider ) APPLE_KEXT_OVERRIDE; + virtual bool handleOpen( IOService * forClient, + IOOptionBits options, + void * arg ) APPLE_KEXT_OVERRIDE; + virtual void handleClose( IOService * forClient, + IOOptionBits options ) APPLE_KEXT_OVERRIDE; + virtual bool handleIsOpen( const IOService * forClient ) const APPLE_KEXT_OVERRIDE; + virtual IOReturn newUserClient( task_t owningTask, void * securityID, + UInt32 type, OSDictionary * properties, + LIBKERN_RETURNS_RETAINED IOUserClient ** handler ) APPLE_KEXT_OVERRIDE; + virtual void joinPMtree( IOService * driver ) APPLE_KEXT_OVERRIDE; + virtual IOReturn setAggressiveness( + unsigned long type, + unsigned long newLevel ) APPLE_KEXT_OVERRIDE; + virtual IOReturn setPowerState( + unsigned long powerStateOrdinal, + IOService * whatDevice ) APPLE_KEXT_OVERRIDE; + virtual IOReturn enable(UInt) APPLE_KEXT_OVERRIDE; + virtual IOReturn disable(UInt) APPLE_KEXT_OVERRIDE; + virtual IOReturn clientConnectWithTask(task_t,IOService *,UInt) APPLE_KEXT_OVERRIDE; + virtual void clientDisconnect(IOService *,UInt) APPLE_KEXT_OVERRIDE; + virtual bool isTerminating(void) APPLE_KEXT_OVERRIDE; + OSMetaClassDeclareReservedUnused( IOSkywalkEthernetInterface, 0 ); + OSMetaClassDeclareReservedUnused( IOSkywalkEthernetInterface, 1 ); + OSMetaClassDeclareReservedUnused( IOSkywalkEthernetInterface, 2 ); + OSMetaClassDeclareReservedUnused( IOSkywalkEthernetInterface, 3 ); + OSMetaClassDeclareReservedUnused( IOSkywalkEthernetInterface, 4 ); + OSMetaClassDeclareReservedUnused( IOSkywalkEthernetInterface, 5 ); + OSMetaClassDeclareReservedUnused( IOSkywalkEthernetInterface, 6 ); + OSMetaClassDeclareReservedUnused( IOSkywalkEthernetInterface, 7 ); + OSMetaClassDeclareReservedUnused( IOSkywalkEthernetInterface, 8 ); + OSMetaClassDeclareReservedUnused( IOSkywalkEthernetInterface, 9 ); + OSMetaClassDeclareReservedUnused( IOSkywalkEthernetInterface, 10 ); }; #endif /* IOSkywalkEthernetInterface_h */ diff --git a/include/Airport/IOSkywalkInterface.h b/include/Airport/IOSkywalkInterface.h index 36464744a..4231d34c5 100644 --- a/include/Airport/IOSkywalkInterface.h +++ b/include/Airport/IOSkywalkInterface.h @@ -13,7 +13,37 @@ class IOSkywalkInterface : public IOService { OSDeclareAbstractStructors(IOSkywalkInterface) +public: + virtual void free() APPLE_KEXT_OVERRIDE; + virtual bool init(OSDictionary *) APPLE_KEXT_OVERRIDE; + virtual bool willTerminate( IOService * provider, IOOptionBits options ) APPLE_KEXT_OVERRIDE; + virtual bool didTerminate( IOService * provider, IOOptionBits options, bool * defer ) APPLE_KEXT_OVERRIDE; + virtual bool handleOpen( IOService * forClient, + IOOptionBits options, + void * arg ) APPLE_KEXT_OVERRIDE; + virtual void handleClose( IOService * forClient, + IOOptionBits options ) APPLE_KEXT_OVERRIDE; + virtual bool handleIsOpen( const IOService * forClient ) const APPLE_KEXT_OVERRIDE; + virtual IOReturn enable( IOOptionBits options ) = 0; + virtual IOReturn disable( IOOptionBits options ) = 0; + virtual IOReturn clientConnectWithTask( task_t task, IOService * forClient, IOOptionBits options ); + virtual void clientDisconnect( IOService * forClient, IOOptionBits options ); + virtual bool isTerminating(void); + OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 0 ); + OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 1 ); + OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 2 ); + OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 3 ); + OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 4 ); + OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 5 ); + OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 6 ); + OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 7 ); + OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 8 ); + OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 9 ); + OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 10 ); + +public: + uint8_t filter[0xB0]; }; #endif /* IOSkywalkInterface_h */ diff --git a/include/Airport/IOSkywalkNetworkInterface.h b/include/Airport/IOSkywalkNetworkInterface.h index 735148f16..f0a0aae25 100644 --- a/include/Airport/IOSkywalkNetworkInterface.h +++ b/include/Airport/IOSkywalkNetworkInterface.h @@ -9,13 +9,106 @@ #ifndef IOSkywalkNetworkInterface_h #define IOSkywalkNetworkInterface_h +#include + #include "IOSkywalkInterface.h" +typedef UInt if_link_status; +class IOSkywalkPacketQueue; +class IOSkywalkLogicalLink; +class IOSkywalkPacketBufferPool; + class IOSkywalkNetworkInterface : public IOSkywalkInterface { OSDeclareAbstractStructors( IOSkywalkNetworkInterface ) + struct RegistrationInfo; + struct IOSkywalkTSOOptions; + public: + virtual void free() APPLE_KEXT_OVERRIDE; + virtual bool init(OSDictionary *) APPLE_KEXT_OVERRIDE; + virtual bool willTerminate( IOService * provider, IOOptionBits options ) APPLE_KEXT_OVERRIDE; + virtual bool didTerminate( IOService * provider, IOOptionBits options, bool * defer ) APPLE_KEXT_OVERRIDE; + virtual void stop(IOService *) APPLE_KEXT_OVERRIDE; + virtual bool handleOpen( IOService * forClient, + IOOptionBits options, + void * arg ) APPLE_KEXT_OVERRIDE; + virtual void handleClose( IOService * forClient, + IOOptionBits options ) APPLE_KEXT_OVERRIDE; + virtual bool handleIsOpen( const IOService * forClient ) const APPLE_KEXT_OVERRIDE; + virtual void joinPMtree( IOService * driver ) APPLE_KEXT_OVERRIDE; + virtual IOReturn setAggressiveness( + unsigned long type, + unsigned long newLevel ) APPLE_KEXT_OVERRIDE; + virtual IOReturn enable(UInt) APPLE_KEXT_OVERRIDE; + virtual IOReturn disable(UInt) APPLE_KEXT_OVERRIDE; + virtual IOReturn clientConnectWithTask(task_t,IOService *,UInt) APPLE_KEXT_OVERRIDE; + virtual void clientDisconnect(IOService *,UInt) APPLE_KEXT_OVERRIDE; + virtual bool isTerminating(void) APPLE_KEXT_OVERRIDE; + OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 0 ); + OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 1 ); + OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 2 ); + OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 3 ); + OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 4 ); + OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 5 ); + OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 6 ); + OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 7 ); + OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 8 ); + OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 9 ); + OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 10 ); + virtual SInt32 initBSDInterfaceParameters(ifnet_init_eparams *,sockaddr_dl **) = 0; + virtual bool prepareBSDInterface(ifnet_t,UInt); + virtual void finalizeBSDInterface(ifnet_t,UInt); + virtual ifnet_t getBSDInterface(void); + virtual void setBSDName(char const*); + virtual const char *getBSDName(void); + virtual IOReturn processBSDCommand(ifnet_t,UInt,void *); + virtual IOReturn processInterfaceCommand(ifdrv *); + virtual IOReturn interfaceAdvisoryEnable(bool); + virtual SInt32 setInterfaceEnable(bool); + virtual SInt32 setRunningState(bool); + virtual IOReturn handleChosenMedia(UInt); + virtual void *getSupportedMediaArray(UInt *,UInt *); + virtual void *getPacketTapInfo(UInt *,UInt *); + virtual UInt getUnsentDataByteCount(UInt *,UInt *,UInt); + virtual UInt32 getSupportedWakeFlags(UInt *); + virtual void enableNetworkWake(UInt); + virtual void calculateRingSizeForQueue(IOSkywalkPacketQueue const*,UInt *); + virtual UInt getMaxTransferUnit(void); + virtual void setMaxTransferUnit(UInt); + virtual UInt getMinPacketSize(void); + virtual UInt getHardwareAssists(void); + virtual void setHardwareAssists(UInt,UInt); + virtual void *getInterfaceFamily(void); + virtual void *getInterfaceSubFamily(void); + virtual UInt getInitialMedia(void); + virtual UInt getFeatureFlags(void); + virtual UInt getTxDataOffset(void); + virtual UInt captureInterfaceState(UInt); + virtual void restoreInterfaceState(UInt); + virtual void setMTU(UInt); + virtual bool bpfTap(UInt,UInt); + virtual const char *getBSDNamePrefix(void); + virtual UInt getBSDUnitNumber(void); + virtual const char *classNameOverride(void); + virtual void deferBSDAttach(bool); + virtual void reportDetailedLinkStatus(if_link_status const*); + virtual IOReturn registerNetworkInterfaceWithLogicalLink(IOSkywalkNetworkInterface::RegistrationInfo const*,IOSkywalkLogicalLink *,IOSkywalkPacketBufferPool *,IOSkywalkPacketBufferPool *,UInt); + virtual IOReturn deregisterLogicalLink(void); + virtual UInt getTSOOptions(IOSkywalkNetworkInterface::IOSkywalkTSOOptions *); + OSMetaClassDeclareReservedUnused( IOSkywalkNetworkInterface, 0); + OSMetaClassDeclareReservedUnused( IOSkywalkNetworkInterface, 1); + OSMetaClassDeclareReservedUnused( IOSkywalkNetworkInterface, 2); + OSMetaClassDeclareReservedUnused( IOSkywalkNetworkInterface, 3); + OSMetaClassDeclareReservedUnused( IOSkywalkNetworkInterface, 4); + OSMetaClassDeclareReservedUnused( IOSkywalkNetworkInterface, 5); + OSMetaClassDeclareReservedUnused( IOSkywalkNetworkInterface, 6); + OSMetaClassDeclareReservedUnused( IOSkywalkNetworkInterface, 7); + OSMetaClassDeclareReservedUnused( IOSkywalkNetworkInterface, 8); + OSMetaClassDeclareReservedUnused( IOSkywalkNetworkInterface, 9); +public: + uint8_t filter[0xD0]; }; #endif /* IOSkywalkNetworkInterface_h */ From 335b5e21a36f6d090676c4465641ac04b590dc70 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Mon, 12 Jun 2023 10:59:42 +0800 Subject: [PATCH 035/114] missing mark override. --- include/Airport/IO80211Controller.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/Airport/IO80211Controller.h b/include/Airport/IO80211Controller.h index 8744be139..160409997 100644 --- a/include/Airport/IO80211Controller.h +++ b/include/Airport/IO80211Controller.h @@ -150,9 +150,9 @@ class IO80211Controller : public IOEthernetController { virtual IOWorkLoop* getWorkLoop(void) const APPLE_KEXT_OVERRIDE; virtual const char* stringFromReturn(int) APPLE_KEXT_OVERRIDE; virtual int errnoFromReturn(int) APPLE_KEXT_OVERRIDE; - virtual int getFeatures(); - virtual const char* newVendorString(); - virtual const char* newModelString(); + virtual UInt32 getFeatures() const APPLE_KEXT_OVERRIDE; + virtual const OSString * newVendorString() const APPLE_KEXT_OVERRIDE; + virtual const OSString * newModelString() const APPLE_KEXT_OVERRIDE; virtual bool createWorkLoop() APPLE_KEXT_OVERRIDE; virtual IOReturn getHardwareAddress(IOEthernetAddress *) APPLE_KEXT_OVERRIDE; virtual IOReturn setHardwareAddress(const IOEthernetAddress * addrP) APPLE_KEXT_OVERRIDE; From 16730aeade8aff771b291d2f027266a8ac50fa2c Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Mon, 12 Jun 2023 18:19:12 +0800 Subject: [PATCH 036/114] IOSkywalkEthernetInterface: Add missing virtual method. --- include/Airport/IOSkywalkEthernetInterface.h | 83 ++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/include/Airport/IOSkywalkEthernetInterface.h b/include/Airport/IOSkywalkEthernetInterface.h index bd0757ee9..bb988e21a 100644 --- a/include/Airport/IOSkywalkEthernetInterface.h +++ b/include/Airport/IOSkywalkEthernetInterface.h @@ -3,9 +3,17 @@ #include "IOSkywalkNetworkInterface.h" +struct nicproxy_limits_info_s; +struct nicproxy_info_s; + class IOSkywalkEthernetInterface : public IOSkywalkNetworkInterface { OSDeclareAbstractStructors( IOSkywalkEthernetInterface ) +public: + struct RegistrationInfo { + uint8_t pad[304]; + } __attribute__((packed)); + public: virtual void free() APPLE_KEXT_OVERRIDE; virtual bool init(OSDictionary *) APPLE_KEXT_OVERRIDE; @@ -33,6 +41,77 @@ class IOSkywalkEthernetInterface : public IOSkywalkNetworkInterface { virtual IOReturn clientConnectWithTask(task_t,IOService *,UInt) APPLE_KEXT_OVERRIDE; virtual void clientDisconnect(IOService *,UInt) APPLE_KEXT_OVERRIDE; virtual bool isTerminating(void) APPLE_KEXT_OVERRIDE; + OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 0 ); + OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 1 ); + OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 2 ); + OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 3 ); + OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 4 ); + OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 5 ); + OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 6 ); + OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 7 ); + OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 8 ); + OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 9 ); + OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 10 ); + virtual SInt32 initBSDInterfaceParameters(ifnet_init_eparams *,sockaddr_dl **) = 0; + virtual bool prepareBSDInterface(ifnet_t,UInt) APPLE_KEXT_OVERRIDE; + virtual void finalizeBSDInterface(ifnet_t,UInt) APPLE_KEXT_OVERRIDE; + virtual ifnet_t getBSDInterface(void) APPLE_KEXT_OVERRIDE; + virtual void setBSDName(char const*) APPLE_KEXT_OVERRIDE; + virtual const char *getBSDName(void) APPLE_KEXT_OVERRIDE; + virtual IOReturn processBSDCommand(ifnet_t,UInt,void *) APPLE_KEXT_OVERRIDE; + virtual IOReturn processInterfaceCommand(ifdrv *) APPLE_KEXT_OVERRIDE; + virtual IOReturn interfaceAdvisoryEnable(bool) APPLE_KEXT_OVERRIDE; + virtual SInt32 setInterfaceEnable(bool) APPLE_KEXT_OVERRIDE; + virtual SInt32 setRunningState(bool) APPLE_KEXT_OVERRIDE; + virtual IOReturn handleChosenMedia(UInt) APPLE_KEXT_OVERRIDE; + virtual void *getSupportedMediaArray(UInt *,UInt *) APPLE_KEXT_OVERRIDE; + virtual void *getPacketTapInfo(UInt *,UInt *) APPLE_KEXT_OVERRIDE; + virtual UInt getUnsentDataByteCount(UInt *,UInt *,UInt) APPLE_KEXT_OVERRIDE; + virtual UInt32 getSupportedWakeFlags(UInt *) APPLE_KEXT_OVERRIDE; + virtual void enableNetworkWake(UInt) APPLE_KEXT_OVERRIDE; + virtual void calculateRingSizeForQueue(IOSkywalkPacketQueue const*,UInt *) APPLE_KEXT_OVERRIDE; + virtual UInt getMaxTransferUnit(void) APPLE_KEXT_OVERRIDE; + virtual void setMaxTransferUnit(UInt) APPLE_KEXT_OVERRIDE; + virtual UInt getMinPacketSize(void) APPLE_KEXT_OVERRIDE; + virtual UInt getHardwareAssists(void) APPLE_KEXT_OVERRIDE; + virtual void setHardwareAssists(UInt,UInt) APPLE_KEXT_OVERRIDE; + virtual void *getInterfaceFamily(void) APPLE_KEXT_OVERRIDE; + virtual void *getInterfaceSubFamily(void) APPLE_KEXT_OVERRIDE; + virtual UInt getInitialMedia(void) APPLE_KEXT_OVERRIDE; + virtual UInt getFeatureFlags(void) APPLE_KEXT_OVERRIDE; + virtual UInt getTxDataOffset(void) APPLE_KEXT_OVERRIDE; + virtual UInt captureInterfaceState(UInt) APPLE_KEXT_OVERRIDE; + virtual void restoreInterfaceState(UInt) APPLE_KEXT_OVERRIDE; + virtual void setMTU(UInt) APPLE_KEXT_OVERRIDE; + virtual bool bpfTap(UInt,UInt) APPLE_KEXT_OVERRIDE; + virtual const char *getBSDNamePrefix(void) APPLE_KEXT_OVERRIDE; + virtual UInt getBSDUnitNumber(void) APPLE_KEXT_OVERRIDE; + virtual const char *classNameOverride(void) APPLE_KEXT_OVERRIDE; + virtual void deferBSDAttach(bool) APPLE_KEXT_OVERRIDE; + virtual void reportDetailedLinkStatus(if_link_status const*) APPLE_KEXT_OVERRIDE; + virtual IOReturn registerNetworkInterfaceWithLogicalLink(IOSkywalkNetworkInterface::RegistrationInfo const*,IOSkywalkLogicalLink *,IOSkywalkPacketBufferPool *,IOSkywalkPacketBufferPool *,UInt) APPLE_KEXT_OVERRIDE; + virtual IOReturn deregisterLogicalLink(void) APPLE_KEXT_OVERRIDE; + virtual UInt getTSOOptions(IOSkywalkNetworkInterface::IOSkywalkTSOOptions *) APPLE_KEXT_OVERRIDE; + OSMetaClassDeclareReservedUnused( IOSkywalkNetworkInterface, 0); + OSMetaClassDeclareReservedUnused( IOSkywalkNetworkInterface, 1); + OSMetaClassDeclareReservedUnused( IOSkywalkNetworkInterface, 2); + OSMetaClassDeclareReservedUnused( IOSkywalkNetworkInterface, 3); + OSMetaClassDeclareReservedUnused( IOSkywalkNetworkInterface, 4); + OSMetaClassDeclareReservedUnused( IOSkywalkNetworkInterface, 5); + OSMetaClassDeclareReservedUnused( IOSkywalkNetworkInterface, 6); + OSMetaClassDeclareReservedUnused( IOSkywalkNetworkInterface, 7); + OSMetaClassDeclareReservedUnused( IOSkywalkNetworkInterface, 8); + OSMetaClassDeclareReservedUnused( IOSkywalkNetworkInterface, 9); + virtual IOReturn registerNetworkInterfaceWithLogicalLink(IOSkywalkEthernetInterface::RegistrationInfo const*, IOSkywalkLogicalLink*, IOSkywalkPacketBufferPool*, IOSkywalkPacketBufferPool*, UInt); + virtual void getHardwareAddress(ether_addr *); + virtual void setHardwareAddress(ether_addr *); + virtual void setLinkLayerAddress(ether_addr *); + virtual bool configureMulticastFilter(UInt,ether_addr const*,UInt); + virtual bool setMulticastAddresses(ether_addr const*,UInt); + virtual void setAllMulticastModeEnable(bool); + virtual IOReturn setPromiscuousModeEnable(bool, UInt); + virtual void reportNicProxyLimits(nicproxy_limits_info_s); + virtual void hwConfigNicProxyData(nicproxy_info_s *); OSMetaClassDeclareReservedUnused( IOSkywalkEthernetInterface, 0 ); OSMetaClassDeclareReservedUnused( IOSkywalkEthernetInterface, 1 ); OSMetaClassDeclareReservedUnused( IOSkywalkEthernetInterface, 2 ); @@ -44,6 +123,10 @@ class IOSkywalkEthernetInterface : public IOSkywalkNetworkInterface { OSMetaClassDeclareReservedUnused( IOSkywalkEthernetInterface, 8 ); OSMetaClassDeclareReservedUnused( IOSkywalkEthernetInterface, 9 ); OSMetaClassDeclareReservedUnused( IOSkywalkEthernetInterface, 10 ); + +public: + bool initRegistrationInfo(IOSkywalkEthernetInterface::RegistrationInfo*, unsigned int, unsigned long); + bool registerEthernetInterface(IOSkywalkEthernetInterface::RegistrationInfo const*, IOSkywalkPacketQueue**, unsigned int, IOSkywalkPacketBufferPool*, IOSkywalkPacketBufferPool*, unsigned int); }; #endif /* IOSkywalkEthernetInterface_h */ From 2e8fc1ed9726849846e73511a09639004021b2b5 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Mon, 12 Jun 2023 18:21:50 +0800 Subject: [PATCH 037/114] IOSkywalkNetworkInterface: Add RegistrationInfo initial size. --- include/Airport/IOSkywalkNetworkInterface.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/Airport/IOSkywalkNetworkInterface.h b/include/Airport/IOSkywalkNetworkInterface.h index f0a0aae25..ddfce79fe 100644 --- a/include/Airport/IOSkywalkNetworkInterface.h +++ b/include/Airport/IOSkywalkNetworkInterface.h @@ -21,7 +21,10 @@ class IOSkywalkPacketBufferPool; class IOSkywalkNetworkInterface : public IOSkywalkInterface { OSDeclareAbstractStructors( IOSkywalkNetworkInterface ) - struct RegistrationInfo; +public: + struct RegistrationInfo { + uint8_t pad[304]; + } __attribute__((packed)); struct IOSkywalkTSOOptions; public: From bab07f3729538ec2c82088c65cbda152fb524057 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Mon, 12 Jun 2023 18:29:55 +0800 Subject: [PATCH 038/114] Add IO80211InfraInterface --- include/Airport/Apple80211.h | 1 + include/Airport/IO80211InfraInterface.h | 152 ++++++++++++++++++++++++ 2 files changed, 153 insertions(+) create mode 100644 include/Airport/IO80211InfraInterface.h diff --git a/include/Airport/Apple80211.h b/include/Airport/Apple80211.h index b68de2f87..0175267f4 100644 --- a/include/Airport/Apple80211.h +++ b/include/Airport/Apple80211.h @@ -23,6 +23,7 @@ #include "IO80211P2PInterface.h" #if __IO80211_TARGET >= __MAC_10_15 #include "IO80211SkywalkInterface.h" +#include "IO80211InfraInterface.h" #endif #endif /* Apple80211_h */ diff --git a/include/Airport/IO80211InfraInterface.h b/include/Airport/IO80211InfraInterface.h new file mode 100644 index 000000000..2f7f97243 --- /dev/null +++ b/include/Airport/IO80211InfraInterface.h @@ -0,0 +1,152 @@ +// +// IO80211InfraInterface.h +// itlwm +// +// Created by qcwap on 2023/6/12. +// Copyright © 2023 钟先耀. All rights reserved. +// + +#ifndef IO80211InfraInterface_h +#define IO80211InfraInterface_h + +struct apple80211_wcl_advisory_info; +struct apple80211_wcl_tx_rx_latency; + +class IO80211InfraInterface : public IO80211SkywalkInterface { + OSDeclareAbstractStructors(IO80211InfraInterface) + +public: + virtual bool init() APPLE_KEXT_OVERRIDE; + virtual void free() APPLE_KEXT_OVERRIDE; + virtual IOReturn configureReport(IOReportChannelList *,UInt,void *,void *) APPLE_KEXT_OVERRIDE; + virtual IOReturn updateReport(IOReportChannelList *,UInt,void *,void *) APPLE_KEXT_OVERRIDE; + virtual bool start(IOService *) APPLE_KEXT_OVERRIDE; + virtual void stop(IOService *) APPLE_KEXT_OVERRIDE; + virtual IOReturn newUserClient( task_t owningTask, void * securityID, + UInt32 type, OSDictionary * properties, + LIBKERN_RETURNS_RETAINED IOUserClient ** handler ) APPLE_KEXT_OVERRIDE; + virtual const char * stringFromReturn( IOReturn rtn ) APPLE_KEXT_OVERRIDE; + virtual int errnoFromReturn( IOReturn rtn ) APPLE_KEXT_OVERRIDE; + virtual IOReturn setPowerState( + unsigned long powerStateOrdinal, + IOService * whatDevice ) APPLE_KEXT_OVERRIDE; + virtual unsigned long maxCapabilityForDomainState( IOPMPowerFlags domainState ) APPLE_KEXT_OVERRIDE; + virtual unsigned long initialPowerStateForDomainState( IOPMPowerFlags domainState ) APPLE_KEXT_OVERRIDE; + virtual IOReturn enable(UInt) APPLE_KEXT_OVERRIDE; + virtual IOReturn disable(UInt) APPLE_KEXT_OVERRIDE; + virtual SInt32 initBSDInterfaceParameters(ifnet_init_eparams *,sockaddr_dl **) APPLE_KEXT_OVERRIDE; + virtual bool prepareBSDInterface(ifnet_t, UInt) APPLE_KEXT_OVERRIDE; + virtual IOReturn processBSDCommand(ifnet_t, UInt, void *) APPLE_KEXT_OVERRIDE; + virtual SInt32 setInterfaceEnable(bool) APPLE_KEXT_OVERRIDE; + virtual SInt32 setRunningState(bool) APPLE_KEXT_OVERRIDE; + virtual IOReturn handleChosenMedia(UInt) APPLE_KEXT_OVERRIDE; + virtual void *getSupportedMediaArray(UInt *,UInt *) APPLE_KEXT_OVERRIDE; + virtual UInt getHardwareAssists(void) APPLE_KEXT_OVERRIDE; + virtual UInt32 getFeatureFlags(void) APPLE_KEXT_OVERRIDE; + virtual bool bpfTap(UInt,UInt) APPLE_KEXT_OVERRIDE; + virtual const char *classNameOverride(void) APPLE_KEXT_OVERRIDE; + virtual void getHardwareAddress(ether_addr *) APPLE_KEXT_OVERRIDE; + virtual void setHardwareAddress(ether_addr *) APPLE_KEXT_OVERRIDE; + virtual IOReturn setPromiscuousModeEnable(bool, UInt) APPLE_KEXT_OVERRIDE; + virtual void *createPeerManager(void) APPLE_KEXT_OVERRIDE; + virtual void postMessage(UInt,void *,unsigned long,bool) APPLE_KEXT_OVERRIDE; + virtual IOReturn reportDataPathEvents(UInt,void *,unsigned long,bool) APPLE_KEXT_OVERRIDE; + virtual IOReturn recordOutputPackets(TxSubmissionDequeueStats *,TxSubmissionDequeueStats *) APPLE_KEXT_OVERRIDE; + virtual IOReturn recordOutputPacket(apple80211_wme_ac,int,int) APPLE_KEXT_OVERRIDE; + virtual void logTxPacket(IO80211NetworkPacket *,PacketSkywalkScratch *,apple80211_wme_ac,bool) APPLE_KEXT_OVERRIDE; + virtual void logTxCompletionPacket(IO80211NetworkPacket *,PacketSkywalkScratch *,unsigned char *,apple80211_wme_ac,int,UInt,bool) APPLE_KEXT_OVERRIDE; + virtual IOReturn recordCompletionPackets(TxCompletionEnqueueStats *,TxCompletionEnqueueStats *) APPLE_KEXT_OVERRIDE; + virtual IOReturn inputPacket(IO80211NetworkPacket *,packet_info_tag *,ether_header *,bool *) APPLE_KEXT_OVERRIDE; + virtual void logSkywalkTxReqPacket(IO80211NetworkPacket *,PacketSkywalkScratch *,unsigned char *,apple80211_wme_ac,bool) APPLE_KEXT_OVERRIDE; + virtual SInt64 pendingPackets(unsigned char) APPLE_KEXT_OVERRIDE; + virtual SInt64 packetSpace(unsigned char) APPLE_KEXT_OVERRIDE; + virtual bool isChipInterfaceReady(void) APPLE_KEXT_OVERRIDE; + virtual bool isDebounceOnGoing(void) APPLE_KEXT_OVERRIDE; + virtual bool setLinkState(IO80211LinkState,UInt,bool debounceTimeout = 30,UInt code = 0) APPLE_KEXT_OVERRIDE; + virtual IO80211LinkState linkState(void) APPLE_KEXT_OVERRIDE; + virtual void setScanningState(UInt,bool,apple80211_scan_data *,int) APPLE_KEXT_OVERRIDE; + virtual void setDataPathState(bool) APPLE_KEXT_OVERRIDE; + virtual void *getScanManager(void) APPLE_KEXT_OVERRIDE; + virtual void updateLinkParameters(apple80211_interface_availability *) APPLE_KEXT_OVERRIDE; + virtual void updateInterfaceCoexRiskPct(unsigned long long) APPLE_KEXT_OVERRIDE; + virtual void setLQM(unsigned long long) APPLE_KEXT_OVERRIDE; + virtual void updateLinkStatus(void) APPLE_KEXT_OVERRIDE; + virtual void updateLinkStatusGated(void) APPLE_KEXT_OVERRIDE; + virtual void setInterfaceExtendedCCA(apple80211_channel,apple80211_cca_report *) APPLE_KEXT_OVERRIDE; + virtual void setInterfaceCCA(apple80211_channel,int) APPLE_KEXT_OVERRIDE; + virtual void setInterfaceNF(apple80211_channel,long long) APPLE_KEXT_OVERRIDE; + virtual void setInterfaceOFDMDesense(apple80211_channel,long long) APPLE_KEXT_OVERRIDE; + virtual void removePacketQueue(IO80211FlowQueueHash *) APPLE_KEXT_OVERRIDE; + virtual void setDebugFlags(unsigned long long,UInt) APPLE_KEXT_OVERRIDE; + virtual SInt64 debugFlags(void) APPLE_KEXT_OVERRIDE; + virtual void setInterfaceChipCounters(apple80211_stat_report *,apple80211_chip_counters_tx *,apple80211_chip_error_counters_tx *,apple80211_chip_counters_rx *) APPLE_KEXT_OVERRIDE; + virtual void setInterfaceMIBdot11(apple80211_stat_report *,apple80211_ManagementInformationBasedot11_counters *) APPLE_KEXT_OVERRIDE; + virtual void setFrameStats(apple80211_stat_report *,apple80211_frame_counters *) APPLE_KEXT_OVERRIDE; + virtual SInt64 getWmeTxCounters(unsigned long long *) APPLE_KEXT_OVERRIDE; + virtual void setEnabledBySystem(bool) APPLE_KEXT_OVERRIDE; + virtual bool enabledBySystem(void) APPLE_KEXT_OVERRIDE; + virtual bool willRoam(ether_addr *,UInt) APPLE_KEXT_OVERRIDE; + virtual void setPeerManagerLogFlag(UInt,UInt,UInt) APPLE_KEXT_OVERRIDE; + virtual void setWoWEnabled(bool) APPLE_KEXT_OVERRIDE; + virtual bool wowEnabled(void) APPLE_KEXT_OVERRIDE; + virtual void printDataPath(userPrintCtx *) APPLE_KEXT_OVERRIDE; + virtual bool findOrCreateFlowQueue(IO80211FlowQueueHash) APPLE_KEXT_OVERRIDE; + virtual UInt64 findOrCreateFlowQueueWithCache(IO80211FlowQueueHash,bool *) APPLE_KEXT_OVERRIDE; + virtual UInt64 findExistingFlowQueue(IO80211FlowQueueHash) APPLE_KEXT_OVERRIDE; + virtual void removePacketQueue(IO80211FlowQueueHash const*) APPLE_KEXT_OVERRIDE; + virtual void flushPacketQueues(void) APPLE_KEXT_OVERRIDE; + virtual void cachePeer(ether_addr *,UInt *) APPLE_KEXT_OVERRIDE; + virtual bool shouldLog(unsigned long long) APPLE_KEXT_OVERRIDE; + virtual void vlogDebug(unsigned long long,char const*,va_list) APPLE_KEXT_OVERRIDE; + virtual void vlogDebugBPF(unsigned long long,char const*,va_list) APPLE_KEXT_OVERRIDE; + virtual UInt64 createLinkQualityMonitor(IO80211Peer *,IOService *) APPLE_KEXT_OVERRIDE; + virtual void releaseLinkQualityMonitor(IO80211Peer *) APPLE_KEXT_OVERRIDE; + virtual void *getP2PSkywalkPeerMgr(void) APPLE_KEXT_OVERRIDE; + virtual bool isCommandProhibited(int) APPLE_KEXT_OVERRIDE; + virtual void setNotificationProperty(OSSymbol const*,OSObject const*) APPLE_KEXT_OVERRIDE; + virtual void *getWorkerMatchingDict(OSString *) APPLE_KEXT_OVERRIDE; + virtual bool init(IOService *) APPLE_KEXT_OVERRIDE; + virtual bool isInterfaceEnabled(void) APPLE_KEXT_OVERRIDE; + virtual ether_addr *getSelfMacAddr(void) APPLE_KEXT_OVERRIDE; + virtual void setSelfMacAddr(ether_addr *) APPLE_KEXT_OVERRIDE; + virtual void *getPacketPool(OSString *) APPLE_KEXT_OVERRIDE; + virtual void *getLogger(void) APPLE_KEXT_OVERRIDE; + virtual IOReturn handleSIOCSIFADDR(void) APPLE_KEXT_OVERRIDE; + virtual IOReturn debugHandler(apple80211_debug_command *) APPLE_KEXT_OVERRIDE; + virtual void statsDump(void) APPLE_KEXT_OVERRIDE; + virtual void powerOnNotification(void) APPLE_KEXT_OVERRIDE; + virtual void powerOffNotification(void) APPLE_KEXT_OVERRIDE; + virtual UInt64 getTxQueueDepth(void) APPLE_KEXT_OVERRIDE; + virtual UInt64 getRxQueueCapacity(void) APPLE_KEXT_OVERRIDE; + virtual void updateRxCounter(unsigned long long) APPLE_KEXT_OVERRIDE; + virtual void *getMultiCastQueue(void) APPLE_KEXT_OVERRIDE; + virtual void *getCurrentBssid(void) APPLE_KEXT_OVERRIDE; + virtual int getAssocState(void) APPLE_KEXT_OVERRIDE; + virtual void notifyQueueState(apple80211_wme_ac,unsigned short) APPLE_KEXT_OVERRIDE; + virtual int getTxHeadroom(void) APPLE_KEXT_OVERRIDE; + virtual void *getRxCompQueue(void) APPLE_KEXT_OVERRIDE; + virtual void *getTxCompQueue(void) APPLE_KEXT_OVERRIDE; + virtual void *getTxSubQueue(apple80211_wme_ac) APPLE_KEXT_OVERRIDE; + virtual void *getTxPacketPool(void) APPLE_KEXT_OVERRIDE; + virtual void *getRxPacketPool(void) APPLE_KEXT_OVERRIDE; + virtual void enableDatapath(void) APPLE_KEXT_OVERRIDE; + virtual void disableDatapath(void) APPLE_KEXT_OVERRIDE; + virtual int getNumTxQueues(void) APPLE_KEXT_OVERRIDE; + virtual void *getLQMSummary(apple80211_lqm_summary *) APPLE_KEXT_OVERRIDE; + virtual int getEventPipeSize(void) APPLE_KEXT_OVERRIDE; + virtual UInt64 createEventPipe(IO80211APIUserClient *) APPLE_KEXT_OVERRIDE; + virtual void destroyEventPipe(IO80211APIUserClient *) APPLE_KEXT_OVERRIDE; + virtual void postMessageIOUC(char const*,UInt,void *,unsigned long) APPLE_KEXT_OVERRIDE; + virtual bool isIOUCPipeOpened(void) APPLE_KEXT_OVERRIDE; + virtual void *getRingMD(IO80211APIUserClient *,unsigned long long) APPLE_KEXT_OVERRIDE; + virtual IOReturn setLinkStateInternal(IO80211LinkState,uint,bool,uint,apple80211_link_changed_event_data &); + virtual void setPoweredOnByUser(bool); + virtual void setCurrentBssid(ether_addr *); + virtual void setWCL_ADVISORTY_INFO(apple80211_wcl_advisory_info *); + virtual void *getWCL_TX_RX_LATENCY(apple80211_wcl_tx_rx_latency *); + +public: + char _data[0x120]; +}; + +#endif /* IO80211InfraInterface_h */ From babe401b656f8d66116805101b9670e8ed16dd7d Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Mon, 12 Jun 2023 18:30:17 +0800 Subject: [PATCH 039/114] Update setPromiscuousModeEnable method. --- include/Airport/IO80211SkywalkInterface.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/Airport/IO80211SkywalkInterface.h b/include/Airport/IO80211SkywalkInterface.h index ad48963c2..109db0182 100644 --- a/include/Airport/IO80211SkywalkInterface.h +++ b/include/Airport/IO80211SkywalkInterface.h @@ -95,7 +95,7 @@ class IO80211SkywalkInterface : public IOSkywalkEthernetInterface { virtual void *getSupportedMediaArray(UInt *,UInt *) APPLE_KEXT_OVERRIDE; virtual UInt32 getFeatureFlags(void) APPLE_KEXT_OVERRIDE; virtual const char *classNameOverride(void) APPLE_KEXT_OVERRIDE; - virtual IOReturn setPromiscuousModeEnable(bool, UInt); + virtual IOReturn setPromiscuousModeEnable(bool, UInt) APPLE_KEXT_OVERRIDE; virtual void *createPeerManager(void); virtual void postMessage(UInt,void *,unsigned long,bool); virtual IOReturn reportDataPathEvents(UInt,void *,unsigned long,bool); @@ -188,6 +188,10 @@ class IO80211SkywalkInterface : public IOSkywalkEthernetInterface { virtual bool isIOUCPipeOpened(void); virtual void *getRingMD(IO80211APIUserClient *,unsigned long long); +public: + OSString *setInterfaceRole(UInt role); + void *setInterfaceId(UInt id); + public: char _data[0x118]; }; From 7db75d934e8322653276328e0d8f44d9d4331696 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Mon, 12 Jun 2023 18:30:35 +0800 Subject: [PATCH 040/114] add IOSkywalkLogicalLink class placeholder. --- include/Airport/IOSkywalkLogicalLink.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 include/Airport/IOSkywalkLogicalLink.h diff --git a/include/Airport/IOSkywalkLogicalLink.h b/include/Airport/IOSkywalkLogicalLink.h new file mode 100644 index 000000000..919bfb777 --- /dev/null +++ b/include/Airport/IOSkywalkLogicalLink.h @@ -0,0 +1,20 @@ +// +// IOSkywalkLogicalLink.h +// itlwm +// +// Created by qcwap on 2023/6/12. +// Copyright © 2023 钟先耀. All rights reserved. +// + +#ifndef IOSkywalkLogicalLink_h +#define IOSkywalkLogicalLink_h + +class IOSkywalkLogicalLink : public IOService { + OSDeclareAbstractStructors(IOSkywalkLogicalLink) + +public: + +public: +}; + +#endif /* IOSkywalkLogicalLink_h */ From 5d5c1fcff57fd067f2b567a5bee848a9c7955b6a Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Tue, 13 Jun 2023 01:08:17 +0800 Subject: [PATCH 041/114] make virtual methods public. --- include/Airport/IOSkywalkEthernetInterface.h | 2 ++ include/Airport/IOSkywalkNetworkInterface.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/include/Airport/IOSkywalkEthernetInterface.h b/include/Airport/IOSkywalkEthernetInterface.h index bb988e21a..c0eb38eb8 100644 --- a/include/Airport/IOSkywalkEthernetInterface.h +++ b/include/Airport/IOSkywalkEthernetInterface.h @@ -52,6 +52,8 @@ class IOSkywalkEthernetInterface : public IOSkywalkNetworkInterface { OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 8 ); OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 9 ); OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 10 ); + +public: virtual SInt32 initBSDInterfaceParameters(ifnet_init_eparams *,sockaddr_dl **) = 0; virtual bool prepareBSDInterface(ifnet_t,UInt) APPLE_KEXT_OVERRIDE; virtual void finalizeBSDInterface(ifnet_t,UInt) APPLE_KEXT_OVERRIDE; diff --git a/include/Airport/IOSkywalkNetworkInterface.h b/include/Airport/IOSkywalkNetworkInterface.h index ddfce79fe..4178978a6 100644 --- a/include/Airport/IOSkywalkNetworkInterface.h +++ b/include/Airport/IOSkywalkNetworkInterface.h @@ -59,6 +59,8 @@ class IOSkywalkNetworkInterface : public IOSkywalkInterface { OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 8 ); OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 9 ); OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 10 ); + +public: virtual SInt32 initBSDInterfaceParameters(ifnet_init_eparams *,sockaddr_dl **) = 0; virtual bool prepareBSDInterface(ifnet_t,UInt); virtual void finalizeBSDInterface(ifnet_t,UInt); From 34f308882e1761cd8dba3cac136a78c86814a666 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Tue, 13 Jun 2023 01:12:05 +0800 Subject: [PATCH 042/114] IO80211SkywalkInterface: add getInterfaceRole function. --- include/Airport/IO80211SkywalkInterface.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/Airport/IO80211SkywalkInterface.h b/include/Airport/IO80211SkywalkInterface.h index 109db0182..81fc76a84 100644 --- a/include/Airport/IO80211SkywalkInterface.h +++ b/include/Airport/IO80211SkywalkInterface.h @@ -191,6 +191,7 @@ class IO80211SkywalkInterface : public IOSkywalkEthernetInterface { public: OSString *setInterfaceRole(UInt role); void *setInterfaceId(UInt id); + int getInterfaceRole(); public: char _data[0x118]; From b65990cb454afee66f914834872e8281cc84ead2 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Tue, 13 Jun 2023 01:34:31 +0800 Subject: [PATCH 043/114] Add IOSkywalkNetworkPacket. --- include/Airport/IOSkywalkNetworkPacket.h | 54 ++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 include/Airport/IOSkywalkNetworkPacket.h diff --git a/include/Airport/IOSkywalkNetworkPacket.h b/include/Airport/IOSkywalkNetworkPacket.h new file mode 100644 index 000000000..630f6b3f5 --- /dev/null +++ b/include/Airport/IOSkywalkNetworkPacket.h @@ -0,0 +1,54 @@ +// +// IOSkywalkNetworkPacket.h +// itlwm +// +// Created by qcwap on 2023/6/13. +// Copyright © 2023 钟先耀. All rights reserved. +// + +#ifndef IOSkywalkInterface_h +#define IOSkywalkInterface_h + +class IOSkywalkPacketBufferPool; +class IOSkywalkPacketDescriptor; +class IOSkywalkPacketBuffer; +class IOSkywalkPacketQueue; + +class IOSkywalkNetworkPacket : public IOService { + OSDeclareAbstractStructors(IOSkywalkNetworkPacket) + +public: + virtual void free() APPLE_KEXT_OVERRIDE; + + virtual bool initWithPool(IOSkywalkPacketBufferPool *,IOSkywalkPacketDescriptor *,uint); + virtual void *getPacketBuffers(IOSkywalkPacketBuffer **,uint); + virtual UInt getPacketBufferCount(void); + virtual IOSkywalkPacketDescriptor *getMemoryDescriptor(void); + virtual void setDataLength(uint); + virtual UInt getDataLength(void); + virtual void setDataOffset(unsigned short); + virtual unsigned short getDataOffset(void); + virtual void setDataOffsetAndLength(unsigned short,uint); + virtual void setDataOff(long long); + virtual long long getDataOff(void); + virtual void setDataOffAndLen(long long,unsigned long); + virtual void *getDataVirtualAddress(void); + virtual void *getDataIOVirtualAddress(void); + virtual bool prepareWithQueue(IOSkywalkPacketQueue *,uint,uint); + virtual bool prepare(IOSkywalkPacketQueue *,unsigned long long,uint); + virtual void completeWithQueue(IOSkywalkPacketQueue *,uint,uint); + virtual void complete(IOSkywalkPacketQueue *,uint); + virtual UInt getPacketType(void); + virtual void setWakeFlag(void); + virtual UInt getTraceID(void); + virtual void setTraceID(UInt); + virtual void traceEvent(uint); + virtual void *generateTraceTag(IOSkywalkPacketQueue *); + virtual void *acquireWithPacketHandle(unsigned long long,uint); + virtual void disposePacket(void); + +public: + uint8_t filter[0x78]; +}; + +#endif /* IOSkywalkInterface_h */ From 48c932a5cfd58bc4eb9b1c5e7fd7218353040793 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Tue, 13 Jun 2023 18:02:12 +0800 Subject: [PATCH 044/114] IO80211Controller: Use void * result, it should be replace later. --- include/Airport/IO80211Controller.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/Airport/IO80211Controller.h b/include/Airport/IO80211Controller.h index 160409997..83e6a5a47 100644 --- a/include/Airport/IO80211Controller.h +++ b/include/Airport/IO80211Controller.h @@ -210,11 +210,11 @@ class IO80211Controller : public IOEthernetController { } virtual UInt getPacketTSCounter(); - virtual UInt64 getDriverTextLog(); + virtual void *getDriverTextLog(); virtual UInt32 selfDiagnosticsReport(int,char const*,UInt); - virtual UInt64 getFaultReporterFromDriver(); + virtual void *getFaultReporterFromDriver(); virtual UInt32 getDataQueueDepth(OSObject *); virtual bool isAssociatedToMovingNetwork(void) { return false; } From eccbae48eef9b85d717ce823323c819d5bbabb05 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Wed, 14 Jun 2023 01:34:41 +0800 Subject: [PATCH 045/114] Add corecapture headers: CCPipe CCDataPipe CCLogPipe CCStream CCLogStream --- include/Airport/CCDataPipe.h | 74 ++++++++++++++++++ include/Airport/CCLogPipe.h | 112 ++++++++++++++++++++++++++++ include/Airport/CCLogStream.h | 52 +++++++++++++ include/Airport/CCPipe.h | 69 +++++++++++++++++ include/Airport/CCStream.h | 40 ++++++++++ include/Airport/IO80211Controller.h | 8 +- 6 files changed, 351 insertions(+), 4 deletions(-) create mode 100644 include/Airport/CCDataPipe.h create mode 100644 include/Airport/CCLogPipe.h create mode 100644 include/Airport/CCLogStream.h create mode 100644 include/Airport/CCPipe.h create mode 100644 include/Airport/CCStream.h diff --git a/include/Airport/CCDataPipe.h b/include/Airport/CCDataPipe.h new file mode 100644 index 000000000..16528abc5 --- /dev/null +++ b/include/Airport/CCDataPipe.h @@ -0,0 +1,74 @@ +// +// CCDataPipe.h +// itlwm +// +// Created by qcwap on 2023/6/14. +// Copyright © 2023 钟先耀. All rights reserved. +// + +#ifndef CCDataPipe_h +#define CCDataPipe_h + +#include "CCPipe.h" +#include + +class CCDataPipeBlob; + +class CCDataPipe : public CCPipe { + OSDeclareDefaultStructors(CCDataPipe) + +public: + virtual void free() APPLE_KEXT_OVERRIDE; + virtual IOReturn configureReport(IOReportChannelList *,UInt,void *,void *) APPLE_KEXT_OVERRIDE; + virtual IOReturn updateReport(IOReportChannelList *,UInt,void *,void *) APPLE_KEXT_OVERRIDE; + virtual bool start( IOService * provider ) APPLE_KEXT_OVERRIDE; + virtual void stop( IOService * provider ) APPLE_KEXT_OVERRIDE; + virtual void detach( IOService * provider ) APPLE_KEXT_OVERRIDE; + virtual IOReturn newUserClient( task_t owningTask, void * securityID, + UInt32 type, OSDictionary * properties, + LIBKERN_RETURNS_RETAINED IOUserClient ** handler ) APPLE_KEXT_OVERRIDE; + virtual bool clientClose(void) APPLE_KEXT_OVERRIDE; + virtual void *getCoreCapturePipeReporter(void) APPLE_KEXT_OVERRIDE; + virtual bool isClientConnected(void) APPLE_KEXT_OVERRIDE; + virtual bool startPipe(void) APPLE_KEXT_OVERRIDE; + virtual void stopPipe(void) APPLE_KEXT_OVERRIDE; + virtual UInt generateStreamId(void) APPLE_KEXT_OVERRIDE; + virtual bool addInitCapture(void) APPLE_KEXT_OVERRIDE; + virtual void removeInitCapture(void) APPLE_KEXT_OVERRIDE; + virtual void removeCapture(void) APPLE_KEXT_OVERRIDE; + virtual bool profileLoaded(void) APPLE_KEXT_OVERRIDE; + virtual bool profileRemoved(void) APPLE_KEXT_OVERRIDE; + virtual bool capture(CCTimestamp *,char const*) APPLE_KEXT_OVERRIDE; + virtual bool capture(CCTimestamp,char const*) APPLE_KEXT_OVERRIDE; + virtual bool hasPrivilege(void) APPLE_KEXT_OVERRIDE; + virtual bool hasPrivilegeAdministrator(task_t) APPLE_KEXT_OVERRIDE; + virtual bool initWithOwnerNameCapacity(IOService *,char const*,char const*,CCPipeOptions const*) APPLE_KEXT_OVERRIDE; + virtual OSString *getClassName(void) APPLE_KEXT_OVERRIDE; + virtual void setCCaptureInRegistry(void) APPLE_KEXT_OVERRIDE; + virtual unsigned long getPipeSize(void) APPLE_KEXT_OVERRIDE; + virtual void setPipeSize(unsigned long) APPLE_KEXT_OVERRIDE; + virtual void freeCCCaptureObject(void) APPLE_KEXT_OVERRIDE; + virtual void *getPipeCallbacks(void) APPLE_KEXT_OVERRIDE; + virtual IOService *getProvider(void) APPLE_KEXT_OVERRIDE; + virtual void *getCurrentOptions(void) APPLE_KEXT_OVERRIDE; + virtual void *getDriverOptions(void) APPLE_KEXT_OVERRIDE; + virtual UInt getLoggingFlags(void) APPLE_KEXT_OVERRIDE; + virtual unsigned long getRingEntryMaxTimeMs(void) APPLE_KEXT_OVERRIDE; + virtual unsigned long getRingEntrySleepTimeMs(void) APPLE_KEXT_OVERRIDE; + virtual CCPipeStatistics *getStatistics(void) APPLE_KEXT_OVERRIDE; + virtual void setStatistics(CCPipeStatistics *) APPLE_KEXT_OVERRIDE; + virtual void publishStatistics(void) APPLE_KEXT_OVERRIDE; + virtual void updateStatistics(bool) APPLE_KEXT_OVERRIDE; + virtual IOReturn configureAllReports(void) APPLE_KEXT_OVERRIDE; + virtual IOReturn updateAllReports(void) APPLE_KEXT_OVERRIDE; + virtual void *createReportSet(void) APPLE_KEXT_OVERRIDE; + virtual IOReturn enqueueBlob(CCDataPipeBlob *); + virtual bool dequeueBlob(CCDataPipeBlob **); + virtual void freeResources(void); + virtual void notifyTimeout(IOTimerEventSource *); + +public: + uint8_t filter[0x98]; +}; + +#endif /* CCDataPipe_h */ diff --git a/include/Airport/CCLogPipe.h b/include/Airport/CCLogPipe.h new file mode 100644 index 000000000..b92e11e81 --- /dev/null +++ b/include/Airport/CCLogPipe.h @@ -0,0 +1,112 @@ +// +// CCLogPipe.h +// itlwm +// +// Created by qcwap on 2023/6/14. +// Copyright © 2023 钟先耀. All rights reserved. +// + +#ifndef CCLogPipe_h +#define CCLogPipe_h + +#include "CCPipe.h" +#include "CCLogStream.h" +#include + +typedef int CCLogPolicy; +typedef int CCLogState; +class CCLogMetadata; + +class CCLogPipe : public CCPipe { + OSDeclareDefaultStructors(CCLogPipe) + +public: + virtual void free() APPLE_KEXT_OVERRIDE; + virtual IOReturn configureReport(IOReportChannelList *,UInt,void *,void *) APPLE_KEXT_OVERRIDE; + virtual IOReturn updateReport(IOReportChannelList *,UInt,void *,void *) APPLE_KEXT_OVERRIDE; + virtual bool start( IOService * provider ) APPLE_KEXT_OVERRIDE; + virtual void stop( IOService * provider ) APPLE_KEXT_OVERRIDE; + virtual void detach( IOService * provider ) APPLE_KEXT_OVERRIDE; + virtual IOReturn newUserClient( task_t owningTask, void * securityID, + UInt32 type, OSDictionary * properties, + LIBKERN_RETURNS_RETAINED IOUserClient ** handler ) APPLE_KEXT_OVERRIDE; + virtual bool clientClose(void) APPLE_KEXT_OVERRIDE; + virtual void *getCoreCapturePipeReporter(void) APPLE_KEXT_OVERRIDE; + virtual bool isClientConnected(void) APPLE_KEXT_OVERRIDE; + virtual bool startPipe(void) APPLE_KEXT_OVERRIDE; + virtual void stopPipe(void) APPLE_KEXT_OVERRIDE; + virtual UInt generateStreamId(void) APPLE_KEXT_OVERRIDE; + virtual bool addInitCapture(void) APPLE_KEXT_OVERRIDE; + virtual void removeInitCapture(void) APPLE_KEXT_OVERRIDE; + virtual void removeCapture(void) APPLE_KEXT_OVERRIDE; + virtual bool profileLoaded(void) APPLE_KEXT_OVERRIDE; + virtual bool profileRemoved(void) APPLE_KEXT_OVERRIDE; + virtual bool capture(CCTimestamp *,char const*) APPLE_KEXT_OVERRIDE; + virtual bool capture(CCTimestamp,char const*) APPLE_KEXT_OVERRIDE; + virtual bool hasPrivilege(void) APPLE_KEXT_OVERRIDE; + virtual bool hasPrivilegeAdministrator(task_t) APPLE_KEXT_OVERRIDE; + virtual bool initWithOwnerNameCapacity(IOService *,char const*,char const*,CCPipeOptions const*) APPLE_KEXT_OVERRIDE; + virtual OSString *getClassName(void) APPLE_KEXT_OVERRIDE; + virtual void setCCaptureInRegistry(void) APPLE_KEXT_OVERRIDE; + virtual unsigned long getPipeSize(void) APPLE_KEXT_OVERRIDE; + virtual void setPipeSize(unsigned long) APPLE_KEXT_OVERRIDE; + virtual void freeCCCaptureObject(void) APPLE_KEXT_OVERRIDE; + virtual void *getPipeCallbacks(void) APPLE_KEXT_OVERRIDE; + virtual IOService *getProvider(void) APPLE_KEXT_OVERRIDE; + virtual void *getCurrentOptions(void) APPLE_KEXT_OVERRIDE; + virtual void *getDriverOptions(void) APPLE_KEXT_OVERRIDE; + virtual UInt getLoggingFlags(void) APPLE_KEXT_OVERRIDE; + virtual unsigned long getRingEntryMaxTimeMs(void) APPLE_KEXT_OVERRIDE; + virtual unsigned long getRingEntrySleepTimeMs(void) APPLE_KEXT_OVERRIDE; + virtual CCPipeStatistics *getStatistics(void) APPLE_KEXT_OVERRIDE; + virtual void setStatistics(CCPipeStatistics *) APPLE_KEXT_OVERRIDE; + virtual void publishStatistics(void) APPLE_KEXT_OVERRIDE; + virtual void updateStatistics(bool) APPLE_KEXT_OVERRIDE; + virtual IOReturn configureAllReports(void) APPLE_KEXT_OVERRIDE; + virtual IOReturn updateAllReports(void) APPLE_KEXT_OVERRIDE; + virtual void *createReportSet(void) APPLE_KEXT_OVERRIDE; + virtual void log(uint,CCStreamLogLevel,char const*,unsigned long long,bool,bool); + virtual void log(uint,char const*,unsigned long long,unsigned long long,unsigned long long); + virtual void log(uint,char const*,unsigned long long); + virtual bool unmapPipe(void); + virtual void setNotifyTimeout(uint); + virtual void setWatermarkLevelToNotify(unsigned long); + virtual bool getPolicy(CCLogPolicy *); + virtual void setPolicy(CCLogPolicy); + virtual void setStreamLogFlags(char const*,unsigned long long); + virtual void updateStreamLogFlags(char const*,char const*,uint); + virtual void setStreamLogLevel(char const*,CCStreamLogLevel); + virtual void setStreamConsoleLogFlags(char const*,unsigned long long); + virtual void setStreamConsoleLogLevel(char const*,CCStreamLogLevel); + virtual void updateStreamConsoleLogFlags(char const*,char const*,uint); + virtual IOReturn getUserSpaceNotificationPort(unsigned long long *); + virtual void notifyUserSpace(void); + virtual bool willDropMessage(uint); + virtual char *getScratchBuffer(unsigned long,unsigned long *,uint); + virtual void putScratchBuffer(char *,int); + virtual void resizeScratchBuffer(char *,unsigned long,unsigned long *); + virtual bool reserveRingEntry(unsigned long long,uint,int *); + virtual UInt getLogIdentifier(void); + virtual void freeResources(void); + virtual void notifyTimeout(IOTimerEventSource *); + virtual void log(CCStreamLogLevel,char const*,unsigned long long,unsigned long long,CCLogState); + virtual bool isValidCCLogMetaData(CCLogMetadata volatile*); + virtual bool isValidStreamLogLevel(CCStreamLogLevel); + virtual bool isPtrInRing(void *); + virtual void addOffset(uint volatile&,unsigned long,unsigned long); + virtual UInt calculateFreeBufferLength(uint,uint); + virtual void incrementRingPtr(unsigned char volatile*&,unsigned long); + virtual void decrementRingPtr(unsigned char volatile*&,unsigned long); + virtual void freeLogBuffer(unsigned long); + virtual const char *getLogLevelShortName(CCStreamLogLevel); + virtual CCLogStream *findStream(char const*); + virtual void releaseStream(CCLogStream *); + virtual void *findStreamEntry(char const*); + virtual bool initScratchBuffers(unsigned long,unsigned long); + virtual void freeScratchBuffers(void); + +public: + uint8_t filter[0x98]; +}; + +#endif /* CCLogPipe_h */ diff --git a/include/Airport/CCLogStream.h b/include/Airport/CCLogStream.h new file mode 100644 index 000000000..cf1e8bc78 --- /dev/null +++ b/include/Airport/CCLogStream.h @@ -0,0 +1,52 @@ +// +// CCLogStream.h +// itlwm +// +// Created by qcwap on 2023/6/14. +// Copyright © 2023 钟先耀. All rights reserved. +// + +#ifndef CCLogStream_h +#define CCLogStream_h + +#include +#include "CCStream.h" + +enum CCStreamLogLevel +{ + LEVEL_1, +}; + +class CCLogStream : public CCStream { + OSDeclareDefaultStructors(CCLogStream) + +public: + virtual void free() APPLE_KEXT_OVERRIDE; + virtual bool init(OSDictionary *) APPLE_KEXT_OVERRIDE; + virtual IOReturn configureReport(IOReportChannelList *,UInt,void *,void *) APPLE_KEXT_OVERRIDE; + virtual IOReturn updateReport(IOReportChannelList *,UInt,void *,void *) APPLE_KEXT_OVERRIDE; + virtual bool start(IOService *) APPLE_KEXT_OVERRIDE; + virtual void stop(IOService *) APPLE_KEXT_OVERRIDE; + virtual bool attach( IOService * provider ) APPLE_KEXT_OVERRIDE; + virtual void detach( IOService * provider ) APPLE_KEXT_OVERRIDE; + virtual bool profileLoaded(void) APPLE_KEXT_OVERRIDE; + virtual bool profileRemoved(void) APPLE_KEXT_OVERRIDE; + virtual CCLogStream const *initWithPipeAndName(CCPipe *,char const*,CCStreamOptions const*) APPLE_KEXT_OVERRIDE; + virtual void setLevel(CCStreamLogLevel); + virtual CCStreamLogLevel getLevel(void); + virtual void setFlags(unsigned long long); + virtual unsigned long long getFlags(void); + virtual void setLogFlag(unsigned long long); + virtual void clearLogFlag(unsigned long long); + virtual void setConsoleLevel(CCStreamLogLevel); + virtual void setConsoleFlags(unsigned long long); + virtual unsigned long long getConsoleFlags(void); + virtual void setConsoleLogFlag(unsigned long long); + virtual void clearConsoleLogFlag(unsigned long long); + +public: + uint8_t filter[0x98]; +}; + +#endif /* CCLogStream_h */ + diff --git a/include/Airport/CCPipe.h b/include/Airport/CCPipe.h new file mode 100644 index 000000000..b8ed9c31d --- /dev/null +++ b/include/Airport/CCPipe.h @@ -0,0 +1,69 @@ +// +// CCPipe.h +// itlwm +// +// Created by qcwap on 2023/6/14. +// Copyright © 2023 钟先耀. All rights reserved. +// + +#ifndef CCPipe_h +#define CCPipe_h + +#include + +class CCTimestamp; +class CCPipeOptions; +class CCPipeStatistics; + +class CCPipe : public IOService { + OSDeclareAbstractStructors(CCPipe) + +public: + virtual void free() APPLE_KEXT_OVERRIDE; + virtual IOReturn configureReport(IOReportChannelList *,UInt,void *,void *) APPLE_KEXT_OVERRIDE; + virtual IOReturn updateReport(IOReportChannelList *,UInt,void *,void *) APPLE_KEXT_OVERRIDE; + virtual void detach( IOService * provider ) APPLE_KEXT_OVERRIDE; + virtual IOReturn newUserClient( task_t owningTask, void * securityID, + UInt32 type, OSDictionary * properties, + LIBKERN_RETURNS_RETAINED IOUserClient ** handler ) = 0; + virtual bool clientClose(void) = 0; + virtual void *getCoreCapturePipeReporter(void); + virtual bool isClientConnected(void) = 0; + virtual bool startPipe(void); + virtual void stopPipe(void); + virtual UInt generateStreamId(void); + virtual bool addInitCapture(void); + virtual void removeInitCapture(void); + virtual void removeCapture(void); + virtual bool profileLoaded(void); + virtual bool profileRemoved(void); + virtual bool capture(CCTimestamp *,char const*) = 0; + virtual bool capture(CCTimestamp,char const*) = 0; + virtual bool hasPrivilege(void); + virtual bool hasPrivilegeAdministrator(task_t); + virtual bool initWithOwnerNameCapacity(IOService *,char const*,char const*,CCPipeOptions const*); + virtual OSString *getClassName(void); + virtual void setCCaptureInRegistry(void); + virtual unsigned long getPipeSize(void); + virtual void setPipeSize(unsigned long); + virtual void freeCCCaptureObject(void); + virtual void *getPipeCallbacks(void); + virtual IOService *getProvider(void); + virtual void *getCurrentOptions(void); + virtual void *getDriverOptions(void); + virtual UInt getLoggingFlags(void); + virtual unsigned long getRingEntryMaxTimeMs(void); + virtual unsigned long getRingEntrySleepTimeMs(void); + virtual CCPipeStatistics *getStatistics(void); + virtual void setStatistics(CCPipeStatistics *); + virtual void publishStatistics(void); + virtual void updateStatistics(bool); + virtual IOReturn configureAllReports(void); + virtual IOReturn updateAllReports(void); + virtual void *createReportSet(void); + +public: + uint8_t filter[0x90]; +}; + +#endif /* CCPipe_h */ diff --git a/include/Airport/CCStream.h b/include/Airport/CCStream.h new file mode 100644 index 000000000..7e5564b52 --- /dev/null +++ b/include/Airport/CCStream.h @@ -0,0 +1,40 @@ +// +// CCStream.h +// itlwm +// +// Created by qcwap on 2023/6/14. +// Copyright © 2023 钟先耀. All rights reserved. +// + +#ifndef CCStream_h +#define CCStream_h + +#include +#include "CCPipe.h" + +struct CCStreamOptions { + +}; + +class CCStream : public IOService { + OSDeclareAbstractStructors(CCStream) + +public: + virtual void free() APPLE_KEXT_OVERRIDE; + virtual IOReturn configureReport(IOReportChannelList *,UInt,void *,void *) APPLE_KEXT_OVERRIDE; + virtual IOReturn updateReport(IOReportChannelList *,UInt,void *,void *) APPLE_KEXT_OVERRIDE; + virtual bool attach( IOService * provider ) APPLE_KEXT_OVERRIDE; + virtual void detach( IOService * provider ) APPLE_KEXT_OVERRIDE; + virtual bool profileLoaded(void); + virtual bool profileRemoved(void); + virtual CCStream const *initWithPipeAndName(CCPipe *,char const*,CCStreamOptions const*); + +public: + CCPipe *getPipe() const; + +public: + uint8_t filter[0x90]; +}; + +#endif /* CCStream_h */ + diff --git a/include/Airport/IO80211Controller.h b/include/Airport/IO80211Controller.h index 83e6a5a47..0d91e7b77 100644 --- a/include/Airport/IO80211Controller.h +++ b/include/Airport/IO80211Controller.h @@ -31,6 +31,10 @@ #include "IO80211SkywalkInterface.h" #include "IO80211WorkLoop.h" #include "IO80211WorkQueue.h" +#include "CCStream.h" +#include "CCDataPipe.h" +#include "CCLogPipe.h" +#include "CCLogStream.h" #define AUTH_TIMEOUT 15 // seconds @@ -72,10 +76,6 @@ typedef enum IO80211FeatureCode IO80211FeatureCode; class IOSkywalkInterface; class IO80211ScanManager; -enum CCStreamLogLevel -{ - LEVEL_1, -}; enum scanSource { From 52f85af5bbf9c723bb152e61f2662bf1792e7863 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Wed, 14 Jun 2023 12:40:20 +0800 Subject: [PATCH 046/114] Add initial options structure. --- include/Airport/CCPipe.h | 32 ++++++++++++++++++++++++++++- include/Airport/CCStream.h | 5 ++++- include/Airport/IO80211Controller.h | 4 ++-- 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/include/Airport/CCPipe.h b/include/Airport/CCPipe.h index b8ed9c31d..6835febfb 100644 --- a/include/Airport/CCPipe.h +++ b/include/Airport/CCPipe.h @@ -12,8 +12,35 @@ #include class CCTimestamp; -class CCPipeOptions; class CCPipeStatistics; +struct CCPipeOptions { + uint64_t pipe_type; // 0x0 + uint64_t log_data_type; // 0x8 + uint64_t pipe_size; // 0x10 + uint64_t min_log_size_notify; // 0x18 + uint32_t notify_threshold; // 0x20 + char file_name[0x100]; // 0x24 + char name[0xF0]; // 0x124 + char pad8[0x10]; // 0x214 + uint32_t pad9; // 0x224 + uint32_t pad10; // 0x228 + uint64_t file_options; // 0x230 + uint64_t log_policy; // 0x238 + uint32_t pad13; + char directory_name[0x100]; // 0x244 + uint8_t pad[0xC]; +}; + +static_assert(offsetof(CCPipeOptions, pipe_size) == 0x10, "Invalid offset"); +static_assert(offsetof(CCPipeOptions, file_name) == 0x24, "Invalid offset"); +static_assert(offsetof(CCPipeOptions, name) == 0x124, "Invalid offset"); +static_assert(offsetof(CCPipeOptions, pad9) == 0x224, "Invalid offset"); +static_assert(offsetof(CCPipeOptions, pad10) == 0x228, "Invalid offset"); +static_assert(offsetof(CCPipeOptions, file_options) == 0x230, "Invalid offset"); +static_assert(offsetof(CCPipeOptions, log_policy) == 0x238, "Invalid offset"); +static_assert(offsetof(CCPipeOptions, directory_name) == 0x244, "Invalid offset"); +static_assert(sizeof(CCPipeOptions) == 0x350, "Invalid offset"); + class CCPipe : public IOService { OSDeclareAbstractStructors(CCPipe) @@ -62,6 +89,9 @@ class CCPipe : public IOService { virtual IOReturn updateAllReports(void); virtual void *createReportSet(void); +public: + static CCPipe *withOwnerNameCapacity(IOService *,char const*,char const*,CCPipeOptions const*); + public: uint8_t filter[0x90]; }; diff --git a/include/Airport/CCStream.h b/include/Airport/CCStream.h index 7e5564b52..9d4096511 100644 --- a/include/Airport/CCStream.h +++ b/include/Airport/CCStream.h @@ -13,7 +13,9 @@ #include "CCPipe.h" struct CCStreamOptions { - + uint64_t stream_type; + uint64_t console_level; + char pad[0x348]; }; class CCStream : public IOService { @@ -30,6 +32,7 @@ class CCStream : public IOService { virtual CCStream const *initWithPipeAndName(CCPipe *,char const*,CCStreamOptions const*); public: + static CCStream *withPipeAndName(CCPipe *,char const*,CCStreamOptions const*); CCPipe *getPipe() const; public: diff --git a/include/Airport/IO80211Controller.h b/include/Airport/IO80211Controller.h index 0d91e7b77..158559d4b 100644 --- a/include/Airport/IO80211Controller.h +++ b/include/Airport/IO80211Controller.h @@ -199,7 +199,7 @@ class IO80211Controller : public IOEthernetController { } virtual IO80211FlowQueueLegacy* requestFlowQueue(FlowIdMetadata const*); virtual void releaseFlowQueue(IO80211FlowQueue *); - virtual void getLogPipes(CCPipe**, CCPipe**, CCPipe**) {}; + virtual bool getLogPipes(CCPipe**, CCPipe**, CCPipe**); virtual void enableFeatureForLoggingFlags(unsigned long long) {}; virtual IOReturn requestQueueSizeAndTimeout(unsigned short *, unsigned short *) { return kIOReturnIOError; }; virtual IOReturn enablePacketTimestamping(void) { @@ -333,7 +333,7 @@ class IO80211Controller : public IOEthernetController { virtual IO80211FlowQueueLegacy* requestFlowQueue(FlowIdMetadata const*); virtual void releaseFlowQueue(IO80211FlowQueue *); #if __IO80211_TARGET >= __MAC_10_15 - virtual void getLogPipes(CCPipe**, CCPipe**, CCPipe**) {}; + virtual bool getLogPipes(CCPipe**, CCPipe**, CCPipe**); #endif virtual IOReturn enablePacketTimestamping(void) { return kIOReturnUnsupported; From 5fb350a4d0d6e5610631a663fb136854717f2ee7 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Wed, 14 Jun 2023 18:21:46 +0800 Subject: [PATCH 047/114] Add IO80211InfraProtocol. --- include/Airport/Apple80211.h | 1 + include/Airport/IO80211InfraProtocol.h | 382 +++++++++++++++++++++++++ 2 files changed, 383 insertions(+) create mode 100644 include/Airport/IO80211InfraProtocol.h diff --git a/include/Airport/Apple80211.h b/include/Airport/Apple80211.h index 0175267f4..f1671f4e7 100644 --- a/include/Airport/Apple80211.h +++ b/include/Airport/Apple80211.h @@ -24,6 +24,7 @@ #if __IO80211_TARGET >= __MAC_10_15 #include "IO80211SkywalkInterface.h" #include "IO80211InfraInterface.h" +#include "IO80211InfraProtocol.h" #endif #endif /* Apple80211_h */ diff --git a/include/Airport/IO80211InfraProtocol.h b/include/Airport/IO80211InfraProtocol.h new file mode 100644 index 000000000..f59c08aaf --- /dev/null +++ b/include/Airport/IO80211InfraProtocol.h @@ -0,0 +1,382 @@ +// +// IO80211InfraProtocol.h +// itlwm +// +// Created by qcwap on 2023/6/14. +// Copyright © 2023 钟先耀. All rights reserved. +// + +#ifndef IO80211InfraProtocol_h +#define IO80211InfraProtocol_h + +#include +#include +#include + +struct apple80211_sta_ie_data; +struct apple80211_sta_stats_data; +struct apple80211_rssi_bounds_data; +struct apple80211_rate_set_data; +struct apple80211_power_debug_info; +struct apple80211_bgscan_cached_network_data_list; +struct apple80211_private_mac_data; +struct apple80211_dbg_guard_time_params; +struct apple80211_ranging_enable_request_t; +struct apple80211_gas_result_t; +struct apple80211_ranging_start_request_t; +struct apple80211_leaky_ap_setting; +struct apple80211_rsdb_capability; +struct apple80211_tko_params; +struct apple80211_tko_dump; +struct apple80211_thermal_index_t; +struct apple80211_btcoex_max_nss_for_ap_data; +struct apple80211_btcoex_2g_chain_disable; +struct apple80211_power_budget_t; +struct apple80211_ranging_capabilities_t; +struct apple80211_suppress_scans_t; +struct apple80211_host_ap_mode_hidden_t; +struct apple80211_lqm_config_t; +struct apple80211_trap_mini_dump_data; +struct apple80211_beacon_info_t; +struct apple80211_softap_params; +struct apple80211_chip_power_limit; +struct apple80211_softap_stats; +struct apple80211_nss_data; +struct apple80211_hw_mac_address; +struct apple80211_he_mcs_index_set_data; +struct appl80211_chip_diags_data; +struct apple80211_hp2p_ctrl; +struct apple80211_assoc_ready; +struct apple80211_txrx_chain_info; +struct apple80211_mimo_status; +struct apple80211_dynsar_detail; +struct apple80211_mac_randomisation_status; +struct apple80211_colocated_network_scope_id; +struct apple80211_slow_wifi_feature_enabled; +struct apple80211_interface_cca_data; +struct apple80211_timesync_info; +struct apple80211_sensing_data_t; +struct apple80211_country_band_support; +struct apple80211_fw_hot_channels; +struct apple80211_low_latency_info; +struct apple80211_beacon_msg; +struct apple80211_wcl_traffic_counters; +struct apple80211_ssid_transition_feature_enabled; +typedef enum { + +} p2pStatusForScan; +struct apple80211ChannelInfo; +struct apple80211_p2p_steering_metrics;; +struct apple80211_rsn_xe_data; +struct apple80211_sib_coex_status; +struct apple80211_extended_bss_info; +struct apple80211_wcl_low_latency_stats; +struct apple80211_noise_per_ant_t; +struct apple80211_blocked_bands; +struct apple80211_disassoc_data; +struct apple80211_bgscan_data; +struct apple80211_sta_authorize_data; +struct apple80211_sta_disassoc_data; +struct apple80211_rsn_conf_data; +struct apple80211_country_channel_data; +struct apple80211_awdl_forced_roam_config; +struct apple80211_offload_arp_data; +struct apple80211_offload_ndp_data; +struct apple80211_offload_scan_data; +struct apple80211_gas_query_t; +struct apple80211_gas_peer_t; +struct apple80211_btcoex_profile; +struct apple80211_btcoex_profile_active_data; +struct apple80211_trap_info_data; +struct apple80211_he_capability; +struct apple80211_pmk; +struct apple80211_wow_test_data; +struct apple80211_reset_command; +struct apple80211_crash_command; +struct apple80211_ranging_authenticate_request_t; +struct apple80211_softap_csa_params; +struct apple80211_softap_wifi_network_info; +struct apple80211_scan_control_params; +struct apple80211_usb_host_notification_data; +struct apple80211_set_mac_address; +struct apple80211_abort_scan; +struct apple80211_set_property_unserialized_data; +struct apple80211_roam_cache_data; +struct apple80211_pm_mode; +struct apple80211_wifi_assertion_data; +struct apple80211_capture_debug_info_t; +struct apple80211_linkdown_debounce_status; +struct apple80211_softap_extended_capabilities_info; +struct apple80211_sensing_enable_t; +struct apple80211_sensing_disable_t; +struct apple80211_nan_link_association_info; +struct apple80211_6G_mode; +struct apple80211_leave_network; +struct apple80211_reassoc; +struct apple80211_set_roam_lock; +struct apple80211_roam_profile_config; +struct apple80211_roam_profile_configV1; +struct apple80211_user_roam_cache; +struct apple80211_set_multi_ap_env; +struct apple80211_wcl_real_time_mode; +struct apple80211_wcl_garp_mode; +struct triggerCC; +struct apple80211ScanRequest; +struct apple80211_assoc_candidates; +struct apple80211_wcl_protect_ip_mode; +struct scanHomeAndAwayTime; +struct apple80211_wcl_voluntary_network_disconnect; +struct apple80211_wcl_update_link_state; +struct apple80211_wcl_ulofdma_state; +struct apple80211_wcl_action_frame; +struct apple80211_wcl_real_time_policy; +struct apple80211_feature_flags; +struct apple80211_dhcp_renewal_data; +struct apple80211_network_flags; +struct apple80211_battery_ps_config; +struct apple80211_mimo_config; +struct apple80211_bg_motion_profile; +struct apple80211_bg_network; +struct apple80211_bg_scan; +struct apple80211_bg_params; + +class IO80211InfraProtocol : public IO80211InfraInterface { + OSDeclareAbstractStructors(IO80211InfraProtocol) + +public: + virtual IOReturn getSSID(apple80211_ssid_data *) = 0; + virtual IOReturn getAUTH_TYPE(apple80211_authtype_data *) = 0; + virtual IOReturn getCHANNEL(apple80211_channel_data *) = 0; + virtual IOReturn getPOWERSAVE(apple80211_powersave_data *) = 0; + virtual IOReturn getTXPOWER(apple80211_txpower_data *) = 0; + virtual IOReturn getRATE(apple80211_rate_data *) = 0; + virtual IOReturn getBSSID(apple80211_bssid_data *) = 0; + virtual IOReturn getSCAN_RESULT(apple80211_scan_result *) = 0; + virtual IOReturn getSTATE(apple80211_state_data *) = 0; + virtual IOReturn getPHY_MODE(apple80211_phymode_data *) = 0; + virtual IOReturn getOP_MODE(apple80211_opmode_data *) = 0; + virtual IOReturn getRSSI(apple80211_rssi_data *) = 0; + virtual IOReturn getNOISE(apple80211_noise_data *) = 0; + virtual IOReturn getSUPPORTED_CHANNELS(apple80211_sup_channel_data *) = 0; + virtual IOReturn getLOCALE(apple80211_locale_data *) = 0; + virtual IOReturn getDEAUTH(apple80211_deauth_data *) = 0; + virtual IOReturn getRATE_SET(apple80211_rate_set_data *) = 0; + virtual IOReturn getDTIM_INT(apple80211_dtim_int_data *) = 0; + virtual IOReturn getSTATION_LIST(apple80211_sta_data *) = 0; + virtual IOReturn getRSN_IE(apple80211_rsn_ie_data *) = 0; + virtual IOReturn getAP_IE_LIST(apple80211_ap_ie_data *) = 0; + virtual IOReturn getSTATS(apple80211_stats_data *) = 0; + virtual IOReturn getASSOCIATION_STATUS(apple80211_assoc_status_data *) = 0; + virtual IOReturn getGUARD_INTERVAL(apple80211_guard_interval_data *) = 0; + virtual IOReturn getMCS(apple80211_mcs_data *) = 0; + virtual IOReturn getMCS_INDEX_SET(apple80211_mcs_index_set_data *) = 0; + virtual IOReturn getWOW_PARAMETERS(apple80211_wow_parameter_data *) = 0; + virtual IOReturn getWOW_ENABLED(apple80211_state_data *) = 0; + virtual IOReturn getPID_LOCK(apple80211_state_data *) = 0; + virtual IOReturn getSTA_IE_LIST(apple80211_sta_ie_data *) = 0; + virtual IOReturn getSTA_STATS(apple80211_sta_stats_data *) = 0; + virtual IOReturn getBT_COEX_FLAGS(apple80211_state_data *) = 0; + virtual IOReturn getCURRENT_NETWORK(apple80211_scan_result *) = 0; + virtual IOReturn getRSSI_BOUNDS(apple80211_rssi_bounds_data *) = 0; + virtual IOReturn getPOWER_DEBUG_INFO(apple80211_power_debug_info *) = 0; + virtual IOReturn getHT_CAPABILITY(apple80211_ht_capability *) = 0; + virtual IOReturn getLINK_CHANGED_EVENT_DATA(apple80211_link_changed_event_data *) = 0; + virtual IOReturn getEXTENDED_STATS(apple80211_extended_stats *) = 0; + virtual IOReturn getBEACON_PERIOD(apple80211_beacon_period_data *) = 0; + virtual IOReturn getVHT_MCS_INDEX_SET(apple80211_vht_mcs_index_set_data *) = 0; + virtual IOReturn getMCS_VHT(apple80211_mcs_vht_data *) = 0; + virtual IOReturn getGAS_RESULTS(apple80211_gas_result_t *) = 0; + virtual IOReturn getCHANNELS_INFO(apple80211_channels_info *) = 0; + virtual IOReturn getVHT_CAPABILITY(apple80211_vht_capability *) = 0; + virtual IOReturn getBGSCAN_CACHE_RESULTS(apple80211_bgscan_cached_network_data_list *) = 0; + virtual IOReturn getROAM_PROFILE(apple80211_roam_profile_band_data *) = 0; + virtual IOReturn getCHIP_COUNTER_STATS(apple80211_chip_stats *) = 0; + virtual IOReturn getDBG_GUARD_TIME_PARAMS(apple80211_dbg_guard_time_params *) = 0; + virtual IOReturn getLEAKY_AP_STATS_MODE(apple80211_leaky_ap_setting *) = 0; + virtual IOReturn getCOUNTRY_CHANNELS(apple80211_country_channel_data *) = 0; + virtual IOReturn getPRIVATE_MAC(apple80211_private_mac_data *) = 0; + virtual IOReturn getRANGING_ENABLE(apple80211_ranging_enable_request_t *) = 0; + virtual IOReturn getRANGING_START(apple80211_ranging_start_request_t *) = 0; + virtual IOReturn getAWDL_RSDB_CAPS(apple80211_rsdb_capability *) = 0; + virtual IOReturn getTKO_PARAMS(apple80211_tko_params *) = 0; + virtual IOReturn getTKO_DUMP(apple80211_tko_dump *) = 0; + virtual IOReturn getHW_SUPPORTED_CHANNELS(apple80211_sup_channel_data *) = 0; + virtual IOReturn getBTCOEX_PROFILE(apple80211_btcoex_profile *) = 0; + virtual IOReturn getBTCOEX_PROFILE_ACTIVE(apple80211_btcoex_profile_active_data *) = 0; + virtual IOReturn getTRAP_INFO(apple80211_trap_info_data *) = 0; + virtual IOReturn getTHERMAL_INDEX(apple80211_thermal_index_t *) = 0; + virtual IOReturn getMAX_NSS_FOR_AP(apple80211_btcoex_max_nss_for_ap_data *) = 0; + virtual IOReturn getBTCOEX_2G_CHAIN_DISABLE(apple80211_btcoex_2g_chain_disable *) = 0; + virtual IOReturn getPOWER_BUDGET(apple80211_power_budget_t *) = 0; + virtual IOReturn getRANGING_CAPS(apple80211_ranging_capabilities_t *) = 0; + virtual IOReturn getSUPPRESS_SCANS(apple80211_suppress_scans_t *) = 0; + virtual IOReturn getHOST_AP_MODE_HIDDEN(apple80211_host_ap_mode_hidden_t *) = 0; + virtual IOReturn getLQM_CONFIG(apple80211_lqm_config_t *) = 0; + virtual IOReturn getTRAP_CRASHTRACER_MINI_DUMP(apple80211_trap_mini_dump_data *) = 0; + virtual IOReturn getHE_CAPABILITY(apple80211_he_capability *) = 0; + virtual IOReturn getBEACON_INFO(apple80211_beacon_info_t *) = 0; + virtual IOReturn getSOFTAP_PARAMS(apple80211_softap_params *) = 0; + virtual IOReturn getCHIP_POWER_RANGE(apple80211_chip_power_limit *) = 0; + virtual IOReturn getSOFTAP_STATS(apple80211_softap_stats *) = 0; + virtual IOReturn getNSS(apple80211_nss_data *) = 0; + virtual IOReturn getHW_ADDR(apple80211_hw_mac_address *) = 0; + virtual IOReturn getHE_MCS_INDEX_SET(apple80211_he_mcs_index_set_data *) = 0; + virtual IOReturn getCHIP_DIAGS(appl80211_chip_diags_data *) = 0; + virtual IOReturn getHP2P_CTRL(apple80211_hp2p_ctrl *) = 0; + virtual IOReturn getREQUEST_BSS_BLACKLIST(void *) = 0; + virtual IOReturn getASSOC_READY_STATUS(apple80211_assoc_ready *) = 0; + virtual IOReturn getTXRX_CHAIN_INFO(apple80211_txrx_chain_info *) = 0; + virtual IOReturn getMIMO_STATUS(apple80211_mimo_status *) = 0; + virtual IOReturn getCUR_PMK(apple80211_pmk *) = 0; + virtual IOReturn getDYNSAR_DETAIL(apple80211_dynsar_detail *) = 0; + virtual IOReturn getRANDOMISATION_STATUS(apple80211_mac_randomisation_status *) = 0; + virtual IOReturn getCOUNTRY_CHANNELS_INFO(apple80211_channels_info *) = 0; + virtual IOReturn getLQM_SUMMARY(apple80211_lqm_summary *) = 0; + virtual IOReturn getCOLOCATED_NETWORK_SCOPE_ID(apple80211_colocated_network_scope_id *) = 0; + virtual IOReturn getBEACON_SCAN_CACHE_REQ(apple80211_scan_result *) = 0; + virtual IOReturn getSLOW_WIFI_FEATURE_ENABLED(apple80211_slow_wifi_feature_enabled *) = 0; + virtual IOReturn getCCA(apple80211_interface_cca_data *) = 0; + virtual IOReturn getRX_RATE(apple80211_rate_data *) = 0; + virtual IOReturn getTIMESYNC_INFO(apple80211_timesync_info *) = 0; + virtual IOReturn getSENSING_DATA(apple80211_sensing_data_t *) = 0; + virtual IOReturn getCOUNTRY_BAND_SUPPORT(apple80211_country_band_support *) = 0; + virtual IOReturn getWCL_FW_HOT_CHANNELS(apple80211_fw_hot_channels *) = 0; + virtual IOReturn getWCL_LOW_LATENCY_INFO(apple80211_low_latency_info *) = 0; + virtual IOReturn getWCL_BSS_INFO(apple80211_beacon_msg *) = 0; + virtual IOReturn getWCL_TRAFFIC_COUNTERS(apple80211_wcl_traffic_counters *) = 0; + virtual IOReturn getWCL_GET_TX_BLANKING_STATUS(uint *) = 0; + virtual IOReturn getSSID_TRANSITION_SUPPORT(apple80211_ssid_transition_feature_enabled *) = 0; + virtual IOReturn getWCL_VALID_CHANNEL_COUNT(unsigned long *) = 0; + virtual IOReturn getWCL_P2P_STATUS_FOR_SCAN(p2pStatusForScan *) = 0; + virtual IOReturn getWCL_CHANNELS_INFO(apple80211ChannelInfo *) = 0; + virtual IOReturn getP2P_STEERING_METRIC(apple80211_p2p_steering_metrics *) = 0; + virtual IOReturn getRSN_XE(apple80211_rsn_xe_data *) = 0; + virtual IOReturn getSIB_COEX_STATUS(apple80211_sib_coex_status *) = 0; + virtual IOReturn getWCL_EXTENDED_BSS_INFO(apple80211_extended_bss_info *) = 0; + virtual IOReturn getWCL_LOW_LATENCY_INFO_STATS(apple80211_wcl_low_latency_stats *) = 0; + virtual IOReturn getWCL_BGSCAN_CACHE_RESULT(apple80211_bgscan_cached_network_data_list *) = 0; + virtual IOReturn getWIFI_NOISE_PER_ANT(apple80211_noise_per_ant_t *) = 0; + virtual IOReturn getBLOCKED_BANDS(apple80211_blocked_bands *) = 0; + virtual IOReturn setSSID(apple80211_ssid_data *) = 0; + virtual IOReturn setAUTH_TYPE(apple80211_authtype_data *) = 0; + virtual IOReturn setCIPHER_KEY(apple80211_key *) = 0; + virtual IOReturn setCHANNEL(apple80211_channel_data *) = 0; + virtual IOReturn setPOWERSAVE(apple80211_powersave_data *) = 0; + virtual IOReturn setTXPOWER(apple80211_txpower_data *) = 0; + virtual IOReturn setRATE(apple80211_rate_data *) = 0; + virtual IOReturn setSCAN_REQ(apple80211_scan_data *) = 0; + virtual IOReturn setASSOCIATE(apple80211_assoc_data *) = 0; + virtual IOReturn setDISASSOCIATE(apple80211_disassoc_data *) = 0; + virtual IOReturn setIBSS_MODE(apple80211_network_data *) = 0; + virtual IOReturn setHOST_AP_MODE(apple80211_network_data *) = 0; + virtual IOReturn setAP_MODE(apple80211_apmode_data *) = 0; + virtual IOReturn setDEAUTH(apple80211_deauth_data *) = 0; + virtual IOReturn setTX_ANTENNA(void *) = 0; + virtual IOReturn setANTENNA_DIVERSITY(void *) = 0; + virtual IOReturn setRSN_IE(apple80211_rsn_ie_data *) = 0; + virtual IOReturn setBACKGROUND_SCAN(apple80211_bgscan_data *) = 0; + virtual IOReturn setWOW_PARAMETERS(apple80211_wow_parameter_data *) = 0; + virtual IOReturn setWOW_ENABLED(apple80211_state_data *) = 0; + virtual IOReturn setPID_LOCK(apple80211_state_data *) = 0; + virtual IOReturn setSTA_AUTHORIZE(apple80211_sta_authorize_data *) = 0; + virtual IOReturn setSTA_DISASSOCIATE(apple80211_sta_disassoc_data *) = 0; + virtual IOReturn setSTA_DEAUTH(apple80211_sta_disassoc_data *) = 0; + virtual IOReturn setRSN_CONF(apple80211_rsn_conf_data *) = 0; + virtual IOReturn setIE(apple80211_ie_data *) = 0; + virtual IOReturn setWOW_TEST(apple80211_wow_test_data *) = 0; + virtual IOReturn setSCANCACHE_CLEAR(void *) = 0; + virtual IOReturn setVIRTUAL_IF_CREATE(apple80211_virt_if_create_data *) = 0; + virtual IOReturn setBT_COEX_FLAGS(apple80211_state_data *) = 0; + virtual IOReturn setROAM(apple80211_sta_roam_data *) = 0; + virtual IOReturn setHT_CAPABILITY(apple80211_ht_capability *) = 0; + virtual IOReturn setAWDL_FORCED_ROAM_CONFIG(apple80211_awdl_forced_roam_config *) = 0; + virtual IOReturn setOFFLOAD_ARP(apple80211_offload_arp_data *) = 0; + virtual IOReturn setOFFLOAD_NDP(apple80211_offload_ndp_data *) = 0; + virtual IOReturn setOFFLOAD_SCAN(apple80211_offload_scan_data *) = 0; + virtual IOReturn setGAS_REQ(apple80211_gas_query_t *) = 0; + virtual IOReturn setGAS_START(apple80211_gas_query_t *) = 0; + virtual IOReturn setGAS_SET_PEER(apple80211_gas_peer_t *) = 0; + virtual IOReturn setVHT_CAPABILITY(apple80211_vht_capability *) = 0; + virtual IOReturn setROAM_PROFILE(apple80211_roam_profile_band_data *) = 0; + virtual IOReturn setAWDL_ENABLE_ROAMING(void *) = 0; + virtual IOReturn setDBG_GUARD_TIME_PARAMS(apple80211_dbg_guard_time_params *) = 0; + virtual IOReturn setLEAKY_AP_STATS_MODE(apple80211_leaky_ap_setting *) = 0; + virtual IOReturn setPRIVATE_MAC(apple80211_private_mac_data *) = 0; + virtual IOReturn setRESET_CHIP(apple80211_reset_command *) = 0; + virtual IOReturn setCRASH(apple80211_crash_command *) = 0; + virtual IOReturn setRANGING_ENABLE(apple80211_ranging_enable_request_t *) = 0; + virtual IOReturn setRANGING_START(apple80211_ranging_start_request_t *) = 0; + virtual IOReturn setRANGING_AUTHENTICATE(apple80211_ranging_authenticate_request_t *) = 0; + virtual IOReturn setTKO_PARAMS(apple80211_tko_params *) = 0; + virtual IOReturn setBTCOEX_PROFILE(apple80211_btcoex_profile *) = 0; + virtual IOReturn setBTCOEX_PROFILE_ACTIVE(apple80211_btcoex_profile_active_data *) = 0; + virtual IOReturn setTHERMAL_INDEX(apple80211_thermal_index_t *) = 0; + virtual IOReturn setBTCOEX_2G_CHAIN_DISABLE(apple80211_btcoex_2g_chain_disable *) = 0; + virtual IOReturn setPOWER_BUDGET(apple80211_power_budget_t *) = 0; + virtual IOReturn setSUPPRESS_SCANS(apple80211_suppress_scans_t *) = 0; + virtual IOReturn setHOST_AP_MODE_HIDDEN(apple80211_host_ap_mode_hidden_t *) = 0; + virtual IOReturn setLQM_CONFIG(apple80211_lqm_config_t *) = 0; + virtual IOReturn setSOFTAP_PARAMS(apple80211_softap_params *) = 0; + virtual IOReturn setSOFTAP_TRIGGER_CSA(apple80211_softap_csa_params *) = 0; + virtual IOReturn setSOFTAP_WIFI_NETWORK_INFO_IE(apple80211_softap_wifi_network_info *) = 0; + virtual IOReturn setBTCOEX_DISABLE_ULOFDMA(uint *) = 0; + virtual IOReturn setSCAN_CONTROL(apple80211_scan_control_params *) = 0; + virtual IOReturn setUSB_HOST_NOTIFICATION(apple80211_usb_host_notification_data *) = 0; + virtual IOReturn setSET_MAC_ADDRESS(apple80211_set_mac_address *) = 0; + virtual IOReturn setHP2P_CTRL(apple80211_hp2p_ctrl *) = 0; + virtual IOReturn setABORT_SCAN(apple80211_abort_scan *) = 0; + virtual IOReturn setSET_PROPERTY(apple80211_set_property_unserialized_data *) = 0; + virtual IOReturn setROAM_CACHE_UPDATE(apple80211_roam_cache_data *) = 0; + virtual IOReturn setPM_MODE(apple80211_pm_mode *) = 0; + virtual IOReturn setSET_WIFI_ASSERTION_STATE(apple80211_wifi_assertion_data *) = 0; + virtual IOReturn setREASSOCIATE_WITH_CORECAPTURE(apple80211_capture_debug_info_t *) = 0; + virtual IOReturn setLINKDOWN_DEBOUNCE_STATUS(apple80211_linkdown_debounce_status *) = 0; + virtual IOReturn setSOFTAP_EXTENDED_CAPABILITIES_IE(apple80211_softap_extended_capabilities_info *) = 0; + virtual IOReturn setREALTIME_QOS_MSCS(apple80211_state_data *) = 0; + virtual IOReturn setSENSING_ENABLE(apple80211_sensing_enable_t *) = 0; + virtual IOReturn setSENSING_DISABLE(apple80211_sensing_disable_t *) = 0; + virtual IOReturn setNANPHS_ASSOCIATION(apple80211_nan_link_association_info *) = 0; + virtual IOReturn setNANPHS_TERMINATED(apple80211_nan_link_association_info *) = 0; + virtual IOReturn set6G_MODE(apple80211_6G_mode *) = 0; + virtual IOReturn setWCL_LEAVE_NETWORK(apple80211_leave_network *) = 0; + virtual IOReturn setWCL_REASSOC(apple80211_reassoc *) = 0; + virtual IOReturn setWCL_SET_ROAM_LOCK(apple80211_set_roam_lock *) = 0; + virtual IOReturn setWCL_ROAM_PROFILE_CONFIG(apple80211_roam_profile_config *) = 0; + virtual IOReturn setWCL_ROAM_PROFILE_CONFIGV1(apple80211_roam_profile_configV1 *) = 0; + virtual IOReturn setWCL_ROAM_USER_CACHE(apple80211_user_roam_cache *) = 0; + virtual IOReturn setWCL_SET_MULTI_AP_ENV(apple80211_set_multi_ap_env *) = 0; + virtual IOReturn setWCL_SCAN_ABORT(void *) = 0; + virtual IOReturn setWCL_REAL_TIME_MODE(apple80211_wcl_real_time_mode *) = 0; + virtual IOReturn setWCL_GARP_MODE(apple80211_wcl_garp_mode *) = 0; + virtual IOReturn setWCL_JOIN_ABORT(void *) = 0; + virtual IOReturn setWCL_TRIGGER_CC(triggerCC *) = 0; + virtual IOReturn setWCL_SCAN_REQ(apple80211ScanRequest *) = 0; + virtual IOReturn setWCL_ASSOCIATE(apple80211_assoc_candidates *) = 0; + virtual IOReturn setWCL_PROTECT_IP(apple80211_wcl_protect_ip_mode *) = 0; + virtual IOReturn setWCL_LINK_UP_DONE(void *) = 0; + virtual IOReturn setWCL_SET_SCAN_HOME_AWAY_TIME(scanHomeAndAwayTime *) = 0; + virtual IOReturn setWCL_VOLUNTARY_NETWORK_DISCONNECT(apple80211_wcl_voluntary_network_disconnect *) = 0; + virtual IOReturn setWCL_LINK_STATE_UPDATE(apple80211_wcl_update_link_state *) = 0; + virtual IOReturn setSLOW_WIFI_RECOVERY(void *) = 0; + virtual IOReturn setRSN_XE(apple80211_rsn_xe_data *) = 0; + virtual IOReturn setWCL_ULOFDMA_STATE(apple80211_wcl_ulofdma_state *) = 0; + virtual IOReturn setWCL_ACTION_FRAME(apple80211_wcl_action_frame *) = 0; + virtual IOReturn setWCL_REAL_TIME_POLICY(apple80211_wcl_real_time_policy *) = 0; + virtual IOReturn setGAS_ABORT(void *) = 0; + virtual IOReturn setOS_FEATURE_FLAGS(apple80211_feature_flags *) = 0; + virtual IOReturn setDHCP_RENEWAL_DATA(apple80211_dhcp_renewal_data *) = 0; + virtual IOReturn setMOVING_NETWORK(apple80211_network_flags *) = 0; + virtual IOReturn setBATTERY_POWERSAVE_CONFIG(apple80211_battery_ps_config *) = 0; + virtual IOReturn setMIMO_CONFIG(apple80211_mimo_config *) = 0; + virtual IOReturn setWCL_CONFIG_BG_MOTIONPROFILE(apple80211_bg_motion_profile *) = 0; + virtual IOReturn setWCL_CONFIG_BG_NETWORK(apple80211_bg_network *) = 0; + virtual IOReturn setWCL_CONFIG_BGSCAN(apple80211_bg_scan *) = 0; + virtual IOReturn setWCL_CONFIG_BG_PARAMS(apple80211_bg_params *) = 0; + virtual IOReturn setBLOCKED_BANDS(apple80211_blocked_bands *) = 0; + +public: + uint8_t filter[0x120]; +}; + +#endif /* IO80211InfraProtocol_h */ + From d663e656113b9c2ea4ee6b1739eff79d711e4bd0 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Tue, 20 Jun 2023 19:25:05 +0800 Subject: [PATCH 048/114] Add IOSkywalkLegacyEthernetInterface, IOSkywalkPacketBufferPool --- include/Airport/Apple80211.h | 4 ++ .../IOSkywalkLegacyEthernetInterface.h | 37 +++++++++++ include/Airport/IOSkywalkPacketBufferPool.h | 62 +++++++++++++++++++ include/Airport/apple80211_ioctl.h | 2 +- include/Airport/apple80211_var.h | 10 +-- 5 files changed, 109 insertions(+), 6 deletions(-) create mode 100644 include/Airport/IOSkywalkLegacyEthernetInterface.h create mode 100644 include/Airport/IOSkywalkPacketBufferPool.h diff --git a/include/Airport/Apple80211.h b/include/Airport/Apple80211.h index f1671f4e7..0e4f3c9d7 100644 --- a/include/Airport/Apple80211.h +++ b/include/Airport/Apple80211.h @@ -23,8 +23,12 @@ #include "IO80211P2PInterface.h" #if __IO80211_TARGET >= __MAC_10_15 #include "IO80211SkywalkInterface.h" +#endif +#if __IO80211_TARGET >= __MAC_14_0 #include "IO80211InfraInterface.h" #include "IO80211InfraProtocol.h" +#include "IOSkywalkPacketBufferPool.h" +#include "IOSkywalkLegacyEthernetInterface.h" #endif #endif /* Apple80211_h */ diff --git a/include/Airport/IOSkywalkLegacyEthernetInterface.h b/include/Airport/IOSkywalkLegacyEthernetInterface.h new file mode 100644 index 000000000..4b4be4644 --- /dev/null +++ b/include/Airport/IOSkywalkLegacyEthernetInterface.h @@ -0,0 +1,37 @@ +// +// IOSkywalkLegacyEthernetInterface.h +// itlwm +// +// Created by qcwap on 2023/6/19. +// Copyright © 2023 钟先耀. All rights reserved. +// + +#ifndef IOSkywalkLegacyEthernetInterface_h +#define IOSkywalkLegacyEthernetInterface_h + +#include + +class IOSkywalkLegacyEthernetInterface : public IOEthernetInterface { + OSDeclareDefaultStructors(IOSkywalkLegacyEthernetInterface) + +public: + virtual void free() APPLE_KEXT_OVERRIDE; + virtual OSObject * getProperty( const OSSymbol * aKey) const APPLE_KEXT_OVERRIDE; + virtual OSObject * copyProperty( const OSSymbol * aKey) const APPLE_KEXT_OVERRIDE; + virtual bool serializeProperties( OSSerialize * serialize ) const APPLE_KEXT_OVERRIDE; + virtual IOReturn setProperties( OSObject * properties ) APPLE_KEXT_OVERRIDE; + virtual bool init( IONetworkController * controller ) APPLE_KEXT_OVERRIDE; + virtual const char * getNamePrefix() const APPLE_KEXT_OVERRIDE; + virtual bool controllerDidOpen(IONetworkController * controller) APPLE_KEXT_OVERRIDE; + virtual void controllerWillClose(IONetworkController * controller) APPLE_KEXT_OVERRIDE; + virtual ifnet_t getIfnet( void ) const APPLE_KEXT_OVERRIDE; + virtual IOReturn attachToDataLinkLayer( IOOptionBits options, void * parameter ) APPLE_KEXT_OVERRIDE; + virtual void detachFromDataLinkLayer( IOOptionBits options, + void * parameter ) APPLE_KEXT_OVERRIDE; + +public: + uint8_t filter[0x160]; +}; + +#endif /* IOSkywalkLegacyEthernetInterface_h */ + diff --git a/include/Airport/IOSkywalkPacketBufferPool.h b/include/Airport/IOSkywalkPacketBufferPool.h new file mode 100644 index 000000000..c196a1933 --- /dev/null +++ b/include/Airport/IOSkywalkPacketBufferPool.h @@ -0,0 +1,62 @@ +// +// IOSkywalkPacketBufferPool.h +// itlwm +// +// Created by qcwap on 2023/6/15. +// Copyright © 2023 钟先耀. All rights reserved. +// + +#ifndef IOSkywalkPacketBufferPool_h +#define IOSkywalkPacketBufferPool_h + +#include + +class IOSkywalkMemorySegment; +class IOSkywalkMemorySegmentDescriptor; +class IOSkywalkPacket; +class IOSkywalkPacketBuffer; +class IOSkywalkPacketDescriptor; +class IOSkywalkPacketBufferDescriptor; + +class IOSkywalkPacketBufferPool : public OSObject { + OSDeclareDefaultStructors(IOSkywalkPacketBufferPool) + +public: + struct PoolOptions { + uint32_t packetCount; + uint32_t bufferCount; + uint32_t bufferSize; + uint32_t maxBuffersPerPacket; + uint32_t memorySegmentSize; + uint32_t poolFlags; + uint64_t pad; + }; + +public: + virtual void free() APPLE_KEXT_OVERRIDE; + virtual bool initWithName(char const*,void *,uint,IOSkywalkPacketBufferPool::PoolOptions const*); + virtual bool initWithName(char const*,OSObject *,uint,IOSkywalkPacketBufferPool::PoolOptions const*); + virtual bool allocatePacket(IOSkywalkPacket **,uint); + virtual bool allocatePacket(uint,IOSkywalkPacket **,uint); + virtual bool allocatePackets(uint,uint *,IOSkywalkPacket **,uint); + virtual void deallocatePacket(IOSkywalkPacket *); + virtual void deallocatePackets(IOSkywalkPacket **,uint); + virtual void deallocatePacketList(IOSkywalkPacket *); + virtual void deallocatePacketChain(unsigned long long); + virtual bool allocatePacketBuffer(IOSkywalkPacketBuffer **,uint); + virtual bool allocatePacketBuffers(uint *,IOSkywalkPacketBuffer **,uint); + virtual void deallocatePacketBuffer(IOSkywalkPacketBuffer *); + virtual void deallocatePacketBuffers(IOSkywalkPacketBuffer **,uint); + virtual bool newPacket(IOSkywalkPacketDescriptor *,IOSkywalkPacket **); + virtual bool newPacketBuffer(IOSkywalkPacketBufferDescriptor *,IOSkywalkPacketBuffer **); + virtual bool newMemorySegment(IOSkywalkMemorySegmentDescriptor *,IOSkywalkMemorySegment **); + +public: + static IOSkywalkPacketBufferPool *withName(char const*,OSObject *,uint,IOSkywalkPacketBufferPool::PoolOptions const*); + +public: + uint8_t filter[0xB8]; +}; + +#endif /* IOSkywalkPacketBufferPool_h */ + diff --git a/include/Airport/apple80211_ioctl.h b/include/Airport/apple80211_ioctl.h index ce0533834..c63da5bd3 100644 --- a/include/Airport/apple80211_ioctl.h +++ b/include/Airport/apple80211_ioctl.h @@ -433,7 +433,7 @@ struct apple80211_bssid_data struct apple80211_capability_data { u_int32_t version; - u_int8_t capabilities[11]; + u_int8_t capabilities[14]; }; struct apple80211_state_data diff --git a/include/Airport/apple80211_var.h b/include/Airport/apple80211_var.h index ad76387f4..9e9ecad43 100644 --- a/include/Airport/apple80211_var.h +++ b/include/Airport/apple80211_var.h @@ -486,13 +486,13 @@ struct apple80211_scan_result uint8_t unk2; u_int32_t asr_age; // (ms) non-zero for cached scan result // 0x84 - u_int16_t unk3; - int16_t asr_ie_len; + u_int16_t unk3; // 0x88 + int16_t asr_ie_len; // 0x8A #if __IO80211_TARGET < __MAC_12_0 - uint32_t asr_unk3; - void* asr_ie_data; + uint32_t asr_unk3; // 0x8C + void* asr_ie_data; // 90 #else - uint8_t asr_ie_data[1024]; + uint8_t asr_ie_data[1024]; // 0x8C #endif } __attribute__((packed)); From bbab8926f8020e06a91f4c379373215d440ed710 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Sun, 25 Jun 2023 18:08:32 +0800 Subject: [PATCH 049/114] Update apple80211_colocated_network_scope_id. --- include/Airport/IO80211InfraProtocol.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/include/Airport/IO80211InfraProtocol.h b/include/Airport/IO80211InfraProtocol.h index f59c08aaf..ee896b2af 100644 --- a/include/Airport/IO80211InfraProtocol.h +++ b/include/Airport/IO80211InfraProtocol.h @@ -51,7 +51,12 @@ struct apple80211_txrx_chain_info; struct apple80211_mimo_status; struct apple80211_dynsar_detail; struct apple80211_mac_randomisation_status; -struct apple80211_colocated_network_scope_id; +struct apple80211_colocated_network_scope_id +{ + uint32_t version; + uint32_t id1; + uint32_t id2; +}; struct apple80211_slow_wifi_feature_enabled; struct apple80211_interface_cca_data; struct apple80211_timesync_info; From 6725b2efd27bdcb9671fa4a347911725fd56b24b Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Mon, 26 Jun 2023 15:56:21 +0800 Subject: [PATCH 050/114] Keep apple80211_country_code_data. --- include/Airport/apple80211_ioctl.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/Airport/apple80211_ioctl.h b/include/Airport/apple80211_ioctl.h index c63da5bd3..b4912731b 100644 --- a/include/Airport/apple80211_ioctl.h +++ b/include/Airport/apple80211_ioctl.h @@ -738,11 +738,20 @@ struct apple80211_stats_data u_int32_t rx_errors; }; +#if __IO80211_TARGET >= __MAC_14_0 +struct apple80211_country_code_data +{ + u_int32_t version; + uint16_t cc; + uint8_t len; +}; +#else struct apple80211_country_code_data { u_int32_t version; u_int8_t cc[APPLE80211_MAX_CC_LEN]; }; +#endif struct apple80211_last_rx_pkt_data { From 820c50d92a1b25cf17fdbee52b898e3594d4b253 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Mon, 26 Jun 2023 15:56:52 +0800 Subject: [PATCH 051/114] Revert getLogPipes placeholder implementation. --- include/Airport/IO80211Controller.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Airport/IO80211Controller.h b/include/Airport/IO80211Controller.h index 158559d4b..7cd8144a7 100644 --- a/include/Airport/IO80211Controller.h +++ b/include/Airport/IO80211Controller.h @@ -333,7 +333,7 @@ class IO80211Controller : public IOEthernetController { virtual IO80211FlowQueueLegacy* requestFlowQueue(FlowIdMetadata const*); virtual void releaseFlowQueue(IO80211FlowQueue *); #if __IO80211_TARGET >= __MAC_10_15 - virtual bool getLogPipes(CCPipe**, CCPipe**, CCPipe**); + virtual void getLogPipes(CCPipe**, CCPipe**, CCPipe**) {}; #endif virtual IOReturn enablePacketTimestamping(void) { return kIOReturnUnsupported; From ddaf311b92ebdb02a005c2c453b3d4b7bf720bfc Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Mon, 26 Jun 2023 16:05:22 +0800 Subject: [PATCH 052/114] Add build to project. --- itlwm.xcodeproj/project.pbxproj | 510 ++++++++++++++++++ .../xcschemes/AirportItlwm (all).xcscheme | 14 + 2 files changed, 524 insertions(+) diff --git a/itlwm.xcodeproj/project.pbxproj b/itlwm.xcodeproj/project.pbxproj index ab4856f24..749349497 100644 --- a/itlwm.xcodeproj/project.pbxproj +++ b/itlwm.xcodeproj/project.pbxproj @@ -332,6 +332,90 @@ F837C9202724577F00B2C499 /* coex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F837C91C2724577F00B2C499 /* coex.cpp */; }; F837C9212724577F00B2C499 /* coex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F837C91C2724577F00B2C499 /* coex.cpp */; }; F837C9222724577F00B2C499 /* coex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F837C91C2724577F00B2C499 /* coex.cpp */; }; + F84AD8862A497DB200DC8DED /* IO80211WorkQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87A2A497DB200DC8DED /* IO80211WorkQueue.h */; }; + F84AD8872A497DB200DC8DED /* IO80211WorkQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87A2A497DB200DC8DED /* IO80211WorkQueue.h */; }; + F84AD8882A497DB200DC8DED /* IO80211WorkQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87A2A497DB200DC8DED /* IO80211WorkQueue.h */; }; + F84AD8892A497DB200DC8DED /* IO80211WorkQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87A2A497DB200DC8DED /* IO80211WorkQueue.h */; }; + F84AD88A2A497DB200DC8DED /* IO80211WorkQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87A2A497DB200DC8DED /* IO80211WorkQueue.h */; }; + F84AD88B2A497DB200DC8DED /* IO80211WorkQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87A2A497DB200DC8DED /* IO80211WorkQueue.h */; }; + F84AD88C2A497DB200DC8DED /* IO80211WorkQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87A2A497DB200DC8DED /* IO80211WorkQueue.h */; }; + F84AD88D2A497DB200DC8DED /* IOSkywalkNetworkPacket.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87B2A497DB200DC8DED /* IOSkywalkNetworkPacket.h */; }; + F84AD88E2A497DB200DC8DED /* IOSkywalkNetworkPacket.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87B2A497DB200DC8DED /* IOSkywalkNetworkPacket.h */; }; + F84AD88F2A497DB200DC8DED /* IOSkywalkNetworkPacket.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87B2A497DB200DC8DED /* IOSkywalkNetworkPacket.h */; }; + F84AD8902A497DB200DC8DED /* IOSkywalkNetworkPacket.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87B2A497DB200DC8DED /* IOSkywalkNetworkPacket.h */; }; + F84AD8912A497DB200DC8DED /* IOSkywalkNetworkPacket.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87B2A497DB200DC8DED /* IOSkywalkNetworkPacket.h */; }; + F84AD8922A497DB200DC8DED /* IOSkywalkNetworkPacket.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87B2A497DB200DC8DED /* IOSkywalkNetworkPacket.h */; }; + F84AD8932A497DB200DC8DED /* IOSkywalkNetworkPacket.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87B2A497DB200DC8DED /* IOSkywalkNetworkPacket.h */; }; + F84AD8942A497DB200DC8DED /* IO80211InfraProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87C2A497DB200DC8DED /* IO80211InfraProtocol.h */; }; + F84AD8952A497DB200DC8DED /* IO80211InfraProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87C2A497DB200DC8DED /* IO80211InfraProtocol.h */; }; + F84AD8962A497DB200DC8DED /* IO80211InfraProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87C2A497DB200DC8DED /* IO80211InfraProtocol.h */; }; + F84AD8972A497DB200DC8DED /* IO80211InfraProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87C2A497DB200DC8DED /* IO80211InfraProtocol.h */; }; + F84AD8982A497DB200DC8DED /* IO80211InfraProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87C2A497DB200DC8DED /* IO80211InfraProtocol.h */; }; + F84AD8992A497DB200DC8DED /* IO80211InfraProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87C2A497DB200DC8DED /* IO80211InfraProtocol.h */; }; + F84AD89A2A497DB200DC8DED /* IO80211InfraProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87C2A497DB200DC8DED /* IO80211InfraProtocol.h */; }; + F84AD89B2A497DB200DC8DED /* CCPipe.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87D2A497DB200DC8DED /* CCPipe.h */; }; + F84AD89C2A497DB200DC8DED /* CCPipe.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87D2A497DB200DC8DED /* CCPipe.h */; }; + F84AD89D2A497DB200DC8DED /* CCPipe.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87D2A497DB200DC8DED /* CCPipe.h */; }; + F84AD89E2A497DB200DC8DED /* CCPipe.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87D2A497DB200DC8DED /* CCPipe.h */; }; + F84AD89F2A497DB200DC8DED /* CCPipe.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87D2A497DB200DC8DED /* CCPipe.h */; }; + F84AD8A02A497DB200DC8DED /* CCPipe.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87D2A497DB200DC8DED /* CCPipe.h */; }; + F84AD8A12A497DB200DC8DED /* CCPipe.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87D2A497DB200DC8DED /* CCPipe.h */; }; + F84AD8A22A497DB200DC8DED /* IOSkywalkLogicalLink.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87E2A497DB200DC8DED /* IOSkywalkLogicalLink.h */; }; + F84AD8A32A497DB200DC8DED /* IOSkywalkLogicalLink.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87E2A497DB200DC8DED /* IOSkywalkLogicalLink.h */; }; + F84AD8A42A497DB200DC8DED /* IOSkywalkLogicalLink.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87E2A497DB200DC8DED /* IOSkywalkLogicalLink.h */; }; + F84AD8A52A497DB200DC8DED /* IOSkywalkLogicalLink.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87E2A497DB200DC8DED /* IOSkywalkLogicalLink.h */; }; + F84AD8A62A497DB200DC8DED /* IOSkywalkLogicalLink.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87E2A497DB200DC8DED /* IOSkywalkLogicalLink.h */; }; + F84AD8A72A497DB200DC8DED /* IOSkywalkLogicalLink.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87E2A497DB200DC8DED /* IOSkywalkLogicalLink.h */; }; + F84AD8A82A497DB200DC8DED /* IOSkywalkLogicalLink.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87E2A497DB200DC8DED /* IOSkywalkLogicalLink.h */; }; + F84AD8A92A497DB200DC8DED /* IO80211InfraInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87F2A497DB200DC8DED /* IO80211InfraInterface.h */; }; + F84AD8AA2A497DB200DC8DED /* IO80211InfraInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87F2A497DB200DC8DED /* IO80211InfraInterface.h */; }; + F84AD8AB2A497DB200DC8DED /* IO80211InfraInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87F2A497DB200DC8DED /* IO80211InfraInterface.h */; }; + F84AD8AC2A497DB200DC8DED /* IO80211InfraInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87F2A497DB200DC8DED /* IO80211InfraInterface.h */; }; + F84AD8AD2A497DB200DC8DED /* IO80211InfraInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87F2A497DB200DC8DED /* IO80211InfraInterface.h */; }; + F84AD8AE2A497DB200DC8DED /* IO80211InfraInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87F2A497DB200DC8DED /* IO80211InfraInterface.h */; }; + F84AD8AF2A497DB200DC8DED /* IO80211InfraInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87F2A497DB200DC8DED /* IO80211InfraInterface.h */; }; + F84AD8B02A497DB200DC8DED /* CCStream.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8802A497DB200DC8DED /* CCStream.h */; }; + F84AD8B12A497DB200DC8DED /* CCStream.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8802A497DB200DC8DED /* CCStream.h */; }; + F84AD8B22A497DB200DC8DED /* CCStream.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8802A497DB200DC8DED /* CCStream.h */; }; + F84AD8B32A497DB200DC8DED /* CCStream.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8802A497DB200DC8DED /* CCStream.h */; }; + F84AD8B42A497DB200DC8DED /* CCStream.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8802A497DB200DC8DED /* CCStream.h */; }; + F84AD8B52A497DB200DC8DED /* CCStream.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8802A497DB200DC8DED /* CCStream.h */; }; + F84AD8B62A497DB200DC8DED /* CCStream.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8802A497DB200DC8DED /* CCStream.h */; }; + F84AD8B72A497DB200DC8DED /* CCDataPipe.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8812A497DB200DC8DED /* CCDataPipe.h */; }; + F84AD8B82A497DB200DC8DED /* CCDataPipe.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8812A497DB200DC8DED /* CCDataPipe.h */; }; + F84AD8B92A497DB200DC8DED /* CCDataPipe.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8812A497DB200DC8DED /* CCDataPipe.h */; }; + F84AD8BA2A497DB200DC8DED /* CCDataPipe.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8812A497DB200DC8DED /* CCDataPipe.h */; }; + F84AD8BB2A497DB200DC8DED /* CCDataPipe.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8812A497DB200DC8DED /* CCDataPipe.h */; }; + F84AD8BC2A497DB200DC8DED /* CCDataPipe.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8812A497DB200DC8DED /* CCDataPipe.h */; }; + F84AD8BD2A497DB200DC8DED /* CCDataPipe.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8812A497DB200DC8DED /* CCDataPipe.h */; }; + F84AD8BE2A497DB200DC8DED /* CCLogStream.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8822A497DB200DC8DED /* CCLogStream.h */; }; + F84AD8BF2A497DB200DC8DED /* CCLogStream.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8822A497DB200DC8DED /* CCLogStream.h */; }; + F84AD8C02A497DB200DC8DED /* CCLogStream.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8822A497DB200DC8DED /* CCLogStream.h */; }; + F84AD8C12A497DB200DC8DED /* CCLogStream.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8822A497DB200DC8DED /* CCLogStream.h */; }; + F84AD8C22A497DB200DC8DED /* CCLogStream.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8822A497DB200DC8DED /* CCLogStream.h */; }; + F84AD8C32A497DB200DC8DED /* CCLogStream.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8822A497DB200DC8DED /* CCLogStream.h */; }; + F84AD8C42A497DB200DC8DED /* CCLogStream.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8822A497DB200DC8DED /* CCLogStream.h */; }; + F84AD8C52A497DB200DC8DED /* IOSkywalkPacketBufferPool.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8832A497DB200DC8DED /* IOSkywalkPacketBufferPool.h */; }; + F84AD8C62A497DB200DC8DED /* IOSkywalkPacketBufferPool.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8832A497DB200DC8DED /* IOSkywalkPacketBufferPool.h */; }; + F84AD8C72A497DB200DC8DED /* IOSkywalkPacketBufferPool.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8832A497DB200DC8DED /* IOSkywalkPacketBufferPool.h */; }; + F84AD8C82A497DB200DC8DED /* IOSkywalkPacketBufferPool.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8832A497DB200DC8DED /* IOSkywalkPacketBufferPool.h */; }; + F84AD8C92A497DB200DC8DED /* IOSkywalkPacketBufferPool.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8832A497DB200DC8DED /* IOSkywalkPacketBufferPool.h */; }; + F84AD8CA2A497DB200DC8DED /* IOSkywalkPacketBufferPool.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8832A497DB200DC8DED /* IOSkywalkPacketBufferPool.h */; }; + F84AD8CB2A497DB200DC8DED /* IOSkywalkPacketBufferPool.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8832A497DB200DC8DED /* IOSkywalkPacketBufferPool.h */; }; + F84AD8CC2A497DB200DC8DED /* IOSkywalkLegacyEthernetInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8842A497DB200DC8DED /* IOSkywalkLegacyEthernetInterface.h */; }; + F84AD8CD2A497DB200DC8DED /* IOSkywalkLegacyEthernetInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8842A497DB200DC8DED /* IOSkywalkLegacyEthernetInterface.h */; }; + F84AD8CE2A497DB200DC8DED /* IOSkywalkLegacyEthernetInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8842A497DB200DC8DED /* IOSkywalkLegacyEthernetInterface.h */; }; + F84AD8CF2A497DB200DC8DED /* IOSkywalkLegacyEthernetInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8842A497DB200DC8DED /* IOSkywalkLegacyEthernetInterface.h */; }; + F84AD8D02A497DB200DC8DED /* IOSkywalkLegacyEthernetInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8842A497DB200DC8DED /* IOSkywalkLegacyEthernetInterface.h */; }; + F84AD8D12A497DB200DC8DED /* IOSkywalkLegacyEthernetInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8842A497DB200DC8DED /* IOSkywalkLegacyEthernetInterface.h */; }; + F84AD8D22A497DB200DC8DED /* IOSkywalkLegacyEthernetInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8842A497DB200DC8DED /* IOSkywalkLegacyEthernetInterface.h */; }; + F84AD8D32A497DB200DC8DED /* CCLogPipe.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8852A497DB200DC8DED /* CCLogPipe.h */; }; + F84AD8D42A497DB200DC8DED /* CCLogPipe.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8852A497DB200DC8DED /* CCLogPipe.h */; }; + F84AD8D52A497DB200DC8DED /* CCLogPipe.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8852A497DB200DC8DED /* CCLogPipe.h */; }; + F84AD8D62A497DB200DC8DED /* CCLogPipe.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8852A497DB200DC8DED /* CCLogPipe.h */; }; + F84AD8D72A497DB200DC8DED /* CCLogPipe.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8852A497DB200DC8DED /* CCLogPipe.h */; }; + F84AD8D82A497DB200DC8DED /* CCLogPipe.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8852A497DB200DC8DED /* CCLogPipe.h */; }; + F84AD8D92A497DB200DC8DED /* CCLogPipe.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8852A497DB200DC8DED /* CCLogPipe.h */; }; F88CB91424FBE9130060B1A5 /* ItlDriverInfo.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F88CB91324FBE9130060B1A5 /* ItlDriverInfo.hpp */; }; F88D2B3D2414E64000BBE700 /* sha1-pbkdf2.c in Sources */ = {isa = PBXBuildFile; fileRef = F88D2B3B2414E64000BBE700 /* sha1-pbkdf2.c */; }; F897ECBA266EFF93005EE8F7 /* debug.h in Headers */ = {isa = PBXBuildFile; fileRef = F89B6C2225027609000F77FF /* debug.h */; }; @@ -584,6 +668,95 @@ F8AE6553285471560085B4CF /* libkmod.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5088ECBC252884870068A63D /* libkmod.a */; }; F8AF3A3124F9F35B008911C1 /* ItlIwm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F8AF3A2F24F9F35B008911C1 /* ItlIwm.cpp */; }; F8AF3A3224F9F35B008911C1 /* ItlIwm.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F8AF3A3024F9F35B008911C1 /* ItlIwm.hpp */; }; + F8B210AB2A2EC2680043ECBD /* debug.h in Headers */ = {isa = PBXBuildFile; fileRef = F89B6C2225027609000F77FF /* debug.h */; }; + F8B210AC2A2EC2680043ECBD /* IOSkywalkEthernetInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = F89B6BD025021E66000F77FF /* IOSkywalkEthernetInterface.h */; }; + F8B210AD2A2EC2680043ECBD /* apple80211_ioctl.h in Headers */ = {isa = PBXBuildFile; fileRef = F89B6BC525021DEC000F77FF /* apple80211_ioctl.h */; }; + F8B210AE2A2EC2680043ECBD /* IO80211P2PInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = F8F7EA36252D834500520FD4 /* IO80211P2PInterface.h */; }; + F8B210AF2A2EC2680043ECBD /* IO80211WorkLoop.h in Headers */ = {isa = PBXBuildFile; fileRef = F8F7EA39252D834500520FD4 /* IO80211WorkLoop.h */; }; + F8B210B02A2EC2680043ECBD /* apple80211_var.h in Headers */ = {isa = PBXBuildFile; fileRef = F89B6BC425021DEC000F77FF /* apple80211_var.h */; }; + F8B210B12A2EC2680043ECBD /* AirportItlwmInterface.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F8CA44A225091AF60036119A /* AirportItlwmInterface.hpp */; }; + F8B210B22A2EC2680043ECBD /* IO80211Interface.h in Headers */ = {isa = PBXBuildFile; fileRef = F8F7EA38252D834500520FD4 /* IO80211Interface.h */; }; + F8B210B32A2EC2680043ECBD /* (null) in Headers */ = {isa = PBXBuildFile; }; + F8B210B42A2EC2680043ECBD /* IO80211SkywalkInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = F8F7EA37252D834500520FD4 /* IO80211SkywalkInterface.h */; }; + F8B210B52A2EC2680043ECBD /* AirportItlwm.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F89B6BBB25021C9C000F77FF /* AirportItlwm.hpp */; }; + F8B210B62A2EC2680043ECBD /* IO80211VirtualInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = F8F7EA34252D834500520FD4 /* IO80211VirtualInterface.h */; }; + F8B210B72A2EC2680043ECBD /* IO80211Controller.h in Headers */ = {isa = PBXBuildFile; fileRef = F8F7EA35252D834500520FD4 /* IO80211Controller.h */; }; + F8B210B82A2EC2680043ECBD /* (null) in Headers */ = {isa = PBXBuildFile; }; + F8B210B92A2EC2680043ECBD /* ieee80211_ra.h in Headers */ = {isa = PBXBuildFile; fileRef = F8C594D225FD935B0007D19C /* ieee80211_ra.h */; }; + F8B210BA2A2EC2680043ECBD /* apple80211_wps.h in Headers */ = {isa = PBXBuildFile; fileRef = F89B6BC325021DEC000F77FF /* apple80211_wps.h */; }; + F8B210BC2A2EC2680043ECBD /* _mbuf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F8D257732495A33500872E4F /* _mbuf.cpp */; }; + F8B210BD2A2EC2680043ECBD /* ieee80211_ra.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C594D125FD935B0007D19C /* ieee80211_ra.c */; }; + F8B210BE2A2EC2680043ECBD /* _task.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F8F9EDE0240B7415009CB8E7 /* _task.cpp */; }; + F8B210BF2A2EC2680043ECBD /* FwBinary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5076FA7F24CC71E40011B2BB /* FwBinary.cpp */; }; + F8B210C02A2EC2680043ECBD /* ieee80211_proto.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC2F24080319007A9422 /* ieee80211_proto.c */; }; + F8B210C12A2EC2680043ECBD /* AirportItlwmInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F8CA44A125091AF60036119A /* AirportItlwmInterface.cpp */; }; + F8B210C22A2EC2680043ECBD /* _string.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC3024080319007A9422 /* _string.c */; }; + F8B210C32A2EC2680043ECBD /* ieee80211_ioctl.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC3224080319007A9422 /* ieee80211_ioctl.c */; }; + F8B210C42A2EC2680043ECBD /* ieee80211.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC3324080319007A9422 /* ieee80211.c */; }; + F8B210C52A2EC2680043ECBD /* ieee80211_rssadapt.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC3424080319007A9422 /* ieee80211_rssadapt.c */; }; + F8B210C62A2EC2680043ECBD /* ieee80211_input.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC3524080319007A9422 /* ieee80211_input.c */; }; + F8B210C72A2EC2680043ECBD /* timeout.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC3724080319007A9422 /* timeout.c */; }; + F8B210C82A2EC2680043ECBD /* ieee80211_mira.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC3924080319007A9422 /* ieee80211_mira.c */; }; + F8B210C92A2EC2680043ECBD /* ieee80211_crypto_bip.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC3B24080319007A9422 /* ieee80211_crypto_bip.c */; }; + F8B210CA2A2EC2680043ECBD /* ieee80211_crypto_tkip.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC3C24080319007A9422 /* ieee80211_crypto_tkip.c */; }; + F8B210CB2A2EC2680043ECBD /* ieee80211_crypto_ccmp.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC3D24080319007A9422 /* ieee80211_crypto_ccmp.c */; }; + F8B210CC2A2EC2680043ECBD /* ieee80211_crypto_wep.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC462408031A007A9422 /* ieee80211_crypto_wep.c */; }; + F8B210CD2A2EC2680043ECBD /* ieee80211_pae_input.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC3E24080319007A9422 /* ieee80211_pae_input.c */; }; + F8B210CE2A2EC2680043ECBD /* ieee80211_amrr.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC4024080319007A9422 /* ieee80211_amrr.c */; }; + F8B210CF2A2EC2680043ECBD /* ieee80211_output.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC472408031A007A9422 /* ieee80211_output.c */; }; + F8B210D02A2EC2680043ECBD /* ieee80211_crypto.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC482408031A007A9422 /* ieee80211_crypto.c */; }; + F8B210D12A2EC2680043ECBD /* CTimeout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC492408031A007A9422 /* CTimeout.cpp */; }; + F8B210D22A2EC2680043ECBD /* ieee80211_regdomain.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC4B2408031A007A9422 /* ieee80211_regdomain.c */; }; + F8B210D32A2EC2680043ECBD /* ieee80211_node.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC4C2408031A007A9422 /* ieee80211_node.c */; }; + F8B210D42A2EC2680043ECBD /* ieee80211_pae_output.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC4D2408031A007A9422 /* ieee80211_pae_output.c */; }; + F8B210D52A2EC2680043ECBD /* sha1-pbkdf2.c in Sources */ = {isa = PBXBuildFile; fileRef = F88D2B3B2414E64000BBE700 /* sha1-pbkdf2.c */; }; + F8B210D62A2EC2680043ECBD /* aes.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07C923FCBC6C009FBA6C /* aes.c */; }; + F8B210D72A2EC2680043ECBD /* hmac.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07CA23FCBC6C009FBA6C /* hmac.c */; }; + F8B210D82A2EC2680043ECBD /* sha2.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07CB23FCBC6C009FBA6C /* sha2.c */; }; + F8B210D92A2EC2680043ECBD /* rijndael.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07CC23FCBC6C009FBA6C /* rijndael.c */; }; + F8B210DA2A2EC2680043ECBD /* ecb3_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07CD23FCBC6C009FBA6C /* ecb3_enc.c */; }; + F8B210DB2A2EC2680043ECBD /* set_key.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07CE23FCBC6C009FBA6C /* set_key.c */; }; + F8B210DC2A2EC2680043ECBD /* cast.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07CF23FCBC6C009FBA6C /* cast.c */; }; + F8B210DD2A2EC2680043ECBD /* michael.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07D123FCBC6C009FBA6C /* michael.c */; }; + F8B210DE2A2EC2680043ECBD /* sha1.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07D823FCBC6C009FBA6C /* sha1.c */; }; + F8B210DF2A2EC2680043ECBD /* cmac.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07DD23FCBC6C009FBA6C /* cmac.c */; }; + F8B210E02A2EC2680043ECBD /* ecb_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07E423FCBC6C009FBA6C /* ecb_enc.c */; }; + F8B210E12A2EC2680043ECBD /* chachapoly.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07E923FCBC6C009FBA6C /* chachapoly.c */; }; + F8B210E22A2EC2680043ECBD /* (null) in Sources */ = {isa = PBXBuildFile; }; + F8B210E32A2EC2680043ECBD /* md5.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07EA23FCBC6C009FBA6C /* md5.c */; }; + F8B210E42A2EC2680043ECBD /* arc4.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07EB23FCBC6C009FBA6C /* arc4.c */; }; + F8B210E52A2EC2680043ECBD /* blf.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07EC23FCBC6C009FBA6C /* blf.c */; }; + F8B210E62A2EC2680043ECBD /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; + F8B210E72A2EC2680043ECBD /* poly1305.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07ED23FCBC6C009FBA6C /* poly1305.c */; }; + F8B210E82A2EC2680043ECBD /* key_wrap.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07F023FCBC6C009FBA6C /* key_wrap.c */; }; + F8B210E92A2EC2680043ECBD /* gmac.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07F223FCBC6C009FBA6C /* gmac.c */; }; + F8B210EA2A2EC2680043ECBD /* rmd160.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07F323FCBC6C009FBA6C /* rmd160.c */; }; + F8B210EB2A2EC2680043ECBD /* idgen.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07F423FCBC6C009FBA6C /* idgen.c */; }; + F8B210EC2A2EC2680043ECBD /* compat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 024A07BA23FCBC6C009FBA6C /* compat.cpp */; }; + F8B210ED2A2EC2680043ECBD /* zutil.c in Sources */ = {isa = PBXBuildFile; fileRef = F8FA0EED2501E8C100B1822E /* zutil.c */; }; + F8B210EE2A2EC2680043ECBD /* ItlHalService.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F8D364F624F93AFD0029340B /* ItlHalService.cpp */; }; + F8B210EF2A2EC2680043ECBD /* ItlIwx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F8D6CD642442E8F200D2A454 /* ItlIwx.cpp */; }; + F8B210F02A2EC2680043ECBD /* utils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 024A08BF23FCD4E2009FBA6C /* utils.cpp */; }; + F8B210F12A2EC2680043ECBD /* fw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 024A08BD23FCD314009FBA6C /* fw.cpp */; }; + F8B210F22A2EC2680043ECBD /* io.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 024A08C123FCD999009FBA6C /* io.cpp */; }; + F8B210F32A2EC2680043ECBD /* rx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 024A08C323FCDC14009FBA6C /* rx.cpp */; }; + F8B210F42A2EC2680043ECBD /* coex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F837C91C2724577F00B2C499 /* coex.cpp */; }; + F8B210F52A2EC2680043ECBD /* tx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 024A08C523FCDC3B009FBA6C /* tx.cpp */; }; + F8B210F62A2EC2680043ECBD /* hw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 024A08C723FCE2ED009FBA6C /* hw.cpp */; }; + F8B210F72A2EC2680043ECBD /* ItlIwn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17FD7F0E255E4AC800611406 /* ItlIwn.cpp */; }; + F8B210F82A2EC2680043ECBD /* phy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 024A08C923FCE537009FBA6C /* phy.cpp */; }; + F8B210F92A2EC2680043ECBD /* mac80211.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 024A08CB23FCE5CA009FBA6C /* mac80211.cpp */; }; + F8B210FA2A2EC2680043ECBD /* nvm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 024A08CD23FCE67F009FBA6C /* nvm.cpp */; }; + F8B210FB2A2EC2680043ECBD /* ctxt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 024A08CF23FCEE88009FBA6C /* ctxt.cpp */; }; + F8B210FC2A2EC2680043ECBD /* led.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 024A08D123FCF395009FBA6C /* led.cpp */; }; + F8B210FD2A2EC2680043ECBD /* power.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 024A08D323FCF3E6009FBA6C /* power.cpp */; }; + F8B210FE2A2EC2680043ECBD /* scan.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 024A08D523FCF4D7009FBA6C /* scan.cpp */; }; + F8B210FF2A2EC2680043ECBD /* ItlIwm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F8AF3A2F24F9F35B008911C1 /* ItlIwm.cpp */; }; + F8B211002A2EC2680043ECBD /* AirportSTAIOCTL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F89B6BDC25022F8C000F77FF /* AirportSTAIOCTL.cpp */; }; + F8B211012A2EC2680043ECBD /* AirportItlwm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F89B6BBD25021C9C000F77FF /* AirportItlwm.cpp */; }; + F8B211022A2EC2680043ECBD /* AirportVirtualIOCTL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F89B6BDE25022FB5000F77FF /* AirportVirtualIOCTL.cpp */; }; + F8B211032A2EC2680043ECBD /* AirportAWDL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F89B6BE025022FC7000F77FF /* AirportAWDL.cpp */; }; + F8B211052A2EC2680043ECBD /* libkmod.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5088ECBC252884870068A63D /* libkmod.a */; }; F8C2EC4F2408031A007A9422 /* ieee80211_proto.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC2F24080319007A9422 /* ieee80211_proto.c */; }; F8C2EC502408031A007A9422 /* _string.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC3024080319007A9422 /* _string.c */; }; F8C2EC512408031A007A9422 /* ieee80211_amrr.h in Headers */ = {isa = PBXBuildFile; fileRef = F8C2EC3124080319007A9422 /* ieee80211_amrr.h */; }; @@ -731,6 +904,13 @@ remoteGlobalIDString = 5066D63825287F7900EE6F38; remoteInfo = fw_gen; }; + F8B210A92A2EC2680043ECBD /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 024A07A323FCBC3C009FBA6C /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5066D63825287F7900EE6F38; + remoteInfo = fw_gen; + }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ @@ -832,6 +1012,18 @@ F800DD9A24FBEBF000789320 /* ItlDriverController.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ItlDriverController.hpp; sourceTree = ""; }; F837C91C2724577F00B2C499 /* coex.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = coex.cpp; sourceTree = ""; }; F837C9252724732B00B2C499 /* iwlwifi-so-a0-gf-a0.pnvm */ = {isa = PBXFileReference; lastKnownFileType = file; path = "iwlwifi-so-a0-gf-a0.pnvm"; sourceTree = ""; }; + F84AD87A2A497DB200DC8DED /* IO80211WorkQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IO80211WorkQueue.h; sourceTree = ""; }; + F84AD87B2A497DB200DC8DED /* IOSkywalkNetworkPacket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IOSkywalkNetworkPacket.h; sourceTree = ""; }; + F84AD87C2A497DB200DC8DED /* IO80211InfraProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IO80211InfraProtocol.h; sourceTree = ""; }; + F84AD87D2A497DB200DC8DED /* CCPipe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCPipe.h; sourceTree = ""; }; + F84AD87E2A497DB200DC8DED /* IOSkywalkLogicalLink.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IOSkywalkLogicalLink.h; sourceTree = ""; }; + F84AD87F2A497DB200DC8DED /* IO80211InfraInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IO80211InfraInterface.h; sourceTree = ""; }; + F84AD8802A497DB200DC8DED /* CCStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCStream.h; sourceTree = ""; }; + F84AD8812A497DB200DC8DED /* CCDataPipe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCDataPipe.h; sourceTree = ""; }; + F84AD8822A497DB200DC8DED /* CCLogStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCLogStream.h; sourceTree = ""; }; + F84AD8832A497DB200DC8DED /* IOSkywalkPacketBufferPool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IOSkywalkPacketBufferPool.h; sourceTree = ""; }; + F84AD8842A497DB200DC8DED /* IOSkywalkLegacyEthernetInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IOSkywalkLegacyEthernetInterface.h; sourceTree = ""; }; + F84AD8852A497DB200DC8DED /* CCLogPipe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCLogPipe.h; sourceTree = ""; }; F883EC1F266F43F200EA018C /* AirportItlwm-Monterey-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "AirportItlwm-Monterey-Info.plist"; sourceTree = ""; }; F88CB91324FBE9130060B1A5 /* ItlDriverInfo.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ItlDriverInfo.hpp; sourceTree = ""; }; F88D2B3B2414E64000BBE700 /* sha1-pbkdf2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "sha1-pbkdf2.c"; sourceTree = ""; }; @@ -850,10 +1042,13 @@ F89B6BDE25022FB5000F77FF /* AirportVirtualIOCTL.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AirportVirtualIOCTL.cpp; sourceTree = ""; }; F89B6BE025022FC7000F77FF /* AirportAWDL.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AirportAWDL.cpp; sourceTree = ""; }; F89B6C2225027609000F77FF /* debug.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = debug.h; sourceTree = ""; }; + F8A2A68B2A305B9E002ABDDB /* IOSkywalkNetworkInterface.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IOSkywalkNetworkInterface.h; sourceTree = ""; }; + F8A2A68C2A305BAC002ABDDB /* IOSkywalkInterface.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IOSkywalkInterface.h; sourceTree = ""; }; F8A763892766B95F004606BE /* iwlwifi-so-a0-gf4-a0.pnvm */ = {isa = PBXFileReference; lastKnownFileType = file; path = "iwlwifi-so-a0-gf4-a0.pnvm"; sourceTree = ""; }; F8AE6558285471560085B4CF /* AirportItlwm.kext */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AirportItlwm.kext; sourceTree = BUILT_PRODUCTS_DIR; }; F8AF3A2F24F9F35B008911C1 /* ItlIwm.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ItlIwm.cpp; sourceTree = ""; }; F8AF3A3024F9F35B008911C1 /* ItlIwm.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ItlIwm.hpp; sourceTree = ""; }; + F8B2110A2A2EC2680043ECBD /* AirportItlwm.kext */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AirportItlwm.kext; sourceTree = BUILT_PRODUCTS_DIR; }; F8B783AF240B9F87004C9777 /* _ifq.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _ifq.h; sourceTree = ""; }; F8BB56172647FDF500F180EC /* _clock.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _clock.h; sourceTree = ""; }; F8BEFA9124CA93E900F6D938 /* _malloc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _malloc.h; sourceTree = ""; }; @@ -1009,6 +1204,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + F8B211042A2EC2680043ECBD /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F8B211052A2EC2680043ECBD /* libkmod.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -1037,6 +1240,7 @@ 35CBE78F251CB8CA00435CBC /* AirportItlwm.kext */, F897ED18266EFF93005EE8F7 /* AirportItlwm.kext */, F8AE6558285471560085B4CF /* AirportItlwm.kext */, + F8B2110A2A2EC2680043ECBD /* AirportItlwm.kext */, ); name = Products; sourceTree = ""; @@ -1193,12 +1397,26 @@ F89B6B7D25021674000F77FF /* Airport */ = { isa = PBXGroup; children = ( + F84AD8812A497DB200DC8DED /* CCDataPipe.h */, + F84AD8852A497DB200DC8DED /* CCLogPipe.h */, + F84AD8822A497DB200DC8DED /* CCLogStream.h */, + F84AD87D2A497DB200DC8DED /* CCPipe.h */, + F84AD8802A497DB200DC8DED /* CCStream.h */, + F84AD87F2A497DB200DC8DED /* IO80211InfraInterface.h */, + F84AD87C2A497DB200DC8DED /* IO80211InfraProtocol.h */, + F84AD87A2A497DB200DC8DED /* IO80211WorkQueue.h */, + F84AD8842A497DB200DC8DED /* IOSkywalkLegacyEthernetInterface.h */, + F84AD87E2A497DB200DC8DED /* IOSkywalkLogicalLink.h */, + F84AD87B2A497DB200DC8DED /* IOSkywalkNetworkPacket.h */, + F84AD8832A497DB200DC8DED /* IOSkywalkPacketBufferPool.h */, F89B6B8325021A79000F77FF /* apple_private_spi.h */, F8F7EA35252D834500520FD4 /* IO80211Controller.h */, F8F7EA38252D834500520FD4 /* IO80211Interface.h */, F8F7EA36252D834500520FD4 /* IO80211P2PInterface.h */, F8F7EA37252D834500520FD4 /* IO80211SkywalkInterface.h */, F89B6BD025021E66000F77FF /* IOSkywalkEthernetInterface.h */, + F8A2A68B2A305B9E002ABDDB /* IOSkywalkNetworkInterface.h */, + F8A2A68C2A305BAC002ABDDB /* IOSkywalkInterface.h */, F8F7EA34252D834500520FD4 /* IO80211VirtualInterface.h */, F8F7EA39252D834500520FD4 /* IO80211WorkLoop.h */, F89B6BC525021DEC000F77FF /* apple80211_ioctl.h */, @@ -1460,17 +1678,29 @@ files = ( 35CBE659251CB89700435CBC /* debug.h in Headers */, 35CBE65A251CB89700435CBC /* IOSkywalkEthernetInterface.h in Headers */, + F84AD8A52A497DB200DC8DED /* IOSkywalkLogicalLink.h in Headers */, + F84AD8892A497DB200DC8DED /* IO80211WorkQueue.h in Headers */, 35CBE65B251CB89700435CBC /* apple80211_ioctl.h in Headers */, + F84AD8B32A497DB200DC8DED /* CCStream.h in Headers */, F8F7EA45252D834600520FD4 /* IO80211P2PInterface.h in Headers */, F8F7EA51252D834600520FD4 /* IO80211WorkLoop.h in Headers */, + F84AD8BA2A497DB200DC8DED /* CCDataPipe.h in Headers */, + F84AD8C12A497DB200DC8DED /* CCLogStream.h in Headers */, 35CBE661251CB89700435CBC /* apple80211_var.h in Headers */, 35CBE664251CB89700435CBC /* AirportItlwmInterface.hpp in Headers */, + F84AD8CF2A497DB200DC8DED /* IOSkywalkLegacyEthernetInterface.h in Headers */, F8F7EA4D252D834600520FD4 /* IO80211Interface.h in Headers */, + F84AD8AC2A497DB200DC8DED /* IO80211InfraInterface.h in Headers */, F8F7EA49252D834600520FD4 /* IO80211SkywalkInterface.h in Headers */, 35CBE666251CB89700435CBC /* AirportItlwm.hpp in Headers */, F8F7EA3D252D834600520FD4 /* IO80211VirtualInterface.h in Headers */, + F84AD89E2A497DB200DC8DED /* CCPipe.h in Headers */, + F84AD8D62A497DB200DC8DED /* CCLogPipe.h in Headers */, F8F7EA41252D834600520FD4 /* IO80211Controller.h in Headers */, + F84AD8C82A497DB200DC8DED /* IOSkywalkPacketBufferPool.h in Headers */, + F84AD8972A497DB200DC8DED /* IO80211InfraProtocol.h in Headers */, F8C594DC25FD935B0007D19C /* ieee80211_ra.h in Headers */, + F84AD8902A497DB200DC8DED /* IOSkywalkNetworkPacket.h in Headers */, 35CBE66F251CB89700435CBC /* apple80211_wps.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1481,17 +1711,29 @@ files = ( 35CBE6C3251CB8BF00435CBC /* debug.h in Headers */, 35CBE6C4251CB8BF00435CBC /* IOSkywalkEthernetInterface.h in Headers */, + F84AD8A32A497DB200DC8DED /* IOSkywalkLogicalLink.h in Headers */, + F84AD8872A497DB200DC8DED /* IO80211WorkQueue.h in Headers */, 35CBE6C5251CB8BF00435CBC /* apple80211_ioctl.h in Headers */, + F84AD8B12A497DB200DC8DED /* CCStream.h in Headers */, F8F7EA43252D834600520FD4 /* IO80211P2PInterface.h in Headers */, F8F7EA4F252D834600520FD4 /* IO80211WorkLoop.h in Headers */, + F84AD8B82A497DB200DC8DED /* CCDataPipe.h in Headers */, + F84AD8BF2A497DB200DC8DED /* CCLogStream.h in Headers */, 35CBE6CB251CB8BF00435CBC /* apple80211_var.h in Headers */, 35CBE6CE251CB8BF00435CBC /* AirportItlwmInterface.hpp in Headers */, + F84AD8CD2A497DB200DC8DED /* IOSkywalkLegacyEthernetInterface.h in Headers */, F8F7EA4B252D834600520FD4 /* IO80211Interface.h in Headers */, + F84AD8AA2A497DB200DC8DED /* IO80211InfraInterface.h in Headers */, F8F7EA47252D834600520FD4 /* IO80211SkywalkInterface.h in Headers */, 35CBE6D0251CB8BF00435CBC /* AirportItlwm.hpp in Headers */, F8F7EA3B252D834600520FD4 /* IO80211VirtualInterface.h in Headers */, + F84AD89C2A497DB200DC8DED /* CCPipe.h in Headers */, + F84AD8D42A497DB200DC8DED /* CCLogPipe.h in Headers */, F8F7EA3F252D834600520FD4 /* IO80211Controller.h in Headers */, + F84AD8C62A497DB200DC8DED /* IOSkywalkPacketBufferPool.h in Headers */, + F84AD8952A497DB200DC8DED /* IO80211InfraProtocol.h in Headers */, F8C594DA25FD935B0007D19C /* ieee80211_ra.h in Headers */, + F84AD88E2A497DB200DC8DED /* IOSkywalkNetworkPacket.h in Headers */, 35CBE6D9251CB8BF00435CBC /* apple80211_wps.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1502,17 +1744,29 @@ files = ( 35CBE72E251CB8CA00435CBC /* debug.h in Headers */, 35CBE72F251CB8CA00435CBC /* IOSkywalkEthernetInterface.h in Headers */, + F84AD8A22A497DB200DC8DED /* IOSkywalkLogicalLink.h in Headers */, + F84AD8862A497DB200DC8DED /* IO80211WorkQueue.h in Headers */, 35CBE730251CB8CA00435CBC /* apple80211_ioctl.h in Headers */, + F84AD8B02A497DB200DC8DED /* CCStream.h in Headers */, F8F7EA42252D834600520FD4 /* IO80211P2PInterface.h in Headers */, F8F7EA4E252D834600520FD4 /* IO80211WorkLoop.h in Headers */, + F84AD8B72A497DB200DC8DED /* CCDataPipe.h in Headers */, + F84AD8BE2A497DB200DC8DED /* CCLogStream.h in Headers */, 35CBE736251CB8CA00435CBC /* apple80211_var.h in Headers */, 35CBE739251CB8CA00435CBC /* AirportItlwmInterface.hpp in Headers */, + F84AD8CC2A497DB200DC8DED /* IOSkywalkLegacyEthernetInterface.h in Headers */, F8F7EA4A252D834600520FD4 /* IO80211Interface.h in Headers */, + F84AD8A92A497DB200DC8DED /* IO80211InfraInterface.h in Headers */, F8F7EA46252D834600520FD4 /* IO80211SkywalkInterface.h in Headers */, 35CBE73B251CB8CA00435CBC /* AirportItlwm.hpp in Headers */, F8F7EA3A252D834600520FD4 /* IO80211VirtualInterface.h in Headers */, + F84AD89B2A497DB200DC8DED /* CCPipe.h in Headers */, + F84AD8D32A497DB200DC8DED /* CCLogPipe.h in Headers */, F8F7EA3E252D834600520FD4 /* IO80211Controller.h in Headers */, + F84AD8C52A497DB200DC8DED /* IOSkywalkPacketBufferPool.h in Headers */, + F84AD8942A497DB200DC8DED /* IO80211InfraProtocol.h in Headers */, F8C594D925FD935B0007D19C /* ieee80211_ra.h in Headers */, + F84AD88D2A497DB200DC8DED /* IOSkywalkNetworkPacket.h in Headers */, 35CBE744251CB8CA00435CBC /* apple80211_wps.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1521,21 +1775,33 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + F84AD8BB2A497DB200DC8DED /* CCDataPipe.h in Headers */, F897ECBA266EFF93005EE8F7 /* debug.h in Headers */, F897ECBB266EFF93005EE8F7 /* IOSkywalkEthernetInterface.h in Headers */, + F84AD8982A497DB200DC8DED /* IO80211InfraProtocol.h in Headers */, + F84AD8A62A497DB200DC8DED /* IOSkywalkLogicalLink.h in Headers */, + F84AD8912A497DB200DC8DED /* IOSkywalkNetworkPacket.h in Headers */, F897ECBC266EFF93005EE8F7 /* apple80211_ioctl.h in Headers */, + F84AD8D72A497DB200DC8DED /* CCLogPipe.h in Headers */, F897ECBD266EFF93005EE8F7 /* IO80211P2PInterface.h in Headers */, + F84AD89F2A497DB200DC8DED /* CCPipe.h in Headers */, F897ECBE266EFF93005EE8F7 /* IO80211WorkLoop.h in Headers */, F897ECBF266EFF93005EE8F7 /* apple80211_var.h in Headers */, + F84AD8C92A497DB200DC8DED /* IOSkywalkPacketBufferPool.h in Headers */, + F84AD8D02A497DB200DC8DED /* IOSkywalkLegacyEthernetInterface.h in Headers */, F897ECC0266EFF93005EE8F7 /* AirportItlwmInterface.hpp in Headers */, F897ECC1266EFF93005EE8F7 /* IO80211Interface.h in Headers */, + F84AD88A2A497DB200DC8DED /* IO80211WorkQueue.h in Headers */, F897ECC2266EFF93005EE8F7 /* (null) in Headers */, + F84AD8AD2A497DB200DC8DED /* IO80211InfraInterface.h in Headers */, F897ECC3266EFF93005EE8F7 /* IO80211SkywalkInterface.h in Headers */, + F84AD8C22A497DB200DC8DED /* CCLogStream.h in Headers */, F897ECC4266EFF93005EE8F7 /* AirportItlwm.hpp in Headers */, F897ECC5266EFF93005EE8F7 /* IO80211VirtualInterface.h in Headers */, F897ECC6266EFF93005EE8F7 /* IO80211Controller.h in Headers */, F897ECC7266EFF93005EE8F7 /* (null) in Headers */, F897ECC8266EFF93005EE8F7 /* ieee80211_ra.h in Headers */, + F84AD8B42A497DB200DC8DED /* CCStream.h in Headers */, F897ECC9266EFF93005EE8F7 /* apple80211_wps.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1546,17 +1812,29 @@ files = ( F89B6C2325027609000F77FF /* debug.h in Headers */, F89B6BD725021E66000F77FF /* IOSkywalkEthernetInterface.h in Headers */, + F84AD8A42A497DB200DC8DED /* IOSkywalkLogicalLink.h in Headers */, + F84AD8882A497DB200DC8DED /* IO80211WorkQueue.h in Headers */, F89B6BCB25021DED000F77FF /* apple80211_ioctl.h in Headers */, + F84AD8B22A497DB200DC8DED /* CCStream.h in Headers */, F8F7EA44252D834600520FD4 /* IO80211P2PInterface.h in Headers */, F8F7EA50252D834600520FD4 /* IO80211WorkLoop.h in Headers */, + F84AD8B92A497DB200DC8DED /* CCDataPipe.h in Headers */, + F84AD8C02A497DB200DC8DED /* CCLogStream.h in Headers */, F89B6BC925021DED000F77FF /* apple80211_var.h in Headers */, F8CA44A425091AF60036119A /* AirportItlwmInterface.hpp in Headers */, + F84AD8CE2A497DB200DC8DED /* IOSkywalkLegacyEthernetInterface.h in Headers */, F8F7EA4C252D834600520FD4 /* IO80211Interface.h in Headers */, + F84AD8AB2A497DB200DC8DED /* IO80211InfraInterface.h in Headers */, F8F7EA48252D834600520FD4 /* IO80211SkywalkInterface.h in Headers */, F89B6BBC25021C9C000F77FF /* AirportItlwm.hpp in Headers */, F8F7EA3C252D834600520FD4 /* IO80211VirtualInterface.h in Headers */, + F84AD89D2A497DB200DC8DED /* CCPipe.h in Headers */, + F84AD8D52A497DB200DC8DED /* CCLogPipe.h in Headers */, F8F7EA40252D834600520FD4 /* IO80211Controller.h in Headers */, + F84AD8C72A497DB200DC8DED /* IOSkywalkPacketBufferPool.h in Headers */, + F84AD8962A497DB200DC8DED /* IO80211InfraProtocol.h in Headers */, F8C594DB25FD935B0007D19C /* ieee80211_ra.h in Headers */, + F84AD88F2A497DB200DC8DED /* IOSkywalkNetworkPacket.h in Headers */, F89B6BC725021DED000F77FF /* apple80211_wps.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1565,25 +1843,72 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + F84AD8BC2A497DB200DC8DED /* CCDataPipe.h in Headers */, F8AE64F9285471560085B4CF /* debug.h in Headers */, F8AE64FA285471560085B4CF /* IOSkywalkEthernetInterface.h in Headers */, + F84AD8992A497DB200DC8DED /* IO80211InfraProtocol.h in Headers */, + F84AD8A72A497DB200DC8DED /* IOSkywalkLogicalLink.h in Headers */, + F84AD8922A497DB200DC8DED /* IOSkywalkNetworkPacket.h in Headers */, F8AE64FB285471560085B4CF /* apple80211_ioctl.h in Headers */, + F84AD8D82A497DB200DC8DED /* CCLogPipe.h in Headers */, F8AE64FC285471560085B4CF /* IO80211P2PInterface.h in Headers */, + F84AD8A02A497DB200DC8DED /* CCPipe.h in Headers */, F8AE64FD285471560085B4CF /* IO80211WorkLoop.h in Headers */, F8AE64FE285471560085B4CF /* apple80211_var.h in Headers */, + F84AD8CA2A497DB200DC8DED /* IOSkywalkPacketBufferPool.h in Headers */, + F84AD8D12A497DB200DC8DED /* IOSkywalkLegacyEthernetInterface.h in Headers */, F8AE64FF285471560085B4CF /* AirportItlwmInterface.hpp in Headers */, F8AE6500285471560085B4CF /* IO80211Interface.h in Headers */, + F84AD88B2A497DB200DC8DED /* IO80211WorkQueue.h in Headers */, F8AE6501285471560085B4CF /* (null) in Headers */, + F84AD8AE2A497DB200DC8DED /* IO80211InfraInterface.h in Headers */, F8AE6502285471560085B4CF /* IO80211SkywalkInterface.h in Headers */, + F84AD8C32A497DB200DC8DED /* CCLogStream.h in Headers */, F8AE6503285471560085B4CF /* AirportItlwm.hpp in Headers */, F8AE6504285471560085B4CF /* IO80211VirtualInterface.h in Headers */, F8AE6505285471560085B4CF /* IO80211Controller.h in Headers */, F8AE6506285471560085B4CF /* (null) in Headers */, F8AE6507285471560085B4CF /* ieee80211_ra.h in Headers */, + F84AD8B52A497DB200DC8DED /* CCStream.h in Headers */, F8AE6508285471560085B4CF /* apple80211_wps.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; + F8B210AA2A2EC2680043ECBD /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + F84AD8BD2A497DB200DC8DED /* CCDataPipe.h in Headers */, + F8B210AB2A2EC2680043ECBD /* debug.h in Headers */, + F8B210AC2A2EC2680043ECBD /* IOSkywalkEthernetInterface.h in Headers */, + F84AD89A2A497DB200DC8DED /* IO80211InfraProtocol.h in Headers */, + F84AD8A82A497DB200DC8DED /* IOSkywalkLogicalLink.h in Headers */, + F84AD8932A497DB200DC8DED /* IOSkywalkNetworkPacket.h in Headers */, + F8B210AD2A2EC2680043ECBD /* apple80211_ioctl.h in Headers */, + F84AD8D92A497DB200DC8DED /* CCLogPipe.h in Headers */, + F8B210AE2A2EC2680043ECBD /* IO80211P2PInterface.h in Headers */, + F84AD8A12A497DB200DC8DED /* CCPipe.h in Headers */, + F8B210AF2A2EC2680043ECBD /* IO80211WorkLoop.h in Headers */, + F8B210B02A2EC2680043ECBD /* apple80211_var.h in Headers */, + F84AD8CB2A497DB200DC8DED /* IOSkywalkPacketBufferPool.h in Headers */, + F84AD8D22A497DB200DC8DED /* IOSkywalkLegacyEthernetInterface.h in Headers */, + F8B210B12A2EC2680043ECBD /* AirportItlwmInterface.hpp in Headers */, + F8B210B22A2EC2680043ECBD /* IO80211Interface.h in Headers */, + F84AD88C2A497DB200DC8DED /* IO80211WorkQueue.h in Headers */, + F8B210B32A2EC2680043ECBD /* (null) in Headers */, + F84AD8AF2A497DB200DC8DED /* IO80211InfraInterface.h in Headers */, + F8B210B42A2EC2680043ECBD /* IO80211SkywalkInterface.h in Headers */, + F84AD8C42A497DB200DC8DED /* CCLogStream.h in Headers */, + F8B210B52A2EC2680043ECBD /* AirportItlwm.hpp in Headers */, + F8B210B62A2EC2680043ECBD /* IO80211VirtualInterface.h in Headers */, + F8B210B72A2EC2680043ECBD /* IO80211Controller.h in Headers */, + F8B210B82A2EC2680043ECBD /* (null) in Headers */, + F8B210B92A2EC2680043ECBD /* ieee80211_ra.h in Headers */, + F84AD8B62A497DB200DC8DED /* CCStream.h in Headers */, + F8B210BA2A2EC2680043ECBD /* apple80211_wps.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ @@ -1720,6 +2045,25 @@ productReference = F8AE6558285471560085B4CF /* AirportItlwm.kext */; productType = "com.apple.product-type.kernel-extension"; }; + F8B210A72A2EC2680043ECBD /* AirportItlwm-Sonoma */ = { + isa = PBXNativeTarget; + buildConfigurationList = F8B211072A2EC2680043ECBD /* Build configuration list for PBXNativeTarget "AirportItlwm-Sonoma" */; + buildPhases = ( + F8B210AA2A2EC2680043ECBD /* Headers */, + F8B210BB2A2EC2680043ECBD /* Sources */, + F8B211042A2EC2680043ECBD /* Frameworks */, + F8B211062A2EC2680043ECBD /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + F8B210A82A2EC2680043ECBD /* PBXTargetDependency */, + ); + name = "AirportItlwm-Sonoma"; + productName = AirportItlwm; + productReference = F8B2110A2A2EC2680043ECBD /* AirportItlwm.kext */; + productType = "com.apple.product-type.kernel-extension"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -1756,6 +2100,9 @@ F8AE64F5285471560085B4CF = { ProvisioningStyle = Manual; }; + F8B210A72A2EC2680043ECBD = { + ProvisioningStyle = Manual; + }; }; }; buildConfigurationList = 024A07A623FCBC3C009FBA6C /* Build configuration list for PBXProject "itlwm" */; @@ -1778,6 +2125,7 @@ 35CBE655251CB89700435CBC /* AirportItlwm-Big Sur */, F897ECB6266EFF93005EE8F7 /* AirportItlwm-Monterey */, F8AE64F5285471560085B4CF /* AirportItlwm-Ventura */, + F8B210A72A2EC2680043ECBD /* AirportItlwm-Sonoma */, 5066D63825287F7900EE6F38 /* fw_gen */, ); }; @@ -1833,6 +2181,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + F8B211062A2EC2680043ECBD /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ @@ -2404,6 +2759,85 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + F8B210BB2A2EC2680043ECBD /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F8B210BC2A2EC2680043ECBD /* _mbuf.cpp in Sources */, + F8B210BD2A2EC2680043ECBD /* ieee80211_ra.c in Sources */, + F8B210BE2A2EC2680043ECBD /* _task.cpp in Sources */, + F8B210BF2A2EC2680043ECBD /* FwBinary.cpp in Sources */, + F8B210C02A2EC2680043ECBD /* ieee80211_proto.c in Sources */, + F8B210C12A2EC2680043ECBD /* AirportItlwmInterface.cpp in Sources */, + F8B210C22A2EC2680043ECBD /* _string.c in Sources */, + F8B210C32A2EC2680043ECBD /* ieee80211_ioctl.c in Sources */, + F8B210C42A2EC2680043ECBD /* ieee80211.c in Sources */, + F8B210C52A2EC2680043ECBD /* ieee80211_rssadapt.c in Sources */, + F8B210C62A2EC2680043ECBD /* ieee80211_input.c in Sources */, + F8B210C72A2EC2680043ECBD /* timeout.c in Sources */, + F8B210C82A2EC2680043ECBD /* ieee80211_mira.c in Sources */, + F8B210C92A2EC2680043ECBD /* ieee80211_crypto_bip.c in Sources */, + F8B210CA2A2EC2680043ECBD /* ieee80211_crypto_tkip.c in Sources */, + F8B210CB2A2EC2680043ECBD /* ieee80211_crypto_ccmp.c in Sources */, + F8B210CC2A2EC2680043ECBD /* ieee80211_crypto_wep.c in Sources */, + F8B210CD2A2EC2680043ECBD /* ieee80211_pae_input.c in Sources */, + F8B210CE2A2EC2680043ECBD /* ieee80211_amrr.c in Sources */, + F8B210CF2A2EC2680043ECBD /* ieee80211_output.c in Sources */, + F8B210D02A2EC2680043ECBD /* ieee80211_crypto.c in Sources */, + F8B210D12A2EC2680043ECBD /* CTimeout.cpp in Sources */, + F8B210D22A2EC2680043ECBD /* ieee80211_regdomain.c in Sources */, + F8B210D32A2EC2680043ECBD /* ieee80211_node.c in Sources */, + F8B210D42A2EC2680043ECBD /* ieee80211_pae_output.c in Sources */, + F8B210D52A2EC2680043ECBD /* sha1-pbkdf2.c in Sources */, + F8B210D62A2EC2680043ECBD /* aes.c in Sources */, + F8B210D72A2EC2680043ECBD /* hmac.c in Sources */, + F8B210D82A2EC2680043ECBD /* sha2.c in Sources */, + F8B210D92A2EC2680043ECBD /* rijndael.c in Sources */, + F8B210DA2A2EC2680043ECBD /* ecb3_enc.c in Sources */, + F8B210DB2A2EC2680043ECBD /* set_key.c in Sources */, + F8B210DC2A2EC2680043ECBD /* cast.c in Sources */, + F8B210DD2A2EC2680043ECBD /* michael.c in Sources */, + F8B210DE2A2EC2680043ECBD /* sha1.c in Sources */, + F8B210DF2A2EC2680043ECBD /* cmac.c in Sources */, + F8B210E02A2EC2680043ECBD /* ecb_enc.c in Sources */, + F8B210E12A2EC2680043ECBD /* chachapoly.c in Sources */, + F8B210E22A2EC2680043ECBD /* (null) in Sources */, + F8B210E32A2EC2680043ECBD /* md5.c in Sources */, + F8B210E42A2EC2680043ECBD /* arc4.c in Sources */, + F8B210E52A2EC2680043ECBD /* blf.c in Sources */, + F8B210E62A2EC2680043ECBD /* _ifq.cpp in Sources */, + F8B210E72A2EC2680043ECBD /* poly1305.c in Sources */, + F8B210E82A2EC2680043ECBD /* key_wrap.c in Sources */, + F8B210E92A2EC2680043ECBD /* gmac.c in Sources */, + F8B210EA2A2EC2680043ECBD /* rmd160.c in Sources */, + F8B210EB2A2EC2680043ECBD /* idgen.c in Sources */, + F8B210EC2A2EC2680043ECBD /* compat.cpp in Sources */, + F8B210ED2A2EC2680043ECBD /* zutil.c in Sources */, + F8B210EE2A2EC2680043ECBD /* ItlHalService.cpp in Sources */, + F8B210EF2A2EC2680043ECBD /* ItlIwx.cpp in Sources */, + F8B210F02A2EC2680043ECBD /* utils.cpp in Sources */, + F8B210F12A2EC2680043ECBD /* fw.cpp in Sources */, + F8B210F22A2EC2680043ECBD /* io.cpp in Sources */, + F8B210F32A2EC2680043ECBD /* rx.cpp in Sources */, + F8B210F42A2EC2680043ECBD /* coex.cpp in Sources */, + F8B210F52A2EC2680043ECBD /* tx.cpp in Sources */, + F8B210F62A2EC2680043ECBD /* hw.cpp in Sources */, + F8B210F72A2EC2680043ECBD /* ItlIwn.cpp in Sources */, + F8B210F82A2EC2680043ECBD /* phy.cpp in Sources */, + F8B210F92A2EC2680043ECBD /* mac80211.cpp in Sources */, + F8B210FA2A2EC2680043ECBD /* nvm.cpp in Sources */, + F8B210FB2A2EC2680043ECBD /* ctxt.cpp in Sources */, + F8B210FC2A2EC2680043ECBD /* led.cpp in Sources */, + F8B210FD2A2EC2680043ECBD /* power.cpp in Sources */, + F8B210FE2A2EC2680043ECBD /* scan.cpp in Sources */, + F8B210FF2A2EC2680043ECBD /* ItlIwm.cpp in Sources */, + F8B211002A2EC2680043ECBD /* AirportSTAIOCTL.cpp in Sources */, + F8B211012A2EC2680043ECBD /* AirportItlwm.cpp in Sources */, + F8B211022A2EC2680043ECBD /* AirportVirtualIOCTL.cpp in Sources */, + F8B211032A2EC2680043ECBD /* AirportAWDL.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -2442,6 +2876,11 @@ target = 5066D63825287F7900EE6F38 /* fw_gen */; targetProxy = F8AE64F7285471560085B4CF /* PBXContainerItemProxy */; }; + F8B210A82A2EC2680043ECBD /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5066D63825287F7900EE6F38 /* fw_gen */; + targetProxy = F8B210A92A2EC2680043ECBD /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ @@ -3021,6 +3460,68 @@ }; name = Release; }; + F8B211082A2EC2680043ECBD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CONFIGURATION_BUILD_DIR = "$(SYMROOT)/$(CONFIGURATION)/Sonoma"; + CURRENT_PROJECT_VERSION = "$(MODULE_VERSION)"; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = itlwm/PrivateSPI.pch; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + USE_APPLE_SUPPLICANT, + AIRPORT, + "__IO80211_TARGET=__MAC_14_0", + __PRIVATE_SPI__, + ); + INFOPLIST_FILE = "AirportItlwm/AirportItlwm-Sonoma-Info.plist"; + LIBRARY_SEARCH_PATHS = ( + "$(PROJECT_DIR)/itl80211", + "$(inherited)", + "$(PROJECT_DIR)/itl80211/openbsd", + "$(PROJECT_DIR)/itl80211/linux", + "$(PROJECT_DIR)/MacKernelSDK/Library/x86_64", + ); + MACOSX_DEPLOYMENT_TARGET = 10.15; + MODULE_NAME = com.zxystd.AirportItlwm; + PRODUCT_BUNDLE_IDENTIFIER = com.zxystd.AirportItlwm; + PRODUCT_NAME = AirportItlwm; + SYSTEM_HEADER_SEARCH_PATHS = "itl80211/openbsd itl80211 include"; + WRAPPER_EXTENSION = kext; + }; + name = Debug; + }; + F8B211092A2EC2680043ECBD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CONFIGURATION_BUILD_DIR = "$(SYMROOT)/$(CONFIGURATION)/Sonoma"; + CURRENT_PROJECT_VERSION = "$(MODULE_VERSION)"; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = itlwm/PrivateSPI.pch; + GCC_PREPROCESSOR_DEFINITIONS = ( + "__IO80211_TARGET=__MAC_14_0", + USE_APPLE_SUPPLICANT, + AIRPORT, + __PRIVATE_SPI__, + "$(inherited)", + ); + INFOPLIST_FILE = "AirportItlwm/AirportItlwm-Sonoma-Info.plist"; + LIBRARY_SEARCH_PATHS = ( + "$(PROJECT_DIR)/itl80211", + "$(inherited)", + "$(PROJECT_DIR)/itl80211/openbsd", + "$(PROJECT_DIR)/itl80211/linux", + "$(PROJECT_DIR)/MacKernelSDK/Library/x86_64", + ); + MACOSX_DEPLOYMENT_TARGET = 10.15; + MODULE_NAME = com.zxystd.AirportItlwm; + PRODUCT_BUNDLE_IDENTIFIER = com.zxystd.AirportItlwm; + PRODUCT_NAME = AirportItlwm; + SYSTEM_HEADER_SEARCH_PATHS = "itl80211/openbsd itl80211 include"; + WRAPPER_EXTENSION = kext; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -3105,6 +3606,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + F8B211072A2EC2680043ECBD /* Build configuration list for PBXNativeTarget "AirportItlwm-Sonoma" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F8B211082A2EC2680043ECBD /* Debug */, + F8B211092A2EC2680043ECBD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ }; rootObject = 024A07A323FCBC3C009FBA6C /* Project object */; diff --git a/itlwm.xcodeproj/xcshareddata/xcschemes/AirportItlwm (all).xcscheme b/itlwm.xcodeproj/xcshareddata/xcschemes/AirportItlwm (all).xcscheme index 11aec955d..fa9a85aec 100644 --- a/itlwm.xcodeproj/xcshareddata/xcschemes/AirportItlwm (all).xcscheme +++ b/itlwm.xcodeproj/xcshareddata/xcschemes/AirportItlwm (all).xcscheme @@ -90,6 +90,20 @@ ReferencedContainer = "container:itlwm.xcodeproj"> + + + + Date: Mon, 26 Jun 2023 16:46:05 +0800 Subject: [PATCH 053/114] separate IO80211ControllerV2. --- include/Airport/Apple80211.h | 17 +- include/Airport/IO80211Controller.h | 137 +------------- include/Airport/IO80211ControllerV2.h | 261 ++++++++++++++++++++++++++ include/Airport/IO80211Interface.h | 4 - itlwm.xcodeproj/project.pbxproj | 16 ++ 5 files changed, 291 insertions(+), 144 deletions(-) create mode 100644 include/Airport/IO80211ControllerV2.h diff --git a/include/Airport/Apple80211.h b/include/Airport/Apple80211.h index 0e4f3c9d7..69423a124 100644 --- a/include/Airport/Apple80211.h +++ b/include/Airport/Apple80211.h @@ -15,8 +15,16 @@ #include "apple_private_spi.h" #include "debug.h" -#include "IO80211WorkQueue.h" #include "IO80211WorkLoop.h" +#ifdef IO80211FAMILY_V2 +#include "IO80211WorkQueue.h" +#include "IO80211ControllerV2.h" +#include "IO80211InfraInterface.h" +#include "IO80211InfraProtocol.h" +#include "IOSkywalkPacketBufferPool.h" +#include "IOSkywalkLegacyEthernetInterface.h" +#include "IO80211SkywalkInterface.h" +#else #include "IO80211Controller.h" #include "IO80211Interface.h" #include "IO80211VirtualInterface.h" @@ -24,11 +32,6 @@ #if __IO80211_TARGET >= __MAC_10_15 #include "IO80211SkywalkInterface.h" #endif -#if __IO80211_TARGET >= __MAC_14_0 -#include "IO80211InfraInterface.h" -#include "IO80211InfraProtocol.h" -#include "IOSkywalkPacketBufferPool.h" -#include "IOSkywalkLegacyEthernetInterface.h" -#endif +#endif /* IO80211FAMILY_V2 */ #endif /* Apple80211_h */ diff --git a/include/Airport/IO80211Controller.h b/include/Airport/IO80211Controller.h index 7cd8144a7..2527e847c 100644 --- a/include/Airport/IO80211Controller.h +++ b/include/Airport/IO80211Controller.h @@ -30,11 +30,6 @@ #include "apple80211_ioctl.h" #include "IO80211SkywalkInterface.h" #include "IO80211WorkLoop.h" -#include "IO80211WorkQueue.h" -#include "CCStream.h" -#include "CCDataPipe.h" -#include "CCLogPipe.h" -#include "CCLogStream.h" #define AUTH_TIMEOUT 15 // seconds @@ -76,6 +71,10 @@ typedef enum IO80211FeatureCode IO80211FeatureCode; class IOSkywalkInterface; class IO80211ScanManager; +enum CCStreamLogLevel +{ + LEVEL_1, +}; enum scanSource { @@ -132,133 +131,6 @@ typedef IOReturn (*IOCTL_FUNC)(IO80211Controller*, IO80211Interface*, IO80211Vir extern IOCTL_FUNC gGetHandlerTable[]; extern IOCTL_FUNC gSetHandlerTable[]; -#ifdef IO80211FAMILY_V2 - -class IO80211InterfaceAVCAdvisory; - -class IO80211Controller : public IOEthernetController { - OSDeclareAbstractStructors(IO80211Controller) - -public: - - virtual void free() APPLE_KEXT_OVERRIDE; - virtual bool init(OSDictionary *) APPLE_KEXT_OVERRIDE; - virtual IOReturn configureReport(IOReportChannelList *,UInt,void *,void *) APPLE_KEXT_OVERRIDE; - virtual IOReturn updateReport(IOReportChannelList *,UInt,void *,void *) APPLE_KEXT_OVERRIDE; - virtual bool start(IOService *) APPLE_KEXT_OVERRIDE; - virtual void stop(IOService *) APPLE_KEXT_OVERRIDE; - virtual IOWorkLoop* getWorkLoop(void) const APPLE_KEXT_OVERRIDE; - virtual const char* stringFromReturn(int) APPLE_KEXT_OVERRIDE; - virtual int errnoFromReturn(int) APPLE_KEXT_OVERRIDE; - virtual UInt32 getFeatures() const APPLE_KEXT_OVERRIDE; - virtual const OSString * newVendorString() const APPLE_KEXT_OVERRIDE; - virtual const OSString * newModelString() const APPLE_KEXT_OVERRIDE; - virtual bool createWorkLoop() APPLE_KEXT_OVERRIDE; - virtual IOReturn getHardwareAddress(IOEthernetAddress *) APPLE_KEXT_OVERRIDE; - virtual IOReturn setHardwareAddress(const IOEthernetAddress * addrP) APPLE_KEXT_OVERRIDE; - virtual IOReturn setMulticastMode(bool active) APPLE_KEXT_OVERRIDE; - virtual IOReturn setPromiscuousMode(bool active) APPLE_KEXT_OVERRIDE; - virtual bool isCommandProhibited(int) = 0; - virtual bool createWorkQueue(); - virtual IO80211WorkQueue *getWorkQueue(); - virtual void requestPacketTx(void*, UInt); - virtual IOCommandGate *getIO80211CommandGate(); - virtual IOReturn getHardwareAddressForInterface(IOEthernetAddress *); - virtual bool useAppleRSNSupplicant(IO80211VirtualInterface *); - virtual IO80211SkywalkInterface* getPrimarySkywalkInterface(void); - virtual int bpfOutputPacket(OSObject *,UInt,mbuf_t m); - virtual SInt32 monitorModeSetEnabled(bool, UInt); - virtual SInt32 apple80211_ioctl(IO80211SkywalkInterface *,unsigned long,void *, bool, bool); - virtual SInt32 apple80211VirtualRequest(UInt,int,IO80211VirtualInterface *,void *); - virtual SInt32 apple80211SkywalkRequest(UInt,int,IO80211SkywalkInterface *,void *); - virtual SInt32 apple80211SkywalkRequest(UInt,int,IO80211SkywalkInterface *,void *,void *); - - virtual SInt32 handleCardSpecific(IO80211SkywalkInterface *,unsigned long,void *,bool) = 0; - - virtual UInt32 hardwareOutputQueueDepth(); - virtual SInt32 performCountryCodeOperation(IO80211CountryCodeOp); - - virtual void dataLinkLayerAttachComplete(); - virtual SInt32 enableFeature(IO80211FeatureCode, void*) = 0; - - virtual IOReturn getDRIVER_VERSION(IO80211SkywalkInterface *,apple80211_version_data *) = 0; - virtual IOReturn getHARDWARE_VERSION(IO80211SkywalkInterface *,apple80211_version_data *) = 0; - virtual IOReturn getCARD_CAPABILITIES(IO80211SkywalkInterface *,apple80211_capability_data *) = 0; - virtual IOReturn getPOWER(IO80211SkywalkInterface *,apple80211_power_data *) = 0; - virtual IOReturn setPOWER(IO80211SkywalkInterface *,apple80211_power_data *) = 0; - virtual IOReturn getCOUNTRY_CODE(IO80211SkywalkInterface *,apple80211_country_code_data *) = 0; - virtual IOReturn setCOUNTRY_CODE(IO80211SkywalkInterface *,apple80211_country_code_data *) = 0; - virtual IOReturn setGET_DEBUG_INFO(IO80211SkywalkInterface *,apple80211_debug_command *) = 0; - - virtual SInt32 setVirtualHardwareAddress(IO80211VirtualInterface *,ether_addr *); - virtual SInt32 enableVirtualInterface(IO80211VirtualInterface *); - virtual SInt32 disableVirtualInterface(IO80211VirtualInterface *); - virtual bool requiresExplicitMBufRelease(); - virtual bool flowIdSupported() { - return false; - } - virtual IO80211FlowQueueLegacy* requestFlowQueue(FlowIdMetadata const*); - virtual void releaseFlowQueue(IO80211FlowQueue *); - virtual bool getLogPipes(CCPipe**, CCPipe**, CCPipe**); - virtual void enableFeatureForLoggingFlags(unsigned long long) {}; - virtual IOReturn requestQueueSizeAndTimeout(unsigned short *, unsigned short *) { return kIOReturnIOError; }; - virtual IOReturn enablePacketTimestamping(void) { - return kIOReturnUnsupported; - } - virtual IOReturn disablePacketTimestamping(void) { - return kIOReturnUnsupported; - } - - virtual UInt getPacketTSCounter(); - virtual void *getDriverTextLog(); - - virtual UInt32 selfDiagnosticsReport(int,char const*,UInt); - - virtual void *getFaultReporterFromDriver(); - - virtual UInt32 getDataQueueDepth(OSObject *); - virtual bool isAssociatedToMovingNetwork(void) { return false; } - virtual bool wasDynSARInFailSafeMode(void) { return false; } - virtual void updateAdvisoryScoresIfNeed(void); - virtual UInt64 getAVCAdvisoryInfo(IO80211InterfaceAVCAdvisory *); - virtual SInt32 apple80211_ioctl_get(IO80211SkywalkInterface *,void *, bool, bool); - virtual SInt32 apple80211_ioctl_set(IO80211SkywalkInterface *,void *, bool, bool); - virtual bool attachInterface(OSObject *,IOService *); - virtual SInt32 apple80211_ioctl_get(IO80211VirtualInterface *,void *,bool,bool); - virtual SInt32 apple80211_ioctl_set(IO80211VirtualInterface *,void *,bool,bool); - virtual void detachInterface(OSObject *,bool); - virtual IO80211VirtualInterface* createVirtualInterface(ether_addr *,UInt); - virtual bool attachVirtualInterface(IO80211VirtualInterface **,ether_addr *,UInt,bool); - virtual bool detachVirtualInterface(IO80211VirtualInterface *,bool); - virtual IOReturn enable(IO80211SkywalkInterface *); - virtual IOReturn disable(IO80211SkywalkInterface *); - - OSMetaClassDeclareReservedUnused( IO80211Controller, 0); - OSMetaClassDeclareReservedUnused( IO80211Controller, 1); - OSMetaClassDeclareReservedUnused( IO80211Controller, 2); - OSMetaClassDeclareReservedUnused( IO80211Controller, 3); - OSMetaClassDeclareReservedUnused( IO80211Controller, 4); - OSMetaClassDeclareReservedUnused( IO80211Controller, 5); - OSMetaClassDeclareReservedUnused( IO80211Controller, 6); - OSMetaClassDeclareReservedUnused( IO80211Controller, 7); - OSMetaClassDeclareReservedUnused( IO80211Controller, 8); - OSMetaClassDeclareReservedUnused( IO80211Controller, 9); - OSMetaClassDeclareReservedUnused( IO80211Controller, 10); - OSMetaClassDeclareReservedUnused( IO80211Controller, 11); - OSMetaClassDeclareReservedUnused( IO80211Controller, 12); - OSMetaClassDeclareReservedUnused( IO80211Controller, 13); - OSMetaClassDeclareReservedUnused( IO80211Controller, 14); - OSMetaClassDeclareReservedUnused( IO80211Controller, 15); - - virtual void postMessage(UInt,void *,unsigned long,UInt,void *); - virtual IOReturn setMulticastList(ether_addr const*, UInt); - -protected: - uint8_t filler[0x128]; -}; - -#else - class IO80211Controller : public IOEthernetController { OSDeclareAbstractStructors(IO80211Controller) @@ -491,7 +363,6 @@ class IO80211Controller : public IOEthernetController { protected: uint8_t filler[0x500]; }; -#endif // 0x215: 1 byte, length of channel sequence, should be 16 // 0x21c: channel sequence, should contain 16 elements of length 12, possibly apple80211_channel (but why 16?) diff --git a/include/Airport/IO80211ControllerV2.h b/include/Airport/IO80211ControllerV2.h new file mode 100644 index 000000000..4f06e19eb --- /dev/null +++ b/include/Airport/IO80211ControllerV2.h @@ -0,0 +1,261 @@ +// +// IOSkywalkInterface.h +// itlwm +// +// Created by qcwap on 2023/6/7. +// Copyright © 2023 钟先耀. All rights reserved. +// + +#ifndef _IO80211CONTROLLER_H +#define _IO80211CONTROLLER_H + +#if defined(KERNEL) && defined(__cplusplus) + +#include +#include + +// This is necessary, because even the latest Xcode does not support properly targeting 11.0. +#ifndef __IO80211_TARGET +#error "Please define __IO80211_TARGET to the requested version" +#endif + +#if VERSION_MAJOR > 8 +#define _MODERN_BPF +#endif + +#include + +#include + +#include +#include + +#include "apple80211_ioctl.h" +#include "IO80211SkywalkInterface.h" +#include "IO80211WorkLoop.h" +#include "IO80211WorkQueue.h" +#include "CCStream.h" +#include "CCDataPipe.h" +#include "CCLogPipe.h" +#include "CCLogStream.h" + +#define AUTH_TIMEOUT 15 // seconds + +/*! @enum LinkSpeed. + @abstract ???. + @discussion ???. + @constant LINK_SPEED_80211A 54 Mbps + @constant LINK_SPEED_80211B 11 Mbps. + @constant LINK_SPEED_80211G 54 Mbps. + */ +enum { + LINK_SPEED_80211A = 54000000ul, // 54 Mbps + LINK_SPEED_80211B = 11000000ul, // 11 Mbps + LINK_SPEED_80211G = 54000000ul, // 54 Mbps + LINK_SPEED_80211N = 300000000ul, // 300 Mbps (MCS index 15, 400ns GI, 40 MHz channel) +}; + +enum IO80211CountryCodeOp +{ + kIO80211CountryCodeReset, // Reset country code to world wide default, and start + // searching for 802.11d beacon +}; +typedef enum IO80211CountryCodeOp IO80211CountryCodeOp; + +enum IO80211SystemPowerState +{ + kIO80211SystemPowerStateUnknown, + kIO80211SystemPowerStateAwake, + kIO80211SystemPowerStateSleeping, +}; +typedef enum IO80211SystemPowerState IO80211SystemPowerState; + +enum IO80211FeatureCode +{ + kIO80211Feature80211n = 1, +}; +typedef enum IO80211FeatureCode IO80211FeatureCode; + + +class IOSkywalkInterface; +class IO80211ScanManager; + +enum scanSource +{ + SOURCE_1, +}; + +enum joinStatus +{ + STATUS_1, +}; + +class IO80211Controller; +class IO80211Interface; +class IO82110WorkLoop; +class IO80211VirtualInterface; +class IO80211ControllerMonitor; +class CCLogPipe; +class CCIOReporterLogStream; +class CCLogStream; +class IO80211VirtualInterface; +class IO80211RangingManager; +class IO80211FlowQueue; +class IO80211FlowQueueLegacy; +class FlowIdMetadata; +class IOReporter; +class IO80211InfraInterface; +extern void IO80211VirtualInterfaceNamerRetain(); + + +struct apple80211_hostap_state; + +struct apple80211_awdl_sync_channel_sequence; +struct ieee80211_ht_capability_ie; +struct apple80211_channel_switch_announcement; +struct apple80211_beacon_period_data; +struct apple80211_power_debug_sub_info; +struct apple80211_stat_report; +struct apple80211_frame_counters; +struct apple80211_leaky_ap_event; +struct apple80211_chip_stats; +struct apple80211_extended_stats; +struct apple80211_ampdu_stat_report; +struct apple80211_btCoex_report; +struct apple80211_cca_report; +class CCPipe; +struct apple80211_lteCoex_report; + +//typedef int scanSource; +//typedef int joinStatus; +//typedef int CCStreamLogLevel; +typedef IOReturn (*IOCTL_FUNC)(IO80211Controller*, IO80211Interface*, IO80211VirtualInterface*, apple80211req*, bool); +extern IOCTL_FUNC gGetHandlerTable[]; +extern IOCTL_FUNC gSetHandlerTable[]; + +class IO80211InterfaceAVCAdvisory; + +class IO80211Controller : public IOEthernetController { + OSDeclareAbstractStructors(IO80211Controller) + +public: + + virtual void free() APPLE_KEXT_OVERRIDE; + virtual bool init(OSDictionary *) APPLE_KEXT_OVERRIDE; + virtual IOReturn configureReport(IOReportChannelList *,UInt,void *,void *) APPLE_KEXT_OVERRIDE; + virtual IOReturn updateReport(IOReportChannelList *,UInt,void *,void *) APPLE_KEXT_OVERRIDE; + virtual bool start(IOService *) APPLE_KEXT_OVERRIDE; + virtual void stop(IOService *) APPLE_KEXT_OVERRIDE; + virtual IOWorkLoop* getWorkLoop(void) const APPLE_KEXT_OVERRIDE; + virtual const char* stringFromReturn(int) APPLE_KEXT_OVERRIDE; + virtual int errnoFromReturn(int) APPLE_KEXT_OVERRIDE; + virtual UInt32 getFeatures() const APPLE_KEXT_OVERRIDE; + virtual const OSString * newVendorString() const APPLE_KEXT_OVERRIDE; + virtual const OSString * newModelString() const APPLE_KEXT_OVERRIDE; + virtual bool createWorkLoop() APPLE_KEXT_OVERRIDE; + virtual IOReturn getHardwareAddress(IOEthernetAddress *) APPLE_KEXT_OVERRIDE; + virtual IOReturn setHardwareAddress(const IOEthernetAddress * addrP) APPLE_KEXT_OVERRIDE; + virtual IOReturn setMulticastMode(bool active) APPLE_KEXT_OVERRIDE; + virtual IOReturn setPromiscuousMode(bool active) APPLE_KEXT_OVERRIDE; + virtual bool isCommandProhibited(int) = 0; + virtual bool createWorkQueue(); + virtual IO80211WorkQueue *getWorkQueue(); + virtual void requestPacketTx(void*, UInt); + virtual IOCommandGate *getIO80211CommandGate(); + virtual IOReturn getHardwareAddressForInterface(IOEthernetAddress *); + virtual bool useAppleRSNSupplicant(IO80211VirtualInterface *); + virtual IO80211SkywalkInterface* getPrimarySkywalkInterface(void); + virtual int bpfOutputPacket(OSObject *,UInt,mbuf_t m); + virtual SInt32 monitorModeSetEnabled(bool, UInt); + virtual SInt32 apple80211_ioctl(IO80211SkywalkInterface *,unsigned long,void *, bool, bool); + virtual SInt32 apple80211VirtualRequest(UInt,int,IO80211VirtualInterface *,void *); + virtual SInt32 apple80211SkywalkRequest(UInt,int,IO80211SkywalkInterface *,void *); + virtual SInt32 apple80211SkywalkRequest(UInt,int,IO80211SkywalkInterface *,void *,void *); + + virtual SInt32 handleCardSpecific(IO80211SkywalkInterface *,unsigned long,void *,bool) = 0; + + virtual UInt32 hardwareOutputQueueDepth(); + virtual SInt32 performCountryCodeOperation(IO80211CountryCodeOp); + + virtual void dataLinkLayerAttachComplete(); + virtual SInt32 enableFeature(IO80211FeatureCode, void*) = 0; + + virtual IOReturn getDRIVER_VERSION(IO80211SkywalkInterface *,apple80211_version_data *) = 0; + virtual IOReturn getHARDWARE_VERSION(IO80211SkywalkInterface *,apple80211_version_data *) = 0; + virtual IOReturn getCARD_CAPABILITIES(IO80211SkywalkInterface *,apple80211_capability_data *) = 0; + virtual IOReturn getPOWER(IO80211SkywalkInterface *,apple80211_power_data *) = 0; + virtual IOReturn setPOWER(IO80211SkywalkInterface *,apple80211_power_data *) = 0; + virtual IOReturn getCOUNTRY_CODE(IO80211SkywalkInterface *,apple80211_country_code_data *) = 0; + virtual IOReturn setCOUNTRY_CODE(IO80211SkywalkInterface *,apple80211_country_code_data *) = 0; + virtual IOReturn setGET_DEBUG_INFO(IO80211SkywalkInterface *,apple80211_debug_command *) = 0; + + virtual SInt32 setVirtualHardwareAddress(IO80211VirtualInterface *,ether_addr *); + virtual SInt32 enableVirtualInterface(IO80211VirtualInterface *); + virtual SInt32 disableVirtualInterface(IO80211VirtualInterface *); + virtual bool requiresExplicitMBufRelease(); + virtual bool flowIdSupported() { + return false; + } + virtual IO80211FlowQueueLegacy* requestFlowQueue(FlowIdMetadata const*); + virtual void releaseFlowQueue(IO80211FlowQueue *); + virtual bool getLogPipes(CCPipe**, CCPipe**, CCPipe**); + virtual void enableFeatureForLoggingFlags(unsigned long long) {}; + virtual IOReturn requestQueueSizeAndTimeout(unsigned short *, unsigned short *) { return kIOReturnIOError; }; + virtual IOReturn enablePacketTimestamping(void) { + return kIOReturnUnsupported; + } + virtual IOReturn disablePacketTimestamping(void) { + return kIOReturnUnsupported; + } + + virtual UInt getPacketTSCounter(); + virtual void *getDriverTextLog(); + + virtual UInt32 selfDiagnosticsReport(int,char const*,UInt); + + virtual void *getFaultReporterFromDriver(); + + virtual UInt32 getDataQueueDepth(OSObject *); + virtual bool isAssociatedToMovingNetwork(void) { return false; } + virtual bool wasDynSARInFailSafeMode(void) { return false; } + virtual void updateAdvisoryScoresIfNeed(void); + virtual UInt64 getAVCAdvisoryInfo(IO80211InterfaceAVCAdvisory *); + virtual SInt32 apple80211_ioctl_get(IO80211SkywalkInterface *,void *, bool, bool); + virtual SInt32 apple80211_ioctl_set(IO80211SkywalkInterface *,void *, bool, bool); + virtual bool attachInterface(OSObject *,IOService *); + virtual SInt32 apple80211_ioctl_get(IO80211VirtualInterface *,void *,bool,bool); + virtual SInt32 apple80211_ioctl_set(IO80211VirtualInterface *,void *,bool,bool); + virtual void detachInterface(OSObject *,bool); + virtual IO80211VirtualInterface* createVirtualInterface(ether_addr *,UInt); + virtual bool attachVirtualInterface(IO80211VirtualInterface **,ether_addr *,UInt,bool); + virtual bool detachVirtualInterface(IO80211VirtualInterface *,bool); + virtual IOReturn enable(IO80211SkywalkInterface *); + virtual IOReturn disable(IO80211SkywalkInterface *); + + OSMetaClassDeclareReservedUnused( IO80211Controller, 0); + OSMetaClassDeclareReservedUnused( IO80211Controller, 1); + OSMetaClassDeclareReservedUnused( IO80211Controller, 2); + OSMetaClassDeclareReservedUnused( IO80211Controller, 3); + OSMetaClassDeclareReservedUnused( IO80211Controller, 4); + OSMetaClassDeclareReservedUnused( IO80211Controller, 5); + OSMetaClassDeclareReservedUnused( IO80211Controller, 6); + OSMetaClassDeclareReservedUnused( IO80211Controller, 7); + OSMetaClassDeclareReservedUnused( IO80211Controller, 8); + OSMetaClassDeclareReservedUnused( IO80211Controller, 9); + OSMetaClassDeclareReservedUnused( IO80211Controller, 10); + OSMetaClassDeclareReservedUnused( IO80211Controller, 11); + OSMetaClassDeclareReservedUnused( IO80211Controller, 12); + OSMetaClassDeclareReservedUnused( IO80211Controller, 13); + OSMetaClassDeclareReservedUnused( IO80211Controller, 14); + OSMetaClassDeclareReservedUnused( IO80211Controller, 15); + + virtual void postMessage(UInt,void *,unsigned long,UInt,void *); + virtual IOReturn setMulticastList(ether_addr const*, UInt); + +protected: + uint8_t filler[0x128]; +}; + +#endif /* defined(KERNEL) && defined(__cplusplus) */ + +#endif /* !_IO80211CONTROLLER_H */ diff --git a/include/Airport/IO80211Interface.h b/include/Airport/IO80211Interface.h index a8e56425b..0c7f3fad6 100644 --- a/include/Airport/IO80211Interface.h +++ b/include/Airport/IO80211Interface.h @@ -22,8 +22,6 @@ #include #include -#ifndef IO80211FAMILY_V2 - enum IO80211LinkState { kIO80211NetworkLinkUndefined, // Starting link state when an interface is created @@ -290,8 +288,6 @@ class IO80211Interface : public IOEthernetInterface u_int8_t dat[0x500]; }; -#endif - #endif /* defined(KERNEL) && defined(__cplusplus) */ #endif /* ! _IO80211INTERFACE_H */ diff --git a/itlwm.xcodeproj/project.pbxproj b/itlwm.xcodeproj/project.pbxproj index 749349497..7990a08d7 100644 --- a/itlwm.xcodeproj/project.pbxproj +++ b/itlwm.xcodeproj/project.pbxproj @@ -577,6 +577,13 @@ F89B6C20250232DC000F77FF /* _mbuf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F8D257732495A33500872E4F /* _mbuf.cpp */; }; F89B6C21250232DC000F77FF /* _task.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F8F9EDE0240B7415009CB8E7 /* _task.cpp */; }; F89B6C2325027609000F77FF /* debug.h in Headers */ = {isa = PBXBuildFile; fileRef = F89B6C2225027609000F77FF /* debug.h */; }; + F89F35F22A49867F00061876 /* IO80211ControllerV2.h in Headers */ = {isa = PBXBuildFile; fileRef = F89F35F12A49867F00061876 /* IO80211ControllerV2.h */; }; + F89F35F32A49867F00061876 /* IO80211ControllerV2.h in Headers */ = {isa = PBXBuildFile; fileRef = F89F35F12A49867F00061876 /* IO80211ControllerV2.h */; }; + F89F35F42A49867F00061876 /* IO80211ControllerV2.h in Headers */ = {isa = PBXBuildFile; fileRef = F89F35F12A49867F00061876 /* IO80211ControllerV2.h */; }; + F89F35F52A49867F00061876 /* IO80211ControllerV2.h in Headers */ = {isa = PBXBuildFile; fileRef = F89F35F12A49867F00061876 /* IO80211ControllerV2.h */; }; + F89F35F62A49867F00061876 /* IO80211ControllerV2.h in Headers */ = {isa = PBXBuildFile; fileRef = F89F35F12A49867F00061876 /* IO80211ControllerV2.h */; }; + F89F35F72A49867F00061876 /* IO80211ControllerV2.h in Headers */ = {isa = PBXBuildFile; fileRef = F89F35F12A49867F00061876 /* IO80211ControllerV2.h */; }; + F89F35F82A49867F00061876 /* IO80211ControllerV2.h in Headers */ = {isa = PBXBuildFile; fileRef = F89F35F12A49867F00061876 /* IO80211ControllerV2.h */; }; F8A4307325062CE300EA545E /* zutil.c in Sources */ = {isa = PBXBuildFile; fileRef = F8FA0EED2501E8C100B1822E /* zutil.c */; }; F8AE64F9285471560085B4CF /* debug.h in Headers */ = {isa = PBXBuildFile; fileRef = F89B6C2225027609000F77FF /* debug.h */; }; F8AE64FA285471560085B4CF /* IOSkywalkEthernetInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = F89B6BD025021E66000F77FF /* IOSkywalkEthernetInterface.h */; }; @@ -1042,6 +1049,7 @@ F89B6BDE25022FB5000F77FF /* AirportVirtualIOCTL.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AirportVirtualIOCTL.cpp; sourceTree = ""; }; F89B6BE025022FC7000F77FF /* AirportAWDL.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AirportAWDL.cpp; sourceTree = ""; }; F89B6C2225027609000F77FF /* debug.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = debug.h; sourceTree = ""; }; + F89F35F12A49867F00061876 /* IO80211ControllerV2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IO80211ControllerV2.h; sourceTree = ""; }; F8A2A68B2A305B9E002ABDDB /* IOSkywalkNetworkInterface.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IOSkywalkNetworkInterface.h; sourceTree = ""; }; F8A2A68C2A305BAC002ABDDB /* IOSkywalkInterface.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IOSkywalkInterface.h; sourceTree = ""; }; F8A763892766B95F004606BE /* iwlwifi-so-a0-gf4-a0.pnvm */ = {isa = PBXFileReference; lastKnownFileType = file; path = "iwlwifi-so-a0-gf4-a0.pnvm"; sourceTree = ""; }; @@ -1411,6 +1419,7 @@ F84AD8832A497DB200DC8DED /* IOSkywalkPacketBufferPool.h */, F89B6B8325021A79000F77FF /* apple_private_spi.h */, F8F7EA35252D834500520FD4 /* IO80211Controller.h */, + F89F35F12A49867F00061876 /* IO80211ControllerV2.h */, F8F7EA38252D834500520FD4 /* IO80211Interface.h */, F8F7EA36252D834500520FD4 /* IO80211P2PInterface.h */, F8F7EA37252D834500520FD4 /* IO80211SkywalkInterface.h */, @@ -1686,6 +1695,7 @@ F8F7EA51252D834600520FD4 /* IO80211WorkLoop.h in Headers */, F84AD8BA2A497DB200DC8DED /* CCDataPipe.h in Headers */, F84AD8C12A497DB200DC8DED /* CCLogStream.h in Headers */, + F89F35F52A49867F00061876 /* IO80211ControllerV2.h in Headers */, 35CBE661251CB89700435CBC /* apple80211_var.h in Headers */, 35CBE664251CB89700435CBC /* AirportItlwmInterface.hpp in Headers */, F84AD8CF2A497DB200DC8DED /* IOSkywalkLegacyEthernetInterface.h in Headers */, @@ -1719,6 +1729,7 @@ F8F7EA4F252D834600520FD4 /* IO80211WorkLoop.h in Headers */, F84AD8B82A497DB200DC8DED /* CCDataPipe.h in Headers */, F84AD8BF2A497DB200DC8DED /* CCLogStream.h in Headers */, + F89F35F32A49867F00061876 /* IO80211ControllerV2.h in Headers */, 35CBE6CB251CB8BF00435CBC /* apple80211_var.h in Headers */, 35CBE6CE251CB8BF00435CBC /* AirportItlwmInterface.hpp in Headers */, F84AD8CD2A497DB200DC8DED /* IOSkywalkLegacyEthernetInterface.h in Headers */, @@ -1752,6 +1763,7 @@ F8F7EA4E252D834600520FD4 /* IO80211WorkLoop.h in Headers */, F84AD8B72A497DB200DC8DED /* CCDataPipe.h in Headers */, F84AD8BE2A497DB200DC8DED /* CCLogStream.h in Headers */, + F89F35F22A49867F00061876 /* IO80211ControllerV2.h in Headers */, 35CBE736251CB8CA00435CBC /* apple80211_var.h in Headers */, 35CBE739251CB8CA00435CBC /* AirportItlwmInterface.hpp in Headers */, F84AD8CC2A497DB200DC8DED /* IOSkywalkLegacyEthernetInterface.h in Headers */, @@ -1797,6 +1809,7 @@ F897ECC3266EFF93005EE8F7 /* IO80211SkywalkInterface.h in Headers */, F84AD8C22A497DB200DC8DED /* CCLogStream.h in Headers */, F897ECC4266EFF93005EE8F7 /* AirportItlwm.hpp in Headers */, + F89F35F62A49867F00061876 /* IO80211ControllerV2.h in Headers */, F897ECC5266EFF93005EE8F7 /* IO80211VirtualInterface.h in Headers */, F897ECC6266EFF93005EE8F7 /* IO80211Controller.h in Headers */, F897ECC7266EFF93005EE8F7 /* (null) in Headers */, @@ -1820,6 +1833,7 @@ F8F7EA50252D834600520FD4 /* IO80211WorkLoop.h in Headers */, F84AD8B92A497DB200DC8DED /* CCDataPipe.h in Headers */, F84AD8C02A497DB200DC8DED /* CCLogStream.h in Headers */, + F89F35F42A49867F00061876 /* IO80211ControllerV2.h in Headers */, F89B6BC925021DED000F77FF /* apple80211_var.h in Headers */, F8CA44A425091AF60036119A /* AirportItlwmInterface.hpp in Headers */, F84AD8CE2A497DB200DC8DED /* IOSkywalkLegacyEthernetInterface.h in Headers */, @@ -1865,6 +1879,7 @@ F8AE6502285471560085B4CF /* IO80211SkywalkInterface.h in Headers */, F84AD8C32A497DB200DC8DED /* CCLogStream.h in Headers */, F8AE6503285471560085B4CF /* AirportItlwm.hpp in Headers */, + F89F35F72A49867F00061876 /* IO80211ControllerV2.h in Headers */, F8AE6504285471560085B4CF /* IO80211VirtualInterface.h in Headers */, F8AE6505285471560085B4CF /* IO80211Controller.h in Headers */, F8AE6506285471560085B4CF /* (null) in Headers */, @@ -1900,6 +1915,7 @@ F8B210B42A2EC2680043ECBD /* IO80211SkywalkInterface.h in Headers */, F84AD8C42A497DB200DC8DED /* CCLogStream.h in Headers */, F8B210B52A2EC2680043ECBD /* AirportItlwm.hpp in Headers */, + F89F35F82A49867F00061876 /* IO80211ControllerV2.h in Headers */, F8B210B62A2EC2680043ECBD /* IO80211VirtualInterface.h in Headers */, F8B210B72A2EC2680043ECBD /* IO80211Controller.h in Headers */, F8B210B82A2EC2680043ECBD /* (null) in Headers */, From 0c91138ea02a5b0624e13524b818bba855f3f355 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Mon, 26 Jun 2023 17:03:58 +0800 Subject: [PATCH 054/114] Clean legacy IO80211SkywalkInterface import. --- include/Airport/Apple80211.h | 3 --- include/Airport/IO80211Controller.h | 2 +- include/Airport/IO80211Interface.h | 7 ------- include/Airport/IO80211SkywalkInterface.h | 15 --------------- include/Airport/IO80211VirtualInterface.h | 20 -------------------- include/Airport/apple80211_var.h | 8 ++++++++ 6 files changed, 9 insertions(+), 46 deletions(-) diff --git a/include/Airport/Apple80211.h b/include/Airport/Apple80211.h index 69423a124..517963a18 100644 --- a/include/Airport/Apple80211.h +++ b/include/Airport/Apple80211.h @@ -29,9 +29,6 @@ #include "IO80211Interface.h" #include "IO80211VirtualInterface.h" #include "IO80211P2PInterface.h" -#if __IO80211_TARGET >= __MAC_10_15 -#include "IO80211SkywalkInterface.h" -#endif #endif /* IO80211FAMILY_V2 */ #endif /* Apple80211_h */ diff --git a/include/Airport/IO80211Controller.h b/include/Airport/IO80211Controller.h index 2527e847c..71d07ea79 100644 --- a/include/Airport/IO80211Controller.h +++ b/include/Airport/IO80211Controller.h @@ -28,7 +28,6 @@ #include #include "apple80211_ioctl.h" -#include "IO80211SkywalkInterface.h" #include "IO80211WorkLoop.h" #define AUTH_TIMEOUT 15 // seconds @@ -86,6 +85,7 @@ enum joinStatus STATUS_1, }; +class IO80211SkywalkInterface; class IO80211Controller; class IO80211Interface; class IO82110WorkLoop; diff --git a/include/Airport/IO80211Interface.h b/include/Airport/IO80211Interface.h index 0c7f3fad6..87b8a624c 100644 --- a/include/Airport/IO80211Interface.h +++ b/include/Airport/IO80211Interface.h @@ -22,13 +22,6 @@ #include #include -enum IO80211LinkState -{ - kIO80211NetworkLinkUndefined, // Starting link state when an interface is created - kIO80211NetworkLinkDown, // Interface not capable of transmitting packets - kIO80211NetworkLinkUp, // Interface capable of transmitting packets -}; -typedef enum IO80211LinkState IO80211LinkState; typedef UInt kIO80211InterfaceType; /*! @defined kIO80211InterfaceClass diff --git a/include/Airport/IO80211SkywalkInterface.h b/include/Airport/IO80211SkywalkInterface.h index 81fc76a84..6e2d8dcde 100644 --- a/include/Airport/IO80211SkywalkInterface.h +++ b/include/Airport/IO80211SkywalkInterface.h @@ -17,8 +17,6 @@ #error "Please define __IO80211_TARGET to the requested version" #endif -#ifdef IO80211FAMILY_V2 - class TxSubmissionDequeueStats; class TxCompletionEnqueueStats; class IO80211NetworkPacket; @@ -39,13 +37,6 @@ struct apple80211_lteCoex_report; struct apple80211_frame_counters; struct userPrintCtx; struct apple80211_lqm_summary; -enum IO80211LinkState -{ - kIO80211NetworkLinkUndefined, // Starting link state when an interface is created - kIO80211NetworkLinkDown, // Interface not capable of transmitting packets - kIO80211NetworkLinkUp, // Interface capable of transmitting packets -}; -typedef enum IO80211LinkState IO80211LinkState; struct TxPacketRequest { uint16_t unk1; // 0 @@ -197,10 +188,4 @@ class IO80211SkywalkInterface : public IOSkywalkEthernetInterface { char _data[0x118]; }; -#else - -class IO80211SkywalkInterface; - -#endif - #endif /* _IO80211SKYWALK_H */ diff --git a/include/Airport/IO80211VirtualInterface.h b/include/Airport/IO80211VirtualInterface.h index c64306cfd..1a364d317 100644 --- a/include/Airport/IO80211VirtualInterface.h +++ b/include/Airport/IO80211VirtualInterface.h @@ -1,19 +1,7 @@ #ifndef IO80211VirtualInterface_h #define IO80211VirtualInterface_h -#include -#include - -// This is necessary, because even the latest Xcode does not support properly targeting 11.0. -#ifndef __IO80211_TARGET -#error "Please define __IO80211_TARGET to the requested version" -#endif - -#ifndef IO80211FAMILY_V2 #include "IO80211Interface.h" -#else -#include "IO80211SkywalkInterface.h" -#endif #include "apple_private_spi.h" typedef UInt64 IO80211FlowQueueHash; @@ -29,14 +17,6 @@ struct apple80211_awdl_statistics; struct apple80211_lowlatency_peer_statistics_evevt; struct apple80211_p2p_airplay_statistics; struct apple80211_awdl_sidecar_statistics; -struct apple80211_pmk_cache_data; -struct apple80211_interface_availability; -struct packet_info_tx; -struct userPrintCtx; -struct apple80211_chip_counters_tx; -struct apple80211_chip_error_counters_tx; -struct apple80211_chip_counters_rx; -struct apple80211_ManagementInformationBasedot11_counters; class IO80211VirtualInterface : public IOService { OSDeclareDefaultStructors(IO80211VirtualInterface) diff --git a/include/Airport/apple80211_var.h b/include/Airport/apple80211_var.h index 9e9ecad43..c624087ae 100644 --- a/include/Airport/apple80211_var.h +++ b/include/Airport/apple80211_var.h @@ -595,6 +595,14 @@ enum apple80211_assoc_flags { APPLE80211_ASSOC_F_CLOSED = 1, // flag: scan was directed, needed to remember closed networks }; +enum IO80211LinkState +{ + kIO80211NetworkLinkUndefined, // Starting link state when an interface is created + kIO80211NetworkLinkDown, // Interface not capable of transmitting packets + kIO80211NetworkLinkUp, // Interface capable of transmitting packets +}; +typedef enum IO80211LinkState IO80211LinkState; + // Kernel messages struct apple80211_status_msg_hdr From 5afc8c5f420681ae33cfc49da2366c8091900234 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Mon, 26 Jun 2023 17:06:24 +0800 Subject: [PATCH 055/114] Add __MAC_14_0 constant. --- itl80211/compat.h | 2 ++ itlwm/PrivateSPI.pch | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/itl80211/compat.h b/itl80211/compat.h index 542089c12..69abccac3 100644 --- a/itl80211/compat.h +++ b/itl80211/compat.h @@ -181,6 +181,8 @@ typedef pci_intr_handle* pci_intr_handle_t; #define DVACT_POWERDOWN 6 /* power device down */ struct device { + IOService *provider; + void *_data; char dv_xname[16]; }; diff --git a/itlwm/PrivateSPI.pch b/itlwm/PrivateSPI.pch index b89ddef7c..65baa28a5 100644 --- a/itlwm/PrivateSPI.pch +++ b/itlwm/PrivateSPI.pch @@ -12,3 +12,7 @@ typedef u_int32_t ifnet_ctl_cmd_t; #ifndef __MAC_13_0 #define __MAC_13_0 130000 #endif + +#ifndef __MAC_14_0 +#define __MAC_14_0 140000 +#endif From 395a9f72b2718d71f72347410f9bdf0b920d1c67 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Mon, 26 Jun 2023 18:23:53 +0800 Subject: [PATCH 056/114] separate struct apple80211_capability_data. --- include/Airport/apple80211_ioctl.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/Airport/apple80211_ioctl.h b/include/Airport/apple80211_ioctl.h index b4912731b..e980625fb 100644 --- a/include/Airport/apple80211_ioctl.h +++ b/include/Airport/apple80211_ioctl.h @@ -430,11 +430,19 @@ struct apple80211_bssid_data struct ether_addr bssid; }; +#if __IO80211_TARGET >= __MAC_14_0 struct apple80211_capability_data { u_int32_t version; u_int8_t capabilities[14]; }; +#else +struct apple80211_capability_data +{ + u_int32_t version; + u_int8_t capabilities[11]; +}; +#endif struct apple80211_state_data { From cb677db5995b6cdba110174aff9f474ea67d941f Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Tue, 27 Jun 2023 09:21:36 +0800 Subject: [PATCH 057/114] Add missing import. --- include/Airport/IOSkywalkLegacyEthernetInterface.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/Airport/IOSkywalkLegacyEthernetInterface.h b/include/Airport/IOSkywalkLegacyEthernetInterface.h index 4b4be4644..71af99776 100644 --- a/include/Airport/IOSkywalkLegacyEthernetInterface.h +++ b/include/Airport/IOSkywalkLegacyEthernetInterface.h @@ -10,6 +10,7 @@ #define IOSkywalkLegacyEthernetInterface_h #include +#include class IOSkywalkLegacyEthernetInterface : public IOEthernetInterface { OSDeclareDefaultStructors(IOSkywalkLegacyEthernetInterface) From 3284ae438fec4fed7fdb4b931a2bd2c04b510a56 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Tue, 27 Jun 2023 18:47:43 +0800 Subject: [PATCH 058/114] revert apple80211_country_code_data. --- include/Airport/apple80211_ioctl.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/include/Airport/apple80211_ioctl.h b/include/Airport/apple80211_ioctl.h index e980625fb..ea6057212 100644 --- a/include/Airport/apple80211_ioctl.h +++ b/include/Airport/apple80211_ioctl.h @@ -746,20 +746,11 @@ struct apple80211_stats_data u_int32_t rx_errors; }; -#if __IO80211_TARGET >= __MAC_14_0 -struct apple80211_country_code_data -{ - u_int32_t version; - uint16_t cc; - uint8_t len; -}; -#else struct apple80211_country_code_data { u_int32_t version; u_int8_t cc[APPLE80211_MAX_CC_LEN]; }; -#endif struct apple80211_last_rx_pkt_data { From ad56e9ce110326afcfeb2aaf8ce558e4314dc39c Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Fri, 30 Jun 2023 12:36:42 +0800 Subject: [PATCH 059/114] Add AirportItlwmV2 to support Sonoma. --- AirportItlwm/AirportItlwm-Sonoma-Info.plist | 76 ++ .../AirportItlwmEthernetInterface.cpp | 70 ++ .../AirportItlwmEthernetInterface.hpp | 42 + AirportItlwm/AirportItlwmSkywalkInterface.cpp | 1003 +++++++++++++++++ AirportItlwm/AirportItlwmSkywalkInterface.hpp | 271 +++++ AirportItlwm/AirportItlwmV2.cpp | 994 ++++++++++++++++ AirportItlwm/AirportItlwmV2.hpp | 254 +++++ AirportItlwm/IOPCIEDeviceWrapper.cpp | 116 ++ AirportItlwm/IOPCIEDeviceWrapper.hpp | 33 + include/Airport/IOSkywalkEthernetInterface.h | 14 + include/Airport/IOSkywalkInterface.h | 4 +- include/Airport/IOSkywalkNetworkInterface.h | 14 +- itlwm.xcodeproj/project.pbxproj | 44 +- 13 files changed, 2921 insertions(+), 14 deletions(-) create mode 100644 AirportItlwm/AirportItlwm-Sonoma-Info.plist create mode 100644 AirportItlwm/AirportItlwmEthernetInterface.cpp create mode 100644 AirportItlwm/AirportItlwmEthernetInterface.hpp create mode 100644 AirportItlwm/AirportItlwmSkywalkInterface.cpp create mode 100644 AirportItlwm/AirportItlwmSkywalkInterface.hpp create mode 100644 AirportItlwm/AirportItlwmV2.cpp create mode 100644 AirportItlwm/AirportItlwmV2.hpp create mode 100644 AirportItlwm/IOPCIEDeviceWrapper.cpp create mode 100644 AirportItlwm/IOPCIEDeviceWrapper.hpp diff --git a/AirportItlwm/AirportItlwm-Sonoma-Info.plist b/AirportItlwm/AirportItlwm-Sonoma-Info.plist new file mode 100644 index 000000000..b85417836 --- /dev/null +++ b/AirportItlwm/AirportItlwm-Sonoma-Info.plist @@ -0,0 +1,76 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + $(MODULE_VERSION) + CFBundleVersion + $(MODULE_VERSION) + IOKitPersonalities + + NetworkController + + CFBundleIdentifier + com.zxystd.AirportItlwm + IOClass + AirportItlwm + IOMatchCategory + WiFiDriver + IONetworkRootType + airport + IOProbeScore + 70000 + IOProviderClass + IOPCIEDeviceWrapper + IOResourceMatch + IOBSD + + itlwm + + CFBundleIdentifier + com.zxystd.AirportItlwm + IOClass + IOPCIEDeviceWrapper + IOPCIMatch + 0x27238086 0x43F08086 0xA0F08086 0x34F08086 0x4DF08086 0x02F08086 0x3DF08086 0x06F08086 0x27208086 0x08b18086 0x08b28086 0x08b38086 0x08b48086 0x095a8086 0x095b8086 0x31658086 0x31668086 0x24f38086 0x24f48086 0x24f58086 0x24f68086 0x24fb8086 0x24fd8086 0x25268086 0x9df08086 0xa3708086 0x31DC8086 0x30DC8086 0x271C8086 0x271B8086 0x42a48086 0x00a08086 0x00a48086 0x02a08086 0x40a48086 0x00608086 0x00648086 0x02608086 0x02648086 0x42298086 0x422b8086 0x422c8086 0x42308086 0x42328086 0x42358086 0x42368086 0x42378086 0x42388086 0x42398086 0x423a8086 0x423b8086 0x423c8086 0x423d8086 0x00828086 0x00838086 0x00848086 0x00858086 0x00878086 0x00898086 0x008a8086 0x008b8086 0x00908086 0x00918086 0x08928086 0x08938086 0x08948086 0x08958086 0x08968086 0x08978086 0x08ae8086 0x08af8086 0x088e8086 0x088f8086 0x08908086 0x08918086 0x08878086 0x08888086 0x27258086 0x27268086 0x7A708086 0x7AF08086 0x51F08086 0x54F08086 0x27298086 0x7E408086 + IOProbeScore + 70000 + IOProviderClass + IOPCIDevice + + + NSHumanReadableCopyright + Copyright © 2020 钟先耀. All rights reserved. + OSBundleLibraries + + com.apple.iokit.IO80211Family + 1200.13.0 + com.apple.iokit.IONetworkingFamily + 3.2 + com.apple.iokit.IOPCIFamily + 2.9 + com.apple.kpi.bsd + 16.7 + com.apple.kpi.iokit + 16.7 + com.apple.kpi.libkern + 16.7 + com.apple.kpi.mach + 16.7 + + OSBundleRequired + Network-Root + + diff --git a/AirportItlwm/AirportItlwmEthernetInterface.cpp b/AirportItlwm/AirportItlwmEthernetInterface.cpp new file mode 100644 index 000000000..d7ea666fd --- /dev/null +++ b/AirportItlwm/AirportItlwmEthernetInterface.cpp @@ -0,0 +1,70 @@ +// +// AirportItlwmEthernetInterface.cpp +// AirportItlwm-Sonoma +// +// Created by qcwap on 2023/6/27. +// Copyright © 2023 钟先耀. All rights reserved. +// + +#include "AirportItlwmEthernetInterface.hpp" + +#include +#include + +#define super IOEthernetInterface +OSDefineMetaClassAndStructors(AirportItlwmEthernetInterface, IOEthernetInterface); + +bool AirportItlwmEthernetInterface:: +initWithSkywalkInterfaceAndProvider(IONetworkController *controller, IO80211SkywalkInterface *interface) +{ + bool ret = super::init(controller); + if (ret) + this->interface = interface; + return ret; +} + +IOReturn AirportItlwmEthernetInterface:: +attachToDataLinkLayer( IOOptionBits options, void *parameter ) +{ + XYLog("%s\n", __FUNCTION__); + char infName[16]; + IOReturn ret = super::IONetworkInterface::attachToDataLinkLayer(options, parameter); + if (ret == kIOReturnSuccess && interface) { + UInt8 builtIn = 0; + interface->setProperty("built-in", OSData::withBytes(&builtIn, sizeof(builtIn))); + snprintf(infName, sizeof(infName), "%s%u", ifnet_name(getIfnet()), ifnet_unit(getIfnet())); + interface->setProperty("IOInterfaceName", OSString::withCString(infName)); +// interface->setProperty("IOInterfaceUnit", OSNumber::withNumber(ifnet_unit(getIfnet()), 8)); + interface->setProperty("IOInterfaceNamePrefix", OSString::withCString("en")); + interface->registerService(); + interface->prepareBSDInterface(getIfnet(), 0); + ret = bpf_attach(getIfnet(), DLT_RAW, 0x48, &AirportItlwmEthernetInterface::bpfOutputPacket, &AirportItlwmEthernetInterface::bpfTap); + } + return ret; +} + +errno_t AirportItlwmEthernetInterface:: +bpfOutputPacket(ifnet_t interface, u_int32_t data_link_type, mbuf_t packet) +{ + XYLog("%s data_link_type: %d\n", __FUNCTION__, data_link_type); + AirportItlwmEthernetInterface *networkInterface = (AirportItlwmEthernetInterface *)ifnet_softc(interface); + return networkInterface->enqueueOutputPacket(packet); +} + +errno_t AirportItlwmEthernetInterface:: +bpfTap(ifnet_t interface, u_int32_t data_link_type, bpf_tap_mode direction) +{ + XYLog("%s data_link_type: %d direction: %d\n", __FUNCTION__, data_link_type, direction); + return 0; +} + +bool AirportItlwmEthernetInterface:: +setLinkState(IO80211LinkState state) +{ + if (state == kIO80211NetworkLinkUp) { + ifnet_set_flags(getIfnet(), ifnet_flags(getIfnet()) | (IFF_UP | IFF_RUNNING), (IFF_UP | IFF_RUNNING)); + } else { + ifnet_set_flags(getIfnet(), ifnet_flags(getIfnet()) & ~(IFF_UP | IFF_RUNNING), 0); + } + return true; +} diff --git a/AirportItlwm/AirportItlwmEthernetInterface.hpp b/AirportItlwm/AirportItlwmEthernetInterface.hpp new file mode 100644 index 000000000..d84ac0ce2 --- /dev/null +++ b/AirportItlwm/AirportItlwmEthernetInterface.hpp @@ -0,0 +1,42 @@ +// +// AirportItlwmEthernetInterface.hpp +// AirportItlwm-Sonoma +// +// Created by qcwap on 2023/6/27. +// Copyright © 2023 钟先耀. All rights reserved. +// + +#ifndef AirportItlwmEthernetInterface_hpp +#define AirportItlwmEthernetInterface_hpp + +extern "C" { +#include +} +#include "Airport/Apple80211.h" +#include +#include +#include +#include + +class AirportItlwmEthernetInterface : public IOEthernetInterface { + OSDeclareDefaultStructors(AirportItlwmEthernetInterface) + +public: + virtual IOReturn attachToDataLinkLayer( IOOptionBits options, + void * parameter ) override; + + virtual bool initWithSkywalkInterfaceAndProvider(IONetworkController *controller, IO80211SkywalkInterface *interface); + + virtual bool setLinkState(IO80211LinkState state); + + static errno_t bpfOutputPacket(ifnet_t interface, u_int32_t data_link_type, + mbuf_t packet); + + static errno_t bpfTap(ifnet_t interface, u_int32_t data_link_type, + bpf_tap_mode direction); + +private: + IO80211SkywalkInterface *interface; +}; + +#endif /* AirportItlwmEthernetInterface_hpp */ diff --git a/AirportItlwm/AirportItlwmSkywalkInterface.cpp b/AirportItlwm/AirportItlwmSkywalkInterface.cpp new file mode 100644 index 000000000..595eeffe7 --- /dev/null +++ b/AirportItlwm/AirportItlwmSkywalkInterface.cpp @@ -0,0 +1,1003 @@ +// +// AirportItlwmSkywalkInterface.cpp +// AirportItlwm-Sonoma +// +// Created by qcwap on 2023/6/27. +// Copyright © 2023 钟先耀. All rights reserved. +// +#include "AirportItlwmV2.hpp" +#include "AirportItlwmSkywalkInterface.hpp" +#include +#include +#include +#include +#include +#include + +#define super IO80211InfraProtocol +OSDefineMetaClassAndStructors(AirportItlwmSkywalkInterface, IO80211InfraProtocol); + +const char* hexdump(uint8_t *buf, size_t len) { + ssize_t str_len = len * 3 + 1; + char *str = (char*)IOMalloc(str_len); + if (!str) + return nullptr; + for (size_t i = 0; i < len; i++) + snprintf(str + 3 * i, (len - i) * 3, "%02x ", buf[i]); + str[MAX(str_len - 2, 0)] = 0; + return str; +} + +static int ieeeChanFlag2appleScanFlagVentura(int flags) +{ + int ret = 0; + if (flags & IEEE80211_CHAN_2GHZ) + ret |= APPLE80211_C_FLAG_2GHZ; + if (flags & IEEE80211_CHAN_5GHZ) + ret |= APPLE80211_C_FLAG_5GHZ; + ret |= (APPLE80211_C_FLAG_ACTIVE | APPLE80211_C_FLAG_20MHZ); + return ret; +} + +static int ieeeChanFlag2apple(int flags, int bw) +{ + int ret = 0; + if (flags & IEEE80211_CHAN_2GHZ) + ret |= APPLE80211_C_FLAG_2GHZ; + if (flags & IEEE80211_CHAN_5GHZ) + ret |= APPLE80211_C_FLAG_5GHZ; + if (!(flags & IEEE80211_CHAN_PASSIVE)) + ret |= APPLE80211_C_FLAG_ACTIVE; + if (flags & IEEE80211_CHAN_DFS) + ret |= APPLE80211_C_FLAG_DFS; + if (bw == -1) { + if (flags & IEEE80211_CHAN_VHT) { + if ((flags & IEEE80211_CHAN_VHT160) || (flags & IEEE80211_CHAN_VHT80_80)) + ret |= APPLE80211_C_FLAG_160MHZ; + if (flags & IEEE80211_CHAN_VHT80) + ret |= APPLE80211_C_FLAG_80MHZ; + } else if ((flags & IEEE80211_CHAN_HT40) && (flags & IEEE80211_CHAN_HT)) { + ret |= APPLE80211_C_FLAG_40MHZ; + if (flags & IEEE80211_CHAN_HT40U) + ret |= APPLE80211_C_FLAG_EXT_ABV; + } else if (flags & IEEE80211_CHAN_HT20) + ret |= APPLE80211_C_FLAG_20MHZ; + else if ((flags & IEEE80211_CHAN_CCK) || (flags & IEEE80211_CHAN_OFDM)) + ret |= APPLE80211_C_FLAG_10MHZ; + } else { + switch (bw) { + case IEEE80211_CHAN_WIDTH_80P80: + case IEEE80211_CHAN_WIDTH_160: + ret |= APPLE80211_C_FLAG_160MHZ; + break; + case IEEE80211_CHAN_WIDTH_80: + ret |= APPLE80211_C_FLAG_80MHZ; + break; + case IEEE80211_CHAN_WIDTH_40: + ret |= APPLE80211_C_FLAG_40MHZ; + if (flags & IEEE80211_CHAN_HT40U) + ret |= APPLE80211_C_FLAG_EXT_ABV; + break; + case IEEE80211_CHAN_WIDTH_20: + ret |= APPLE80211_C_FLAG_20MHZ; + break; + default: + if (flags & IEEE80211_CHAN_HT20) + ret |= APPLE80211_C_FLAG_20MHZ; + else if ((flags & IEEE80211_CHAN_CCK) || (flags & IEEE80211_CHAN_OFDM)) + ret |= APPLE80211_C_FLAG_10MHZ; + break; + } + } + return ret; +} + +void AirportItlwmSkywalkInterface::associateSSID(uint8_t *ssid, uint32_t ssid_len, const struct ether_addr &bssid, uint32_t authtype_lower, uint32_t authtype_upper, uint8_t *key, uint32_t key_len, int key_index) +{ + struct ieee80211com *ic = fHalService->get80211Controller(); + + ieee80211_disable_rsn(ic); + ieee80211_disable_wep(ic); + + struct ieee80211_wpaparams wpa; + struct ieee80211_nwkey nwkey; + bzero(&wpa, sizeof(wpa)); + bzero(&nwkey, sizeof(nwkey)); + + memset(ic->ic_des_essid, 0, IEEE80211_NWID_LEN); + memcpy(ic->ic_des_essid, ssid, ssid_len); + ic->ic_des_esslen = ssid_len; + + bool is_zero = true; + for (int i = 0; i < IEEE80211_ADDR_LEN; i++) + is_zero &= bssid.octet[i] == 0; + + if (!is_zero) { + IEEE80211_ADDR_COPY(ic->ic_des_bssid, bssid.octet); + ic->ic_flags |= IEEE80211_F_DESBSSID; + } + else { + memset(ic->ic_des_bssid, 0, IEEE80211_ADDR_LEN); + ic->ic_flags &= ~IEEE80211_F_DESBSSID; + } + + // AUTHTYPE_WPA3_SAE AUTHTYPE_WPA3_FT_SAE + // we don't really support WPA3, but we have announced we support WPA3 in card capability function. so we fake it as WPA2 to support some WPA2/WPA3 mix wifi connection. + if (authtype_upper == APPLE80211_AUTHTYPE_WPA3_SAE || authtype_upper == APPLE80211_AUTHTYPE_WPA3_FT_SAE) { + wpa.i_protos |= IEEE80211_WPA_PROTO_WPA2; + authtype_upper |= APPLE80211_AUTHTYPE_WPA2_PSK;// hack + } + // AUTHTYPE_WPA3_ENTERPRISE AUTHTYPE_WPA3_FT_ENTERPRISE + if (authtype_upper == APPLE80211_AUTHTYPE_WPA3_ENTERPRISE || authtype_upper == APPLE80211_AUTHTYPE_WPA3_FT_ENTERPRISE) { + wpa.i_protos |= IEEE80211_WPA_PROTO_WPA2; + authtype_upper |= APPLE80211_AUTHTYPE_WPA2;// hack + } + + if (authtype_upper & (APPLE80211_AUTHTYPE_WPA | APPLE80211_AUTHTYPE_WPA_PSK | APPLE80211_AUTHTYPE_WPA2 | APPLE80211_AUTHTYPE_WPA2_PSK | APPLE80211_AUTHTYPE_SHA256_PSK | APPLE80211_AUTHTYPE_SHA256_8021X)) { + XYLog("%s %d\n", __FUNCTION__, __LINE__); + wpa.i_protos = IEEE80211_WPA_PROTO_WPA1 | IEEE80211_WPA_PROTO_WPA2; + } + + if (authtype_upper & (APPLE80211_AUTHTYPE_WPA_PSK | APPLE80211_AUTHTYPE_WPA2_PSK | APPLE80211_AUTHTYPE_SHA256_PSK)) { + XYLog("%s %d\n", __FUNCTION__, __LINE__); + wpa.i_akms |= IEEE80211_WPA_AKM_PSK | IEEE80211_WPA_AKM_SHA256_PSK; + wpa.i_enabled = 1; + memcpy(ic->ic_psk, key, sizeof(ic->ic_psk)); + ic->ic_flags |= IEEE80211_F_PSK; + ieee80211_ioctl_setwpaparms(ic, &wpa); + } + if (authtype_upper & (APPLE80211_AUTHTYPE_WPA | APPLE80211_AUTHTYPE_WPA2 | APPLE80211_AUTHTYPE_SHA256_8021X)) { + XYLog("%s %d\n", __FUNCTION__, __LINE__); + wpa.i_akms |= IEEE80211_WPA_AKM_8021X | IEEE80211_WPA_AKM_SHA256_8021X; + wpa.i_enabled = 1; + ieee80211_ioctl_setwpaparms(ic, &wpa); + } + + if (authtype_lower == APPLE80211_AUTHTYPE_SHARED) { + XYLog("shared key authentication is not supported!\n"); + return; + } + + if (authtype_upper == APPLE80211_AUTHTYPE_NONE && authtype_lower == APPLE80211_AUTHTYPE_OPEN) { // Open or WEP Open System + if (key_len > 0) { + XYLog("%s %d\n", __FUNCTION__, __LINE__); + nwkey.i_wepon = IEEE80211_NWKEY_WEP; + nwkey.i_defkid = key_index + 1; + nwkey.i_key[key_index].i_keylen = (int)key_len; + nwkey.i_key[key_index].i_keydat = key; + ieee80211_ioctl_setnwkeys(ic, &nwkey); + } + } +} + +void AirportItlwmSkywalkInterface::setPTK(const u_int8_t *key, size_t key_len) { + struct ieee80211com *ic = fHalService->get80211Controller(); + struct ieee80211_node * ni = ic->ic_bss; + struct ieee80211_key *k; + int keylen; + + ni->ni_rsn_supp_state = RNSA_SUPP_PTKDONE; + + if (ni->ni_rsncipher != IEEE80211_CIPHER_USEGROUP) { + u_int64_t prsc; + + /* check that key length matches that of pairwise cipher */ + keylen = ieee80211_cipher_keylen(ni->ni_rsncipher); + if (key_len != keylen) { + XYLog("PTK length mismatch. expected %d, got %zu\n", keylen, key_len); + return; + } + prsc = /*(gtk == NULL) ? LE_READ_6(key->rsc) :*/ 0; + + /* map PTK to 802.11 key */ + k = &ni->ni_pairwise_key; + memset(k, 0, sizeof(*k)); + k->k_cipher = ni->ni_rsncipher; + k->k_rsc[0] = prsc; + k->k_len = keylen; + memcpy(k->k_key, key, k->k_len); + /* install the PTK */ + if ((*ic->ic_set_key)(ic, ni, k) != 0) { + XYLog("setting PTK failed\n"); + return; + } + else + XYLog("setting PTK successfully\n"); + ni->ni_flags &= ~IEEE80211_NODE_RSN_NEW_PTK; + ni->ni_flags &= ~IEEE80211_NODE_TXRXPROT; + ni->ni_flags |= IEEE80211_NODE_RXPROT; + } else if (ni->ni_rsncipher != IEEE80211_CIPHER_USEGROUP) + XYLog("%s: unexpected pairwise key update received from %s\n", + ic->ic_if.if_xname, ether_sprintf(ni->ni_macaddr)); +} + +void AirportItlwmSkywalkInterface::setGTK(const u_int8_t *gtk, size_t key_len, u_int8_t kid, u_int8_t *rsc) { + struct ieee80211com *ic = fHalService->get80211Controller(); + struct ieee80211_node * ni = ic->ic_bss; + struct ieee80211_key *k; + int keylen; + + if (gtk != NULL) { + /* check that key length matches that of group cipher */ + keylen = ieee80211_cipher_keylen(ni->ni_rsngroupcipher); + if (key_len != keylen) { + XYLog("GTK length mismatch. expected %d, got %zu\n", keylen, key_len); + return; + } + /* map GTK to 802.11 key */ + k = &ic->ic_nw_keys[kid]; + if (k->k_cipher == IEEE80211_CIPHER_NONE || k->k_len != keylen || memcmp(k->k_key, gtk, keylen) != 0) { + memset(k, 0, sizeof(*k)); + k->k_id = kid; /* 0-3 */ + k->k_cipher = ni->ni_rsngroupcipher; + k->k_flags = IEEE80211_KEY_GROUP; + //if (gtk[6] & (1 << 2)) + // k->k_flags |= IEEE80211_KEY_TX; + k->k_rsc[0] = LE_READ_6(rsc); + k->k_len = keylen; + memcpy(k->k_key, gtk, k->k_len); + /* install the GTK */ + if ((*ic->ic_set_key)(ic, ni, k) != 0) { + XYLog("setting GTK failed\n"); + return; + } + else + XYLog("setting GTK successfully\n"); + } + } + + if (true) { + ni->ni_flags |= IEEE80211_NODE_TXRXPROT; +#ifndef IEEE80211_STA_ONLY + if (ic->ic_opmode != IEEE80211_M_IBSS || + ++ni->ni_key_count == 2) +#endif + { + XYLog("marking port %s valid\n", + ether_sprintf(ni->ni_macaddr)); + ni->ni_port_valid = 1; + ieee80211_set_link_state(ic, LINK_STATE_UP); + ni->ni_assoc_fail = 0; + if (ic->ic_opmode == IEEE80211_M_STA) + ic->ic_rsngroupcipher = ni->ni_rsngroupcipher; + } + } +} + +bool AirportItlwmSkywalkInterface:: +init(IOService *provider) +{ + bool ret = IO80211InfraInterface::init(); + if (!ret) { + XYLog("%s IO80211InfraInterface init failed\n", __PRETTY_FUNCTION__); + return false; + } + instance = OSDynamicCast(AirportItlwm, provider); + if (!instance) + return false; + this->fHalService = instance->fHalService; + this->scanSource = instance->scanSource; + return ret; +} + +//ifnet_t AirportItlwmSkywalkInterface:: +//getBSDInterface() +//{ +// if (instance->bsdInterface) +// return instance->bsdInterface->getIfnet(); +// return NULL; +//} + +IOReturn AirportItlwmSkywalkInterface:: +getSSID(struct apple80211_ssid_data *sd) +{ + struct ieee80211com * ic = fHalService->get80211Controller(); + if (ic->ic_state == IEEE80211_S_RUN) { + memset(sd, 0, sizeof(*sd)); + sd->version = APPLE80211_VERSION; + memcpy(sd->ssid_bytes, ic->ic_des_essid, strlen((const char*)ic->ic_des_essid)); + sd->ssid_len = (uint32_t)strlen((const char*)ic->ic_des_essid); + return kIOReturnSuccess; + } + return 6; +} + +IOReturn AirportItlwmSkywalkInterface:: +getAUTH_TYPE(struct apple80211_authtype_data *ad) +{ + ad->version = APPLE80211_VERSION; + ad->authtype_lower = current_authtype_lower; + ad->authtype_upper = current_authtype_upper; + return kIOReturnSuccess; +} + +IOReturn AirportItlwmSkywalkInterface:: +setAUTH_TYPE(struct apple80211_authtype_data *ad) +{ + current_authtype_lower = ad->authtype_lower; + current_authtype_upper = ad->authtype_upper; + return kIOReturnSuccess; +} + +IOReturn AirportItlwmSkywalkInterface:: +setCIPHER_KEY(struct apple80211_key *key) +{ + XYLog("%s", __FUNCTION__); + const char* keydump = hexdump(key->key, key->key_len); + const char* rscdump = hexdump(key->key_rsc, key->key_rsc_len); + const char* eadump = hexdump(key->key_ea.octet, APPLE80211_ADDR_LEN); + static_assert(__offsetof(struct apple80211_key, key_ea) == 92, "struct corrupted"); + static_assert(__offsetof(struct apple80211_key, key_rsc_len) == 80, "struct corrupted"); + static_assert(__offsetof(struct apple80211_key, wowl_kck_len) == 100, "struct corrupted"); + static_assert(__offsetof(struct apple80211_key, wowl_kek_len) == 120, "struct corrupted"); + static_assert(__offsetof(struct apple80211_key, wowl_kck_key) == 104, "struct corrupted"); + if (keydump && rscdump && eadump) + XYLog("Set key request: len=%d cipher_type=%d flags=%d index=%d key=%s rsc_len=%d rsc=%s ea=%s\n", + key->key_len, key->key_cipher_type, key->key_flags, key->key_index, keydump, key->key_rsc_len, rscdump, eadump); + else + XYLog("Set key request, but failed to allocate memory for hexdump\n"); + + if (keydump) + IOFree((void*)keydump, 3 * key->key_len + 1); + if (rscdump) + IOFree((void*)rscdump, 3 * key->key_rsc_len + 1); + if (eadump) + IOFree((void*)eadump, 3 * APPLE80211_ADDR_LEN + 1); + + switch (key->key_cipher_type) { + case APPLE80211_CIPHER_NONE: + // clear existing key +// XYLog("Setting NONE key is not supported\n"); + break; + case APPLE80211_CIPHER_WEP_40: + case APPLE80211_CIPHER_WEP_104: + XYLog("Setting WEP key %d is not supported\n", key->key_index); + break; + case APPLE80211_CIPHER_TKIP: + case APPLE80211_CIPHER_AES_OCB: + case APPLE80211_CIPHER_AES_CCM: + switch (key->key_flags) { + case 4: // PTK + setPTK(key->key, key->key_len); + break; + case 0: // GTK + setGTK(key->key, key->key_len, key->key_index, key->key_rsc); + break; + } + break; + case APPLE80211_CIPHER_PMK: + XYLog("Setting WPA PMK is not supported\n"); + break; + case APPLE80211_CIPHER_PMKSA: + XYLog("Setting WPA PMKSA is not supported\n"); + break; + } + //fInterface->postMessage(APPLE80211_M_CIPHER_KEY_CHANGED); + return kIOReturnSuccess; +} + +IOReturn AirportItlwmSkywalkInterface:: +getPHY_MODE(struct apple80211_phymode_data *pd) +{ + struct ieee80211com *ic = fHalService->get80211Controller(); + + pd->version = APPLE80211_VERSION; + pd->phy_mode = APPLE80211_MODE_11A + | APPLE80211_MODE_11B + | APPLE80211_MODE_11G + | APPLE80211_MODE_11N; + + if (ic->ic_flags & IEEE80211_F_VHTON) + pd->phy_mode |= APPLE80211_MODE_11AC; + + if (ic->ic_flags & IEEE80211_F_HEON) + pd->phy_mode |= APPLE80211_MODE_11AX; + + switch (fHalService->get80211Controller()->ic_curmode) { + case IEEE80211_MODE_AUTO: + pd->active_phy_mode = APPLE80211_MODE_AUTO; + break; + case IEEE80211_MODE_11A: + pd->active_phy_mode = APPLE80211_MODE_11A; + break; + case IEEE80211_MODE_11B: + pd->active_phy_mode = APPLE80211_MODE_11B; + break; + case IEEE80211_MODE_11G: + pd->active_phy_mode = APPLE80211_MODE_11G; + break; + case IEEE80211_MODE_11N: + pd->active_phy_mode = APPLE80211_MODE_11N; + break; + case IEEE80211_MODE_11AC: + pd->active_phy_mode = APPLE80211_MODE_11AC; + break; + case IEEE80211_MODE_11AX: + pd->active_phy_mode = APPLE80211_MODE_11AX; + break; + + default: + pd->active_phy_mode = APPLE80211_MODE_AUTO; + break; + } + + return kIOReturnSuccess; +} + +IOReturn AirportItlwmSkywalkInterface:: +getCHANNEL(struct apple80211_channel_data *cd) +{ + struct ieee80211com * ic = fHalService->get80211Controller(); + if (ic->ic_state == IEEE80211_S_RUN) { + memset(cd, 0, sizeof(apple80211_channel_data)); + cd->version = APPLE80211_VERSION; + cd->channel.version = APPLE80211_VERSION; + cd->channel.channel = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan); + cd->channel.flags = ieeeChanFlag2apple(ic->ic_bss->ni_chan->ic_flags, ic->ic_bss->ni_chw); + return kIOReturnSuccess; + } + return 6; +} + +IOReturn AirportItlwmSkywalkInterface:: +getSTATE(struct apple80211_state_data *sd) +{ + memset(sd, 0, sizeof(*sd)); + sd->version = APPLE80211_VERSION; + sd->state = fHalService->get80211Controller()->ic_state; + return kIOReturnSuccess; +} + +IOReturn AirportItlwmSkywalkInterface:: +getMCS_INDEX_SET(struct apple80211_mcs_index_set_data *ad) +{ + struct ieee80211com *ic = fHalService->get80211Controller(); + if (ic->ic_state == IEEE80211_S_RUN) { + memset(ad, 0, sizeof(*ad)); + ad->version = APPLE80211_VERSION; + size_t size = min(ARRAY_SIZE(ic->ic_bss->ni_rxmcs), ARRAY_SIZE(ad->mcs_set_map)); + for (int i = 0; i < size; i++) + ad->mcs_set_map[i] = ic->ic_bss->ni_rxmcs[i]; + return kIOReturnSuccess; + } + return 6; +} + +IOReturn AirportItlwmSkywalkInterface:: +getVHT_MCS_INDEX_SET(struct apple80211_vht_mcs_index_set_data *data) +{ + struct ieee80211com *ic = fHalService->get80211Controller(); + if (ic->ic_bss == NULL || ic->ic_curmode < IEEE80211_MODE_11AC) { + return kIOReturnError; + } + memset(data, 0, sizeof(struct apple80211_vht_mcs_index_set_data)); + data->version = APPLE80211_VERSION; + data->mcs_map = ic->ic_bss->ni_vht_mcsinfo.tx_mcs_map; + return kIOReturnSuccess; +} + +IOReturn AirportItlwmSkywalkInterface:: +getMCS_VHT(struct apple80211_mcs_vht_data *data) +{ + struct ieee80211com *ic = fHalService->get80211Controller(); + if (ic->ic_bss == NULL || ic->ic_curmode < IEEE80211_MODE_11AC) { + return kIOReturnError; + } + memset(data, 0, sizeof(struct apple80211_mcs_vht_data)); + data->version = APPLE80211_VERSION; + data->guard_interval = (ieee80211_node_supports_vht_sgi80(ic->ic_bss) || ieee80211_node_supports_vht_sgi160(ic->ic_bss)) ? APPLE80211_GI_SHORT : APPLE80211_GI_LONG; + data->index = ic->ic_bss->ni_txmcs; + data->nss = fHalService->getDriverInfo()->getTxNSS(); + switch (ic->ic_bss->ni_chw) { + case IEEE80211_CHAN_WIDTH_40: + data->bw = 40; + break; + case IEEE80211_CHAN_WIDTH_80: + data->bw = 80; + break; + case IEEE80211_CHAN_WIDTH_80P80: + case IEEE80211_CHAN_WIDTH_160: + data->bw = 160; + break; + + default: + data->bw = 20; + break; + } + return kIOReturnSuccess; +} + +IOReturn AirportItlwmSkywalkInterface:: +getRATE_SET(struct apple80211_rate_set_data *ad) +{ + struct ieee80211com *ic = fHalService->get80211Controller(); + if (ic->ic_state == IEEE80211_S_RUN) { + memset(ad, 0, sizeof(*ad)); + ad->version = APPLE80211_VERSION; + ad->num_rates = ic->ic_bss->ni_rates.rs_nrates; + size_t size = min(ic->ic_bss->ni_rates.rs_nrates, ARRAY_SIZE(ad->rates)); + for (int i=0; i < size; i++) { + struct apple80211_rate apple_rate = ad->rates[i]; + apple_rate.version = APPLE80211_VERSION; + apple_rate.rate = ic->ic_bss->ni_rates.rs_rates[i]; + apple_rate.flags = 0; + } + return kIOReturnSuccess; + } + return 6; +} + +IOReturn AirportItlwmSkywalkInterface:: +getOP_MODE(struct apple80211_opmode_data *od) +{ + od->version = APPLE80211_VERSION; + od->op_mode = APPLE80211_M_STA; + return kIOReturnSuccess; +} + +IOReturn AirportItlwmSkywalkInterface:: +getTXPOWER(struct apple80211_txpower_data *txd) +{ + struct ieee80211com *ic = fHalService->get80211Controller(); + if (ic->ic_state == IEEE80211_S_RUN) { + memset(txd, 0, sizeof(*txd)); + txd->version = APPLE80211_VERSION; + txd->txpower = ic->ic_txpower; + txd->txpower_unit = APPLE80211_UNIT_PERCENT; + return kIOReturnSuccess; + } + return 6; +} + +IOReturn AirportItlwmSkywalkInterface:: +getRATE(struct apple80211_rate_data *rd) +{ + struct ieee80211com *ic = fHalService->get80211Controller(); + if (ic->ic_bss == NULL) + return 6; + int nss; + int sgi; + int index = 0; + if (ic->ic_state == IEEE80211_S_RUN) { + memset(rd, 0, sizeof(*rd)); + rd->version = APPLE80211_VERSION; + rd->num_radios = 1; + sgi = ieee80211_node_supports_sgi(ic->ic_bss); + if (ic->ic_curmode == IEEE80211_MODE_11AC) { + if (sgi) + index += 1; + nss = fHalService->getDriverInfo()->getTxNSS(); + switch (ic->ic_bss->ni_chw) { + case IEEE80211_CHAN_WIDTH_40: + index += 4; + break; + case IEEE80211_CHAN_WIDTH_80: + index += 8; + break; + case IEEE80211_CHAN_WIDTH_80P80: + case IEEE80211_CHAN_WIDTH_160: + index += 12; + break; + + default: + break; + } + index += 2 * (nss - 1); + const struct ieee80211_vht_rateset *rs = &ieee80211_std_ratesets_11ac[index]; + rd->rate[0] = rs->rates[ic->ic_bss->ni_txmcs % rs->nrates] / 2; + } else if (ic->ic_curmode == IEEE80211_MODE_11N) { + int is_40mhz = ic->ic_bss->ni_chw == IEEE80211_CHAN_WIDTH_40; + if (sgi) + index += 1; + if (is_40mhz) + index += (IEEE80211_HT_RATESET_MIMO4_SGI + 1); + index += (ic->ic_bss->ni_txmcs / 16); + nss = ic->ic_bss->ni_txmcs / 8 + 1; + index += 2 * (nss - 1); + rd->rate[0] = ieee80211_std_ratesets_11n[index].rates[ic->ic_bss->ni_txmcs % 8] / 2; + } else + rd->rate[0] = ic->ic_bss->ni_rates.rs_rates[ic->ic_bss->ni_txrate]; + return kIOReturnSuccess; + } + return 6; +} + +IOReturn AirportItlwmSkywalkInterface:: +getBSSID(struct apple80211_bssid_data *bd) +{ + struct ieee80211com *ic = fHalService->get80211Controller(); + if (ic->ic_state == IEEE80211_S_RUN) { + memset(bd, 0, sizeof(*bd)); + bd->version = APPLE80211_VERSION; + memcpy(bd->bssid.octet, ic->ic_bss->ni_bssid, APPLE80211_ADDR_LEN); + return kIOReturnSuccess; + } + return 6; +} + +IOReturn AirportItlwmSkywalkInterface:: +getRSSI(struct apple80211_rssi_data *rd) +{ + struct ieee80211com *ic = fHalService->get80211Controller(); + if (ic->ic_state == IEEE80211_S_RUN) { + memset(rd, 0, sizeof(*rd)); + rd->num_radios = 1; + rd->rssi_unit = APPLE80211_UNIT_DBM; + rd->rssi[0] = rd->aggregate_rssi + = rd->rssi_ext[0] + = rd->aggregate_rssi_ext + = -(0 - IWM_MIN_DBM - ic->ic_bss->ni_rssi); + return kIOReturnSuccess; + } + return 6; +} + +IOReturn AirportItlwmSkywalkInterface:: +getRSN_IE(struct apple80211_rsn_ie_data *data) +{ +#ifdef USE_APPLE_SUPPLICANT + struct ieee80211com *ic = fHalService->get80211Controller(); + if (ic->ic_bss == NULL || ic->ic_bss->ni_rsnie == NULL) { + return kIOReturnError; + } + data->version = APPLE80211_VERSION; + if (ic->ic_rsn_ie_override[1] > 0) { + data->len = 2 + ic->ic_rsn_ie_override[1]; + memcpy(data->ie, ic->ic_rsn_ie_override, data->len); + } + else { + data->len = 2 + ic->ic_bss->ni_rsnie[1]; + memcpy(data->ie, ic->ic_bss->ni_rsnie, data->len); + } + return kIOReturnSuccess; +#else + return kIOReturnUnsupported; +#endif +} + +IOReturn AirportItlwmSkywalkInterface:: +setRSN_IE(struct apple80211_rsn_ie_data *data) +{ +#ifdef USE_APPLE_SUPPLICANT + struct ieee80211com *ic = fHalService->get80211Controller(); + if (!data) + return kIOReturnError; + static_assert(sizeof(ic->ic_rsn_ie_override) == APPLE80211_MAX_RSN_IE_LEN, "Max RSN IE length mismatch"); + memcpy(ic->ic_rsn_ie_override, data->ie, APPLE80211_MAX_RSN_IE_LEN); + if (ic->ic_state == IEEE80211_S_RUN && ic->ic_bss != nullptr) + ieee80211_save_ie(data->ie, &ic->ic_bss->ni_rsnie); + return kIOReturnSuccess; +#else + return kIOReturnUnsupported; +#endif +} + +IOReturn AirportItlwmSkywalkInterface:: +getAP_IE_LIST(struct apple80211_ap_ie_data *data) +{ + struct ieee80211com *ic = fHalService->get80211Controller(); + if (!data) + return kIOReturnError; + if (ic->ic_bss == NULL || ic->ic_bss->ni_rsnie_tlv == NULL || ic->ic_bss->ni_rsnie_tlv_len == 0 || ic->ic_bss->ni_rsnie_tlv_len > data->len || ic->ic_bss->ni_rsnie_tlv_len > 1024) + return kIOReturnError; + data->version = APPLE80211_VERSION; + data->len = ic->ic_bss->ni_rsnie_tlv_len; + memcpy(data->ie_data, ic->ic_bss->ni_rsnie_tlv, data->len); + return kIOReturnSuccess; +} + +IOReturn AirportItlwmSkywalkInterface:: +getNOISE(struct apple80211_noise_data *nd) +{ + struct ieee80211com *ic = fHalService->get80211Controller(); + if (ic->ic_state == IEEE80211_S_RUN) { + memset(nd, 0, sizeof(*nd)); + nd->version = APPLE80211_VERSION; + nd->num_radios = 1; + nd->noise[0] + = nd->aggregate_noise = -fHalService->getDriverInfo()->getBSSNoise(); + nd->noise_unit = APPLE80211_UNIT_DBM; + return kIOReturnSuccess; + } + return 6; +} + +IOReturn AirportItlwmSkywalkInterface:: +getPOWERSAVE(struct apple80211_powersave_data *pd) +{ + pd->version = APPLE80211_VERSION; + pd->powersave_level = APPLE80211_POWERSAVE_MODE_DISABLED; + return kIOReturnSuccess; +} + +IOReturn AirportItlwmSkywalkInterface:: +getNSS(struct apple80211_nss_data *data) +{ + memset(data, 0, sizeof(*data)); + data->version = APPLE80211_VERSION; + data->nss = fHalService->getDriverInfo()->getTxNSS(); + return kIOReturnSuccess; +} + +IOReturn AirportItlwmSkywalkInterface:: +setASSOCIATE(struct apple80211_assoc_data *ad) +{ + XYLog("%s [%s] mode=%d ad_auth_lower=%d ad_auth_upper=%d rsn_ie_len=%d%s%s%s%s%s%s%s\n", __FUNCTION__, ad->ad_ssid, ad->ad_mode, ad->ad_auth_lower, ad->ad_auth_upper, ad->ad_rsn_ie_len, + (ad->ad_flags & 2) ? ", Instant Hotspot" : "", + (ad->ad_flags & 4) ? ", Auto Instant Hotspot" : "", + (ad->ad_rsn_ie[APPLE80211_MAX_RSN_IE_LEN] & 1) ? ", don't disassociate" : "", + (ad->ad_rsn_ie[APPLE80211_MAX_RSN_IE_LEN] & 2) ? ", don't blacklist" : "", + (ad->ad_rsn_ie[APPLE80211_MAX_RSN_IE_LEN] & 4) ? ", closed Network" : "", + (ad->ad_rsn_ie[APPLE80211_MAX_RSN_IE_LEN] & 8) ? ", 802.1X" : "", + (ad->ad_rsn_ie[APPLE80211_MAX_RSN_IE_LEN] & 0x20) ? ", force BSSID" : ""); + + struct apple80211_rsn_ie_data rsn_ie_data; + struct apple80211_authtype_data auth_type_data; + struct ieee80211com *ic = fHalService->get80211Controller(); + + if (!ad) + return kIOReturnError; + + if (ic->ic_state < IEEE80211_S_SCAN) + return kIOReturnSuccess; + + if (ic->ic_state == IEEE80211_S_ASSOC || ic->ic_state == IEEE80211_S_AUTH) + return kIOReturnSuccess; + + if (ad->ad_mode != APPLE80211_AP_MODE_IBSS) { + disassocIsVoluntary = false; + auth_type_data.version = APPLE80211_VERSION; + auth_type_data.authtype_upper = ad->ad_auth_upper; + auth_type_data.authtype_lower = ad->ad_auth_lower; + setAUTH_TYPE(&auth_type_data); + rsn_ie_data.version = APPLE80211_VERSION; + rsn_ie_data.len = ad->ad_rsn_ie[1] + 2; + memcpy(rsn_ie_data.ie, ad->ad_rsn_ie, rsn_ie_data.len); + setRSN_IE(&rsn_ie_data); + + associateSSID(ad->ad_ssid, ad->ad_ssid_len, ad->ad_bssid, ad->ad_auth_lower, ad->ad_auth_upper, ad->ad_key.key, ad->ad_key.key_len, ad->ad_key.key_index); + } + return kIOReturnSuccess; +} + +IOReturn AirportItlwmSkywalkInterface:: +setDISASSOCIATE(struct apple80211_disassoc_data *ad) +{ + XYLog("%s\n", __FUNCTION__); + struct ieee80211com *ic = fHalService->get80211Controller(); + + if (ic->ic_state < IEEE80211_S_SCAN) + return kIOReturnSuccess; + + if (ic->ic_state > IEEE80211_S_AUTH && ic->ic_bss != NULL) + IEEE80211_SEND_MGMT(ic, ic->ic_bss, IEEE80211_FC0_SUBTYPE_DEAUTH, IEEE80211_REASON_AUTH_LEAVE); + + if (ic->ic_state == IEEE80211_S_ASSOC || ic->ic_state == IEEE80211_S_AUTH) + return kIOReturnSuccess; + + disassocIsVoluntary = true; + + ieee80211_del_ess(ic, nullptr, 0, 1); + ieee80211_deselect_ess(ic); +#ifdef USE_APPLE_SUPPLICANT + ic->ic_rsn_ie_override[1] = 0; +#endif + ic->ic_assoc_status = APPLE80211_STATUS_UNAVAILABLE; + ic->ic_deauth_reason = APPLE80211_REASON_ASSOC_LEAVING; + ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); + return kIOReturnSuccess; +} + +IOReturn AirportItlwmSkywalkInterface:: +getSUPPORTED_CHANNELS(struct apple80211_sup_channel_data *ad) +{ + if (!ad) + return kIOReturnError; + ad->version = APPLE80211_VERSION; + ad->num_channels = 0; + struct ieee80211com *ic = fHalService->get80211Controller(); + for (int i = 0; i < IEEE80211_CHAN_MAX; i++) { + if (ic->ic_channels[i].ic_freq != 0) { + ad->supported_channels[ad->num_channels].channel = ieee80211_chan2ieee(ic, &ic->ic_channels[i]); + ad->supported_channels[ad->num_channels].flags = ieeeChanFlag2appleScanFlagVentura(ic->ic_channels[i].ic_flags); + ad->num_channels++; + } + } + return kIOReturnSuccess; +} + +IOReturn AirportItlwmSkywalkInterface:: +getLOCALE(struct apple80211_locale_data *ld) +{ + if (!ld) + return kIOReturnError; + ld->version = APPLE80211_VERSION; + ld->locale = APPLE80211_LOCALE_FCC; + + return kIOReturnSuccess; +} + +IOReturn AirportItlwmSkywalkInterface:: +getDEAUTH(struct apple80211_deauth_data *da) +{ + if (!da) + return kIOReturnError; + da->version = APPLE80211_VERSION; + struct ieee80211com *ic = fHalService->get80211Controller(); + da->deauth_reason = ic->ic_deauth_reason; +// XYLog("%s, %d\n", __FUNCTION__, da->deauth_reason); + return kIOReturnSuccess; +} + +IOReturn AirportItlwmSkywalkInterface:: +getASSOCIATION_STATUS(struct apple80211_assoc_status_data *hv) +{ + struct ieee80211com *ic = fHalService->get80211Controller(); + + if (!hv) + return kIOReturnError; + memset(hv, 0, sizeof(*hv)); + hv->version = APPLE80211_VERSION; + if (ic->ic_state == IEEE80211_S_RUN) + hv->status = APPLE80211_STATUS_SUCCESS; + else + hv->status = APPLE80211_STATUS_UNAVAILABLE; +// XYLog("%s, %d\n", __FUNCTION__, hv->status); + return kIOReturnSuccess; +} + +IOReturn AirportItlwmSkywalkInterface:: +setSCANCACHE_CLEAR(void *req) +{ + XYLog("%s\n", __FUNCTION__); + struct ieee80211com *ic = fHalService->get80211Controller(); + //if doing background or active scan, don't free nodes. + if ((ic->ic_flags & IEEE80211_F_BGSCAN) || (ic->ic_flags & IEEE80211_F_ASCAN)) + return kIOReturnSuccess; + ieee80211_free_allnodes(ic, 0); + return kIOReturnSuccess; +} + +IOReturn AirportItlwmSkywalkInterface:: +setDEAUTH(struct apple80211_deauth_data *da) +{ + XYLog("%s\n", __FUNCTION__); + return kIOReturnSuccess; +} + +IOReturn AirportItlwmSkywalkInterface:: +getMCS(struct apple80211_mcs_data* md) +{ + struct ieee80211com *ic = fHalService->get80211Controller(); + if (ic->ic_state != IEEE80211_S_RUN || ic->ic_bss == NULL || !md) + return 6; + md->version = APPLE80211_VERSION; + md->index = ic->ic_bss->ni_txmcs; + return kIOReturnSuccess; +} + +IOReturn AirportItlwmSkywalkInterface:: +getLINK_CHANGED_EVENT_DATA(struct apple80211_link_changed_event_data *ed) +{ + if (ed == nullptr) + return 16; + + struct ieee80211com *ic = fHalService->get80211Controller(); + + bzero(ed, sizeof(apple80211_link_changed_event_data)); + ed->isLinkDown = !(instance->currentStatus & kIONetworkLinkActive); + if (ed->isLinkDown) { + ed->voluntary = disassocIsVoluntary; + ed->reason = APPLE80211_LINK_DOWN_REASON_DEAUTH; + } else + ed->rssi = -(0 - IWM_MIN_DBM - ic->ic_bss->ni_rssi); + XYLog("Link %s, reason: %d, voluntary: %d\n", ed->isLinkDown ? "down" : "up", ed->reason, ed->voluntary); + return kIOReturnSuccess; +} + +IOReturn AirportItlwmSkywalkInterface:: +setSCAN_REQ(struct apple80211_scan_data *sd) +{ + struct ieee80211com *ic = fHalService->get80211Controller(); +#if 0 + XYLog("%s Type: %u BSS Type: %u PHY Mode: %u Dwell time: %u Rest time: %u Num channels: %u SSID: %s BSSID: %s\n", + __FUNCTION__, + sd->scan_type, + sd->bss_type, + sd->phy_mode, + sd->dwell_time, + sd->rest_time, + sd->num_channels, + sd->ssid, + ether_sprintf(sd->bssid.octet)); +#endif + if (fScanResultWrapping) + return 22; + if (ic->ic_state <= IEEE80211_S_INIT) + return 22; + if (sd->scan_type == APPLE80211_SCAN_TYPE_FAST || sd->scan_type == APPLE80211_SCAN_TYPE_PASSIVE) { + if (scanSource) { + scanSource->setTimeoutMS(100); + scanSource->enable(); + } + return kIOReturnSuccess; + } + ieee80211_begin_cache_bgscan(&ic->ic_ac.ac_if); + if (scanSource) { + scanSource->setTimeoutMS(100); + scanSource->enable(); + } + return kIOReturnSuccess; +} + +extern OSDictionary *convertScanToDictionary(apple80211_scan_result *a1); + +static int convertNodeToScanResult(ItlHalService *fHalService, struct ieee80211_node *fNextNodeToSend, apple80211_scan_result *result) +{ + bzero(result, sizeof(*result)); + result->version = APPLE80211_VERSION; + if (fNextNodeToSend->ni_rsnie_tlv && fNextNodeToSend->ni_rsnie_tlv_len > 0) { + result->asr_ie_len = fNextNodeToSend->ni_rsnie_tlv_len; + memcpy(result->asr_ie_data, fNextNodeToSend->ni_rsnie_tlv, MIN(result->asr_ie_len, sizeof(result->asr_ie_data))); + } else { + result->asr_ie_len = 0; + } + result->asr_beacon_int = fNextNodeToSend->ni_intval; + for (int i = 0; i < result->asr_nrates; i++ ) + result->asr_rates[i] = fNextNodeToSend->ni_rates.rs_rates[i]; + result->asr_nrates = fNextNodeToSend->ni_rates.rs_nrates; + result->asr_age = (uint32_t)(airport_up_time() - fNextNodeToSend->ni_age_ts); + result->asr_cap = fNextNodeToSend->ni_capinfo; + result->asr_channel.version = APPLE80211_VERSION; + result->asr_channel.channel = ieee80211_chan2ieee(fHalService->get80211Controller(), fNextNodeToSend->ni_chan); + result->asr_channel.flags = ieeeChanFlag2appleScanFlagVentura(fNextNodeToSend->ni_chan->ic_flags); + result->asr_noise = -fHalService->getDriverInfo()->getBSSNoise(); + result->asr_rssi = -(0 - IWM_MIN_DBM - fNextNodeToSend->ni_rssi); + memcpy(result->asr_bssid, fNextNodeToSend->ni_bssid, IEEE80211_ADDR_LEN); + result->asr_ssid_len = fNextNodeToSend->ni_esslen; + if (result->asr_ssid_len != 0) + memcpy(&result->asr_ssid, fNextNodeToSend->ni_essid, result->asr_ssid_len); + return 0; +} + +IOReturn AirportItlwmSkywalkInterface:: +getCURRENT_NETWORK(apple80211_scan_result *sr) +{ + if (fHalService->get80211Controller()->ic_state != IEEE80211_S_RUN || fHalService->get80211Controller()->ic_bss == NULL) + return kIOReturnError; + convertNodeToScanResult(fHalService, fHalService->get80211Controller()->ic_bss, sr); + return kIOReturnSuccess; +} + +IOReturn AirportItlwmSkywalkInterface:: +getCOLOCATED_NETWORK_SCOPE_ID(apple80211_colocated_network_scope_id *as) +{ + if (!as) + return kIOReturnBadArgument; + as->version = APPLE80211_VERSION; + return kIOReturnSuccess; +} + +IOReturn AirportItlwmSkywalkInterface:: +getSCAN_RESULT(struct apple80211_scan_result *sr) +{ + if (fNextNodeToSend == NULL) { + if (fScanResultWrapping) { + fScanResultWrapping = false; + return 5; + } else { + fNextNodeToSend = RB_MIN(ieee80211_tree, &fHalService->get80211Controller()->ic_tree); + if (fNextNodeToSend == NULL) { + return 5; + } + } + } +// XYLog("%s ni_bssid=%s ni_essid=%s channel=%d flags=%d asr_cap=%d asr_nrates=%d asr_ssid_len=%d asr_ie_len=%d asr_rssi=%d\n", __FUNCTION__, ether_sprintf(fNextNodeToSend->ni_bssid), fNextNodeToSend->ni_essid, ieee80211_chan2ieee(ic, fNextNodeToSend->ni_chan), ieeeChanFlag2apple(fNextNodeToSend->ni_chan->ic_flags, -1), fNextNodeToSend->ni_capinfo, fNextNodeToSend->ni_rates.rs_nrates, fNextNodeToSend->ni_esslen, fNextNodeToSend->ni_rsnie_tlv == NULL ? 0 : fNextNodeToSend->ni_rsnie_tlv_len, fNextNodeToSend->ni_rssi); + convertNodeToScanResult(fHalService, fNextNodeToSend, sr); + + fNextNodeToSend = RB_NEXT(ieee80211_tree, &HalService->get80211Controller()->ic_tree, fNextNodeToSend); + if (fNextNodeToSend == NULL) + fScanResultWrapping = true; + + return kIOReturnSuccess; +} diff --git a/AirportItlwm/AirportItlwmSkywalkInterface.hpp b/AirportItlwm/AirportItlwmSkywalkInterface.hpp new file mode 100644 index 000000000..2e4a3fc20 --- /dev/null +++ b/AirportItlwm/AirportItlwmSkywalkInterface.hpp @@ -0,0 +1,271 @@ +// +// AirportItlwmSkywalkInterface.hpp +// AirportItlwm-Sonoma +// +// Created by qcwap on 2023/6/27. +// Copyright © 2023 钟先耀. All rights reserved. +// + +#ifndef AirportItlwmSkywalkInterface_hpp +#define AirportItlwmSkywalkInterface_hpp + +#include + +class AirportItlwmSkywalkInterface : public IO80211InfraProtocol { + OSDeclareDefaultStructors(AirportItlwmSkywalkInterface) + +public: + virtual bool init(IOService *) override; +// virtual ifnet_t getBSDInterface(void) override; + + void associateSSID(uint8_t *ssid, uint32_t ssid_len, const struct ether_addr &bssid, uint32_t authtype_lower, uint32_t authtype_upper, uint8_t *key, uint32_t key_len, int key_index); + void setPTK(const u_int8_t *key, size_t key_len); + void setGTK(const u_int8_t *key, size_t key_len, u_int8_t kid, u_int8_t *rsc); + +public: + virtual IOReturn getSSID(apple80211_ssid_data *) override; + virtual IOReturn getAUTH_TYPE(apple80211_authtype_data *) override; + virtual IOReturn getCHANNEL(apple80211_channel_data *) override; + virtual IOReturn getPOWERSAVE(apple80211_powersave_data *) override; + virtual IOReturn getTXPOWER(apple80211_txpower_data *) override; + virtual IOReturn getRATE(apple80211_rate_data *) override; + virtual IOReturn getBSSID(apple80211_bssid_data *) override; + virtual IOReturn getSCAN_RESULT(apple80211_scan_result *) override; + virtual IOReturn getSTATE(apple80211_state_data *) override; + virtual IOReturn getPHY_MODE(apple80211_phymode_data *) override; + virtual IOReturn getOP_MODE(apple80211_opmode_data *) override; + virtual IOReturn getRSSI(apple80211_rssi_data *) override; + virtual IOReturn getNOISE(apple80211_noise_data *) override; + virtual IOReturn getSUPPORTED_CHANNELS(apple80211_sup_channel_data *) override; + virtual IOReturn getLOCALE(apple80211_locale_data *) override; + virtual IOReturn getDEAUTH(apple80211_deauth_data *) override; + virtual IOReturn getRATE_SET(apple80211_rate_set_data *) override; + virtual IOReturn getDTIM_INT(apple80211_dtim_int_data *) override { return kIOReturnUnsupported; } + virtual IOReturn getSTATION_LIST(apple80211_sta_data *) override { return kIOReturnUnsupported; } + virtual IOReturn getRSN_IE(apple80211_rsn_ie_data *) override; + virtual IOReturn getAP_IE_LIST(apple80211_ap_ie_data *) override; + virtual IOReturn getSTATS(apple80211_stats_data *) override { return kIOReturnUnsupported; } + virtual IOReturn getASSOCIATION_STATUS(apple80211_assoc_status_data *) override; + virtual IOReturn getGUARD_INTERVAL(apple80211_guard_interval_data *) override { return kIOReturnUnsupported; } + virtual IOReturn getMCS(apple80211_mcs_data *) override; + virtual IOReturn getMCS_INDEX_SET(apple80211_mcs_index_set_data *) override; + virtual IOReturn getWOW_PARAMETERS(apple80211_wow_parameter_data *) override { return kIOReturnUnsupported; } + virtual IOReturn getWOW_ENABLED(apple80211_state_data *) override { return kIOReturnUnsupported; } + virtual IOReturn getPID_LOCK(apple80211_state_data *) override { return kIOReturnUnsupported; } + virtual IOReturn getSTA_IE_LIST(apple80211_sta_ie_data *) override { return kIOReturnUnsupported; } + virtual IOReturn getSTA_STATS(apple80211_sta_stats_data *) override { return kIOReturnUnsupported; } + virtual IOReturn getBT_COEX_FLAGS(apple80211_state_data *) override { return kIOReturnUnsupported; } + virtual IOReturn getCURRENT_NETWORK(apple80211_scan_result *) override; + virtual IOReturn getRSSI_BOUNDS(apple80211_rssi_bounds_data *) override { return kIOReturnUnsupported; } + virtual IOReturn getPOWER_DEBUG_INFO(apple80211_power_debug_info *) override { return kIOReturnUnsupported; } + virtual IOReturn getHT_CAPABILITY(apple80211_ht_capability *) override { return kIOReturnUnsupported; } + virtual IOReturn getLINK_CHANGED_EVENT_DATA(apple80211_link_changed_event_data *) override; + virtual IOReturn getEXTENDED_STATS(apple80211_extended_stats *) override { return kIOReturnUnsupported; } + virtual IOReturn getBEACON_PERIOD(apple80211_beacon_period_data *) override { return kIOReturnUnsupported; } + virtual IOReturn getVHT_MCS_INDEX_SET(apple80211_vht_mcs_index_set_data *) override; + virtual IOReturn getMCS_VHT(apple80211_mcs_vht_data *) override; + virtual IOReturn getGAS_RESULTS(apple80211_gas_result_t *) override { return kIOReturnUnsupported; } + virtual IOReturn getCHANNELS_INFO(apple80211_channels_info *) override { return kIOReturnUnsupported; } + virtual IOReturn getVHT_CAPABILITY(apple80211_vht_capability *) override { return kIOReturnUnsupported; } + virtual IOReturn getBGSCAN_CACHE_RESULTS(apple80211_bgscan_cached_network_data_list *) override { return kIOReturnUnsupported; } + virtual IOReturn getROAM_PROFILE(apple80211_roam_profile_band_data *) override { return kIOReturnUnsupported; } + virtual IOReturn getCHIP_COUNTER_STATS(apple80211_chip_stats *) override { return kIOReturnUnsupported; } + virtual IOReturn getDBG_GUARD_TIME_PARAMS(apple80211_dbg_guard_time_params *) override { return kIOReturnUnsupported; } + virtual IOReturn getLEAKY_AP_STATS_MODE(apple80211_leaky_ap_setting *) override { return kIOReturnUnsupported; } + virtual IOReturn getCOUNTRY_CHANNELS(apple80211_country_channel_data *) override { return kIOReturnUnsupported; } + virtual IOReturn getPRIVATE_MAC(apple80211_private_mac_data *) override { return kIOReturnUnsupported; } + virtual IOReturn getRANGING_ENABLE(apple80211_ranging_enable_request_t *) override { return kIOReturnUnsupported; } + virtual IOReturn getRANGING_START(apple80211_ranging_start_request_t *) override { return kIOReturnUnsupported; } + virtual IOReturn getAWDL_RSDB_CAPS(apple80211_rsdb_capability *) override { return kIOReturnUnsupported; } + virtual IOReturn getTKO_PARAMS(apple80211_tko_params *) override { return kIOReturnUnsupported; } + virtual IOReturn getTKO_DUMP(apple80211_tko_dump *) override { return kIOReturnUnsupported; } + virtual IOReturn getHW_SUPPORTED_CHANNELS(apple80211_sup_channel_data *) override { return kIOReturnUnsupported; } + virtual IOReturn getBTCOEX_PROFILE(apple80211_btcoex_profile *) override { return kIOReturnUnsupported; } + virtual IOReturn getBTCOEX_PROFILE_ACTIVE(apple80211_btcoex_profile_active_data *) override { return kIOReturnUnsupported; } + virtual IOReturn getTRAP_INFO(apple80211_trap_info_data *) override { return kIOReturnUnsupported; } + virtual IOReturn getTHERMAL_INDEX(apple80211_thermal_index_t *) override { return kIOReturnUnsupported; } + virtual IOReturn getMAX_NSS_FOR_AP(apple80211_btcoex_max_nss_for_ap_data *) override { return kIOReturnUnsupported; } + virtual IOReturn getBTCOEX_2G_CHAIN_DISABLE(apple80211_btcoex_2g_chain_disable *) override { return kIOReturnUnsupported; } + virtual IOReturn getPOWER_BUDGET(apple80211_power_budget_t *) override { return kIOReturnUnsupported; } + virtual IOReturn getRANGING_CAPS(apple80211_ranging_capabilities_t *) override { return kIOReturnUnsupported; } + virtual IOReturn getSUPPRESS_SCANS(apple80211_suppress_scans_t *) override { return kIOReturnUnsupported; } + virtual IOReturn getHOST_AP_MODE_HIDDEN(apple80211_host_ap_mode_hidden_t *) override { return kIOReturnUnsupported; } + virtual IOReturn getLQM_CONFIG(apple80211_lqm_config_t *) override { return kIOReturnUnsupported; } + virtual IOReturn getTRAP_CRASHTRACER_MINI_DUMP(apple80211_trap_mini_dump_data *) override { return kIOReturnUnsupported; } + virtual IOReturn getHE_CAPABILITY(apple80211_he_capability *) override { return kIOReturnUnsupported; } + virtual IOReturn getBEACON_INFO(apple80211_beacon_info_t *) override { return kIOReturnUnsupported; } + virtual IOReturn getSOFTAP_PARAMS(apple80211_softap_params *) override { return kIOReturnUnsupported; } + virtual IOReturn getCHIP_POWER_RANGE(apple80211_chip_power_limit *) override { return kIOReturnUnsupported; } + virtual IOReturn getSOFTAP_STATS(apple80211_softap_stats *) override { return kIOReturnUnsupported; } + virtual IOReturn getNSS(apple80211_nss_data *) override; + virtual IOReturn getHW_ADDR(apple80211_hw_mac_address *) override { return kIOReturnUnsupported; } + virtual IOReturn getHE_MCS_INDEX_SET(apple80211_he_mcs_index_set_data *) override { return kIOReturnUnsupported; } + virtual IOReturn getCHIP_DIAGS(appl80211_chip_diags_data *) override { return kIOReturnUnsupported; } + virtual IOReturn getHP2P_CTRL(apple80211_hp2p_ctrl *) override { return kIOReturnUnsupported; } + virtual IOReturn getREQUEST_BSS_BLACKLIST(void *) override { return kIOReturnUnsupported; } + virtual IOReturn getASSOC_READY_STATUS(apple80211_assoc_ready *) override { return kIOReturnUnsupported; } + virtual IOReturn getTXRX_CHAIN_INFO(apple80211_txrx_chain_info *) override { return kIOReturnUnsupported; } + virtual IOReturn getMIMO_STATUS(apple80211_mimo_status *) override { return kIOReturnUnsupported; } + virtual IOReturn getCUR_PMK(apple80211_pmk *) override { return kIOReturnUnsupported; } + virtual IOReturn getDYNSAR_DETAIL(apple80211_dynsar_detail *) override { return kIOReturnUnsupported; } + virtual IOReturn getRANDOMISATION_STATUS(apple80211_mac_randomisation_status *) override { return kIOReturnUnsupported; } + virtual IOReturn getCOUNTRY_CHANNELS_INFO(apple80211_channels_info *) override { return kIOReturnUnsupported; } + virtual IOReturn getLQM_SUMMARY(apple80211_lqm_summary *) override { return kIOReturnUnsupported; } + virtual IOReturn getCOLOCATED_NETWORK_SCOPE_ID(apple80211_colocated_network_scope_id *) override; + virtual IOReturn getBEACON_SCAN_CACHE_REQ(apple80211_scan_result *) override { return kIOReturnUnsupported; } + virtual IOReturn getSLOW_WIFI_FEATURE_ENABLED(apple80211_slow_wifi_feature_enabled *) override { return kIOReturnUnsupported; } + virtual IOReturn getCCA(apple80211_interface_cca_data *) override { return kIOReturnUnsupported; } + virtual IOReturn getRX_RATE(apple80211_rate_data *) override { return kIOReturnUnsupported; } + virtual IOReturn getTIMESYNC_INFO(apple80211_timesync_info *) override { return kIOReturnUnsupported; } + virtual IOReturn getSENSING_DATA(apple80211_sensing_data_t *) override { return kIOReturnUnsupported; } + virtual IOReturn getCOUNTRY_BAND_SUPPORT(apple80211_country_band_support *) override { return kIOReturnUnsupported; } + virtual IOReturn getWCL_FW_HOT_CHANNELS(apple80211_fw_hot_channels *) override { return kIOReturnUnsupported; } + virtual IOReturn getWCL_LOW_LATENCY_INFO(apple80211_low_latency_info *) override { return kIOReturnUnsupported; } + virtual IOReturn getWCL_BSS_INFO(apple80211_beacon_msg *) override { return kIOReturnUnsupported; } + virtual IOReturn getWCL_TRAFFIC_COUNTERS(apple80211_wcl_traffic_counters *) override { return kIOReturnUnsupported; } + virtual IOReturn getWCL_GET_TX_BLANKING_STATUS(uint *) override { return kIOReturnUnsupported; } + virtual IOReturn getSSID_TRANSITION_SUPPORT(apple80211_ssid_transition_feature_enabled *) override { return kIOReturnUnsupported; } + virtual IOReturn getWCL_VALID_CHANNEL_COUNT(unsigned long *) override { return kIOReturnUnsupported; } + virtual IOReturn getWCL_P2P_STATUS_FOR_SCAN(p2pStatusForScan *) override { return kIOReturnUnsupported; } + virtual IOReturn getWCL_CHANNELS_INFO(apple80211ChannelInfo *) override { return kIOReturnUnsupported; } + virtual IOReturn getP2P_STEERING_METRIC(apple80211_p2p_steering_metrics *) override { return kIOReturnUnsupported; } + virtual IOReturn getRSN_XE(apple80211_rsn_xe_data *) override { return kIOReturnUnsupported; } + virtual IOReturn getSIB_COEX_STATUS(apple80211_sib_coex_status *) override { return kIOReturnUnsupported; } + virtual IOReturn getWCL_EXTENDED_BSS_INFO(apple80211_extended_bss_info *) override { return kIOReturnUnsupported; } + virtual IOReturn getWCL_LOW_LATENCY_INFO_STATS(apple80211_wcl_low_latency_stats *) override { return kIOReturnUnsupported; } + virtual IOReturn getWCL_BGSCAN_CACHE_RESULT(apple80211_bgscan_cached_network_data_list *) override { return kIOReturnUnsupported; } + virtual IOReturn getWIFI_NOISE_PER_ANT(apple80211_noise_per_ant_t *) override { return kIOReturnUnsupported; } + virtual IOReturn getBLOCKED_BANDS(apple80211_blocked_bands *) override { return kIOReturnUnsupported; } + virtual IOReturn setSSID(apple80211_ssid_data *) override { return kIOReturnUnsupported; } + virtual IOReturn setAUTH_TYPE(apple80211_authtype_data *) override; + virtual IOReturn setCIPHER_KEY(apple80211_key *) override; + virtual IOReturn setCHANNEL(apple80211_channel_data *) override { return kIOReturnUnsupported; } + virtual IOReturn setPOWERSAVE(apple80211_powersave_data *) override { return kIOReturnUnsupported; } + virtual IOReturn setTXPOWER(apple80211_txpower_data *) override { return kIOReturnUnsupported; } + virtual IOReturn setRATE(apple80211_rate_data *) override { return kIOReturnUnsupported; } + virtual IOReturn setSCAN_REQ(apple80211_scan_data *) override; + virtual IOReturn setASSOCIATE(apple80211_assoc_data *) override; + virtual IOReturn setDISASSOCIATE(apple80211_disassoc_data *) override; + virtual IOReturn setIBSS_MODE(apple80211_network_data *) override { return kIOReturnUnsupported; } + virtual IOReturn setHOST_AP_MODE(apple80211_network_data *) override { return kIOReturnUnsupported; } + virtual IOReturn setAP_MODE(apple80211_apmode_data *) override { return kIOReturnUnsupported; } + virtual IOReturn setDEAUTH(apple80211_deauth_data *) override; + virtual IOReturn setTX_ANTENNA(void *) override { return kIOReturnUnsupported; } + virtual IOReturn setANTENNA_DIVERSITY(void *) override { return kIOReturnUnsupported; } + virtual IOReturn setRSN_IE(apple80211_rsn_ie_data *) override; + virtual IOReturn setBACKGROUND_SCAN(apple80211_bgscan_data *) override { return kIOReturnUnsupported; } + virtual IOReturn setWOW_PARAMETERS(apple80211_wow_parameter_data *) override { return kIOReturnUnsupported; } + virtual IOReturn setWOW_ENABLED(apple80211_state_data *) override { return kIOReturnUnsupported; } + virtual IOReturn setPID_LOCK(apple80211_state_data *) override { return kIOReturnUnsupported; } + virtual IOReturn setSTA_AUTHORIZE(apple80211_sta_authorize_data *) override { return kIOReturnUnsupported; } + virtual IOReturn setSTA_DISASSOCIATE(apple80211_sta_disassoc_data *) override { return kIOReturnUnsupported; } + virtual IOReturn setSTA_DEAUTH(apple80211_sta_disassoc_data *) override { return kIOReturnUnsupported; } + virtual IOReturn setRSN_CONF(apple80211_rsn_conf_data *) override { return kIOReturnUnsupported; } + virtual IOReturn setIE(apple80211_ie_data *) override { return kIOReturnUnsupported; } + virtual IOReturn setWOW_TEST(apple80211_wow_test_data *) override { return kIOReturnUnsupported; } + virtual IOReturn setSCANCACHE_CLEAR(void *) override; + virtual IOReturn setVIRTUAL_IF_CREATE(apple80211_virt_if_create_data *) override { return kIOReturnUnsupported; } + virtual IOReturn setBT_COEX_FLAGS(apple80211_state_data *) override { return kIOReturnUnsupported; } + virtual IOReturn setROAM(apple80211_sta_roam_data *) override { return kIOReturnUnsupported; } + virtual IOReturn setHT_CAPABILITY(apple80211_ht_capability *) override { return kIOReturnUnsupported; } + virtual IOReturn setAWDL_FORCED_ROAM_CONFIG(apple80211_awdl_forced_roam_config *) override { return kIOReturnUnsupported; } + virtual IOReturn setOFFLOAD_ARP(apple80211_offload_arp_data *) override { return kIOReturnUnsupported; } + virtual IOReturn setOFFLOAD_NDP(apple80211_offload_ndp_data *) override { return kIOReturnUnsupported; } + virtual IOReturn setOFFLOAD_SCAN(apple80211_offload_scan_data *) override { return kIOReturnUnsupported; } + virtual IOReturn setGAS_REQ(apple80211_gas_query_t *) override { return kIOReturnUnsupported; } + virtual IOReturn setGAS_START(apple80211_gas_query_t *) override { return kIOReturnUnsupported; } + virtual IOReturn setGAS_SET_PEER(apple80211_gas_peer_t *) override { return kIOReturnUnsupported; } + virtual IOReturn setVHT_CAPABILITY(apple80211_vht_capability *) override { return kIOReturnUnsupported; } + virtual IOReturn setROAM_PROFILE(apple80211_roam_profile_band_data *) override { return kIOReturnUnsupported; } + virtual IOReturn setAWDL_ENABLE_ROAMING(void *) override { return kIOReturnUnsupported; } + virtual IOReturn setDBG_GUARD_TIME_PARAMS(apple80211_dbg_guard_time_params *) override { return kIOReturnUnsupported; } + virtual IOReturn setLEAKY_AP_STATS_MODE(apple80211_leaky_ap_setting *) override { return kIOReturnUnsupported; } + virtual IOReturn setPRIVATE_MAC(apple80211_private_mac_data *) override { return kIOReturnUnsupported; } + virtual IOReturn setRESET_CHIP(apple80211_reset_command *) override { return kIOReturnUnsupported; } + virtual IOReturn setCRASH(apple80211_crash_command *) override { return kIOReturnUnsupported; } + virtual IOReturn setRANGING_ENABLE(apple80211_ranging_enable_request_t *) override { return kIOReturnUnsupported; } + virtual IOReturn setRANGING_START(apple80211_ranging_start_request_t *) override { return kIOReturnUnsupported; } + virtual IOReturn setRANGING_AUTHENTICATE(apple80211_ranging_authenticate_request_t *) override { return kIOReturnUnsupported; } + virtual IOReturn setTKO_PARAMS(apple80211_tko_params *) override { return kIOReturnUnsupported; } + virtual IOReturn setBTCOEX_PROFILE(apple80211_btcoex_profile *) override { return kIOReturnUnsupported; } + virtual IOReturn setBTCOEX_PROFILE_ACTIVE(apple80211_btcoex_profile_active_data *) override { return kIOReturnUnsupported; } + virtual IOReturn setTHERMAL_INDEX(apple80211_thermal_index_t *) override { return kIOReturnUnsupported; } + virtual IOReturn setBTCOEX_2G_CHAIN_DISABLE(apple80211_btcoex_2g_chain_disable *) override { return kIOReturnUnsupported; } + virtual IOReturn setPOWER_BUDGET(apple80211_power_budget_t *) override { return kIOReturnUnsupported; } + virtual IOReturn setSUPPRESS_SCANS(apple80211_suppress_scans_t *) override { return kIOReturnUnsupported; } + virtual IOReturn setHOST_AP_MODE_HIDDEN(apple80211_host_ap_mode_hidden_t *) override { return kIOReturnUnsupported; } + virtual IOReturn setLQM_CONFIG(apple80211_lqm_config_t *) override { return kIOReturnUnsupported; } + virtual IOReturn setSOFTAP_PARAMS(apple80211_softap_params *) override { return kIOReturnUnsupported; } + virtual IOReturn setSOFTAP_TRIGGER_CSA(apple80211_softap_csa_params *) override { return kIOReturnUnsupported; } + virtual IOReturn setSOFTAP_WIFI_NETWORK_INFO_IE(apple80211_softap_wifi_network_info *) override { return kIOReturnUnsupported; } + virtual IOReturn setBTCOEX_DISABLE_ULOFDMA(uint *) override { return kIOReturnUnsupported; } + virtual IOReturn setSCAN_CONTROL(apple80211_scan_control_params *) override { return kIOReturnUnsupported; } + virtual IOReturn setUSB_HOST_NOTIFICATION(apple80211_usb_host_notification_data *) override { return kIOReturnUnsupported; } + virtual IOReturn setSET_MAC_ADDRESS(apple80211_set_mac_address *) override { return kIOReturnUnsupported; } + virtual IOReturn setHP2P_CTRL(apple80211_hp2p_ctrl *) override { return kIOReturnUnsupported; } + virtual IOReturn setABORT_SCAN(apple80211_abort_scan *) override { return kIOReturnUnsupported; } + virtual IOReturn setSET_PROPERTY(apple80211_set_property_unserialized_data *) override { return kIOReturnUnsupported; } + virtual IOReturn setROAM_CACHE_UPDATE(apple80211_roam_cache_data *) override { return kIOReturnUnsupported; } + virtual IOReturn setPM_MODE(apple80211_pm_mode *) override { return kIOReturnUnsupported; } + virtual IOReturn setSET_WIFI_ASSERTION_STATE(apple80211_wifi_assertion_data *) override { return kIOReturnUnsupported; } + virtual IOReturn setREASSOCIATE_WITH_CORECAPTURE(apple80211_capture_debug_info_t *) override { return kIOReturnUnsupported; } + virtual IOReturn setLINKDOWN_DEBOUNCE_STATUS(apple80211_linkdown_debounce_status *) override { return kIOReturnUnsupported; } + virtual IOReturn setSOFTAP_EXTENDED_CAPABILITIES_IE(apple80211_softap_extended_capabilities_info *) override { return kIOReturnUnsupported; } + virtual IOReturn setREALTIME_QOS_MSCS(apple80211_state_data *) override { return kIOReturnUnsupported; } + virtual IOReturn setSENSING_ENABLE(apple80211_sensing_enable_t *) override { return kIOReturnUnsupported; } + virtual IOReturn setSENSING_DISABLE(apple80211_sensing_disable_t *) override { return kIOReturnUnsupported; } + virtual IOReturn setNANPHS_ASSOCIATION(apple80211_nan_link_association_info *) override { return kIOReturnUnsupported; } + virtual IOReturn setNANPHS_TERMINATED(apple80211_nan_link_association_info *) override { return kIOReturnUnsupported; } + virtual IOReturn set6G_MODE(apple80211_6G_mode *) override { return kIOReturnUnsupported; } + virtual IOReturn setWCL_LEAVE_NETWORK(apple80211_leave_network *) override { return kIOReturnUnsupported; } + virtual IOReturn setWCL_REASSOC(apple80211_reassoc *) override { return kIOReturnUnsupported; } + virtual IOReturn setWCL_SET_ROAM_LOCK(apple80211_set_roam_lock *) override { return kIOReturnUnsupported; } + virtual IOReturn setWCL_ROAM_PROFILE_CONFIG(apple80211_roam_profile_config *) override { return kIOReturnUnsupported; } + virtual IOReturn setWCL_ROAM_PROFILE_CONFIGV1(apple80211_roam_profile_configV1 *) override { return kIOReturnUnsupported; } + virtual IOReturn setWCL_ROAM_USER_CACHE(apple80211_user_roam_cache *) override { return kIOReturnUnsupported; } + virtual IOReturn setWCL_SET_MULTI_AP_ENV(apple80211_set_multi_ap_env *) override { return kIOReturnUnsupported; } + virtual IOReturn setWCL_SCAN_ABORT(void *) override { return kIOReturnUnsupported; } + virtual IOReturn setWCL_REAL_TIME_MODE(apple80211_wcl_real_time_mode *) override { return kIOReturnUnsupported; } + virtual IOReturn setWCL_GARP_MODE(apple80211_wcl_garp_mode *) override { return kIOReturnUnsupported; } + virtual IOReturn setWCL_JOIN_ABORT(void *) override { return kIOReturnUnsupported; } + virtual IOReturn setWCL_TRIGGER_CC(triggerCC *) override { return kIOReturnUnsupported; } + virtual IOReturn setWCL_SCAN_REQ(apple80211ScanRequest *) override { return kIOReturnUnsupported; } + virtual IOReturn setWCL_ASSOCIATE(apple80211_assoc_candidates *) override { return kIOReturnUnsupported; } + virtual IOReturn setWCL_PROTECT_IP(apple80211_wcl_protect_ip_mode *) override { return kIOReturnUnsupported; } + virtual IOReturn setWCL_LINK_UP_DONE(void *) override { return kIOReturnUnsupported; } + virtual IOReturn setWCL_SET_SCAN_HOME_AWAY_TIME(scanHomeAndAwayTime *) override { return kIOReturnUnsupported; } + virtual IOReturn setWCL_VOLUNTARY_NETWORK_DISCONNECT(apple80211_wcl_voluntary_network_disconnect *) override { return kIOReturnUnsupported; } + virtual IOReturn setWCL_LINK_STATE_UPDATE(apple80211_wcl_update_link_state *) override { return kIOReturnUnsupported; } + virtual IOReturn setSLOW_WIFI_RECOVERY(void *) override { return kIOReturnUnsupported; } + virtual IOReturn setRSN_XE(apple80211_rsn_xe_data *) override { return kIOReturnUnsupported; } + virtual IOReturn setWCL_ULOFDMA_STATE(apple80211_wcl_ulofdma_state *) override { return kIOReturnUnsupported; } + virtual IOReturn setWCL_ACTION_FRAME(apple80211_wcl_action_frame *) override { return kIOReturnUnsupported; } + virtual IOReturn setWCL_REAL_TIME_POLICY(apple80211_wcl_real_time_policy *) override { return kIOReturnUnsupported; } + virtual IOReturn setGAS_ABORT(void *) override { return kIOReturnUnsupported; } + virtual IOReturn setOS_FEATURE_FLAGS(apple80211_feature_flags *) override { return kIOReturnUnsupported; } + virtual IOReturn setDHCP_RENEWAL_DATA(apple80211_dhcp_renewal_data *) override { return kIOReturnUnsupported; } + virtual IOReturn setMOVING_NETWORK(apple80211_network_flags *) override { return kIOReturnUnsupported; } + virtual IOReturn setBATTERY_POWERSAVE_CONFIG(apple80211_battery_ps_config *) override { return kIOReturnUnsupported; } + virtual IOReturn setMIMO_CONFIG(apple80211_mimo_config *) override { return kIOReturnUnsupported; } + virtual IOReturn setWCL_CONFIG_BG_MOTIONPROFILE(apple80211_bg_motion_profile *) override { return kIOReturnUnsupported; } + virtual IOReturn setWCL_CONFIG_BG_NETWORK(apple80211_bg_network *) override { return kIOReturnUnsupported; } + virtual IOReturn setWCL_CONFIG_BGSCAN(apple80211_bg_scan *) override { return kIOReturnUnsupported; } + virtual IOReturn setWCL_CONFIG_BG_PARAMS(apple80211_bg_params *) override { return kIOReturnUnsupported; } + virtual IOReturn setBLOCKED_BANDS(apple80211_blocked_bands *) override { return kIOReturnUnsupported; } + +private: + AirportItlwm *instance; + ItlHalService *fHalService; + + //IO80211 + struct ieee80211_node *fNextNodeToSend; + IOTimerEventSource *scanSource; + bool fScanResultWrapping; + + u_int32_t current_authtype_lower; + u_int32_t current_authtype_upper; + bool disassocIsVoluntary; +}; + + +#endif /* AirportItlwmSkywalkInterface_hpp */ diff --git a/AirportItlwm/AirportItlwmV2.cpp b/AirportItlwm/AirportItlwmV2.cpp new file mode 100644 index 000000000..db2e26e9a --- /dev/null +++ b/AirportItlwm/AirportItlwmV2.cpp @@ -0,0 +1,994 @@ +// +// AirportItlwmV2.cpp +// AirportItlwm-Sonoma +// +// Created by qcwap on 2023/6/27. +// Copyright © 2023 钟先耀. All rights reserved. +// + +#include "AirportItlwmV2.hpp" +#include +#include +#include +#include + +#include "AirportItlwmSkywalkInterface.hpp" +#include "IOPCIEDeviceWrapper.hpp" + +#define super IO80211Controller +OSDefineMetaClassAndStructors(AirportItlwm, IO80211Controller); +OSDefineMetaClassAndStructors(CTimeout, OSObject) + +IO80211WorkQueue *_fWorkloop; +IOCommandGate *_fCommandGate; + +void AirportItlwm::releaseAll() +{ + if (fHalService) { + fHalService->release(); + fHalService = NULL; + } + if (_fWorkloop) { + if (_fCommandGate) { +// _fCommandGate->disable(); + _fWorkloop->removeEventSource(_fCommandGate); + _fCommandGate->release(); + _fCommandGate = NULL; + } + if (scanSource) { + scanSource->cancelTimeout(); + scanSource->disable(); + _fWorkloop->removeEventSource(scanSource); + scanSource->release(); + scanSource = NULL; + } + if (fWatchdogWorkLoop && watchdogTimer) { + watchdogTimer->cancelTimeout(); + fWatchdogWorkLoop->removeEventSource(watchdogTimer); + watchdogTimer->release(); + watchdogTimer = NULL; + fWatchdogWorkLoop->release(); + fWatchdogWorkLoop = NULL; + } + _fWorkloop->release(); + _fWorkloop = NULL; + } + unregistPM(); +} + +void AirportItlwm:: +eventHandler(struct ieee80211com *ic, int msgCode, void *data) +{ + AirportItlwm *that = OSDynamicCast(AirportItlwm, ic->ic_ac.ac_if.controller); + IO80211SkywalkInterface *interface = that->fNetIf; + if (!interface) + return; + switch (msgCode) { + case IEEE80211_EVT_COUNTRY_CODE_UPDATE: + interface->postMessage(APPLE80211_M_COUNTRY_CODE_CHANGED, NULL, 0, 0); + break; + case IEEE80211_EVT_STA_ASSOC_DONE: + interface->postMessage(APPLE80211_M_ASSOC_DONE, NULL, 0, 0); + break; + case IEEE80211_EVT_STA_DEAUTH: + interface->postMessage(APPLE80211_M_DEAUTH_RECEIVED, NULL, 0, 0); + break; + default: + break; + } +} + +void AirportItlwm::watchdogAction(IOTimerEventSource *timer) +{ + struct _ifnet *ifp = &fHalService->get80211Controller()->ic_ac.ac_if; + (*ifp->if_watchdog)(ifp); + watchdogTimer->setTimeoutMS(kWatchDogTimerPeriod); +} + +void AirportItlwm::fakeScanDone(OSObject *owner, IOTimerEventSource *sender) +{ + UInt32 msg = 0; + AirportItlwm *that = (AirportItlwm *)owner; + that->fNetIf->postMessage(APPLE80211_M_SCAN_DONE, &msg, 4, 0); +} + +bool AirportItlwm::init(OSDictionary *properties) +{ + XYLog("%s\n", __PRETTY_FUNCTION__); + bool ret = super::init(properties); + awdlSyncEnable = true; + power_state = 0; + memset(geo_location_cc, 0, sizeof(geo_location_cc)); + return ret; +} + +IOService* AirportItlwm::probe(IOService *provider, SInt32 *score) +{ + XYLog("%s\n", __PRETTY_FUNCTION__); + IOPCIEDeviceWrapper *wrapper = OSDynamicCast(IOPCIEDeviceWrapper, provider); + if (!wrapper) { + XYLog("%s Not a IOPCIEDeviceWrapper instance\n", __FUNCTION__); + return NULL; + } + pciNub = wrapper->pciNub; + fHalService = wrapper->fHalService; + if (!pciNub || !fHalService) { + XYLog("%s Not a valid IOPCIEDeviceWrapper instance\n", __FUNCTION__); + return NULL; + } + return super::probe(provider, score); +} + +#define LOWER32(x) ((uint64_t)(x) & 0xffffffff) +#define HIGHER32(x) ((uint64_t)(x) >> 32) + +bool AirportItlwm::start(IOService *provider) +{ + XYLog("%s\n", __PRETTY_FUNCTION__); + struct IOSkywalkEthernetInterface::RegistrationInfo registInfo; + int boot_value = 0; + + setProperty("DriverKitDriver", kOSBooleanFalse); + if (!super::start(provider)) { + return false; + } + pciNub->setBusMasterEnable(true); + pciNub->setIOEnable(true); + pciNub->setMemoryEnable(true); + pciNub->configWrite8(0x41, 0); + if (pciNub->requestPowerDomainState(kIOPMPowerOn, + (IOPowerConnection *) getParentEntry(gIOPowerPlane), IOPMLowestState) != IOPMNoErr) { + super::stop(provider); + return false; + } + if (initPCIPowerManagment(pciNub) == false) { + super::stop(pciNub); + return false; + } + if (_fWorkloop == NULL) { + XYLog("No _fWorkloop!!\n"); + super::stop(pciNub); + releaseAll(); + return false; + } + _fCommandGate = IOCommandGate::commandGate(this, (IOCommandGate::Action)AirportItlwm::tsleepHandler); + if (_fCommandGate == 0) { + XYLog("No command gate!!\n"); + super::stop(pciNub); + releaseAll(); + return false; + } + _fWorkloop->addEventSource(_fCommandGate); + const IONetworkMedium *primaryMedium; + if (!createMediumTables(&primaryMedium) || + !setCurrentMedium(primaryMedium) || !setSelectedMedium(primaryMedium)) { + XYLog("setup medium fail\n"); + releaseAll(); + return false; + } + fHalService->initWithController(this, _fWorkloop, _fCommandGate); + fHalService->get80211Controller()->ic_event_handler = eventHandler; + + if (PE_parse_boot_argn("-novht", &boot_value, sizeof(boot_value))) + fHalService->get80211Controller()->ic_userflags |= IEEE80211_F_NOVHT; + if (PE_parse_boot_argn("-noht40", &boot_value, sizeof(boot_value))) + fHalService->get80211Controller()->ic_userflags |= IEEE80211_F_NOHT40; + + if (!fHalService->attach(pciNub)) { + XYLog("attach fail\n"); + super::stop(pciNub); + releaseAll(); + return false; + } + fWatchdogWorkLoop = IOWorkLoop::workLoop(); + if (fWatchdogWorkLoop == NULL) { + XYLog("init watchdog workloop fail\n"); + fHalService->detach(pciNub); + super::stop(pciNub); + releaseAll(); + return false; + } + watchdogTimer = IOTimerEventSource::timerEventSource(this, OSMemberFunctionCast(IOTimerEventSource::Action, this, &AirportItlwm::watchdogAction)); + if (!watchdogTimer) { + XYLog("init watchdog fail\n"); + fHalService->detach(pciNub); + super::stop(pciNub); + releaseAll(); + return false; + } + fWatchdogWorkLoop->addEventSource(watchdogTimer); + scanSource = IOTimerEventSource::timerEventSource(this, &fakeScanDone); + _fWorkloop->addEventSource(scanSource); + scanSource->enable(); + + fNetIf = new AirportItlwmSkywalkInterface; + if (!fNetIf->init(this)) { + XYLog("Skywalk interface init fail\n"); + super::stop(provider); + releaseAll(); + return false; + } + fNetIf->setInterfaceRole(1); + fNetIf->setInterfaceId(1); + CCPipeOptions driverLogOptions = { 0 }; + driverLogOptions.pipe_type = 0; + driverLogOptions.log_data_type = 1; + driverLogOptions.pipe_size = 0x200000; + driverLogOptions.min_log_size_notify = 0xccccc; + driverLogOptions.notify_threshold = 1000; + strlcpy(driverLogOptions.file_name, "AppleBCMWLAN_Logs", sizeof(driverLogOptions.file_name)); + snprintf(driverLogOptions.name, sizeof(driverLogOptions.name), "wlan%d", 0); + strlcpy(driverLogOptions.directory_name, "WiFi", sizeof(driverLogOptions.directory_name)); + driverLogOptions.pad9 = 0x1000000; + driverLogOptions.pad10 = 2; + driverLogOptions.file_options = 0; + driverLogOptions.log_policy = 0; + driverLogPipe = CCPipe::withOwnerNameCapacity(this, "com.zxystd.RTL008", "DriverLogs", &driverLogOptions); + XYLog("%s driverLogPipeRet %d\n", __FUNCTION__, driverLogPipe != NULL); + + memset(&driverLogOptions, 0, sizeof(driverLogOptions)); + driverLogOptions.pipe_type = 0; + driverLogOptions.log_data_type = 0; + driverLogOptions.pipe_size = 0x200000; + driverLogOptions.min_log_size_notify = 0xccccc; + driverLogOptions.notify_threshold = 1000; + strlcpy(driverLogOptions.file_name, "AppleBCMWLAN_Datapath", sizeof(driverLogOptions.file_name)); + strlcpy(driverLogOptions.directory_name, "WiFi", sizeof(driverLogOptions.directory_name)); + driverLogOptions.pad9 = HIGHER32(0x202800000); + driverLogOptions.pad10 = LOWER32(0x202800000); + driverLogOptions.file_options = 0; + driverLogOptions.log_policy = 0; + driverDataPathPipe = CCPipe::withOwnerNameCapacity(this, "com.zxystd.RTL008", "DatapathEvents", &driverLogOptions); + XYLog("%s driverDataPathPipeRet %d\n", __FUNCTION__, driverDataPathPipe != NULL); + + memset(&driverLogOptions, 0, sizeof(driverLogOptions)); + driverLogOptions.pipe_type = 0x200000001; + driverLogOptions.log_data_type = 2; + strlcpy(driverLogOptions.file_name, "StateSnapshots", sizeof(driverLogOptions.file_name)); + strlcpy(driverLogOptions.name, "0", sizeof(driverLogOptions.name)); + strlcpy(driverLogOptions.directory_name, "WiFi", sizeof(driverLogOptions.directory_name)); + driverLogOptions.pipe_size = 128; + driverSnapshotsPipe = CCPipe::withOwnerNameCapacity(this, "com.zxystd.RTL008", "StateSnapshots", &driverLogOptions); + XYLog("%s driverSnapshotsPipeRet %d\n", __FUNCTION__, driverSnapshotsPipe != NULL); + + CCStreamOptions faultReportOptions = { 0 }; + faultReportOptions.stream_type = 1; + faultReportOptions.console_level = 0xFFFFFFFFFFFFFFFF; + driverFaultReporter = CCStream::withPipeAndName(driverSnapshotsPipe, "FaultReporter", &faultReportOptions); + XYLog("%s driverFaultReporterRet %d\n", __FUNCTION__, driverFaultReporter != NULL); + + if (!fNetIf->attach(this)) { + XYLog("attach to service fail\n"); + super::stop(provider); + releaseAll(); + return false; + } + if (!attachInterface(fNetIf, this)) { + XYLog("attach to interface fail\n"); + super::stop(provider); + releaseAll(); + return false; + } + if (!IONetworkController::attachInterface((IONetworkInterface **)&bsdInterface, true)) { + XYLog("attach to IONetworkController interface fail\n"); + super::stop(provider); + releaseAll(); + return false; + } + memset(®istInfo, 0, sizeof(registInfo)); + if (!fNetIf->initRegistrationInfo(®istInfo, 1, sizeof(registInfo))) { + XYLog("initRegistrationInfo fail\n"); + super::stop(provider); + releaseAll(); + return false; + } + if (!fNetIf->initRegistrationInfo(®istInfo, 1, sizeof(registInfo))) { + XYLog("initRegistrationInfo fail\n"); + super::stop(provider); + releaseAll(); + return false; + } + fNetIf->mExpansionData->fRegistrationInfo = (struct IOSkywalkNetworkInterface::RegistrationInfo *)IOMalloc(sizeof(struct IOSkywalkNetworkInterface::RegistrationInfo)); + fNetIf->mExpansionData2->fRegistrationInfo = (struct IOSkywalkEthernetInterface::RegistrationInfo *)IOMalloc(sizeof(struct IOSkywalkEthernetInterface::RegistrationInfo)); + memcpy(fNetIf->mExpansionData->fRegistrationInfo, ®istInfo, sizeof(registInfo)); + memcpy(fNetIf->mExpansionData2->fRegistrationInfo, ®istInfo, sizeof(registInfo)); + if (fNetIf->getInterfaceRole() == 1) + fNetIf->deferBSDAttach(true); + fNetIf->start(this); + + setLinkStatus(kIONetworkLinkValid); + if (TAILQ_EMPTY(&fHalService->get80211Controller()->ic_ess)) + fHalService->get80211Controller()->ic_flags |= IEEE80211_F_AUTO_JOIN; + registerService(); + fNetIf->registerService(); + return true; +} + +void AirportItlwm::stop(IOService *provider) +{ + XYLog("%s\n", __PRETTY_FUNCTION__);XYLog("%s\n", __PRETTY_FUNCTION__); + struct _ifnet *ifp = &fHalService->get80211Controller()->ic_ac.ac_if; + super::stop(provider); + disableAdapter(bsdInterface); + setLinkStatus(kIONetworkLinkValid); + fHalService->detach(pciNub); + ether_ifdetach(ifp); + detachInterface(fNetIf, true); + OSSafeReleaseNULL(fNetIf); + releaseAll(); +} + +void AirportItlwm::free() +{ + XYLog("%s\n", __PRETTY_FUNCTION__); + if (fHalService != NULL) { + fHalService->release(); + fHalService = NULL; + } + if (syncFrameTemplate != NULL && syncFrameTemplateLength > 0) { + IOFree(syncFrameTemplate, syncFrameTemplateLength); + syncFrameTemplateLength = 0; + syncFrameTemplate = NULL; + } + if (roamProfile != NULL) { + IOFree(roamProfile, sizeof(struct apple80211_roam_profile_band_data)); + roamProfile = NULL; + } + if (btcProfile != NULL) { + IOFree(btcProfile, sizeof(struct apple80211_btc_profiles_data)); + btcProfile = NULL; + } + super::free(); +} + +bool AirportItlwm::createWorkQueue() +{ + XYLog("%s %d\n", __FUNCTION__, _fWorkloop != 0); + return _fWorkloop != 0; +} + +IO80211WorkQueue *AirportItlwm::getWorkQueue() +{ + return _fWorkloop; +} + +void *AirportItlwm::getFaultReporterFromDriver() +{ + return driverFaultReporter; +} + +IOReturn AirportItlwm::enable(IO80211SkywalkInterface *netif) +{ + XYLog("%s\n", __PRETTY_FUNCTION__); + super::enable(netif); + _fCommandGate->enable(); + if (power_state) + enableAdapter(bsdInterface); + return kIOReturnSuccess; +} + +IOReturn AirportItlwm::disable(IO80211SkywalkInterface *netif) +{ + XYLog("%s\n", __PRETTY_FUNCTION__); + super::disable(netif); + setLinkStatus(kIONetworkLinkValid); + return kIOReturnSuccess; +} + +bool AirportItlwm::configureInterface(IONetworkInterface *netif) +{ + IONetworkData *nd; + struct _ifnet *ifp = &fHalService->get80211Controller()->ic_ac.ac_if; + + if (super::configureInterface(netif) == false) { + XYLog("super failed\n"); + return false; + } + + nd = netif->getParameter(kIONetworkStatsKey); + if (!nd || !(fpNetStats = (IONetworkStats *)nd->getBuffer())) { + XYLog("network statistics buffer unavailable?\n"); + return false; + } + ifp->netStat = fpNetStats; + ether_ifattach(ifp, OSDynamicCast(IOEthernetInterface, netif)); + fpNetStats->collisions = 0; +#ifdef __PRIVATE_SPI__ + netif->configureOutputPullModel(fHalService->getDriverInfo()->getTxQueueSize(), 0, 0, IOEthernetInterface::kOutputPacketSchedulingModelNormal, 0); +#endif + + return true; +} + +IONetworkInterface *AirportItlwm::createInterface() +{ + AirportItlwmEthernetInterface *netif = new AirportItlwmEthernetInterface; + if (!netif) + return NULL; + if (!netif->initWithSkywalkInterfaceAndProvider(this, fNetIf)) { + netif->release(); + return NULL; + } + return netif; +} + +bool AirportItlwm::createMediumTables(const IONetworkMedium **primary) +{ + IONetworkMedium *medium; + + OSDictionary *mediumDict = OSDictionary::withCapacity(2); + if (mediumDict == NULL) { + XYLog("Cannot allocate OSDictionary\n"); + return false; + } + + medium = IONetworkMedium::medium(kIOMediumIEEE80211, 54000000); + IONetworkMedium::addMedium(mediumDict, medium); + medium->release(); + if (primary) { + *primary = medium; + } + medium = IONetworkMedium::medium(kIOMediumIEEE80211None, 0); + IONetworkMedium::addMedium(mediumDict, medium); + medium->release(); + + bool result = publishMediumDictionary(mediumDict); + if (!result) { + XYLog("Cannot publish medium dictionary!\n"); + } + + mediumDict->release(); + return result; +} + +IOReturn AirportItlwm::selectMedium(const IONetworkMedium *medium) { + setSelectedMedium(medium); + return kIOReturnSuccess; +} + +bool AirportItlwm:: +setLinkStatus(UInt32 status, const IONetworkMedium * activeMedium, UInt64 speed, OSData * data) +{ + struct _ifnet *ifq = &fHalService->get80211Controller()->ic_ac.ac_if; + if (status == currentStatus) { + return true; + } + bool ret = super::setLinkStatus(status, activeMedium, speed, data); + currentStatus = status; + if (fNetIf) { + if (status & kIONetworkLinkActive) { +#ifdef __PRIVATE_SPI__ + bsdInterface->startOutputThread(); +#endif + getCommandGate()->runAction(setLinkStateGated, (void *)kIO80211NetworkLinkUp, (void *)0); +// fNetIf->setLinkQualityMetric(100); + } else if (!(status & kIONetworkLinkNoNetworkChange)) { +#ifdef __PRIVATE_SPI__ + bsdInterface->stopOutputThread(); + bsdInterface->flushOutputQueue(); +#endif + ifq_flush(&ifq->if_snd); + mq_purge(&fHalService->get80211Controller()->ic_mgtq); + getCommandGate()->runAction(setLinkStateGated, (void *)kIO80211NetworkLinkDown, (void *)fHalService->get80211Controller()->ic_deauth_reason); + } + } + return ret; +} + +IOReturn AirportItlwm:: +setLinkStateGated(OSObject *target, void *arg0, void *arg1, void *arg2, void *arg3) +{ + AirportItlwm *that = OSDynamicCast(AirportItlwm, target); + IOReturn ret = that->fNetIf->setLinkState((IO80211LinkState)(uint64_t)arg0, (unsigned int)(uint64_t)arg1); + that->fNetIf->setRunningState((IO80211LinkState)(uint64_t)arg0 == kIO80211NetworkLinkUp); + that->fNetIf->postMessage(APPLE80211_M_LINK_CHANGED, NULL, 0, false); + that->fNetIf->postMessage(APPLE80211_M_BSSID_CHANGED, NULL, 0, false); + that->fNetIf->postMessage(APPLE80211_M_SSID_CHANGED, NULL, 0, false); + if ((IO80211LinkState)(uint64_t)arg0 == kIO80211NetworkLinkUp) { + that->fNetIf->reportLinkStatus(3, 0x80); + } else { + that->fNetIf->reportLinkStatus(1, 0); + } + that->bsdInterface->setLinkState((IO80211LinkState)(uint64_t)arg0); + if ((ifnet_flags(that->bsdInterface->getIfnet()) & (IFF_UP | IFF_RUNNING)) != (IFF_UP | IFF_RUNNING)) { + XYLog("stf: IFF_DOWN\n"); + } + return ret; +} + +#ifdef __PRIVATE_SPI__ +IOReturn AirportItlwm::outputStart(IONetworkInterface *interface, IOOptionBits options) +{ + struct _ifnet *ifp = &fHalService->get80211Controller()->ic_ac.ac_if; + mbuf_t m = NULL; + if (ifq_is_oactive(&ifp->if_snd)) + return kIOReturnNoResources; + while (kIOReturnSuccess == interface->dequeueOutputPackets(1, &m)) { + if (outputPacket(m, NULL)!= kIOReturnOutputSuccess || + ifq_is_oactive(&ifp->if_snd)) + return kIOReturnNoResources; + } + return kIOReturnSuccess; +} + +IOReturn AirportItlwm::networkInterfaceNotification( + IONetworkInterface * interface, + uint32_t type, + void * argument ) +{ + XYLog("%s\n", __FUNCTION__); + return kIOReturnSuccess; +} +#endif + +UInt32 AirportItlwm::outputPacket(mbuf_t m, void *param) +{ +// XYLog("%s\n", __FUNCTION__); + IOReturn ret = kIOReturnOutputSuccess; + struct _ifnet *ifp = &fHalService->get80211Controller()->ic_ac.ac_if; + + if (fHalService->get80211Controller()->ic_state != IEEE80211_S_RUN || ifp->if_snd.queue == NULL) { + if (m && mbuf_type(m) != MBUF_TYPE_FREE) + freePacket(m); + return kIOReturnOutputDropped; + } + if (m == NULL) { + XYLog("%s m==NULL!!\n", __FUNCTION__); + ifp->netStat->outputErrors++; + ret = kIOReturnOutputDropped; + } + if (!(mbuf_flags(m) & MBUF_PKTHDR) ){ + XYLog("%s pkthdr is NULL!!\n", __FUNCTION__); + ifp->netStat->outputErrors++; + freePacket(m); + ret = kIOReturnOutputDropped; + } + if (mbuf_type(m) == MBUF_TYPE_FREE) { + XYLog("%s mbuf is FREE!!\n", __FUNCTION__); + ifp->netStat->outputErrors++; + ret = kIOReturnOutputDropped; + } + if (!ifp->if_snd.queue->lockEnqueue(m)) { + freePacket(m); + ret = kIOReturnOutputDropped; + } + (*ifp->if_start)(ifp); + return ret; +} + +const OSString * AirportItlwm::newVendorString() const +{ + return OSString::withCString("Apple"); +} + +const OSString * AirportItlwm::newModelString() const +{ + return OSString::withCString(fHalService->getDriverInfo()->getFirmwareName()); +} + +IOReturn AirportItlwm::getHardwareAddress(IOEthernetAddress *addrP) +{ + if (IEEE80211_ADDR_EQ(etheranyaddr, fHalService->get80211Controller()->ic_myaddr)) + return kIOReturnError; + else { + IEEE80211_ADDR_COPY(addrP, fHalService->get80211Controller()->ic_myaddr); + return kIOReturnSuccess; + } +} + +IOReturn AirportItlwm::setHardwareAddress(const void *addrP, UInt32 addrBytes) +{ + if (!fNetIf || !addrP) + return kIOReturnError; + if_setlladdr(&fHalService->get80211Controller()->ic_ac.ac_if, (const UInt8 *)addrP); + if (fHalService->get80211Controller()->ic_state > IEEE80211_S_INIT) { + fHalService->disable(bsdInterface); + fHalService->enable(bsdInterface); + } + return kIOReturnSuccess; +} + +UInt32 AirportItlwm::getFeatures() const +{ + return fHalService->getDriverInfo()->supportedFeatures(); +} + +IOReturn AirportItlwm::setPromiscuousMode(IOEnetPromiscuousMode mode) +{ + return kIOReturnSuccess; +} + +IOReturn AirportItlwm::setMulticastMode(IOEnetMulticastMode mode) +{ + return kIOReturnSuccess; +} + +IOReturn AirportItlwm::setMulticastList(IOEthernetAddress* addr, UInt32 len) +{ + return fHalService->getDriverController()->setMulticastList(addr, len); +} + +IOReturn AirportItlwm::getPacketFilters(const OSSymbol *group, UInt32 *filters) const +{ + IOReturn rtn = kIOReturnSuccess; + if (group == gIOEthernetWakeOnLANFilterGroup && magicPacketSupported) + *filters = kIOEthernetWakeOnMagicPacket; + else if (group == gIONetworkFilterGroup) + *filters = kIOPacketFilterMulticast | kIOPacketFilterPromiscuous; + else + rtn = IOEthernetController::getPacketFilters(group, filters); + return rtn; +} + +SInt32 AirportItlwm:: +enableFeature(IO80211FeatureCode code, void *data) +{ + if (code == kIO80211Feature80211n) { + return 0; + } + return 102; +} + +bool AirportItlwm::getLogPipes(CCPipe**logPipe, CCPipe**eventPipe, CCPipe**snapshotsPipe) +{ + bool ret = false; + if (logPipe) { + *logPipe = driverLogPipe; + ret = true; + } + if (eventPipe) { + *eventPipe = driverDataPathPipe; + ret = true; + } + if (snapshotsPipe) { + *snapshotsPipe = driverSnapshotsPipe; + ret = true; + } + return ret; +} + +#define APPLE80211_CAPA_AWDL_FEATURE_AUTO_UNLOCK 0x00000004 +#define APPLE80211_CAPA_AWDL_FEATURE_WOW 0x00000080 + +IOReturn AirportItlwm:: +getCARD_CAPABILITIES(OSObject *object, + struct apple80211_capability_data *cd) +{ + cd->version = APPLE80211_VERSION; + *(uint16_t *)&cd->capabilities[0] = 0xEE6F; + cd->capabilities[5] = 0x40; + cd->capabilities[2] = 0x61; + *(uint16_t *)&cd->capabilities[8] = 0x201; +// +// cd->capabilities[2] |= 0x10; +// cd->capabilities[5] |= 0x1; +// +// cd->capabilities[2] |= 0x2; +// +// cd->capabilities[3] |= 0x20; +// +// cd->capabilities[0] |= 0x80; +// +// cd->capabilities[3] |= 0x80; +// cd->capabilities[4] |= 0x4; +// +// cd->capabilities[4] |= 0x1; +// cd->capabilities[3] |= 0x1; +// cd->capabilities[6] |= 0x8; +// +// cd->capabilities[3] |= 3; +// cd->capabilities[4] |= 2; +// cd->capabilities[6] |= 0x10; +// cd->capabilities[5] |= 0x20; +// cd->capabilities[5] |= 0x80; +// +// if (cd->capabilities[6] & 0x20) { +// cd->capabilities[2] |= 8; +// } +// cd->capabilities[5] |= 8; +// cd->capabilities[8] |= 2; +// +// cd->capabilities[11] |= (2 | 4 | 8 | 0x10 | 0x20 | 0x40 | 0x80); + + return kIOReturnSuccess; +} + +IOReturn AirportItlwm:: +getDRIVER_VERSION(OSObject *object, + struct apple80211_version_data *hv) +{ + if (!hv) + return kIOReturnError; + hv->version = APPLE80211_VERSION; + snprintf(hv->string, sizeof(hv->string), "itlwm: %s%s fw: %s", ITLWM_VERSION, GIT_COMMIT, fHalService->getDriverInfo()->getFirmwareVersion()); + hv->string_len = strlen(hv->string); + return kIOReturnSuccess; +} + +IOReturn AirportItlwm:: +getHARDWARE_VERSION(OSObject *object, + struct apple80211_version_data *hv) +{ + if (!hv) + return kIOReturnError; + hv->version = APPLE80211_VERSION; + strncpy(hv->string, fHalService->getDriverInfo()->getFirmwareVersion(), sizeof(hv->string)); + hv->string_len = strlen(fHalService->getDriverInfo()->getFirmwareVersion()); + return kIOReturnSuccess; +} + +IOReturn AirportItlwm:: +getCOUNTRY_CODE(OSObject *object, + struct apple80211_country_code_data *cd) +{ + char user_override_cc[3]; + const char *cc_fw = fHalService->getDriverInfo()->getFirmwareCountryCode(); + + if (!cd) + return kIOReturnError; + cd->version = APPLE80211_VERSION; + memset(user_override_cc, 0, sizeof(user_override_cc)); + PE_parse_boot_argn("itlwm_cc", user_override_cc, 3); + /* user_override_cc > firmware_cc > geo_location_cc */ + strncpy((char*)cd->cc, user_override_cc[0] ? user_override_cc : ((cc_fw[0] == 'Z' && cc_fw[1] == 'Z' && geo_location_cc[0]) ? geo_location_cc : cc_fw), sizeof(cd->cc)); + return kIOReturnSuccess; +} + +IOReturn AirportItlwm:: +setCOUNTRY_CODE(OSObject *object, struct apple80211_country_code_data *data) +{ + XYLog("%s cc=%s\n", __FUNCTION__, data->cc); + if (data && data->cc[0] != 120 && data->cc[0] != 88) { + memcpy(geo_location_cc, data->cc, sizeof(geo_location_cc)); + fNetIf->postMessage(APPLE80211_M_COUNTRY_CODE_CHANGED, NULL, 0, 0); + } + return kIOReturnSuccess; +} + +IOReturn AirportItlwm:: +getPOWER(OSObject *object, + struct apple80211_power_data *pd) +{ + if (!pd) + return kIOReturnError; + pd->version = APPLE80211_VERSION; + pd->num_radios = 4; + pd->power_state[0] = power_state; + pd->power_state[1] = power_state; + pd->power_state[2] = power_state; + pd->power_state[3] = power_state; + return kIOReturnSuccess; +} + +IOReturn AirportItlwm:: +setPOWER(OSObject *object, + struct apple80211_power_data *pd) +{ + if (!pd) + return kIOReturnError; + IOLog("itlwm: setPOWER: num_radios[%d] power_state(0:%u 1:%u 2:%u 3:%u)\n", pd->num_radios, pd->power_state[0], pd->power_state[1], pd->power_state[2], pd->power_state[3]); + if (pd->num_radios > 0) { + bool isRunning = (fHalService->get80211Controller()->ic_ac.ac_if.if_flags & (IFF_UP | IFF_RUNNING)) != 0; + if (pd->power_state[0] == 0) { + changePowerStateToPriv(1); + if (isRunning) { + net80211_ifstats(fHalService->get80211Controller()); + disableAdapter(bsdInterface); + } + } else { + changePowerStateToPriv(2); + if (!isRunning) + enableAdapter(bsdInterface); + } + power_state = (pd->power_state[0]); + } + + return kIOReturnSuccess; +} + +SInt32 AirportItlwm::apple80211_ioctl(IO80211SkywalkInterface *interface,unsigned long cmd,void *data, bool b1, bool b2) +{ + if (!ml_at_interrupt_context()) + XYLog("%s cmd: %s b1: %d b2: %d\n", __FUNCTION__, convertApple80211IOCTLToString((unsigned int)cmd), b1, b2); + return super::apple80211_ioctl(interface, cmd, data, b1, b2); +} + +SInt32 AirportItlwm::apple80211SkywalkRequest(UInt request,int cmd,IO80211SkywalkInterface *interface,void *data) +{ + if (!ml_at_interrupt_context()) + XYLog("%s 1 cmd: %s request: %d\n", __FUNCTION__, convertApple80211IOCTLToString(cmd), request); + return kIOReturnUnsupported; +} + +SInt32 AirportItlwm::apple80211SkywalkRequest(UInt request,int cmd,IO80211SkywalkInterface *interface,void *data,void *) +{ + if (!ml_at_interrupt_context()) + XYLog("%s 2 cmd: %s request: %d\n", __FUNCTION__, convertApple80211IOCTLToString(cmd), request); + return kIOReturnUnsupported; +} + +IOReturn AirportItlwm::enableAdapter(IONetworkInterface *netif) +{ + fHalService->enable(netif); + watchdogTimer->setTimeoutMS(kWatchDogTimerPeriod); + watchdogTimer->enable(); + return kIOReturnSuccess; +} + +void AirportItlwm::disableAdapter(IONetworkInterface *netif) +{ + watchdogTimer->cancelTimeout(); + watchdogTimer->disable(); + fHalService->disable(netif); +} + +IOReturn AirportItlwm:: +tsleepHandler(OSObject* owner, void* arg0, void* arg1, void* arg2, void* arg3) +{ + AirportItlwm* dev = OSDynamicCast(AirportItlwm, owner); + if (dev == 0) + return kIOReturnError; + + if (arg1 == 0) { + if (_fCommandGate->commandSleep(arg0, THREAD_INTERRUPTIBLE) == THREAD_AWAKENED) + return kIOReturnSuccess; + else + return kIOReturnTimeout; + } else { + AbsoluteTime deadline; + clock_interval_to_deadline((*(int*)arg1), kNanosecondScale, reinterpret_cast (&deadline)); + if (_fCommandGate->commandSleep(arg0, deadline, THREAD_INTERRUPTIBLE) == THREAD_AWAKENED) + return kIOReturnSuccess; + else + return kIOReturnTimeout; + } +} + +bool AirportItlwm::initPCIPowerManagment(IOPCIDevice *provider) +{ + UInt16 reg16; + + reg16 = provider->configRead16(kIOPCIConfigCommand); + + reg16 |= ( kIOPCICommandBusMaster | + kIOPCICommandMemorySpace | + kIOPCICommandMemWrInvalidate ); + + reg16 &= ~kIOPCICommandIOSpace; // disable I/O space + + provider->configWrite16( kIOPCIConfigCommand, reg16 ); + provider->findPCICapability(kIOPCIPowerManagementCapability, + &pmPCICapPtr); + if (pmPCICapPtr) { + UInt16 pciPMCReg = provider->configRead32( pmPCICapPtr ) >> 16; + if (pciPMCReg & kPCIPMCPMESupportFromD3Cold) + magicPacketSupported = true; + provider->configWrite16((pmPCICapPtr + 4), 0x8000 ); + IOSleep(10); + } + return true; +} + +static IOPMPowerState powerStateArray[kPowerStateCount] = +{ + {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, kIOPMDeviceUsable, kIOPMPowerOn, kIOPMPowerOn, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +void AirportItlwm::unregistPM() +{ + if (powerOffThreadCall) { + thread_call_free(powerOffThreadCall); + powerOffThreadCall = NULL; + } + if (powerOnThreadCall) { + thread_call_free(powerOnThreadCall); + powerOnThreadCall = NULL; + } +} + +IOReturn AirportItlwm::setPowerState(unsigned long powerStateOrdinal, IOService *policyMaker) +{ + IOReturn result = IOPMAckImplied; + + if (pmPowerState == powerStateOrdinal) + return result; + switch (powerStateOrdinal) { + case kPowerStateOff: + if (powerOffThreadCall) { + retain(); + if (thread_call_enter(powerOffThreadCall)) + release(); + result = 5000000; + } + break; + case kPowerStateOn: + if (powerOnThreadCall) { + retain(); + if (thread_call_enter(powerOnThreadCall)) + release(); + result = 5000000; + } + break; + + default: + break; + } + return result; +} + +IOReturn AirportItlwm::setWakeOnMagicPacket(bool active) +{ + magicPacketEnabled = active; + return kIOReturnSuccess; +} + +static void handleSetPowerStateOff(thread_call_param_t param0, + thread_call_param_t param1) +{ + AirportItlwm *self = (AirportItlwm *)param0; + + if (param1 == 0) + { + self->getCommandGate()->runAction((IOCommandGate::Action) + handleSetPowerStateOff, + (void *) 1); + } + else + { + self->setPowerStateOff(); + self->release(); + } +} + +static void handleSetPowerStateOn(thread_call_param_t param0, + thread_call_param_t param1) +{ + AirportItlwm *self = (AirportItlwm *) param0; + + if (param1 == 0) + { + self->getCommandGate()->runAction((IOCommandGate::Action) + handleSetPowerStateOn, + (void *) 1); + } + else + { + self->setPowerStateOn(); + self->release(); + } +} + +IOReturn AirportItlwm::registerWithPolicyMaker(IOService *policyMaker) +{ + IOReturn ret; + + pmPowerState = kPowerStateOn; + pmPolicyMaker = policyMaker; + + powerOffThreadCall = thread_call_allocate( + (thread_call_func_t)handleSetPowerStateOff, + (thread_call_param_t)this); + powerOnThreadCall = thread_call_allocate( + (thread_call_func_t)handleSetPowerStateOn, + (thread_call_param_t)this); + ret = pmPolicyMaker->registerPowerDriver(this, + powerStateArray, + kPowerStateCount); + return ret; +} + +void AirportItlwm::setPowerStateOff() +{ + XYLog("%s\n", __FUNCTION__); + pmPowerState = kPowerStateOff; + disableAdapter(bsdInterface); + pmPolicyMaker->acknowledgeSetPowerState(); +} + +void AirportItlwm::setPowerStateOn() +{ + XYLog("%s\n", __FUNCTION__); + pmPowerState = kPowerStateOn; + pmPolicyMaker->acknowledgeSetPowerState(); +} diff --git a/AirportItlwm/AirportItlwmV2.hpp b/AirportItlwm/AirportItlwmV2.hpp new file mode 100644 index 000000000..0514f7e2f --- /dev/null +++ b/AirportItlwm/AirportItlwmV2.hpp @@ -0,0 +1,254 @@ +// +// AirportItlwmV2.hpp +// AirportItlwm-Sonoma +// +// Created by qcwap on 2023/6/27. +// Copyright © 2023 钟先耀. All rights reserved. +// + +#ifndef AirportItlwmV2_hpp +#define AirportItlwmV2_hpp + +#include "Apple80211.h" + +#include "IOKit/network/IOGatedOutputQueue.h" +#include +#include +#include +#include +#include +#include +#include + +#include "ItlIwm.hpp" +#include "ItlIwx.hpp" +#include "ItlIwn.hpp" + +#include "AirportItlwmEthernetInterface.hpp" + +enum +{ + kPowerStateOff = 0, + kPowerStateOn, + kPowerStateCount +}; + +#define kWatchDogTimerPeriod 1000 + +extern "C" { +const char *convertApple80211IOCTLToString(signed int cmd); +} + +class AirportItlwm : public IO80211Controller { + OSDeclareDefaultStructors(AirportItlwm) +#define IOCTL(REQ_TYPE, REQ, DATA_TYPE) \ +if (REQ_TYPE == SIOCGA80211) { \ +ret = get##REQ(interface, (struct DATA_TYPE* )data); \ +} else { \ +ret = set##REQ(interface, (struct DATA_TYPE* )data); \ +} + +#define IOCTL_GET(REQ_TYPE, REQ, DATA_TYPE) \ +if (REQ_TYPE == SIOCGA80211) { \ +ret = get##REQ(interface, (struct DATA_TYPE* )data); \ +} +#define IOCTL_SET(REQ_TYPE, REQ, DATA_TYPE) \ +if (REQ_TYPE == SIOCSA80211) { \ +ret = set##REQ(interface, (struct DATA_TYPE* )data); \ +} +#define FUNC_IOCTL(REQ, DATA_TYPE) \ +FUNC_IOCTL_GET(REQ, DATA_TYPE) \ +FUNC_IOCTL_SET(REQ, DATA_TYPE) +#define FUNC_IOCTL_GET(REQ, DATA_TYPE) \ +IOReturn get##REQ(OSObject *object, struct DATA_TYPE *data); +#define FUNC_IOCTL_SET(REQ, DATA_TYPE) \ +IOReturn set##REQ(OSObject *object, struct DATA_TYPE *data); + +public: + virtual bool init(OSDictionary *properties) override; + virtual void free() override; + virtual IOService* probe(IOService* provider, SInt32* score) override; + virtual bool start(IOService *provider) override; + virtual void stop(IOService *provider) override; + virtual IOReturn enable(IO80211SkywalkInterface *netif) override; + virtual IOReturn disable(IO80211SkywalkInterface *netif) override; + virtual IOReturn setHardwareAddress(const void *addr, UInt32 addrBytes) override; + virtual IOReturn getHardwareAddress(IOEthernetAddress* addrP) override; + virtual IOReturn getPacketFilters(const OSSymbol *group, UInt32 *filters) const override; + virtual IOReturn setPromiscuousMode(IOEnetPromiscuousMode mode) override; + virtual IOReturn setMulticastMode(IOEnetMulticastMode mode) override; + virtual IOReturn setMulticastList(IOEthernetAddress* addr, UInt32 len) override; + virtual UInt32 getFeatures() const override; + virtual const OSString * newVendorString() const override; + virtual const OSString * newModelString() const override; + virtual IOReturn selectMedium(const IONetworkMedium *medium) override; + virtual bool createWorkQueue() override; + virtual IONetworkInterface * createInterface() override; + virtual bool configureInterface(IONetworkInterface *netif) override; + virtual UInt32 outputPacket(mbuf_t, void * param) override; +#ifdef __PRIVATE_SPI__ + virtual IOReturn outputStart(IONetworkInterface *interface, IOOptionBits options) override; + virtual IOReturn networkInterfaceNotification( + IONetworkInterface * interface, + uint32_t type, + void * argument ) override; +#endif + virtual bool setLinkStatus( + UInt32 status, + const IONetworkMedium * activeMedium = 0, + UInt64 speed = 0, + OSData * data = 0) override; + static IOReturn setLinkStateGated(OSObject *target, void *arg0, void *arg1, void *arg2, void *arg3); + + static IOReturn tsleepHandler(OSObject* owner, void* arg0 = 0, void* arg1 = 0, void* arg2 = 0, void* arg3 = 0); + static void eventHandler(struct ieee80211com *, int, void *); + IOReturn enableAdapter(IONetworkInterface *netif); + void disableAdapter(IONetworkInterface *netif); + + virtual IO80211WorkQueue *getWorkQueue() override; + virtual bool requiresExplicitMBufRelease() override { + return false; + } + virtual bool flowIdSupported() override { + return false; + } + virtual SInt32 monitorModeSetEnabled(bool, UInt) override { + return kIOReturnSuccess; + } + virtual IOReturn requestQueueSizeAndTimeout(unsigned short *queue, unsigned short *timeout) override { + XYLog("%s\n", __FUNCTION__); + return kIOReturnSuccess; + } + + virtual bool getLogPipes(CCPipe**, CCPipe**, CCPipe**) override; + + virtual void *getFaultReporterFromDriver() override; + + virtual SInt32 apple80211_ioctl(IO80211SkywalkInterface *,unsigned long,void *, bool, bool) override; + virtual SInt32 apple80211SkywalkRequest(UInt,int,IO80211SkywalkInterface *,void *) override; + virtual SInt32 apple80211SkywalkRequest(UInt,int,IO80211SkywalkInterface *,void *,void *) override; + + bool createMediumTables(const IONetworkMedium **primary); + void releaseAll(); + void watchdogAction(IOTimerEventSource *timer); + + virtual SInt32 enableFeature(IO80211FeatureCode, void*) override; + virtual bool isCommandProhibited(int command) override { +// if (!ml_at_interrupt_context()) +// XYLog("%s %s\n", __FUNCTION__, convertApple80211IOCTLToString(command)); + return false; + }; + virtual SInt32 handleCardSpecific(IO80211SkywalkInterface *,unsigned long,void *,bool) override { + XYLog("%s\n", __FUNCTION__); + return 0; + }; + virtual IOReturn getDRIVER_VERSION(IO80211SkywalkInterface *interface,apple80211_version_data *data) override { + XYLog("%s\n", __FUNCTION__); + return getDRIVER_VERSION((OSObject *)interface, data); + }; + virtual IOReturn getHARDWARE_VERSION(IO80211SkywalkInterface *interface,apple80211_version_data *data) override { + XYLog("%s\n", __FUNCTION__); + return getHARDWARE_VERSION((OSObject *)interface, data); + }; + virtual IOReturn getCARD_CAPABILITIES(IO80211SkywalkInterface *interface,apple80211_capability_data *data) override { +// XYLog("%s\n", __FUNCTION__); + return getCARD_CAPABILITIES((OSObject *)interface, data); + } + virtual IOReturn getPOWER(IO80211SkywalkInterface *interface,apple80211_power_data *data) override { +// XYLog("%s\n", __FUNCTION__); + return getPOWER((OSObject *)interface, data); + } + virtual IOReturn setPOWER(IO80211SkywalkInterface *interface,apple80211_power_data *data) override { +// XYLog("%s\n", __FUNCTION__); + return setPOWER((OSObject *)interface, data); + } + virtual IOReturn getCOUNTRY_CODE(IO80211SkywalkInterface *interface,apple80211_country_code_data *data) override { +// XYLog("%s\n", __FUNCTION__); + return getCOUNTRY_CODE((OSObject *)interface, data); + } + virtual IOReturn setCOUNTRY_CODE(IO80211SkywalkInterface *interface,apple80211_country_code_data *data) override { +// XYLog("%s\n", __FUNCTION__); + return setCOUNTRY_CODE((OSObject *)interface, data); + } + virtual IOReturn setGET_DEBUG_INFO(IO80211SkywalkInterface *interface,apple80211_debug_command *data) override { + XYLog("%s\n", __FUNCTION__); + return kIOReturnSuccess; + } + + //scan + static void fakeScanDone(OSObject *owner, IOTimerEventSource *sender); + + //----------------------------------------------------------------------- + // Power management support. + //----------------------------------------------------------------------- + virtual IOReturn registerWithPolicyMaker( IOService * policyMaker ) override; + virtual IOReturn setPowerState( unsigned long powerStateOrdinal, + IOService * policyMaker) override; + virtual IOReturn setWakeOnMagicPacket( bool active ) override; + void setPowerStateOff(void); + void setPowerStateOn(void); + void unregistPM(); + bool initPCIPowerManagment(IOPCIDevice *provider); + + FUNC_IOCTL_GET(CARD_CAPABILITIES, apple80211_capability_data) + FUNC_IOCTL(POWER, apple80211_power_data) + FUNC_IOCTL_GET(DRIVER_VERSION, apple80211_version_data) + FUNC_IOCTL_GET(HARDWARE_VERSION, apple80211_version_data) + FUNC_IOCTL(COUNTRY_CODE, apple80211_country_code_data) + +public: + IOInterruptEventSource* fInterrupt; + IOTimerEventSource *watchdogTimer; + IOPCIDevice *pciNub; + IONetworkStats *fpNetStats; + AirportItlwmEthernetInterface *bsdInterface; + IO80211SkywalkInterface *fNetIf; + IOWorkLoop *fWatchdogWorkLoop; + ItlHalService *fHalService; + + //IO80211 + uint8_t power_state; + struct ieee80211_node *fNextNodeToSend; + bool fScanResultWrapping; + IOTimerEventSource *scanSource; + + u_int32_t current_authtype_lower; + u_int32_t current_authtype_upper; + UInt64 currentSpeed; + UInt32 currentStatus; + bool disassocIsVoluntary; + char geo_location_cc[3]; + + //pm + thread_call_t powerOnThreadCall; + thread_call_t powerOffThreadCall; + UInt32 pmPowerState; + IOService *pmPolicyMaker; + UInt8 pmPCICapPtr; + bool magicPacketEnabled; + bool magicPacketSupported; + + //AWDL + uint8_t *syncFrameTemplate; + uint32_t syncFrameTemplateLength; + uint8_t awdlBSSID[6]; + uint32_t awdlSyncState; + uint32_t awdlElectionId; + uint32_t awdlPresenceMode; + uint16_t awdlMasterChannel; + uint16_t awdlSecondaryMasterChannel; + uint8_t *roamProfile; + struct apple80211_btc_profiles_data *btcProfile; + struct apple80211_btc_config_data btcConfig; + uint32_t btcMode; + uint32_t btcOptions; + bool awdlSyncEnable; + + CCPipe *driverLogPipe; + CCPipe *driverDataPathPipe; + CCPipe *driverSnapshotsPipe; + + CCStream *driverFaultReporter; +}; + +#endif /* AirportItlwmV2_hpp */ diff --git a/AirportItlwm/IOPCIEDeviceWrapper.cpp b/AirportItlwm/IOPCIEDeviceWrapper.cpp new file mode 100644 index 000000000..225725c80 --- /dev/null +++ b/AirportItlwm/IOPCIEDeviceWrapper.cpp @@ -0,0 +1,116 @@ +// +// IOPCIEDeviceWrapper.cpp +// AirportItlwm-Sonoma +// +// Created by qcwap on 2023/6/27. +// Copyright © 2023 钟先耀. All rights reserved. +// + +#include "IOPCIEDeviceWrapper.hpp" +#include "Apple80211.h" + +#include "ItlIwm.hpp" +#include "ItlIwx.hpp" +#include "ItlIwn.hpp" + +#define super IOService +OSDefineMetaClassAndStructors(IOPCIEDeviceWrapper, IOService); + +#define PCI_MSI_FLAGS 2 /* Message Control */ +#define PCI_CAP_ID_MSI 0x05 /* Message Signalled Interrupts */ +#define PCI_MSIX_FLAGS 2 /* Message Control */ +#define PCI_CAP_ID_MSIX 0x11 /* MSI-X */ +#define PCI_MSIX_FLAGS_ENABLE 0x8000 /* MSI-X enable */ +#define PCI_MSI_FLAGS_ENABLE 0x0001 /* MSI feature enabled */ + +static void pciMsiSetEnable(IOPCIDevice *device, UInt8 msiCap, int enable) +{ + UInt16 control; + + control = device->configRead16(msiCap + PCI_MSI_FLAGS); + control &= ~PCI_MSI_FLAGS_ENABLE; + if (enable) + control |= PCI_MSI_FLAGS_ENABLE; + device->configWrite16(msiCap + PCI_MSI_FLAGS, control); +} + +static void pciMsiXClearAndSet(IOPCIDevice *device, UInt8 msixCap, UInt16 clear, UInt16 set) +{ + UInt16 ctrl; + + ctrl = device->configRead16(msixCap + PCI_MSIX_FLAGS); + ctrl &= ~clear; + ctrl |= set; + device->configWrite16(msixCap + PCI_MSIX_FLAGS, ctrl); +} + +extern IOWorkLoop *_fWorkloop; + +IOWorkLoop *IOPCIEDeviceWrapper::getWorkLoop() const +{ + return _fWorkloop; +} + +IOService* IOPCIEDeviceWrapper:: +probe(IOService *provider, SInt32 *score) +{ + XYLog("%s\n", __PRETTY_FUNCTION__); + bool isMatch = false; + super::probe(provider, score); + UInt8 msiCap; + UInt8 msixCap; + IOPCIDevice* device = OSDynamicCast(IOPCIDevice, provider); + if (!device) + return NULL; + if (ItlIwx::iwx_match(device)) { + isMatch = true; + fHalService = new ItlIwx; + } + if (!isMatch && ItlIwm::iwm_match(device)) { + isMatch = true; + fHalService = new ItlIwm; + } + if (!isMatch && ItlIwn::iwn_match(device)) { + isMatch = true; + fHalService = new ItlIwn; + } + if (isMatch) { + XYLog("%s Found\n", __FUNCTION__); + device->findPCICapability(PCI_CAP_ID_MSIX, &msixCap); + if (msixCap) + pciMsiXClearAndSet(device, msixCap, PCI_MSIX_FLAGS_ENABLE, 0); + device->findPCICapability(PCI_CAP_ID_MSI, &msiCap); + if (msiCap) + pciMsiSetEnable(device, msiCap, 1); + if (!msiCap && !msixCap) { + XYLog("%s No MSI cap\n", __FUNCTION__); + fHalService->release(); + fHalService = NULL; + return NULL; + } + this->pciNub = device; + return this; + } + return NULL; +} + +bool IOPCIEDeviceWrapper:: +start(IOService *provider) +{ + XYLog("%s\n", __PRETTY_FUNCTION__); + _fWorkloop = IO80211WorkQueue::workQueue(); + if (!super::start(provider)) { + return false; + } + IOLog("%s::super start succeed\n", getName()); + + registerService(); + return true; +} + +void IOPCIEDeviceWrapper:: +stop(IOService *provider) +{ + XYLog("%s\n", __PRETTY_FUNCTION__); + super::stop(provider); +} diff --git a/AirportItlwm/IOPCIEDeviceWrapper.hpp b/AirportItlwm/IOPCIEDeviceWrapper.hpp new file mode 100644 index 000000000..b658ef231 --- /dev/null +++ b/AirportItlwm/IOPCIEDeviceWrapper.hpp @@ -0,0 +1,33 @@ +// +// IOPCIEDeviceWrapper.hpp +// AirportItlwm-Sonoma +// +// Created by qcwap on 2023/6/27. +// Copyright © 2023 钟先耀. All rights reserved. +// + +#ifndef IOPCIEDeviceWrapper_hpp +#define IOPCIEDeviceWrapper_hpp + +#include +#include +#include +#include + +#include + +class IOPCIEDeviceWrapper : public IOService { + OSDeclareDefaultStructors(IOPCIEDeviceWrapper) + +public: + virtual IOService* probe(IOService* provider, SInt32* score) override; + virtual bool start(IOService *provider) override; + virtual void stop(IOService *provider) override; + virtual IOWorkLoop* getWorkLoop() const override; + +public: + ItlHalService *fHalService; + IOPCIDevice *pciNub; +}; + +#endif /* IOPCIEDeviceWrapper_hpp */ diff --git a/include/Airport/IOSkywalkEthernetInterface.h b/include/Airport/IOSkywalkEthernetInterface.h index c0eb38eb8..5cea9b2b0 100644 --- a/include/Airport/IOSkywalkEthernetInterface.h +++ b/include/Airport/IOSkywalkEthernetInterface.h @@ -129,6 +129,20 @@ class IOSkywalkEthernetInterface : public IOSkywalkNetworkInterface { public: bool initRegistrationInfo(IOSkywalkEthernetInterface::RegistrationInfo*, unsigned int, unsigned long); bool registerEthernetInterface(IOSkywalkEthernetInterface::RegistrationInfo const*, IOSkywalkPacketQueue**, unsigned int, IOSkywalkPacketBufferPool*, IOSkywalkPacketBufferPool*, unsigned int); + +public: + void *vptr; + uint8_t pad1[0x30]; + struct ExpansionData + { + RegistrationInfo *fRegistrationInfo; + ifnet_t fBSDInterface; + }; + ExpansionData *mExpansionData2; }; +static_assert(__offsetof(IOSkywalkEthernetInterface, mExpansionData2) == 0x108, "Invalid class size"); + +static_assert(sizeof(IOSkywalkEthernetInterface) == 0x110, "Invalid class size"); + #endif /* IOSkywalkEthernetInterface_h */ diff --git a/include/Airport/IOSkywalkInterface.h b/include/Airport/IOSkywalkInterface.h index 4231d34c5..e9f6fc22f 100644 --- a/include/Airport/IOSkywalkInterface.h +++ b/include/Airport/IOSkywalkInterface.h @@ -43,7 +43,9 @@ class IOSkywalkInterface : public IOService { OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 10 ); public: - uint8_t filter[0xB0]; + uint8_t filter[0xB0 - 136]; }; +static_assert(sizeof(IOSkywalkInterface) == 0xB0, "Invalid class size"); + #endif /* IOSkywalkInterface_h */ diff --git a/include/Airport/IOSkywalkNetworkInterface.h b/include/Airport/IOSkywalkNetworkInterface.h index 4178978a6..611bd5454 100644 --- a/include/Airport/IOSkywalkNetworkInterface.h +++ b/include/Airport/IOSkywalkNetworkInterface.h @@ -113,7 +113,19 @@ class IOSkywalkNetworkInterface : public IOSkywalkInterface { OSMetaClassDeclareReservedUnused( IOSkywalkNetworkInterface, 9); public: - uint8_t filter[0xD0]; + void reportLinkStatus(unsigned int, unsigned int); + +public: + void *vptr; + struct ExpansionData + { + RegistrationInfo *fRegistrationInfo; + ifnet_t fBSDInterface; + }; + ExpansionData *mExpansionData; + uint8_t pad[2 * 8]; }; +static_assert(sizeof(IOSkywalkNetworkInterface) == 0xD0, "Invalid class size"); + #endif /* IOSkywalkNetworkInterface_h */ diff --git a/itlwm.xcodeproj/project.pbxproj b/itlwm.xcodeproj/project.pbxproj index 7990a08d7..e907c52e9 100644 --- a/itlwm.xcodeproj/project.pbxproj +++ b/itlwm.xcodeproj/project.pbxproj @@ -584,6 +584,14 @@ F89F35F62A49867F00061876 /* IO80211ControllerV2.h in Headers */ = {isa = PBXBuildFile; fileRef = F89F35F12A49867F00061876 /* IO80211ControllerV2.h */; }; F89F35F72A49867F00061876 /* IO80211ControllerV2.h in Headers */ = {isa = PBXBuildFile; fileRef = F89F35F12A49867F00061876 /* IO80211ControllerV2.h */; }; F89F35F82A49867F00061876 /* IO80211ControllerV2.h in Headers */ = {isa = PBXBuildFile; fileRef = F89F35F12A49867F00061876 /* IO80211ControllerV2.h */; }; + F8A028222A4A7DDC00C6DE90 /* AirportItlwmV2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F8A028202A4A7DDC00C6DE90 /* AirportItlwmV2.cpp */; }; + F8A028232A4A7DDC00C6DE90 /* AirportItlwmV2.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F8A028212A4A7DDC00C6DE90 /* AirportItlwmV2.hpp */; }; + F8A0282F2A4A7E0400C6DE90 /* AirportItlwmEthernetInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F8A0282D2A4A7E0400C6DE90 /* AirportItlwmEthernetInterface.cpp */; }; + F8A028302A4A7E0500C6DE90 /* AirportItlwmEthernetInterface.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F8A0282E2A4A7E0400C6DE90 /* AirportItlwmEthernetInterface.hpp */; }; + F8A028722A4A7FE100C6DE90 /* AirportItlwmSkywalkInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F8A028702A4A7FE100C6DE90 /* AirportItlwmSkywalkInterface.cpp */; }; + F8A028732A4A7FE100C6DE90 /* AirportItlwmSkywalkInterface.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F8A028712A4A7FE100C6DE90 /* AirportItlwmSkywalkInterface.hpp */; }; + F8A0287F2A4A80EA00C6DE90 /* IOPCIEDeviceWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F8A0287D2A4A80EA00C6DE90 /* IOPCIEDeviceWrapper.cpp */; }; + F8A028802A4A80EA00C6DE90 /* IOPCIEDeviceWrapper.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F8A0287E2A4A80EA00C6DE90 /* IOPCIEDeviceWrapper.hpp */; }; F8A4307325062CE300EA545E /* zutil.c in Sources */ = {isa = PBXBuildFile; fileRef = F8FA0EED2501E8C100B1822E /* zutil.c */; }; F8AE64F9285471560085B4CF /* debug.h in Headers */ = {isa = PBXBuildFile; fileRef = F89B6C2225027609000F77FF /* debug.h */; }; F8AE64FA285471560085B4CF /* IOSkywalkEthernetInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = F89B6BD025021E66000F77FF /* IOSkywalkEthernetInterface.h */; }; @@ -696,7 +704,6 @@ F8B210BE2A2EC2680043ECBD /* _task.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F8F9EDE0240B7415009CB8E7 /* _task.cpp */; }; F8B210BF2A2EC2680043ECBD /* FwBinary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5076FA7F24CC71E40011B2BB /* FwBinary.cpp */; }; F8B210C02A2EC2680043ECBD /* ieee80211_proto.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC2F24080319007A9422 /* ieee80211_proto.c */; }; - F8B210C12A2EC2680043ECBD /* AirportItlwmInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F8CA44A125091AF60036119A /* AirportItlwmInterface.cpp */; }; F8B210C22A2EC2680043ECBD /* _string.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC3024080319007A9422 /* _string.c */; }; F8B210C32A2EC2680043ECBD /* ieee80211_ioctl.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC3224080319007A9422 /* ieee80211_ioctl.c */; }; F8B210C42A2EC2680043ECBD /* ieee80211.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC3324080319007A9422 /* ieee80211.c */; }; @@ -759,10 +766,6 @@ F8B210FD2A2EC2680043ECBD /* power.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 024A08D323FCF3E6009FBA6C /* power.cpp */; }; F8B210FE2A2EC2680043ECBD /* scan.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 024A08D523FCF4D7009FBA6C /* scan.cpp */; }; F8B210FF2A2EC2680043ECBD /* ItlIwm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F8AF3A2F24F9F35B008911C1 /* ItlIwm.cpp */; }; - F8B211002A2EC2680043ECBD /* AirportSTAIOCTL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F89B6BDC25022F8C000F77FF /* AirportSTAIOCTL.cpp */; }; - F8B211012A2EC2680043ECBD /* AirportItlwm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F89B6BBD25021C9C000F77FF /* AirportItlwm.cpp */; }; - F8B211022A2EC2680043ECBD /* AirportVirtualIOCTL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F89B6BDE25022FB5000F77FF /* AirportVirtualIOCTL.cpp */; }; - F8B211032A2EC2680043ECBD /* AirportAWDL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F89B6BE025022FC7000F77FF /* AirportAWDL.cpp */; }; F8B211052A2EC2680043ECBD /* libkmod.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5088ECBC252884870068A63D /* libkmod.a */; }; F8C2EC4F2408031A007A9422 /* ieee80211_proto.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC2F24080319007A9422 /* ieee80211_proto.c */; }; F8C2EC502408031A007A9422 /* _string.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC3024080319007A9422 /* _string.c */; }; @@ -1050,6 +1053,14 @@ F89B6BE025022FC7000F77FF /* AirportAWDL.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AirportAWDL.cpp; sourceTree = ""; }; F89B6C2225027609000F77FF /* debug.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = debug.h; sourceTree = ""; }; F89F35F12A49867F00061876 /* IO80211ControllerV2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IO80211ControllerV2.h; sourceTree = ""; }; + F8A028202A4A7DDC00C6DE90 /* AirportItlwmV2.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AirportItlwmV2.cpp; sourceTree = ""; }; + F8A028212A4A7DDC00C6DE90 /* AirportItlwmV2.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = AirportItlwmV2.hpp; sourceTree = ""; }; + F8A0282D2A4A7E0400C6DE90 /* AirportItlwmEthernetInterface.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AirportItlwmEthernetInterface.cpp; sourceTree = ""; }; + F8A0282E2A4A7E0400C6DE90 /* AirportItlwmEthernetInterface.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = AirportItlwmEthernetInterface.hpp; sourceTree = ""; }; + F8A028702A4A7FE100C6DE90 /* AirportItlwmSkywalkInterface.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AirportItlwmSkywalkInterface.cpp; sourceTree = ""; }; + F8A028712A4A7FE100C6DE90 /* AirportItlwmSkywalkInterface.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = AirportItlwmSkywalkInterface.hpp; sourceTree = ""; }; + F8A0287D2A4A80EA00C6DE90 /* IOPCIEDeviceWrapper.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = IOPCIEDeviceWrapper.cpp; sourceTree = ""; }; + F8A0287E2A4A80EA00C6DE90 /* IOPCIEDeviceWrapper.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = IOPCIEDeviceWrapper.hpp; sourceTree = ""; }; F8A2A68B2A305B9E002ABDDB /* IOSkywalkNetworkInterface.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IOSkywalkNetworkInterface.h; sourceTree = ""; }; F8A2A68C2A305BAC002ABDDB /* IOSkywalkInterface.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IOSkywalkInterface.h; sourceTree = ""; }; F8A763892766B95F004606BE /* iwlwifi-so-a0-gf4-a0.pnvm */ = {isa = PBXFileReference; lastKnownFileType = file; path = "iwlwifi-so-a0-gf4-a0.pnvm"; sourceTree = ""; }; @@ -1449,6 +1460,14 @@ F8CA44A225091AF60036119A /* AirportItlwmInterface.hpp */, F89B6BBF25021C9C000F77FF /* Info.plist */, F883EC1F266F43F200EA018C /* AirportItlwm-Monterey-Info.plist */, + F8A028202A4A7DDC00C6DE90 /* AirportItlwmV2.cpp */, + F8A028212A4A7DDC00C6DE90 /* AirportItlwmV2.hpp */, + F8A0282D2A4A7E0400C6DE90 /* AirportItlwmEthernetInterface.cpp */, + F8A0282E2A4A7E0400C6DE90 /* AirportItlwmEthernetInterface.hpp */, + F8A028702A4A7FE100C6DE90 /* AirportItlwmSkywalkInterface.cpp */, + F8A028712A4A7FE100C6DE90 /* AirportItlwmSkywalkInterface.hpp */, + F8A0287D2A4A80EA00C6DE90 /* IOPCIEDeviceWrapper.cpp */, + F8A0287E2A4A80EA00C6DE90 /* IOPCIEDeviceWrapper.hpp */, ); path = AirportItlwm; sourceTree = ""; @@ -1898,6 +1917,7 @@ F8B210AC2A2EC2680043ECBD /* IOSkywalkEthernetInterface.h in Headers */, F84AD89A2A497DB200DC8DED /* IO80211InfraProtocol.h in Headers */, F84AD8A82A497DB200DC8DED /* IOSkywalkLogicalLink.h in Headers */, + F8A028302A4A7E0500C6DE90 /* AirportItlwmEthernetInterface.hpp in Headers */, F84AD8932A497DB200DC8DED /* IOSkywalkNetworkPacket.h in Headers */, F8B210AD2A2EC2680043ECBD /* apple80211_ioctl.h in Headers */, F84AD8D92A497DB200DC8DED /* CCLogPipe.h in Headers */, @@ -1914,11 +1934,14 @@ F84AD8AF2A497DB200DC8DED /* IO80211InfraInterface.h in Headers */, F8B210B42A2EC2680043ECBD /* IO80211SkywalkInterface.h in Headers */, F84AD8C42A497DB200DC8DED /* CCLogStream.h in Headers */, + F8A028732A4A7FE100C6DE90 /* AirportItlwmSkywalkInterface.hpp in Headers */, F8B210B52A2EC2680043ECBD /* AirportItlwm.hpp in Headers */, F89F35F82A49867F00061876 /* IO80211ControllerV2.h in Headers */, + F8A028802A4A80EA00C6DE90 /* IOPCIEDeviceWrapper.hpp in Headers */, F8B210B62A2EC2680043ECBD /* IO80211VirtualInterface.h in Headers */, F8B210B72A2EC2680043ECBD /* IO80211Controller.h in Headers */, F8B210B82A2EC2680043ECBD /* (null) in Headers */, + F8A028232A4A7DDC00C6DE90 /* AirportItlwmV2.hpp in Headers */, F8B210B92A2EC2680043ECBD /* ieee80211_ra.h in Headers */, F84AD8B62A497DB200DC8DED /* CCStream.h in Headers */, F8B210BA2A2EC2680043ECBD /* apple80211_wps.h in Headers */, @@ -2784,7 +2807,6 @@ F8B210BE2A2EC2680043ECBD /* _task.cpp in Sources */, F8B210BF2A2EC2680043ECBD /* FwBinary.cpp in Sources */, F8B210C02A2EC2680043ECBD /* ieee80211_proto.c in Sources */, - F8B210C12A2EC2680043ECBD /* AirportItlwmInterface.cpp in Sources */, F8B210C22A2EC2680043ECBD /* _string.c in Sources */, F8B210C32A2EC2680043ECBD /* ieee80211_ioctl.c in Sources */, F8B210C42A2EC2680043ECBD /* ieee80211.c in Sources */, @@ -2817,9 +2839,12 @@ F8B210DF2A2EC2680043ECBD /* cmac.c in Sources */, F8B210E02A2EC2680043ECBD /* ecb_enc.c in Sources */, F8B210E12A2EC2680043ECBD /* chachapoly.c in Sources */, + F8A028222A4A7DDC00C6DE90 /* AirportItlwmV2.cpp in Sources */, F8B210E22A2EC2680043ECBD /* (null) in Sources */, F8B210E32A2EC2680043ECBD /* md5.c in Sources */, F8B210E42A2EC2680043ECBD /* arc4.c in Sources */, + F8A0282F2A4A7E0400C6DE90 /* AirportItlwmEthernetInterface.cpp in Sources */, + F8A028722A4A7FE100C6DE90 /* AirportItlwmSkywalkInterface.cpp in Sources */, F8B210E52A2EC2680043ECBD /* blf.c in Sources */, F8B210E62A2EC2680043ECBD /* _ifq.cpp in Sources */, F8B210E72A2EC2680043ECBD /* poly1305.c in Sources */, @@ -2846,11 +2871,8 @@ F8B210FC2A2EC2680043ECBD /* led.cpp in Sources */, F8B210FD2A2EC2680043ECBD /* power.cpp in Sources */, F8B210FE2A2EC2680043ECBD /* scan.cpp in Sources */, + F8A0287F2A4A80EA00C6DE90 /* IOPCIEDeviceWrapper.cpp in Sources */, F8B210FF2A2EC2680043ECBD /* ItlIwm.cpp in Sources */, - F8B211002A2EC2680043ECBD /* AirportSTAIOCTL.cpp in Sources */, - F8B211012A2EC2680043ECBD /* AirportItlwm.cpp in Sources */, - F8B211022A2EC2680043ECBD /* AirportVirtualIOCTL.cpp in Sources */, - F8B211032A2EC2680043ECBD /* AirportAWDL.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3485,7 +3507,6 @@ GCC_PREFIX_HEADER = itlwm/PrivateSPI.pch; GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", - USE_APPLE_SUPPLICANT, AIRPORT, "__IO80211_TARGET=__MAC_14_0", __PRIVATE_SPI__, @@ -3516,7 +3537,6 @@ GCC_PREFIX_HEADER = itlwm/PrivateSPI.pch; GCC_PREPROCESSOR_DEFINITIONS = ( "__IO80211_TARGET=__MAC_14_0", - USE_APPLE_SUPPLICANT, AIRPORT, __PRIVATE_SPI__, "$(inherited)", From 72182cb93f9631c0c703a84bf1e7889bd8e58c29 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Fri, 30 Jun 2023 18:26:06 +0800 Subject: [PATCH 060/114] Clean non-override functions to match vtables. --- include/Airport/IO80211InfraInterface.h | 71 -------------------- include/Airport/IO80211SkywalkInterface.h | 5 -- include/Airport/IOSkywalkEthernetInterface.h | 71 +------------------- include/Airport/IOSkywalkNetworkInterface.h | 24 ------- 4 files changed, 1 insertion(+), 170 deletions(-) diff --git a/include/Airport/IO80211InfraInterface.h b/include/Airport/IO80211InfraInterface.h index 2f7f97243..76bd137ba 100644 --- a/include/Airport/IO80211InfraInterface.h +++ b/include/Airport/IO80211InfraInterface.h @@ -21,46 +21,22 @@ class IO80211InfraInterface : public IO80211SkywalkInterface { virtual IOReturn configureReport(IOReportChannelList *,UInt,void *,void *) APPLE_KEXT_OVERRIDE; virtual IOReturn updateReport(IOReportChannelList *,UInt,void *,void *) APPLE_KEXT_OVERRIDE; virtual bool start(IOService *) APPLE_KEXT_OVERRIDE; - virtual void stop(IOService *) APPLE_KEXT_OVERRIDE; - virtual IOReturn newUserClient( task_t owningTask, void * securityID, - UInt32 type, OSDictionary * properties, - LIBKERN_RETURNS_RETAINED IOUserClient ** handler ) APPLE_KEXT_OVERRIDE; - virtual const char * stringFromReturn( IOReturn rtn ) APPLE_KEXT_OVERRIDE; - virtual int errnoFromReturn( IOReturn rtn ) APPLE_KEXT_OVERRIDE; - virtual IOReturn setPowerState( - unsigned long powerStateOrdinal, - IOService * whatDevice ) APPLE_KEXT_OVERRIDE; - virtual unsigned long maxCapabilityForDomainState( IOPMPowerFlags domainState ) APPLE_KEXT_OVERRIDE; - virtual unsigned long initialPowerStateForDomainState( IOPMPowerFlags domainState ) APPLE_KEXT_OVERRIDE; - virtual IOReturn enable(UInt) APPLE_KEXT_OVERRIDE; - virtual IOReturn disable(UInt) APPLE_KEXT_OVERRIDE; virtual SInt32 initBSDInterfaceParameters(ifnet_init_eparams *,sockaddr_dl **) APPLE_KEXT_OVERRIDE; virtual bool prepareBSDInterface(ifnet_t, UInt) APPLE_KEXT_OVERRIDE; virtual IOReturn processBSDCommand(ifnet_t, UInt, void *) APPLE_KEXT_OVERRIDE; virtual SInt32 setInterfaceEnable(bool) APPLE_KEXT_OVERRIDE; - virtual SInt32 setRunningState(bool) APPLE_KEXT_OVERRIDE; - virtual IOReturn handleChosenMedia(UInt) APPLE_KEXT_OVERRIDE; - virtual void *getSupportedMediaArray(UInt *,UInt *) APPLE_KEXT_OVERRIDE; virtual UInt getHardwareAssists(void) APPLE_KEXT_OVERRIDE; - virtual UInt32 getFeatureFlags(void) APPLE_KEXT_OVERRIDE; virtual bool bpfTap(UInt,UInt) APPLE_KEXT_OVERRIDE; - virtual const char *classNameOverride(void) APPLE_KEXT_OVERRIDE; virtual void getHardwareAddress(ether_addr *) APPLE_KEXT_OVERRIDE; virtual void setHardwareAddress(ether_addr *) APPLE_KEXT_OVERRIDE; - virtual IOReturn setPromiscuousModeEnable(bool, UInt) APPLE_KEXT_OVERRIDE; - virtual void *createPeerManager(void) APPLE_KEXT_OVERRIDE; virtual void postMessage(UInt,void *,unsigned long,bool) APPLE_KEXT_OVERRIDE; - virtual IOReturn reportDataPathEvents(UInt,void *,unsigned long,bool) APPLE_KEXT_OVERRIDE; virtual IOReturn recordOutputPackets(TxSubmissionDequeueStats *,TxSubmissionDequeueStats *) APPLE_KEXT_OVERRIDE; - virtual IOReturn recordOutputPacket(apple80211_wme_ac,int,int) APPLE_KEXT_OVERRIDE; virtual void logTxPacket(IO80211NetworkPacket *,PacketSkywalkScratch *,apple80211_wme_ac,bool) APPLE_KEXT_OVERRIDE; virtual void logTxCompletionPacket(IO80211NetworkPacket *,PacketSkywalkScratch *,unsigned char *,apple80211_wme_ac,int,UInt,bool) APPLE_KEXT_OVERRIDE; virtual IOReturn recordCompletionPackets(TxCompletionEnqueueStats *,TxCompletionEnqueueStats *) APPLE_KEXT_OVERRIDE; virtual IOReturn inputPacket(IO80211NetworkPacket *,packet_info_tag *,ether_header *,bool *) APPLE_KEXT_OVERRIDE; - virtual void logSkywalkTxReqPacket(IO80211NetworkPacket *,PacketSkywalkScratch *,unsigned char *,apple80211_wme_ac,bool) APPLE_KEXT_OVERRIDE; virtual SInt64 pendingPackets(unsigned char) APPLE_KEXT_OVERRIDE; virtual SInt64 packetSpace(unsigned char) APPLE_KEXT_OVERRIDE; - virtual bool isChipInterfaceReady(void) APPLE_KEXT_OVERRIDE; virtual bool isDebounceOnGoing(void) APPLE_KEXT_OVERRIDE; virtual bool setLinkState(IO80211LinkState,UInt,bool debounceTimeout = 30,UInt code = 0) APPLE_KEXT_OVERRIDE; virtual IO80211LinkState linkState(void) APPLE_KEXT_OVERRIDE; @@ -76,7 +52,6 @@ class IO80211InfraInterface : public IO80211SkywalkInterface { virtual void setInterfaceCCA(apple80211_channel,int) APPLE_KEXT_OVERRIDE; virtual void setInterfaceNF(apple80211_channel,long long) APPLE_KEXT_OVERRIDE; virtual void setInterfaceOFDMDesense(apple80211_channel,long long) APPLE_KEXT_OVERRIDE; - virtual void removePacketQueue(IO80211FlowQueueHash *) APPLE_KEXT_OVERRIDE; virtual void setDebugFlags(unsigned long long,UInt) APPLE_KEXT_OVERRIDE; virtual SInt64 debugFlags(void) APPLE_KEXT_OVERRIDE; virtual void setInterfaceChipCounters(apple80211_stat_report *,apple80211_chip_counters_tx *,apple80211_chip_error_counters_tx *,apple80211_chip_counters_rx *) APPLE_KEXT_OVERRIDE; @@ -89,56 +64,10 @@ class IO80211InfraInterface : public IO80211SkywalkInterface { virtual void setPeerManagerLogFlag(UInt,UInt,UInt) APPLE_KEXT_OVERRIDE; virtual void setWoWEnabled(bool) APPLE_KEXT_OVERRIDE; virtual bool wowEnabled(void) APPLE_KEXT_OVERRIDE; - virtual void printDataPath(userPrintCtx *) APPLE_KEXT_OVERRIDE; - virtual bool findOrCreateFlowQueue(IO80211FlowQueueHash) APPLE_KEXT_OVERRIDE; - virtual UInt64 findOrCreateFlowQueueWithCache(IO80211FlowQueueHash,bool *) APPLE_KEXT_OVERRIDE; - virtual UInt64 findExistingFlowQueue(IO80211FlowQueueHash) APPLE_KEXT_OVERRIDE; - virtual void removePacketQueue(IO80211FlowQueueHash const*) APPLE_KEXT_OVERRIDE; - virtual void flushPacketQueues(void) APPLE_KEXT_OVERRIDE; - virtual void cachePeer(ether_addr *,UInt *) APPLE_KEXT_OVERRIDE; - virtual bool shouldLog(unsigned long long) APPLE_KEXT_OVERRIDE; - virtual void vlogDebug(unsigned long long,char const*,va_list) APPLE_KEXT_OVERRIDE; - virtual void vlogDebugBPF(unsigned long long,char const*,va_list) APPLE_KEXT_OVERRIDE; virtual UInt64 createLinkQualityMonitor(IO80211Peer *,IOService *) APPLE_KEXT_OVERRIDE; virtual void releaseLinkQualityMonitor(IO80211Peer *) APPLE_KEXT_OVERRIDE; - virtual void *getP2PSkywalkPeerMgr(void) APPLE_KEXT_OVERRIDE; - virtual bool isCommandProhibited(int) APPLE_KEXT_OVERRIDE; - virtual void setNotificationProperty(OSSymbol const*,OSObject const*) APPLE_KEXT_OVERRIDE; - virtual void *getWorkerMatchingDict(OSString *) APPLE_KEXT_OVERRIDE; - virtual bool init(IOService *) APPLE_KEXT_OVERRIDE; - virtual bool isInterfaceEnabled(void) APPLE_KEXT_OVERRIDE; - virtual ether_addr *getSelfMacAddr(void) APPLE_KEXT_OVERRIDE; - virtual void setSelfMacAddr(ether_addr *) APPLE_KEXT_OVERRIDE; - virtual void *getPacketPool(OSString *) APPLE_KEXT_OVERRIDE; - virtual void *getLogger(void) APPLE_KEXT_OVERRIDE; - virtual IOReturn handleSIOCSIFADDR(void) APPLE_KEXT_OVERRIDE; - virtual IOReturn debugHandler(apple80211_debug_command *) APPLE_KEXT_OVERRIDE; - virtual void statsDump(void) APPLE_KEXT_OVERRIDE; - virtual void powerOnNotification(void) APPLE_KEXT_OVERRIDE; - virtual void powerOffNotification(void) APPLE_KEXT_OVERRIDE; - virtual UInt64 getTxQueueDepth(void) APPLE_KEXT_OVERRIDE; - virtual UInt64 getRxQueueCapacity(void) APPLE_KEXT_OVERRIDE; - virtual void updateRxCounter(unsigned long long) APPLE_KEXT_OVERRIDE; - virtual void *getMultiCastQueue(void) APPLE_KEXT_OVERRIDE; - virtual void *getCurrentBssid(void) APPLE_KEXT_OVERRIDE; virtual int getAssocState(void) APPLE_KEXT_OVERRIDE; - virtual void notifyQueueState(apple80211_wme_ac,unsigned short) APPLE_KEXT_OVERRIDE; - virtual int getTxHeadroom(void) APPLE_KEXT_OVERRIDE; - virtual void *getRxCompQueue(void) APPLE_KEXT_OVERRIDE; - virtual void *getTxCompQueue(void) APPLE_KEXT_OVERRIDE; - virtual void *getTxSubQueue(apple80211_wme_ac) APPLE_KEXT_OVERRIDE; - virtual void *getTxPacketPool(void) APPLE_KEXT_OVERRIDE; - virtual void *getRxPacketPool(void) APPLE_KEXT_OVERRIDE; - virtual void enableDatapath(void) APPLE_KEXT_OVERRIDE; - virtual void disableDatapath(void) APPLE_KEXT_OVERRIDE; - virtual int getNumTxQueues(void) APPLE_KEXT_OVERRIDE; virtual void *getLQMSummary(apple80211_lqm_summary *) APPLE_KEXT_OVERRIDE; - virtual int getEventPipeSize(void) APPLE_KEXT_OVERRIDE; - virtual UInt64 createEventPipe(IO80211APIUserClient *) APPLE_KEXT_OVERRIDE; - virtual void destroyEventPipe(IO80211APIUserClient *) APPLE_KEXT_OVERRIDE; - virtual void postMessageIOUC(char const*,UInt,void *,unsigned long) APPLE_KEXT_OVERRIDE; - virtual bool isIOUCPipeOpened(void) APPLE_KEXT_OVERRIDE; - virtual void *getRingMD(IO80211APIUserClient *,unsigned long long) APPLE_KEXT_OVERRIDE; virtual IOReturn setLinkStateInternal(IO80211LinkState,uint,bool,uint,apple80211_link_changed_event_data &); virtual void setPoweredOnByUser(bool); virtual void setCurrentBssid(ether_addr *); diff --git a/include/Airport/IO80211SkywalkInterface.h b/include/Airport/IO80211SkywalkInterface.h index 6e2d8dcde..f92d01fc1 100644 --- a/include/Airport/IO80211SkywalkInterface.h +++ b/include/Airport/IO80211SkywalkInterface.h @@ -65,11 +65,6 @@ class IO80211SkywalkInterface : public IOSkywalkEthernetInterface { virtual IOReturn updateReport(IOReportChannelList *,UInt,void *,void *) APPLE_KEXT_OVERRIDE; virtual bool start(IOService *) APPLE_KEXT_OVERRIDE; virtual void stop(IOService *) APPLE_KEXT_OVERRIDE; - virtual IOReturn newUserClient( task_t owningTask, void * securityID, - UInt32 type, OSDictionary * properties, - LIBKERN_RETURNS_RETAINED IOUserClient ** handler ) APPLE_KEXT_OVERRIDE; - virtual const char * stringFromReturn( IOReturn rtn ) APPLE_KEXT_OVERRIDE; - virtual int errnoFromReturn( IOReturn rtn ) APPLE_KEXT_OVERRIDE; virtual IOReturn setPowerState( unsigned long powerStateOrdinal, IOService * whatDevice ) APPLE_KEXT_OVERRIDE; diff --git a/include/Airport/IOSkywalkEthernetInterface.h b/include/Airport/IOSkywalkEthernetInterface.h index 5cea9b2b0..7b1f86aac 100644 --- a/include/Airport/IOSkywalkEthernetInterface.h +++ b/include/Airport/IOSkywalkEthernetInterface.h @@ -17,93 +17,24 @@ class IOSkywalkEthernetInterface : public IOSkywalkNetworkInterface { public: virtual void free() APPLE_KEXT_OVERRIDE; virtual bool init(OSDictionary *) APPLE_KEXT_OVERRIDE; - virtual bool willTerminate( IOService * provider, IOOptionBits options ) APPLE_KEXT_OVERRIDE; - virtual bool didTerminate( IOService * provider, IOOptionBits options, bool * defer ) APPLE_KEXT_OVERRIDE; - virtual void stop( IOService * provider ) APPLE_KEXT_OVERRIDE; - virtual bool handleOpen( IOService * forClient, - IOOptionBits options, - void * arg ) APPLE_KEXT_OVERRIDE; - virtual void handleClose( IOService * forClient, - IOOptionBits options ) APPLE_KEXT_OVERRIDE; - virtual bool handleIsOpen( const IOService * forClient ) const APPLE_KEXT_OVERRIDE; virtual IOReturn newUserClient( task_t owningTask, void * securityID, UInt32 type, OSDictionary * properties, LIBKERN_RETURNS_RETAINED IOUserClient ** handler ) APPLE_KEXT_OVERRIDE; - virtual void joinPMtree( IOService * driver ) APPLE_KEXT_OVERRIDE; - virtual IOReturn setAggressiveness( - unsigned long type, - unsigned long newLevel ) APPLE_KEXT_OVERRIDE; virtual IOReturn setPowerState( unsigned long powerStateOrdinal, IOService * whatDevice ) APPLE_KEXT_OVERRIDE; virtual IOReturn enable(UInt) APPLE_KEXT_OVERRIDE; - virtual IOReturn disable(UInt) APPLE_KEXT_OVERRIDE; - virtual IOReturn clientConnectWithTask(task_t,IOService *,UInt) APPLE_KEXT_OVERRIDE; - virtual void clientDisconnect(IOService *,UInt) APPLE_KEXT_OVERRIDE; - virtual bool isTerminating(void) APPLE_KEXT_OVERRIDE; - OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 0 ); - OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 1 ); - OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 2 ); - OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 3 ); - OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 4 ); - OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 5 ); - OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 6 ); - OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 7 ); - OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 8 ); - OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 9 ); - OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 10 ); - -public: - virtual SInt32 initBSDInterfaceParameters(ifnet_init_eparams *,sockaddr_dl **) = 0; + virtual SInt32 initBSDInterfaceParameters(ifnet_init_eparams *,sockaddr_dl **) APPLE_KEXT_OVERRIDE; virtual bool prepareBSDInterface(ifnet_t,UInt) APPLE_KEXT_OVERRIDE; - virtual void finalizeBSDInterface(ifnet_t,UInt) APPLE_KEXT_OVERRIDE; - virtual ifnet_t getBSDInterface(void) APPLE_KEXT_OVERRIDE; - virtual void setBSDName(char const*) APPLE_KEXT_OVERRIDE; - virtual const char *getBSDName(void) APPLE_KEXT_OVERRIDE; virtual IOReturn processBSDCommand(ifnet_t,UInt,void *) APPLE_KEXT_OVERRIDE; - virtual IOReturn processInterfaceCommand(ifdrv *) APPLE_KEXT_OVERRIDE; - virtual IOReturn interfaceAdvisoryEnable(bool) APPLE_KEXT_OVERRIDE; - virtual SInt32 setInterfaceEnable(bool) APPLE_KEXT_OVERRIDE; - virtual SInt32 setRunningState(bool) APPLE_KEXT_OVERRIDE; - virtual IOReturn handleChosenMedia(UInt) APPLE_KEXT_OVERRIDE; - virtual void *getSupportedMediaArray(UInt *,UInt *) APPLE_KEXT_OVERRIDE; virtual void *getPacketTapInfo(UInt *,UInt *) APPLE_KEXT_OVERRIDE; - virtual UInt getUnsentDataByteCount(UInt *,UInt *,UInt) APPLE_KEXT_OVERRIDE; - virtual UInt32 getSupportedWakeFlags(UInt *) APPLE_KEXT_OVERRIDE; virtual void enableNetworkWake(UInt) APPLE_KEXT_OVERRIDE; - virtual void calculateRingSizeForQueue(IOSkywalkPacketQueue const*,UInt *) APPLE_KEXT_OVERRIDE; virtual UInt getMaxTransferUnit(void) APPLE_KEXT_OVERRIDE; - virtual void setMaxTransferUnit(UInt) APPLE_KEXT_OVERRIDE; virtual UInt getMinPacketSize(void) APPLE_KEXT_OVERRIDE; - virtual UInt getHardwareAssists(void) APPLE_KEXT_OVERRIDE; - virtual void setHardwareAssists(UInt,UInt) APPLE_KEXT_OVERRIDE; virtual void *getInterfaceFamily(void) APPLE_KEXT_OVERRIDE; virtual void *getInterfaceSubFamily(void) APPLE_KEXT_OVERRIDE; virtual UInt getInitialMedia(void) APPLE_KEXT_OVERRIDE; - virtual UInt getFeatureFlags(void) APPLE_KEXT_OVERRIDE; - virtual UInt getTxDataOffset(void) APPLE_KEXT_OVERRIDE; - virtual UInt captureInterfaceState(UInt) APPLE_KEXT_OVERRIDE; - virtual void restoreInterfaceState(UInt) APPLE_KEXT_OVERRIDE; - virtual void setMTU(UInt) APPLE_KEXT_OVERRIDE; - virtual bool bpfTap(UInt,UInt) APPLE_KEXT_OVERRIDE; virtual const char *getBSDNamePrefix(void) APPLE_KEXT_OVERRIDE; - virtual UInt getBSDUnitNumber(void) APPLE_KEXT_OVERRIDE; - virtual const char *classNameOverride(void) APPLE_KEXT_OVERRIDE; - virtual void deferBSDAttach(bool) APPLE_KEXT_OVERRIDE; - virtual void reportDetailedLinkStatus(if_link_status const*) APPLE_KEXT_OVERRIDE; - virtual IOReturn registerNetworkInterfaceWithLogicalLink(IOSkywalkNetworkInterface::RegistrationInfo const*,IOSkywalkLogicalLink *,IOSkywalkPacketBufferPool *,IOSkywalkPacketBufferPool *,UInt) APPLE_KEXT_OVERRIDE; - virtual IOReturn deregisterLogicalLink(void) APPLE_KEXT_OVERRIDE; - virtual UInt getTSOOptions(IOSkywalkNetworkInterface::IOSkywalkTSOOptions *) APPLE_KEXT_OVERRIDE; - OSMetaClassDeclareReservedUnused( IOSkywalkNetworkInterface, 0); - OSMetaClassDeclareReservedUnused( IOSkywalkNetworkInterface, 1); - OSMetaClassDeclareReservedUnused( IOSkywalkNetworkInterface, 2); - OSMetaClassDeclareReservedUnused( IOSkywalkNetworkInterface, 3); - OSMetaClassDeclareReservedUnused( IOSkywalkNetworkInterface, 4); - OSMetaClassDeclareReservedUnused( IOSkywalkNetworkInterface, 5); - OSMetaClassDeclareReservedUnused( IOSkywalkNetworkInterface, 6); - OSMetaClassDeclareReservedUnused( IOSkywalkNetworkInterface, 7); - OSMetaClassDeclareReservedUnused( IOSkywalkNetworkInterface, 8); - OSMetaClassDeclareReservedUnused( IOSkywalkNetworkInterface, 9); virtual IOReturn registerNetworkInterfaceWithLogicalLink(IOSkywalkEthernetInterface::RegistrationInfo const*, IOSkywalkLogicalLink*, IOSkywalkPacketBufferPool*, IOSkywalkPacketBufferPool*, UInt); virtual void getHardwareAddress(ether_addr *); virtual void setHardwareAddress(ether_addr *); diff --git a/include/Airport/IOSkywalkNetworkInterface.h b/include/Airport/IOSkywalkNetworkInterface.h index 611bd5454..153d7f1c5 100644 --- a/include/Airport/IOSkywalkNetworkInterface.h +++ b/include/Airport/IOSkywalkNetworkInterface.h @@ -30,37 +30,13 @@ class IOSkywalkNetworkInterface : public IOSkywalkInterface { public: virtual void free() APPLE_KEXT_OVERRIDE; virtual bool init(OSDictionary *) APPLE_KEXT_OVERRIDE; - virtual bool willTerminate( IOService * provider, IOOptionBits options ) APPLE_KEXT_OVERRIDE; - virtual bool didTerminate( IOService * provider, IOOptionBits options, bool * defer ) APPLE_KEXT_OVERRIDE; virtual void stop(IOService *) APPLE_KEXT_OVERRIDE; - virtual bool handleOpen( IOService * forClient, - IOOptionBits options, - void * arg ) APPLE_KEXT_OVERRIDE; - virtual void handleClose( IOService * forClient, - IOOptionBits options ) APPLE_KEXT_OVERRIDE; - virtual bool handleIsOpen( const IOService * forClient ) const APPLE_KEXT_OVERRIDE; virtual void joinPMtree( IOService * driver ) APPLE_KEXT_OVERRIDE; virtual IOReturn setAggressiveness( unsigned long type, unsigned long newLevel ) APPLE_KEXT_OVERRIDE; virtual IOReturn enable(UInt) APPLE_KEXT_OVERRIDE; virtual IOReturn disable(UInt) APPLE_KEXT_OVERRIDE; - virtual IOReturn clientConnectWithTask(task_t,IOService *,UInt) APPLE_KEXT_OVERRIDE; - virtual void clientDisconnect(IOService *,UInt) APPLE_KEXT_OVERRIDE; - virtual bool isTerminating(void) APPLE_KEXT_OVERRIDE; - OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 0 ); - OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 1 ); - OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 2 ); - OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 3 ); - OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 4 ); - OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 5 ); - OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 6 ); - OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 7 ); - OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 8 ); - OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 9 ); - OSMetaClassDeclareReservedUnused( IOSkywalkInterface, 10 ); - -public: virtual SInt32 initBSDInterfaceParameters(ifnet_init_eparams *,sockaddr_dl **) = 0; virtual bool prepareBSDInterface(ifnet_t,UInt); virtual void finalizeBSDInterface(ifnet_t,UInt); From ea7e802d97a7f29dd22bab560c36eab163a1fbcd Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Sat, 1 Jul 2023 00:24:05 +0800 Subject: [PATCH 061/114] Update dependencies to satisfied OpenCore injection. --- AirportItlwm/AirportItlwm-Sonoma-Info.plist | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/AirportItlwm/AirportItlwm-Sonoma-Info.plist b/AirportItlwm/AirportItlwm-Sonoma-Info.plist index b85417836..91560253d 100644 --- a/AirportItlwm/AirportItlwm-Sonoma-Info.plist +++ b/AirportItlwm/AirportItlwm-Sonoma-Info.plist @@ -56,11 +56,15 @@ OSBundleLibraries com.apple.iokit.IO80211Family - 1200.13.0 + 1.5.0 com.apple.iokit.IONetworkingFamily 3.2 com.apple.iokit.IOPCIFamily 2.9 + com.apple.driver.corecapture + 1.0.0 + com.apple.iokit.IOSkywalkFamily + 1.0 com.apple.kpi.bsd 16.7 com.apple.kpi.iokit From a84edc89ecec3bb953595392f1269abc18abaf12 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Sun, 2 Jul 2023 23:51:41 +0800 Subject: [PATCH 062/114] Add arp.c for arp packet debugging. --- AirportItlwm/AirportItlwmV2.cpp | 2 + itl80211/openbsd/sys/_mbuf.cpp | 12 +- itl80211/openbsd/sys/arp.c | 301 ++++++++++++++++++++++++++++++++ itl80211/openbsd/sys/arp.h | 16 ++ itlwm.xcodeproj/project.pbxproj | 20 +++ 5 files changed, 350 insertions(+), 1 deletion(-) create mode 100644 itl80211/openbsd/sys/arp.c create mode 100644 itl80211/openbsd/sys/arp.h diff --git a/AirportItlwm/AirportItlwmV2.cpp b/AirportItlwm/AirportItlwmV2.cpp index db2e26e9a..3c75c386d 100644 --- a/AirportItlwm/AirportItlwmV2.cpp +++ b/AirportItlwm/AirportItlwmV2.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include "AirportItlwmSkywalkInterface.hpp" #include "IOPCIEDeviceWrapper.hpp" @@ -548,6 +549,7 @@ UInt32 AirportItlwm::outputPacket(mbuf_t m, void *param) ifp->netStat->outputErrors++; ret = kIOReturnOutputDropped; } + debug_print_arp(__func__, m); if (!ifp->if_snd.queue->lockEnqueue(m)) { freePacket(m); ret = kIOReturnOutputDropped; diff --git a/itl80211/openbsd/sys/_mbuf.cpp b/itl80211/openbsd/sys/_mbuf.cpp index 31e5ed05a..307a96293 100644 --- a/itl80211/openbsd/sys/_mbuf.cpp +++ b/itl80211/openbsd/sys/_mbuf.cpp @@ -20,17 +20,25 @@ */ #include - +extern "C" { +#include +} +#include #include extern IOCommandGate *_fCommandGate; +struct network_header { + char pad[0x48]; +}; + static IOReturn _if_input(OSObject *target, void *arg0, void *arg1, void *arg2, void *arg3) { mbuf_t m; bool isEmpty = true; struct _ifnet *ifq = (struct _ifnet *)arg0; struct mbuf_list *ml = (struct mbuf_list *)arg1; + struct network_header header = { 0 }; MBUF_LIST_FOREACH(ml, m) { if (ifq->iface == NULL) { @@ -43,6 +51,8 @@ static IOReturn _if_input(OSObject *target, void *arg0, void *arg1, void *arg2, } // XYLog("%s %d 啊啊啊啊 ifq->iface->inputPacket(m) hdr_len=%d len=%d\n", __FUNCTION__, __LINE__, mbuf_pkthdr_len(m), mbuf_len(m)); isEmpty = false; + debug_print_arp(__func__, m); + bpf_tap_in(ifq->iface->getIfnet(), DLT_RAW, m, &header, 0x48); ifq->iface->inputPacket(m, 0, IONetworkInterface::kInputOptionQueuePacket); if (ifq->netStat != NULL) { ifq->netStat->inputPackets++; diff --git a/itl80211/openbsd/sys/arp.c b/itl80211/openbsd/sys/arp.c new file mode 100644 index 000000000..5cb3dc772 --- /dev/null +++ b/itl80211/openbsd/sys/arp.c @@ -0,0 +1,301 @@ +// +// arp.c +// itlwm +// +// Created by zxystd on 2023/7/1. +// Copyright © 2023 钟先耀. All rights reserved. +// + +#include "arp.h" + +#include +#include +#include + +#define EXTRACT_16BITS(p) \ +((u_int16_t)*((const u_int8_t *)(p) + 0) << 8 | \ +(u_int16_t)*((const u_int8_t *)(p) + 1)) +#define EXTRACT_32BITS(p) \ +((u_int32_t)*((const u_int8_t *)(p) + 0) << 24 | \ +(u_int32_t)*((const u_int8_t *)(p) + 1) << 16 | \ +(u_int32_t)*((const u_int8_t *)(p) + 2) << 8 | \ +(u_int32_t)*((const u_int8_t *)(p) + 3)) +#define EXTRACT_24BITS(p) \ +((u_int32_t)*((const u_int8_t *)(p) + 0) << 16 | \ +(u_int32_t)*((const u_int8_t *)(p) + 1) << 8 | \ +(u_int32_t)*((const u_int8_t *)(p) + 2)) +#define EXTRACT_LE_8BITS(p) (*(p)) +#define EXTRACT_LE_16BITS(p) \ + ((u_int16_t)*((const u_int8_t *)(p) + 1) << 8 | \ + (u_int16_t)*((const u_int8_t *)(p) + 0)) +#define EXTRACT_LE_32BITS(p) \ + ((u_int32_t)*((const u_int8_t *)(p) + 3) << 24 | \ + (u_int32_t)*((const u_int8_t *)(p) + 2) << 16 | \ + (u_int32_t)*((const u_int8_t *)(p) + 1) << 8 | \ + (u_int32_t)*((const u_int8_t *)(p) + 0)) +#define EXTRACT_LE_64BITS(p) \ + ((u_int64_t)*((const u_int8_t *)(p) + 7) << 56 | \ + (u_int64_t)*((const u_int8_t *)(p) + 6) << 48 | \ + (u_int64_t)*((const u_int8_t *)(p) + 5) << 40 | \ + (u_int64_t)*((const u_int8_t *)(p) + 4) << 32 | \ + (u_int64_t)*((const u_int8_t *)(p) + 3) << 24 | \ + (u_int64_t)*((const u_int8_t *)(p) + 2) << 16 | \ + (u_int64_t)*((const u_int8_t *)(p) + 1) << 8 | \ + (u_int64_t)*((const u_int8_t *)(p) + 0)) + +#define ESRC(ep) ((ep)->ether_shost) +#define EDST(ep) ((ep)->ether_dhost) +#define SHA(ap) ((ap)->arp_sha) +#define THA(ap) ((ap)->arp_tha) +#define SPA(ap) ((ap)->arp_spa) +#define TPA(ap) ((ap)->arp_tpa) + +#define HASHNAMESIZE 4096 + +struct hnamemem { + u_int32_t addr; + char *name; + struct hnamemem *nxt; +}; + +struct enamemem { + u_short e_addr0; + u_short e_addr1; + u_short e_addr2; + char *e_name; + u_char *e_nsap; /* used only for nsaptable[] */ +#define e_bs e_nsap /* for bytestringtable */ + struct enamemem *e_nxt; +}; + +struct hnamemem hnametable[HASHNAMESIZE]; +struct enamemem enametable[HASHNAMESIZE]; + +struct hnamemem * +newhnamemem(void) +{ + struct hnamemem *p; + static struct hnamemem *ptr = NULL; + static u_int num = 0; + + if (num <= 0) { + num = 64; + ptr = (struct hnamemem *)malloc(num * sizeof (*ptr), 0, 0); + } + --num; + p = ptr++; + return (p); +} + +char * +intoa(u_int32_t addr) +{ + char *cp; + u_int byte; + int n; + static char buf[sizeof(".xxx.xxx.xxx.xxx")]; + + NTOHL(addr); + cp = &buf[sizeof buf]; + *--cp = '\0'; + + n = 4; + do { + byte = addr & 0xff; + *--cp = byte % 10 + '0'; + byte /= 10; + if (byte > 0) { + *--cp = byte % 10 + '0'; + byte /= 10; + if (byte > 0) + *--cp = byte + '0'; + } + *--cp = '.'; + addr >>= 8; + } while (--n > 0); + + return cp + 1; +} + +char * +savestr(const char *str) +{ + size_t size; + char *p; + static char *strptr = NULL; + static size_t strsize = 0; + + size = strlen(str) + 1; + if (size > strsize) { + strsize = 1024; + if (strsize < size) + strsize = size; + strptr = (char *)malloc(strsize, 0, 0); + } + (void)strlcpy(strptr, str, size); + p = strptr; + strptr += size; + strsize -= size; + return (p); +} + +#define HOST_NAME_MAX 255 + +char * +getname(const u_char *ap) +{ + char host[HOST_NAME_MAX+1]; + u_int32_t addr; + struct hnamemem *p; + + /* + * Extract 32 bits in network order, dealing with alignment. + */ + switch ((intptr_t)ap & (sizeof(u_int32_t)-1)) { + + case 0: + addr = *(u_int32_t *)ap; + break; + + case 2: +#if BYTE_ORDER == BIG_ENDIAN + addr = ((u_int32_t)*(u_short *)ap << 16) | + (u_int32_t)*(u_short *)(ap + 2); +#else + addr = ((u_int32_t)*(u_short *)(ap + 2) << 16) | + (u_int32_t)*(u_short *)ap; +#endif + break; + + default: +#if BYTE_ORDER == BIG_ENDIAN + addr = ((u_int32_t)ap[0] << 24) | + ((u_int32_t)ap[1] << 16) | + ((u_int32_t)ap[2] << 8) | + (u_int32_t)ap[3]; +#else + addr = ((u_int32_t)ap[3] << 24) | + ((u_int32_t)ap[2] << 16) | + ((u_int32_t)ap[1] << 8) | + (u_int32_t)ap[0]; +#endif + break; + } + + p = &hnametable[addr & (HASHNAMESIZE-1)]; + for (; p->nxt; p = p->nxt) { + if (p->addr == addr) + return (p->name); + } + p->addr = addr; + p->nxt = newhnamemem(); + + p->name = savestr(intoa(addr)); + return (p->name); +} + +char * +ether_ntoa(struct ether_addr *e) +{ + static char a[] = "xx:xx:xx:xx:xx:xx"; + + (void)snprintf(a, sizeof a, "%02x:%02x:%02x:%02x:%02x:%02x", + e->ether_addr_octet[0], e->ether_addr_octet[1], + e->ether_addr_octet[2], e->ether_addr_octet[3], + e->ether_addr_octet[4], e->ether_addr_octet[5]); + + return (a); +} + +static inline struct enamemem * +lookup_emem(const u_char *ep) +{ + u_int i, j, k; + struct enamemem *tp; + + k = (ep[0] << 8) | ep[1]; + j = (ep[2] << 8) | ep[3]; + i = (ep[4] << 8) | ep[5]; + + tp = &enametable[(i ^ j) & (HASHNAMESIZE-1)]; + while (tp->e_nxt) + if (tp->e_addr0 == i && + tp->e_addr1 == j && + tp->e_addr2 == k) + return tp; + else + tp = tp->e_nxt; + tp->e_addr0 = i; + tp->e_addr1 = j; + tp->e_addr2 = k; + tp->e_nxt = (struct enamemem *)malloc(1 * sizeof(*tp), 0, 0); + + return tp; +} + +char * +etheraddr_string(const u_char *ep) +{ + struct enamemem *tp; + struct ether_addr e; + + tp = lookup_emem(ep); + if (tp->e_name) + return (tp->e_name); + memcpy(e.ether_addr_octet, ep, sizeof(e.ether_addr_octet)); + tp->e_name = savestr(ether_ntoa(&e)); + return (tp->e_name); +} + +#define ipaddr_string(p) getname((const u_char *)(p)) + +void +debug_print_arp(const char *tag, mbuf_t m) +{ + size_t len = mbuf_len(m); + ether_header_t *eh = (ether_header_t *)mbuf_data(m); + if (len >= sizeof(ether_header_t) && + (eh->ether_type == htons(ETHERTYPE_ARP) || eh->ether_type == htons(ETHERTYPE_REVARP))) { + u_char *p = (u_char *)eh + sizeof(ether_header); + len -= sizeof(ether_header); + const struct ether_arp *ap = (const struct ether_arp *)p; + u_short pro, hrd, op; + pro = EXTRACT_16BITS(&ap->arp_pro); + hrd = EXTRACT_16BITS(&ap->arp_hrd); + op = EXTRACT_16BITS(&ap->arp_op); + if ((pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL) + || ap->arp_hln != sizeof(SHA(ap)) + || ap->arp_pln != sizeof(SPA(ap))) { + XYLog("%s arp-#%d for proto #%d (%d) hardware #%d (%d)\n", + tag, op, pro, ap->arp_pln, hrd, ap->arp_hln); + } + if (pro == ETHERTYPE_TRAIL) + XYLog("%s trailer-\n", tag); + switch (op) { + + case ARPOP_REQUEST: + XYLog("%s arp who-has %s tell %s\n", tag, ipaddr_string(TPA(ap)), ipaddr_string(SPA(ap))); + break; + + case ARPOP_REPLY: + XYLog("%s arp reply %s is-at %s\n", tag, ipaddr_string(SPA(ap)), etheraddr_string(SHA(ap))); + break; + + case ARPOP_REVREQUEST: + XYLog("%s rarp who-is %s tell %s\n", tag, etheraddr_string(THA(ap)), + etheraddr_string(SHA(ap))); + break; + + case ARPOP_REVREPLY: + XYLog("%s rarp reply %s at %s\n", tag, etheraddr_string(THA(ap)), + ipaddr_string(TPA(ap))); + break; + + default: + XYLog("%s arp-#%d\n", tag, op); + break; + } + if (hrd != ARPHRD_ETHER) + XYLog("%s hardware #%d\n", tag, hrd); + } +} diff --git a/itl80211/openbsd/sys/arp.h b/itl80211/openbsd/sys/arp.h new file mode 100644 index 000000000..7caf46698 --- /dev/null +++ b/itl80211/openbsd/sys/arp.h @@ -0,0 +1,16 @@ +// +// arp.h +// itlwm +// +// Created by zxystd on 2023/7/1. +// Copyright © 2023 钟先耀. All rights reserved. +// + +#ifndef arp_h +#define arp_h + +#include + +void debug_print_arp(const char *tag, mbuf_t m); + +#endif /* arp_h */ diff --git a/itlwm.xcodeproj/project.pbxproj b/itlwm.xcodeproj/project.pbxproj index e907c52e9..43e6ebc2a 100644 --- a/itlwm.xcodeproj/project.pbxproj +++ b/itlwm.xcodeproj/project.pbxproj @@ -317,6 +317,14 @@ 5088ECBF252884AF0068A63D /* libkmod.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5088ECBC252884870068A63D /* libkmod.a */; }; 5088ECC0252884C10068A63D /* libkmod.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5088ECBC252884870068A63D /* libkmod.a */; }; 5088ECC1252884D70068A63D /* libkmod.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5088ECBC252884870068A63D /* libkmod.a */; }; + A5A0C5242A501E6800EF9328 /* arp.c in Sources */ = {isa = PBXBuildFile; fileRef = A5A0C5232A501E6800EF9328 /* arp.c */; }; + A5A0C5252A501E6800EF9328 /* arp.c in Sources */ = {isa = PBXBuildFile; fileRef = A5A0C5232A501E6800EF9328 /* arp.c */; }; + A5A0C5262A501E6800EF9328 /* arp.c in Sources */ = {isa = PBXBuildFile; fileRef = A5A0C5232A501E6800EF9328 /* arp.c */; }; + A5A0C5272A501E6800EF9328 /* arp.c in Sources */ = {isa = PBXBuildFile; fileRef = A5A0C5232A501E6800EF9328 /* arp.c */; }; + A5A0C5282A501E6800EF9328 /* arp.c in Sources */ = {isa = PBXBuildFile; fileRef = A5A0C5232A501E6800EF9328 /* arp.c */; }; + A5A0C5292A501E6800EF9328 /* arp.c in Sources */ = {isa = PBXBuildFile; fileRef = A5A0C5232A501E6800EF9328 /* arp.c */; }; + A5A0C52A2A501E6800EF9328 /* arp.c in Sources */ = {isa = PBXBuildFile; fileRef = A5A0C5232A501E6800EF9328 /* arp.c */; }; + A5A0C52B2A501E6800EF9328 /* arp.c in Sources */ = {isa = PBXBuildFile; fileRef = A5A0C5232A501E6800EF9328 /* arp.c */; }; A5FA2AE428A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; A5FA2AE528A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; A5FA2AE628A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; @@ -1018,6 +1026,8 @@ A5213EBC27A0C3ED00D7EAB1 /* iwm-8000C-36 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "iwm-8000C-36"; sourceTree = ""; }; A5213EBD27A0C3ED00D7EAB1 /* iwm-9260-46 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "iwm-9260-46"; sourceTree = ""; }; A5213EBE27A0C3ED00D7EAB1 /* iwm-8265-36 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "iwm-8265-36"; sourceTree = ""; }; + A5A0C5222A501E2900EF9328 /* arp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = arp.h; sourceTree = ""; }; + A5A0C5232A501E6800EF9328 /* arp.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = arp.c; sourceTree = ""; }; A5FA2AE328A797B200847103 /* _ifq.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = _ifq.cpp; sourceTree = ""; }; F800DD9A24FBEBF000789320 /* ItlDriverController.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ItlDriverController.hpp; sourceTree = ""; }; F837C91C2724577F00B2C499 /* coex.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = coex.cpp; sourceTree = ""; }; @@ -1584,6 +1594,8 @@ F8BEFA9124CA93E900F6D938 /* _malloc.h */, F8C7EF7B263125DE00BA87B6 /* _netstat.h */, F8BB56172647FDF500F180EC /* _clock.h */, + A5A0C5222A501E2900EF9328 /* arp.h */, + A5A0C5232A501E6800EF9328 /* arp.c */, ); path = sys; sourceTree = ""; @@ -2315,6 +2327,7 @@ 024A085723FCBC6C009FBA6C /* gmac.c in Sources */, F8C2EC592408031A007A9422 /* ieee80211_mira.c in Sources */, 024A083223FCBC6C009FBA6C /* ecb3_enc.c in Sources */, + A5A0C5242A501E6800EF9328 /* arp.c in Sources */, 024A08D023FCEE88009FBA6C /* ctxt.cpp in Sources */, F8D76362244F21BB00DEA040 /* pm.cpp in Sources */, 024A08C023FCD4E2009FBA6C /* utils.cpp in Sources */, @@ -2365,6 +2378,7 @@ 35CBE68E251CB89700435CBC /* rijndael.c in Sources */, 35CBE68F251CB89700435CBC /* ecb3_enc.c in Sources */, 35CBE690251CB89700435CBC /* set_key.c in Sources */, + A5A0C5282A501E6800EF9328 /* arp.c in Sources */, 35CBE691251CB89700435CBC /* cast.c in Sources */, 35CBE692251CB89700435CBC /* michael.c in Sources */, 35CBE693251CB89700435CBC /* sha1.c in Sources */, @@ -2443,6 +2457,7 @@ 35CBE6F8251CB8BF00435CBC /* rijndael.c in Sources */, 35CBE6F9251CB8BF00435CBC /* ecb3_enc.c in Sources */, 35CBE6FA251CB8BF00435CBC /* set_key.c in Sources */, + A5A0C5262A501E6800EF9328 /* arp.c in Sources */, 35CBE6FB251CB8BF00435CBC /* cast.c in Sources */, 35CBE6FC251CB8BF00435CBC /* michael.c in Sources */, 35CBE6FD251CB8BF00435CBC /* sha1.c in Sources */, @@ -2521,6 +2536,7 @@ 35CBE763251CB8CA00435CBC /* rijndael.c in Sources */, 35CBE764251CB8CA00435CBC /* ecb3_enc.c in Sources */, 35CBE765251CB8CA00435CBC /* set_key.c in Sources */, + A5A0C5252A501E6800EF9328 /* arp.c in Sources */, 35CBE766251CB8CA00435CBC /* cast.c in Sources */, 35CBE767251CB8CA00435CBC /* michael.c in Sources */, 35CBE768251CB8CA00435CBC /* sha1.c in Sources */, @@ -2633,6 +2649,7 @@ F897ED0A266EFF93005EE8F7 /* led.cpp in Sources */, F897ED0B266EFF93005EE8F7 /* power.cpp in Sources */, F897ED0C266EFF93005EE8F7 /* scan.cpp in Sources */, + A5A0C5292A501E6800EF9328 /* arp.c in Sources */, F897ED0D266EFF93005EE8F7 /* ItlIwm.cpp in Sources */, F897ED0E266EFF93005EE8F7 /* AirportSTAIOCTL.cpp in Sources */, F897ED0F266EFF93005EE8F7 /* AirportItlwm.cpp in Sources */, @@ -2678,6 +2695,7 @@ F89B6C0D250231E4000F77FF /* rijndael.c in Sources */, F89B6C0E250231E4000F77FF /* ecb3_enc.c in Sources */, F89B6C0F250231E4000F77FF /* set_key.c in Sources */, + A5A0C5272A501E6800EF9328 /* arp.c in Sources */, F89B6C10250231E4000F77FF /* cast.c in Sources */, F89B6C11250231E4000F77FF /* michael.c in Sources */, F89B6C12250231E4000F77FF /* sha1.c in Sources */, @@ -2790,6 +2808,7 @@ F8AE654A285471560085B4CF /* led.cpp in Sources */, F8AE654B285471560085B4CF /* power.cpp in Sources */, F8AE654C285471560085B4CF /* scan.cpp in Sources */, + A5A0C52A2A501E6800EF9328 /* arp.c in Sources */, F8AE654D285471560085B4CF /* ItlIwm.cpp in Sources */, F8AE654E285471560085B4CF /* AirportSTAIOCTL.cpp in Sources */, F8AE654F285471560085B4CF /* AirportItlwm.cpp in Sources */, @@ -2835,6 +2854,7 @@ F8B210DB2A2EC2680043ECBD /* set_key.c in Sources */, F8B210DC2A2EC2680043ECBD /* cast.c in Sources */, F8B210DD2A2EC2680043ECBD /* michael.c in Sources */, + A5A0C52B2A501E6800EF9328 /* arp.c in Sources */, F8B210DE2A2EC2680043ECBD /* sha1.c in Sources */, F8B210DF2A2EC2680043ECBD /* cmac.c in Sources */, F8B210E02A2EC2680043ECBD /* ecb_enc.c in Sources */, From 801ecc4658e78f43ab9df3a7a376e57d43ef9a1e Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Mon, 3 Jul 2023 18:06:11 +0800 Subject: [PATCH 063/114] AirportItlwm: Fix DHCP issue on Sonoma. --- AirportItlwm/AirportItlwmEthernetInterface.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AirportItlwm/AirportItlwmEthernetInterface.cpp b/AirportItlwm/AirportItlwmEthernetInterface.cpp index d7ea666fd..bd5889ae8 100644 --- a/AirportItlwm/AirportItlwmEthernetInterface.cpp +++ b/AirportItlwm/AirportItlwmEthernetInterface.cpp @@ -27,8 +27,8 @@ IOReturn AirportItlwmEthernetInterface:: attachToDataLinkLayer( IOOptionBits options, void *parameter ) { XYLog("%s\n", __FUNCTION__); - char infName[16]; - IOReturn ret = super::IONetworkInterface::attachToDataLinkLayer(options, parameter); + char infName[IFNAMSIZ]; + IOReturn ret = super::attachToDataLinkLayer(options, parameter); if (ret == kIOReturnSuccess && interface) { UInt8 builtIn = 0; interface->setProperty("built-in", OSData::withBytes(&builtIn, sizeof(builtIn))); From c6023f5a4fbc916dbfddb135cd68bb6484e07d46 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Mon, 3 Jul 2023 18:07:18 +0800 Subject: [PATCH 064/114] Clean ARP debug calling. --- AirportItlwm/AirportItlwmEthernetInterface.cpp | 6 +++--- AirportItlwm/AirportItlwmV2.cpp | 11 ++++------- itl80211/openbsd/sys/_mbuf.cpp | 4 ---- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/AirportItlwm/AirportItlwmEthernetInterface.cpp b/AirportItlwm/AirportItlwmEthernetInterface.cpp index bd5889ae8..ce153a3e0 100644 --- a/AirportItlwm/AirportItlwmEthernetInterface.cpp +++ b/AirportItlwm/AirportItlwmEthernetInterface.cpp @@ -34,11 +34,11 @@ attachToDataLinkLayer( IOOptionBits options, void *parameter ) interface->setProperty("built-in", OSData::withBytes(&builtIn, sizeof(builtIn))); snprintf(infName, sizeof(infName), "%s%u", ifnet_name(getIfnet()), ifnet_unit(getIfnet())); interface->setProperty("IOInterfaceName", OSString::withCString(infName)); -// interface->setProperty("IOInterfaceUnit", OSNumber::withNumber(ifnet_unit(getIfnet()), 8)); - interface->setProperty("IOInterfaceNamePrefix", OSString::withCString("en")); + interface->setProperty("IOInterfaceUnit", OSNumber::withNumber(ifnet_unit(getIfnet()), 8)); + interface->setProperty("IOInterfaceNamePrefix", OSString::withCString(ifnet_name(getIfnet()))); interface->registerService(); interface->prepareBSDInterface(getIfnet(), 0); - ret = bpf_attach(getIfnet(), DLT_RAW, 0x48, &AirportItlwmEthernetInterface::bpfOutputPacket, &AirportItlwmEthernetInterface::bpfTap); +// ret = bpf_attach(getIfnet(), DLT_RAW, 0x48, &RTLEthernetInterface::bpfOutputPacket, &RTLEthernetInterface::bpfTap); } return ret; } diff --git a/AirportItlwm/AirportItlwmV2.cpp b/AirportItlwm/AirportItlwmV2.cpp index 3c75c386d..6093b0a86 100644 --- a/AirportItlwm/AirportItlwmV2.cpp +++ b/AirportItlwm/AirportItlwmV2.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include "AirportItlwmSkywalkInterface.hpp" #include "IOPCIEDeviceWrapper.hpp" @@ -217,14 +216,14 @@ bool AirportItlwm::start(IOService *provider) driverLogOptions.pipe_size = 0x200000; driverLogOptions.min_log_size_notify = 0xccccc; driverLogOptions.notify_threshold = 1000; - strlcpy(driverLogOptions.file_name, "AppleBCMWLAN_Logs", sizeof(driverLogOptions.file_name)); + strlcpy(driverLogOptions.file_name, "Itlwm_Logs", sizeof(driverLogOptions.file_name)); snprintf(driverLogOptions.name, sizeof(driverLogOptions.name), "wlan%d", 0); strlcpy(driverLogOptions.directory_name, "WiFi", sizeof(driverLogOptions.directory_name)); driverLogOptions.pad9 = 0x1000000; driverLogOptions.pad10 = 2; driverLogOptions.file_options = 0; driverLogOptions.log_policy = 0; - driverLogPipe = CCPipe::withOwnerNameCapacity(this, "com.zxystd.RTL008", "DriverLogs", &driverLogOptions); + driverLogPipe = CCPipe::withOwnerNameCapacity(this, "com.zxystd.AirportItlwm", "DriverLogs", &driverLogOptions); XYLog("%s driverLogPipeRet %d\n", __FUNCTION__, driverLogPipe != NULL); memset(&driverLogOptions, 0, sizeof(driverLogOptions)); @@ -239,7 +238,7 @@ bool AirportItlwm::start(IOService *provider) driverLogOptions.pad10 = LOWER32(0x202800000); driverLogOptions.file_options = 0; driverLogOptions.log_policy = 0; - driverDataPathPipe = CCPipe::withOwnerNameCapacity(this, "com.zxystd.RTL008", "DatapathEvents", &driverLogOptions); + driverDataPathPipe = CCPipe::withOwnerNameCapacity(this, "com.zxystd.AirportItlwm", "DatapathEvents", &driverLogOptions); XYLog("%s driverDataPathPipeRet %d\n", __FUNCTION__, driverDataPathPipe != NULL); memset(&driverLogOptions, 0, sizeof(driverLogOptions)); @@ -249,7 +248,7 @@ bool AirportItlwm::start(IOService *provider) strlcpy(driverLogOptions.name, "0", sizeof(driverLogOptions.name)); strlcpy(driverLogOptions.directory_name, "WiFi", sizeof(driverLogOptions.directory_name)); driverLogOptions.pipe_size = 128; - driverSnapshotsPipe = CCPipe::withOwnerNameCapacity(this, "com.zxystd.RTL008", "StateSnapshots", &driverLogOptions); + driverSnapshotsPipe = CCPipe::withOwnerNameCapacity(this, "com.zxystd.AirportItlwm", "StateSnapshots", &driverLogOptions); XYLog("%s driverSnapshotsPipeRet %d\n", __FUNCTION__, driverSnapshotsPipe != NULL); CCStreamOptions faultReportOptions = { 0 }; @@ -301,7 +300,6 @@ bool AirportItlwm::start(IOService *provider) if (TAILQ_EMPTY(&fHalService->get80211Controller()->ic_ess)) fHalService->get80211Controller()->ic_flags |= IEEE80211_F_AUTO_JOIN; registerService(); - fNetIf->registerService(); return true; } @@ -549,7 +547,6 @@ UInt32 AirportItlwm::outputPacket(mbuf_t m, void *param) ifp->netStat->outputErrors++; ret = kIOReturnOutputDropped; } - debug_print_arp(__func__, m); if (!ifp->if_snd.queue->lockEnqueue(m)) { freePacket(m); ret = kIOReturnOutputDropped; diff --git a/itl80211/openbsd/sys/_mbuf.cpp b/itl80211/openbsd/sys/_mbuf.cpp index 307a96293..93fed10dc 100644 --- a/itl80211/openbsd/sys/_mbuf.cpp +++ b/itl80211/openbsd/sys/_mbuf.cpp @@ -23,7 +23,6 @@ extern "C" { #include } -#include #include extern IOCommandGate *_fCommandGate; @@ -38,7 +37,6 @@ static IOReturn _if_input(OSObject *target, void *arg0, void *arg1, void *arg2, bool isEmpty = true; struct _ifnet *ifq = (struct _ifnet *)arg0; struct mbuf_list *ml = (struct mbuf_list *)arg1; - struct network_header header = { 0 }; MBUF_LIST_FOREACH(ml, m) { if (ifq->iface == NULL) { @@ -51,8 +49,6 @@ static IOReturn _if_input(OSObject *target, void *arg0, void *arg1, void *arg2, } // XYLog("%s %d 啊啊啊啊 ifq->iface->inputPacket(m) hdr_len=%d len=%d\n", __FUNCTION__, __LINE__, mbuf_pkthdr_len(m), mbuf_len(m)); isEmpty = false; - debug_print_arp(__func__, m); - bpf_tap_in(ifq->iface->getIfnet(), DLT_RAW, m, &header, 0x48); ifq->iface->inputPacket(m, 0, IONetworkInterface::kInputOptionQueuePacket); if (ifq->netStat != NULL) { ifq->netStat->inputPackets++; From e77713f517e271ff89b00ecbc86cf1c8cf29bee1 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Tue, 4 Jul 2023 22:49:14 +0800 Subject: [PATCH 065/114] Clean some logs. --- AirportItlwm/AirportItlwmSkywalkInterface.cpp | 2 +- AirportItlwm/AirportItlwmV2.cpp | 3 --- AirportItlwm/AirportSTAIOCTL.cpp | 2 +- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/AirportItlwm/AirportItlwmSkywalkInterface.cpp b/AirportItlwm/AirportItlwmSkywalkInterface.cpp index 595eeffe7..c25ff871b 100644 --- a/AirportItlwm/AirportItlwmSkywalkInterface.cpp +++ b/AirportItlwm/AirportItlwmSkywalkInterface.cpp @@ -322,7 +322,7 @@ setAUTH_TYPE(struct apple80211_authtype_data *ad) IOReturn AirportItlwmSkywalkInterface:: setCIPHER_KEY(struct apple80211_key *key) { - XYLog("%s", __FUNCTION__); + XYLog("%s\n", __FUNCTION__); const char* keydump = hexdump(key->key, key->key_len); const char* rscdump = hexdump(key->key_rsc, key->key_rsc_len); const char* eadump = hexdump(key->key_ea.octet, APPLE80211_ADDR_LEN); diff --git a/AirportItlwm/AirportItlwmV2.cpp b/AirportItlwm/AirportItlwmV2.cpp index 6093b0a86..e7a37c3d8 100644 --- a/AirportItlwm/AirportItlwmV2.cpp +++ b/AirportItlwm/AirportItlwmV2.cpp @@ -489,9 +489,6 @@ setLinkStateGated(OSObject *target, void *arg0, void *arg1, void *arg2, void *ar that->fNetIf->reportLinkStatus(1, 0); } that->bsdInterface->setLinkState((IO80211LinkState)(uint64_t)arg0); - if ((ifnet_flags(that->bsdInterface->getIfnet()) & (IFF_UP | IFF_RUNNING)) != (IFF_UP | IFF_RUNNING)) { - XYLog("stf: IFF_DOWN\n"); - } return ret; } diff --git a/AirportItlwm/AirportSTAIOCTL.cpp b/AirportItlwm/AirportSTAIOCTL.cpp index f93e1c88f..c87deeecc 100644 --- a/AirportItlwm/AirportSTAIOCTL.cpp +++ b/AirportItlwm/AirportSTAIOCTL.cpp @@ -254,7 +254,7 @@ setAUTH_TYPE(OSObject *object, struct apple80211_authtype_data *ad) IOReturn AirportItlwm:: setCIPHER_KEY(OSObject *object, struct apple80211_key *key) { - XYLog("%s", __FUNCTION__); + XYLog("%s\n", __FUNCTION__); const char* keydump = hexdump(key->key, key->key_len); const char* rscdump = hexdump(key->key_rsc, key->key_rsc_len); const char* eadump = hexdump(key->key_ea.octet, APPLE80211_ADDR_LEN); From 424c2d2183a0e2d2ce49981caadd86adaea56eea Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Wed, 5 Jul 2023 17:33:40 +0800 Subject: [PATCH 066/114] AirportItlwm: Refactor cclog instances initialization. --- AirportItlwm/AirportItlwmV2.cpp | 104 ++++++++++++++++++-------------- AirportItlwm/AirportItlwmV2.hpp | 1 + 2 files changed, 59 insertions(+), 46 deletions(-) diff --git a/AirportItlwm/AirportItlwmV2.cpp b/AirportItlwm/AirportItlwmV2.cpp index e7a37c3d8..89b7bb14a 100644 --- a/AirportItlwm/AirportItlwmV2.cpp +++ b/AirportItlwm/AirportItlwmV2.cpp @@ -122,6 +122,58 @@ IOService* AirportItlwm::probe(IOService *provider, SInt32 *score) #define LOWER32(x) ((uint64_t)(x) & 0xffffffff) #define HIGHER32(x) ((uint64_t)(x) >> 32) +bool AirportItlwm:: +initCCLogs() +{ + CCPipeOptions driverLogOptions = { 0 }; + driverLogOptions.pipe_type = 0; + driverLogOptions.log_data_type = 1; + driverLogOptions.pipe_size = 0x200000; + driverLogOptions.min_log_size_notify = 0xccccc; + driverLogOptions.notify_threshold = 1000; + strlcpy(driverLogOptions.file_name, "Itlwm_Logs", sizeof(driverLogOptions.file_name)); + snprintf(driverLogOptions.name, sizeof(driverLogOptions.name), "wlan%d", 0); + strlcpy(driverLogOptions.directory_name, "WiFi", sizeof(driverLogOptions.directory_name)); + driverLogOptions.pad9 = 0x1000000; + driverLogOptions.pad10 = 2; + driverLogOptions.file_options = 0; + driverLogOptions.log_policy = 0; + driverLogPipe = CCPipe::withOwnerNameCapacity(this, "com.zxystd.AirportItlwm", "DriverLogs", &driverLogOptions); + XYLog("%s driverLogPipeRet %d\n", __FUNCTION__, driverLogPipe != NULL); + + memset(&driverLogOptions, 0, sizeof(driverLogOptions)); + driverLogOptions.pipe_type = 0; + driverLogOptions.log_data_type = 0; + driverLogOptions.pipe_size = 0x200000; + driverLogOptions.min_log_size_notify = 0xccccc; + driverLogOptions.notify_threshold = 1000; + strlcpy(driverLogOptions.file_name, "AppleBCMWLAN_Datapath", sizeof(driverLogOptions.file_name)); + strlcpy(driverLogOptions.directory_name, "WiFi", sizeof(driverLogOptions.directory_name)); + driverLogOptions.pad9 = HIGHER32(0x202800000); + driverLogOptions.pad10 = LOWER32(0x202800000); + driverLogOptions.file_options = 0; + driverLogOptions.log_policy = 0; + driverDataPathPipe = CCPipe::withOwnerNameCapacity(this, "com.zxystd.AirportItlwm", "DatapathEvents", &driverLogOptions); + XYLog("%s driverDataPathPipeRet %d\n", __FUNCTION__, driverDataPathPipe != NULL); + + memset(&driverLogOptions, 0, sizeof(driverLogOptions)); + driverLogOptions.pipe_type = 0x200000001; + driverLogOptions.log_data_type = 2; + strlcpy(driverLogOptions.file_name, "StateSnapshots", sizeof(driverLogOptions.file_name)); + strlcpy(driverLogOptions.name, "0", sizeof(driverLogOptions.name)); + strlcpy(driverLogOptions.directory_name, "WiFi", sizeof(driverLogOptions.directory_name)); + driverLogOptions.pipe_size = 128; + driverSnapshotsPipe = CCPipe::withOwnerNameCapacity(this, "com.zxystd.AirportItlwm", "StateSnapshots", &driverLogOptions); + XYLog("%s driverSnapshotsPipeRet %d\n", __FUNCTION__, driverSnapshotsPipe != NULL); + + CCStreamOptions faultReportOptions = { 0 }; + faultReportOptions.stream_type = 1; + faultReportOptions.console_level = 0xFFFFFFFFFFFFFFFF; + driverFaultReporter = CCStream::withPipeAndName(driverSnapshotsPipe, "FaultReporter", &faultReportOptions); + XYLog("%s driverFaultReporterRet %d\n", __FUNCTION__, driverFaultReporter != NULL); + return driverLogPipe && driverDataPathPipe && driverSnapshotsPipe && driverFaultReporter; +} + bool AirportItlwm::start(IOService *provider) { XYLog("%s\n", __PRETTY_FUNCTION__); @@ -210,53 +262,13 @@ bool AirportItlwm::start(IOService *provider) } fNetIf->setInterfaceRole(1); fNetIf->setInterfaceId(1); - CCPipeOptions driverLogOptions = { 0 }; - driverLogOptions.pipe_type = 0; - driverLogOptions.log_data_type = 1; - driverLogOptions.pipe_size = 0x200000; - driverLogOptions.min_log_size_notify = 0xccccc; - driverLogOptions.notify_threshold = 1000; - strlcpy(driverLogOptions.file_name, "Itlwm_Logs", sizeof(driverLogOptions.file_name)); - snprintf(driverLogOptions.name, sizeof(driverLogOptions.name), "wlan%d", 0); - strlcpy(driverLogOptions.directory_name, "WiFi", sizeof(driverLogOptions.directory_name)); - driverLogOptions.pad9 = 0x1000000; - driverLogOptions.pad10 = 2; - driverLogOptions.file_options = 0; - driverLogOptions.log_policy = 0; - driverLogPipe = CCPipe::withOwnerNameCapacity(this, "com.zxystd.AirportItlwm", "DriverLogs", &driverLogOptions); - XYLog("%s driverLogPipeRet %d\n", __FUNCTION__, driverLogPipe != NULL); - - memset(&driverLogOptions, 0, sizeof(driverLogOptions)); - driverLogOptions.pipe_type = 0; - driverLogOptions.log_data_type = 0; - driverLogOptions.pipe_size = 0x200000; - driverLogOptions.min_log_size_notify = 0xccccc; - driverLogOptions.notify_threshold = 1000; - strlcpy(driverLogOptions.file_name, "AppleBCMWLAN_Datapath", sizeof(driverLogOptions.file_name)); - strlcpy(driverLogOptions.directory_name, "WiFi", sizeof(driverLogOptions.directory_name)); - driverLogOptions.pad9 = HIGHER32(0x202800000); - driverLogOptions.pad10 = LOWER32(0x202800000); - driverLogOptions.file_options = 0; - driverLogOptions.log_policy = 0; - driverDataPathPipe = CCPipe::withOwnerNameCapacity(this, "com.zxystd.AirportItlwm", "DatapathEvents", &driverLogOptions); - XYLog("%s driverDataPathPipeRet %d\n", __FUNCTION__, driverDataPathPipe != NULL); - - memset(&driverLogOptions, 0, sizeof(driverLogOptions)); - driverLogOptions.pipe_type = 0x200000001; - driverLogOptions.log_data_type = 2; - strlcpy(driverLogOptions.file_name, "StateSnapshots", sizeof(driverLogOptions.file_name)); - strlcpy(driverLogOptions.name, "0", sizeof(driverLogOptions.name)); - strlcpy(driverLogOptions.directory_name, "WiFi", sizeof(driverLogOptions.directory_name)); - driverLogOptions.pipe_size = 128; - driverSnapshotsPipe = CCPipe::withOwnerNameCapacity(this, "com.zxystd.AirportItlwm", "StateSnapshots", &driverLogOptions); - XYLog("%s driverSnapshotsPipeRet %d\n", __FUNCTION__, driverSnapshotsPipe != NULL); - - CCStreamOptions faultReportOptions = { 0 }; - faultReportOptions.stream_type = 1; - faultReportOptions.console_level = 0xFFFFFFFFFFFFFFFF; - driverFaultReporter = CCStream::withPipeAndName(driverSnapshotsPipe, "FaultReporter", &faultReportOptions); - XYLog("%s driverFaultReporterRet %d\n", __FUNCTION__, driverFaultReporter != NULL); + if (!initCCLogs()) { + XYLog("CCLog init fail\n"); + super::stop(provider); + releaseAll(); + return false; + } if (!fNetIf->attach(this)) { XYLog("attach to service fail\n"); super::stop(provider); diff --git a/AirportItlwm/AirportItlwmV2.hpp b/AirportItlwm/AirportItlwmV2.hpp index 0514f7e2f..2c2f74c92 100644 --- a/AirportItlwm/AirportItlwmV2.hpp +++ b/AirportItlwm/AirportItlwmV2.hpp @@ -104,6 +104,7 @@ IOReturn set##REQ(OSObject *object, struct DATA_TYPE *data); static void eventHandler(struct ieee80211com *, int, void *); IOReturn enableAdapter(IONetworkInterface *netif); void disableAdapter(IONetworkInterface *netif); + bool initCCLogs(); virtual IO80211WorkQueue *getWorkQueue() override; virtual bool requiresExplicitMBufRelease() override { From 4014e9fa63826336acc70bc5a0fa812c5c87d566 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Wed, 5 Jul 2023 17:34:10 +0800 Subject: [PATCH 067/114] AirportItlwm: Safe release cclog instances. --- AirportItlwm/AirportItlwmV2.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/AirportItlwm/AirportItlwmV2.cpp b/AirportItlwm/AirportItlwmV2.cpp index 89b7bb14a..8c6a47c92 100644 --- a/AirportItlwm/AirportItlwmV2.cpp +++ b/AirportItlwm/AirportItlwmV2.cpp @@ -24,6 +24,10 @@ IOCommandGate *_fCommandGate; void AirportItlwm::releaseAll() { + OSSafeReleaseNULL(driverLogPipe); + OSSafeReleaseNULL(driverDataPathPipe); + OSSafeReleaseNULL(driverSnapshotsPipe); + OSSafeReleaseNULL(driverFaultReporter); if (fHalService) { fHalService->release(); fHalService = NULL; From f1cad0fd7bbb62e13ccd96ef4359f3ed79708b96 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Thu, 6 Jul 2023 18:40:28 +0800 Subject: [PATCH 068/114] iwx: support Intel(R) Wi-Fi 6 AX101, from the spec, ax101 doesn't support 160MHz mode. --- itlwm/hal_iwx/ItlIwx.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/itlwm/hal_iwx/ItlIwx.cpp b/itlwm/hal_iwx/ItlIwx.cpp index e98448737..f7efe2203 100644 --- a/itlwm/hal_iwx/ItlIwx.cpp +++ b/itlwm/hal_iwx/ItlIwx.cpp @@ -12582,7 +12582,7 @@ static const struct iwl_dev_info iwl_dev_info_table[] = { _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY, IWL_CFG_RF_TYPE_HR1, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, + IWL_CFG_NO_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, iwl_cfg_so_a0_hr_a0, iwl_ax101_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY, From bd47afe94836e178402bf9ca7bb031d35ea6d90b Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Thu, 6 Jul 2023 18:43:58 +0800 Subject: [PATCH 069/114] iwx: Redo last commit. --- itlwm/hal_iwx/ItlIwx.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/itlwm/hal_iwx/ItlIwx.cpp b/itlwm/hal_iwx/ItlIwx.cpp index f7efe2203..264d09fb9 100644 --- a/itlwm/hal_iwx/ItlIwx.cpp +++ b/itlwm/hal_iwx/ItlIwx.cpp @@ -12565,7 +12565,7 @@ static const struct iwl_dev_info iwl_dev_info_table[] = { _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_SO, IWL_CFG_ANY, IWL_CFG_RF_TYPE_HR1, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, + IWL_CFG_NO_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, iwl_cfg_so_a0_hr_a0, iwl_ax101_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_SO, IWL_CFG_ANY, From d738c780b566fc160c51e5e838b82f7c5ef687b1 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Fri, 7 Jul 2023 18:18:05 +0800 Subject: [PATCH 070/114] AirportItlwm: Add built-in property. --- AirportItlwm/AirportItlwmEthernetInterface.cpp | 8 ++++++-- AirportItlwm/AirportItlwmV2.cpp | 2 ++ AirportItlwm/IOPCIEDeviceWrapper.cpp | 3 ++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/AirportItlwm/AirportItlwmEthernetInterface.cpp b/AirportItlwm/AirportItlwmEthernetInterface.cpp index ce153a3e0..97de695fa 100644 --- a/AirportItlwm/AirportItlwmEthernetInterface.cpp +++ b/AirportItlwm/AirportItlwmEthernetInterface.cpp @@ -31,11 +31,15 @@ attachToDataLinkLayer( IOOptionBits options, void *parameter ) IOReturn ret = super::attachToDataLinkLayer(options, parameter); if (ret == kIOReturnSuccess && interface) { UInt8 builtIn = 0; + IOEthernetAddress addr; interface->setProperty("built-in", OSData::withBytes(&builtIn, sizeof(builtIn))); snprintf(infName, sizeof(infName), "%s%u", ifnet_name(getIfnet()), ifnet_unit(getIfnet())); interface->setProperty("IOInterfaceName", OSString::withCString(infName)); - interface->setProperty("IOInterfaceUnit", OSNumber::withNumber(ifnet_unit(getIfnet()), 8)); - interface->setProperty("IOInterfaceNamePrefix", OSString::withCString(ifnet_name(getIfnet()))); + interface->setProperty(kIOInterfaceUnit, OSNumber::withNumber(ifnet_unit(getIfnet()), 8)); + interface->setProperty(kIOInterfaceNamePrefix, OSString::withCString(ifnet_name(getIfnet()))); + if (OSDynamicCast(IOEthernetController, getController())->getHardwareAddress(&addr) == kIOReturnSuccess) + setProperty(kIOMACAddress, (void *) &addr, + kIOEthernetAddressSize); interface->registerService(); interface->prepareBSDInterface(getIfnet(), 0); // ret = bpf_attach(getIfnet(), DLT_RAW, 0x48, &RTLEthernetInterface::bpfOutputPacket, &RTLEthernetInterface::bpfTap); diff --git a/AirportItlwm/AirportItlwmV2.cpp b/AirportItlwm/AirportItlwmV2.cpp index 8c6a47c92..e46ceab6d 100644 --- a/AirportItlwm/AirportItlwmV2.cpp +++ b/AirportItlwm/AirportItlwmV2.cpp @@ -184,6 +184,8 @@ bool AirportItlwm::start(IOService *provider) struct IOSkywalkEthernetInterface::RegistrationInfo registInfo; int boot_value = 0; + UInt8 builtIn = 0; + setProperty("built-in", OSData::withBytes(&builtIn, sizeof(builtIn))); setProperty("DriverKitDriver", kOSBooleanFalse); if (!super::start(provider)) { return false; diff --git a/AirportItlwm/IOPCIEDeviceWrapper.cpp b/AirportItlwm/IOPCIEDeviceWrapper.cpp index 225725c80..b1b39fa29 100644 --- a/AirportItlwm/IOPCIEDeviceWrapper.cpp +++ b/AirportItlwm/IOPCIEDeviceWrapper.cpp @@ -103,7 +103,8 @@ start(IOService *provider) return false; } IOLog("%s::super start succeed\n", getName()); - + UInt8 builtIn = 0; + setProperty("built-in", OSData::withBytes(&builtIn, sizeof(builtIn))); registerService(); return true; } From 9566be52b9351056d765694081225fd59b22e0fb Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Mon, 17 Jul 2023 18:03:56 +0800 Subject: [PATCH 071/114] AirportItlwm: update CARD_CAPABILITIES, only known WPA/WPA2 networks supported. --- AirportItlwm/AirportItlwmV2.cpp | 39 +++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/AirportItlwm/AirportItlwmV2.cpp b/AirportItlwm/AirportItlwmV2.cpp index e46ceab6d..89beff970 100644 --- a/AirportItlwm/AirportItlwmV2.cpp +++ b/AirportItlwm/AirportItlwmV2.cpp @@ -668,10 +668,45 @@ IOReturn AirportItlwm:: getCARD_CAPABILITIES(OSObject *object, struct apple80211_capability_data *cd) { + uint32_t caps = fHalService->get80211Controller()->ic_caps; + memset(cd, 0, sizeof(struct apple80211_capability_data)); + + if (caps & IEEE80211_C_WEP) + cd->capabilities[0] |= 1 << APPLE80211_CAP_WEP; + if (caps & IEEE80211_C_RSN) + cd->capabilities[0] |= 1 << APPLE80211_CAP_TKIP | 1 << APPLE80211_CAP_AES_CCM; + // Disable not implemented capabilities + // if (caps & IEEE80211_C_PMGT) + // cd->capabilities[0] |= 1 << APPLE80211_CAP_PMGT; + // if (caps & IEEE80211_C_IBSS) + // cd->capabilities[0] |= 1 << APPLE80211_CAP_IBSS; + // if (caps & IEEE80211_C_HOSTAP) + // cd->capabilities[0] |= 1 << APPLE80211_CAP_HOSTAP; + // AES not enabled, like on Apple cards + + if (caps & IEEE80211_C_SHSLOT) + cd->capabilities[1] |= 1 << (APPLE80211_CAP_SHSLOT - 8); + if (caps & IEEE80211_C_SHPREAMBLE) + cd->capabilities[1] |= 1 << (APPLE80211_CAP_SHPREAMBLE - 8); + if (caps & IEEE80211_C_RSN) + cd->capabilities[1] |= 1 << (APPLE80211_CAP_WPA1 - 8) | 1 << (APPLE80211_CAP_WPA2 - 8) | 1 << (APPLE80211_CAP_TKIPMIC - 8); + // Disable not implemented capabilities + // if (caps & IEEE80211_C_TXPMGT) + // cd->capabilities[1] |= 1 << (APPLE80211_CAP_TXPMGT - 8); + // if (caps & IEEE80211_C_MONITOR) + // cd->capabilities[1] |= 1 << (APPLE80211_CAP_MONITOR - 8); + // WPA not enabled, like on Apple cards + cd->version = APPLE80211_VERSION; - *(uint16_t *)&cd->capabilities[0] = 0xEE6F; + cd->capabilities[2] = 0xFF; // BURST, WME, SHORT_GI_40MHZ, SHORT_GI_20MHZ, WOW, TSN, ?, ? + cd->capabilities[3] = 0x2B; cd->capabilities[5] = 0x40; - cd->capabilities[2] = 0x61; + cd->capabilities[6] = ( +// 1 | //MFP capable + 0x8 | + 0x4 | + 0x80 + ); *(uint16_t *)&cd->capabilities[8] = 0x201; // // cd->capabilities[2] |= 0x10; From 8e898d087efeda72f46fde2c993c0804e0f95e0d Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Tue, 18 Jul 2023 16:56:33 +0800 Subject: [PATCH 072/114] AirportItlwm: Support Enterprise network. --- .../AirportItlwmEthernetInterface.cpp | 20 ++++++++++++++++++- .../AirportItlwmEthernetInterface.hpp | 6 ++++++ AirportItlwm/AirportItlwmSkywalkInterface.cpp | 9 ++++++++- AirportItlwm/AirportItlwmV2.cpp | 10 ++++++++++ include/Airport/Apple80211.h | 4 ---- .../openbsd/net80211/ieee80211_crypto_tkip.c | 2 +- itl80211/openbsd/net80211/ieee80211_input.c | 11 +++++++++- itl80211/openbsd/net80211/ieee80211_output.c | 4 ++-- itl80211/openbsd/net80211/ieee80211_proto.c | 7 +++++-- itl80211/openbsd/net80211/ieee80211_var.h | 2 +- itlwm.xcodeproj/project.pbxproj | 2 ++ 11 files changed, 64 insertions(+), 13 deletions(-) diff --git a/AirportItlwm/AirportItlwmEthernetInterface.cpp b/AirportItlwm/AirportItlwmEthernetInterface.cpp index 97de695fa..cff687346 100644 --- a/AirportItlwm/AirportItlwmEthernetInterface.cpp +++ b/AirportItlwm/AirportItlwmEthernetInterface.cpp @@ -42,7 +42,7 @@ attachToDataLinkLayer( IOOptionBits options, void *parameter ) kIOEthernetAddressSize); interface->registerService(); interface->prepareBSDInterface(getIfnet(), 0); -// ret = bpf_attach(getIfnet(), DLT_RAW, 0x48, &RTLEthernetInterface::bpfOutputPacket, &RTLEthernetInterface::bpfTap); +// ret = bpf_attach(getIfnet(), DLT_RAW, 0x48, &AirportItlwmEthernetInterface::bpfOutputPacket, &AirportItlwmEthernetInterface::bpfTap); } return ret; } @@ -72,3 +72,21 @@ setLinkState(IO80211LinkState state) } return true; } + +extern const char* hexdump(uint8_t *buf, size_t len); + +UInt32 AirportItlwmEthernetInterface:: +inputPacket(mbuf_t packet, UInt32 length, IOOptionBits options, void *param) +{ + ether_header_t *eh; + size_t len = mbuf_len(packet); + + eh = (ether_header_t *)mbuf_data(packet); + if (len >= sizeof(ether_header_t) && eh->ether_type == htons(ETHERTYPE_PAE)) { // EAPOL packet + const char* dump = hexdump((uint8_t*)mbuf_data(packet), len); + XYLog("input EAPOL packet, len: %zu, data: %s\n", len, dump ? dump : "Failed to allocate memory"); + if (dump) + IOFree((void*)dump, 3 * len + 1); + } + return IOEthernetInterface::inputPacket(packet, length, options, param); +} diff --git a/AirportItlwm/AirportItlwmEthernetInterface.hpp b/AirportItlwm/AirportItlwmEthernetInterface.hpp index d84ac0ce2..7044b3a06 100644 --- a/AirportItlwm/AirportItlwmEthernetInterface.hpp +++ b/AirportItlwm/AirportItlwmEthernetInterface.hpp @@ -35,6 +35,12 @@ class AirportItlwmEthernetInterface : public IOEthernetInterface { static errno_t bpfTap(ifnet_t interface, u_int32_t data_link_type, bpf_tap_mode direction); + virtual UInt32 inputPacket( + mbuf_t packet, + UInt32 length = 0, + IOOptionBits options = 0, + void * param = 0 ) override; + private: IO80211SkywalkInterface *interface; }; diff --git a/AirportItlwm/AirportItlwmSkywalkInterface.cpp b/AirportItlwm/AirportItlwmSkywalkInterface.cpp index c25ff871b..7ac518c2b 100644 --- a/AirportItlwm/AirportItlwmSkywalkInterface.cpp +++ b/AirportItlwm/AirportItlwmSkywalkInterface.cpp @@ -368,8 +368,15 @@ setCIPHER_KEY(struct apple80211_key *key) case APPLE80211_CIPHER_PMK: XYLog("Setting WPA PMK is not supported\n"); break; + case APPLE80211_CIPHER_MSK: + XYLog("Setting MSK\n"); + ieee80211_pmksa_add(fHalService->get80211Controller(), IEEE80211_AKM_8021X, + fHalService->get80211Controller()->ic_bss->ni_macaddr, key->key, 0); + break; case APPLE80211_CIPHER_PMKSA: - XYLog("Setting WPA PMKSA is not supported\n"); + XYLog("Setting WPA PMKSA\n"); + ieee80211_pmksa_add(fHalService->get80211Controller(), IEEE80211_AKM_8021X, + fHalService->get80211Controller()->ic_bss->ni_macaddr, key->key, 0); break; } //fInterface->postMessage(APPLE80211_M_CIPHER_KEY_CHANGED); diff --git a/AirportItlwm/AirportItlwmV2.cpp b/AirportItlwm/AirportItlwmV2.cpp index 89beff970..9d0485fec 100644 --- a/AirportItlwm/AirportItlwmV2.cpp +++ b/AirportItlwm/AirportItlwmV2.cpp @@ -535,6 +535,8 @@ IOReturn AirportItlwm::networkInterfaceNotification( } #endif +extern const char* hexdump(uint8_t *buf, size_t len); + UInt32 AirportItlwm::outputPacket(mbuf_t m, void *param) { // XYLog("%s\n", __FUNCTION__); @@ -562,6 +564,14 @@ UInt32 AirportItlwm::outputPacket(mbuf_t m, void *param) ifp->netStat->outputErrors++; ret = kIOReturnOutputDropped; } + size_t len = mbuf_len(m); + ether_header_t *eh = (ether_header_t *)mbuf_data(m); + if (len >= sizeof(ether_header_t) && eh->ether_type == htons(ETHERTYPE_PAE)) { // EAPOL packet + const char* dump = hexdump((uint8_t*)mbuf_data(m), len); + XYLog("output EAPOL packet, len: %zu, data: %s\n", len, dump ? dump : "Failed to allocate memory"); + if (dump) + IOFree((void*)dump, 3 * len + 1); + } if (!ifp->if_snd.queue->lockEnqueue(m)) { freePacket(m); ret = kIOReturnOutputDropped; diff --git a/include/Airport/Apple80211.h b/include/Airport/Apple80211.h index 517963a18..fe317e324 100644 --- a/include/Airport/Apple80211.h +++ b/include/Airport/Apple80211.h @@ -9,10 +9,6 @@ #ifndef Apple80211_h #define Apple80211_h -#if __IO80211_TARGET >= __MAC_14_0 -#define IO80211FAMILY_V2 -#endif - #include "apple_private_spi.h" #include "debug.h" #include "IO80211WorkLoop.h" diff --git a/itl80211/openbsd/net80211/ieee80211_crypto_tkip.c b/itl80211/openbsd/net80211/ieee80211_crypto_tkip.c index a4569698b..7df2cde9e 100644 --- a/itl80211/openbsd/net80211/ieee80211_crypto_tkip.c +++ b/itl80211/openbsd/net80211/ieee80211_crypto_tkip.c @@ -98,7 +98,7 @@ ieee80211_tkip_set_key(struct ieee80211com *ic, struct ieee80211_key *k) } else #endif { -#if (defined AIRPORT) && (defined USE_APPLE_SUPPLICANT) +#ifdef USE_APPLE_SUPPLICANT ctx->txmic = &k->k_key[16]; ctx->rxmic = &k->k_key[24]; #else diff --git a/itl80211/openbsd/net80211/ieee80211_input.c b/itl80211/openbsd/net80211/ieee80211_input.c index c1eb1c014..72512823c 100644 --- a/itl80211/openbsd/net80211/ieee80211_input.c +++ b/itl80211/openbsd/net80211/ieee80211_input.c @@ -1068,6 +1068,7 @@ ieee80211_enqueue_data(struct ieee80211com *ic, mbuf_t m, struct _ifnet *ifp = &ic->ic_if; struct ether_header *eh; mbuf_t m1; + mbuf_t m2; eh = mtod(m, struct ether_header *); @@ -1128,9 +1129,17 @@ ieee80211_enqueue_data(struct ieee80211com *ic, mbuf_t m, if (ifp->if_bpf && m1 == NULL) bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN); #endif -#if (defined AIRPORT) && (defined USE_APPLE_SUPPLICANT) +#ifdef USE_APPLE_SUPPLICANT ml_enqueue(ml, m); #else +#ifdef IO80211FAMILY_V2 + if (ieee80211_is_8021x_akm((enum ieee80211_akm)ni->ni_rsnakms)) { + XYLog("%s Duplicate EAPOL packet to user space\n", __FUNCTION__); + mbuf_dup(m, MBUF_DONTWAIT, &m2); + if (m2 != NULL) + ifp->iface->inputPacket(m2, mbuf_len(m2)); + } +#endif ieee80211_eapol_key_input(ic, m, ni); #endif } else { diff --git a/itl80211/openbsd/net80211/ieee80211_output.c b/itl80211/openbsd/net80211/ieee80211_output.c index 2da63b462..8789cb191 100644 --- a/itl80211/openbsd/net80211/ieee80211_output.c +++ b/itl80211/openbsd/net80211/ieee80211_output.c @@ -1599,7 +1599,7 @@ ieee80211_get_assoc_req(struct ieee80211com *ic, struct ieee80211_node *ni, frm = ieee80211_add_xrates(frm, rs); if ((ic->ic_flags & IEEE80211_F_RSNON) && (ni->ni_rsnprotos & IEEE80211_PROTO_RSN)) { -#if (defined AIRPORT) && (defined USE_APPLE_SUPPLICANT) +#ifdef USE_APPLE_SUPPLICANT if (ic->ic_rsn_ie_override[1] > 0) { memcpy(frm, ic->ic_rsn_ie_override, 2 + ic->ic_rsn_ie_override[1]); frm += 2 + ic->ic_rsn_ie_override[1]; @@ -1612,7 +1612,7 @@ ieee80211_get_assoc_req(struct ieee80211com *ic, struct ieee80211_node *ni, frm = ieee80211_add_qos_capability(frm, ic); if ((ic->ic_flags & IEEE80211_F_RSNON) && (ni->ni_rsnprotos & IEEE80211_PROTO_WPA)) { -#if (defined AIRPORT) && (defined USE_APPLE_SUPPLICANT) +#ifdef USE_APPLE_SUPPLICANT if (ic->ic_rsn_ie_override[1] > 0) { memcpy(frm, ic->ic_rsn_ie_override, 2 + ic->ic_rsn_ie_override[1]); frm += 2 + ic->ic_rsn_ie_override[1]; diff --git a/itl80211/openbsd/net80211/ieee80211_proto.c b/itl80211/openbsd/net80211/ieee80211_proto.c index 3e61d1b5b..82d96bb89 100644 --- a/itl80211/openbsd/net80211/ieee80211_proto.c +++ b/itl80211/openbsd/net80211/ieee80211_proto.c @@ -1592,8 +1592,11 @@ ieee80211_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, (ni->ni_flags & IEEE80211_NODE_HE) ? " HE enabled" : ""); } -#if (defined AIRPORT) && (defined USE_APPLE_SUPPLICANT) - { +#ifdef USE_APPLE_SUPPLICANT + { +#elif (defined IO80211FAMILY_V2) + if (ieee80211_is_8021x_akm((enum ieee80211_akm)ni->ni_rsnakms) || + !(ic->ic_flags & IEEE80211_F_RSNON)) { #else if (!(ic->ic_flags & IEEE80211_F_RSNON)) { #endif diff --git a/itl80211/openbsd/net80211/ieee80211_var.h b/itl80211/openbsd/net80211/ieee80211_var.h index 5d9fbe120..bac10dc32 100644 --- a/itl80211/openbsd/net80211/ieee80211_var.h +++ b/itl80211/openbsd/net80211/ieee80211_var.h @@ -497,7 +497,7 @@ struct ieee80211com { u_int8_t ic_des_essid[IEEE80211_NWID_LEN]; struct ieee80211_channel *ic_des_chan; /* desired channel */ u_int8_t ic_des_bssid[IEEE80211_ADDR_LEN]; -#if (defined AIRPORT) && (defined USE_APPLE_SUPPLICANT) +#ifdef USE_APPLE_SUPPLICANT u_int8_t ic_rsn_ie_override[257]; #endif u_int16_t ic_deauth_reason; diff --git a/itlwm.xcodeproj/project.pbxproj b/itlwm.xcodeproj/project.pbxproj index 43e6ebc2a..64bfa543d 100644 --- a/itlwm.xcodeproj/project.pbxproj +++ b/itlwm.xcodeproj/project.pbxproj @@ -3530,6 +3530,7 @@ AIRPORT, "__IO80211_TARGET=__MAC_14_0", __PRIVATE_SPI__, + IO80211FAMILY_V2, ); INFOPLIST_FILE = "AirportItlwm/AirportItlwm-Sonoma-Info.plist"; LIBRARY_SEARCH_PATHS = ( @@ -3560,6 +3561,7 @@ AIRPORT, __PRIVATE_SPI__, "$(inherited)", + IO80211FAMILY_V2, ); INFOPLIST_FILE = "AirportItlwm/AirportItlwm-Sonoma-Info.plist"; LIBRARY_SEARCH_PATHS = ( From d93923051d205f9dc245c69c38e9f0f35bfb5e89 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Mon, 24 Jul 2023 23:34:02 +0800 Subject: [PATCH 073/114] Avoid deactivating twice if the driver is already in deactivating state. --- itlwm/hal_iwm/ItlIwm.cpp | 4 ++++ itlwm/hal_iwn/ItlIwn.cpp | 4 ++++ itlwm/hal_iwx/ItlIwx.cpp | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/itlwm/hal_iwm/ItlIwm.cpp b/itlwm/hal_iwm/ItlIwm.cpp index 49d2c729d..aca21518b 100644 --- a/itlwm/hal_iwm/ItlIwm.cpp +++ b/itlwm/hal_iwm/ItlIwm.cpp @@ -106,6 +106,10 @@ IOReturn ItlIwm:: disable(IONetworkInterface *netif) { struct _ifnet *ifp = &com.sc_ic.ic_ac.ac_if; + if (!(ifp->if_flags & IFF_UP)) { + XYLog("%s already in diactivating state\n", __FUNCTION__); + return kIOReturnSuccess; + } ifp->if_flags &= ~IFF_UP; iwm_activate(&com, DVACT_QUIESCE); return kIOReturnSuccess; diff --git a/itlwm/hal_iwn/ItlIwn.cpp b/itlwm/hal_iwn/ItlIwn.cpp index e24e66e8e..8b505ad57 100644 --- a/itlwm/hal_iwn/ItlIwn.cpp +++ b/itlwm/hal_iwn/ItlIwn.cpp @@ -166,6 +166,10 @@ IOReturn ItlIwn::disable(IONetworkInterface *netif) { XYLog("%s\n", __FUNCTION__); struct _ifnet *ifp = &com.sc_ic.ic_ac.ac_if; + if (!(ifp->if_flags & IFF_UP)) { + XYLog("%s already in diactivating state\n", __FUNCTION__); + return kIOReturnSuccess; + } ifp->if_flags &= ~IFF_UP; iwn_activate(&com, DVACT_QUIESCE); return kIOReturnSuccess; diff --git a/itlwm/hal_iwx/ItlIwx.cpp b/itlwm/hal_iwx/ItlIwx.cpp index 264d09fb9..e4892c980 100644 --- a/itlwm/hal_iwx/ItlIwx.cpp +++ b/itlwm/hal_iwx/ItlIwx.cpp @@ -227,6 +227,10 @@ IOReturn ItlIwx::disable(IONetworkInterface *netif) { XYLog("%s\n", __FUNCTION__); struct _ifnet *ifp = &com.sc_ic.ic_ac.ac_if; + if (!(ifp->if_flags & IFF_UP)) { + XYLog("%s already in diactivating state\n", __FUNCTION__); + return kIOReturnSuccess; + } ifp->if_flags &= ~IFF_UP; iwx_activate(&com, DVACT_QUIESCE); return kIOReturnSuccess; From c13f2ed32aaabf8b1ea51f6ca687063fba044ce7 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Wed, 9 Aug 2023 18:31:11 +0800 Subject: [PATCH 074/114] AirportItlwm; Support Sonoma beta 5+ and drop support for beta 4- --- AirportItlwm/AirportItlwmSkywalkInterface.hpp | 2 ++ include/Airport/IO80211InfraProtocol.h | 3 +++ include/Airport/IO80211SkywalkInterface.h | 1 + 3 files changed, 6 insertions(+) diff --git a/AirportItlwm/AirportItlwmSkywalkInterface.hpp b/AirportItlwm/AirportItlwmSkywalkInterface.hpp index 2e4a3fc20..12d8c93a0 100644 --- a/AirportItlwm/AirportItlwmSkywalkInterface.hpp +++ b/AirportItlwm/AirportItlwmSkywalkInterface.hpp @@ -87,6 +87,7 @@ class AirportItlwmSkywalkInterface : public IO80211InfraProtocol { virtual IOReturn getMAX_NSS_FOR_AP(apple80211_btcoex_max_nss_for_ap_data *) override { return kIOReturnUnsupported; } virtual IOReturn getBTCOEX_2G_CHAIN_DISABLE(apple80211_btcoex_2g_chain_disable *) override { return kIOReturnUnsupported; } virtual IOReturn getPOWER_BUDGET(apple80211_power_budget_t *) override { return kIOReturnUnsupported; } + virtual IOReturn getOFFLOAD_TCPKA_ENABLE(apple80211_offload_tcpka_enable_t *) override { return kIOReturnUnsupported; } virtual IOReturn getRANGING_CAPS(apple80211_ranging_capabilities_t *) override { return kIOReturnUnsupported; } virtual IOReturn getSUPPRESS_SCANS(apple80211_suppress_scans_t *) override { return kIOReturnUnsupported; } virtual IOReturn getHOST_AP_MODE_HIDDEN(apple80211_host_ap_mode_hidden_t *) override { return kIOReturnUnsupported; } @@ -192,6 +193,7 @@ class AirportItlwmSkywalkInterface : public IO80211InfraProtocol { virtual IOReturn setTHERMAL_INDEX(apple80211_thermal_index_t *) override { return kIOReturnUnsupported; } virtual IOReturn setBTCOEX_2G_CHAIN_DISABLE(apple80211_btcoex_2g_chain_disable *) override { return kIOReturnUnsupported; } virtual IOReturn setPOWER_BUDGET(apple80211_power_budget_t *) override { return kIOReturnUnsupported; } + virtual IOReturn setOFFLOAD_TCPKA_ENABLE(apple80211_offload_tcpka_enable_t *) override { return kIOReturnUnsupported; } virtual IOReturn setSUPPRESS_SCANS(apple80211_suppress_scans_t *) override { return kIOReturnUnsupported; } virtual IOReturn setHOST_AP_MODE_HIDDEN(apple80211_host_ap_mode_hidden_t *) override { return kIOReturnUnsupported; } virtual IOReturn setLQM_CONFIG(apple80211_lqm_config_t *) override { return kIOReturnUnsupported; } diff --git a/include/Airport/IO80211InfraProtocol.h b/include/Airport/IO80211InfraProtocol.h index ee896b2af..0be25f396 100644 --- a/include/Airport/IO80211InfraProtocol.h +++ b/include/Airport/IO80211InfraProtocol.h @@ -144,6 +144,7 @@ struct apple80211_bg_motion_profile; struct apple80211_bg_network; struct apple80211_bg_scan; struct apple80211_bg_params; +typedef UInt apple80211_offload_tcpka_enable_t; class IO80211InfraProtocol : public IO80211InfraInterface { OSDeclareAbstractStructors(IO80211InfraProtocol) @@ -213,6 +214,7 @@ class IO80211InfraProtocol : public IO80211InfraInterface { virtual IOReturn getMAX_NSS_FOR_AP(apple80211_btcoex_max_nss_for_ap_data *) = 0; virtual IOReturn getBTCOEX_2G_CHAIN_DISABLE(apple80211_btcoex_2g_chain_disable *) = 0; virtual IOReturn getPOWER_BUDGET(apple80211_power_budget_t *) = 0; + virtual IOReturn getOFFLOAD_TCPKA_ENABLE(apple80211_offload_tcpka_enable_t *) = 0; virtual IOReturn getRANGING_CAPS(apple80211_ranging_capabilities_t *) = 0; virtual IOReturn getSUPPRESS_SCANS(apple80211_suppress_scans_t *) = 0; virtual IOReturn getHOST_AP_MODE_HIDDEN(apple80211_host_ap_mode_hidden_t *) = 0; @@ -318,6 +320,7 @@ class IO80211InfraProtocol : public IO80211InfraInterface { virtual IOReturn setTHERMAL_INDEX(apple80211_thermal_index_t *) = 0; virtual IOReturn setBTCOEX_2G_CHAIN_DISABLE(apple80211_btcoex_2g_chain_disable *) = 0; virtual IOReturn setPOWER_BUDGET(apple80211_power_budget_t *) = 0; + virtual IOReturn setOFFLOAD_TCPKA_ENABLE(apple80211_offload_tcpka_enable_t *) = 0; virtual IOReturn setSUPPRESS_SCANS(apple80211_suppress_scans_t *) = 0; virtual IOReturn setHOST_AP_MODE_HIDDEN(apple80211_host_ap_mode_hidden_t *) = 0; virtual IOReturn setLQM_CONFIG(apple80211_lqm_config_t *) = 0; diff --git a/include/Airport/IO80211SkywalkInterface.h b/include/Airport/IO80211SkywalkInterface.h index f92d01fc1..f98ffdadb 100644 --- a/include/Airport/IO80211SkywalkInterface.h +++ b/include/Airport/IO80211SkywalkInterface.h @@ -91,6 +91,7 @@ class IO80211SkywalkInterface : public IOSkywalkEthernetInterface { virtual void logTxCompletionPacket(IO80211NetworkPacket *,PacketSkywalkScratch *,unsigned char *,apple80211_wme_ac,int,UInt,bool); virtual IOReturn recordCompletionPackets(TxCompletionEnqueueStats *,TxCompletionEnqueueStats *); virtual IOReturn inputPacket(IO80211NetworkPacket *,packet_info_tag *,ether_header *,bool *); + virtual IOReturn forwardInfraRelayPackets(IO80211NetworkPacket*, ether_header*); virtual void logSkywalkTxReqPacket(IO80211NetworkPacket *,PacketSkywalkScratch *,unsigned char *,apple80211_wme_ac,bool); virtual SInt64 pendingPackets(unsigned char); virtual SInt64 packetSpace(unsigned char); From e66257e525b55930f4ea7f0958d6f09d945ab3cf Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Wed, 13 Sep 2023 23:55:00 +0800 Subject: [PATCH 075/114] HE: Don't announce the reserved bits on the opposite bands, the bandwidth should be handle for each bands later. #913 --- itlwm/hal_iwx/ItlIwx.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/itlwm/hal_iwx/ItlIwx.cpp b/itlwm/hal_iwx/ItlIwx.cpp index e4892c980..2ab12d6ff 100644 --- a/itlwm/hal_iwx/ItlIwx.cpp +++ b/itlwm/hal_iwx/ItlIwx.cpp @@ -4076,10 +4076,6 @@ iwx_setup_he_rates(struct iwx_softc *sc) IEEE80211_HE_MAC_CAP5_UL_2x996_TONE_RU | IEEE80211_HE_MAC_CAP5_HE_DYNAMIC_SM_PS | IEEE80211_HE_MAC_CAP5_HT_VHT_TRIG_FRAME_RX, - .phy_cap_info[0] = - IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G | - IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G | - IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G, .phy_cap_info[1] = IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK | IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A | From 63131bce1cf39aadba61ab2002ae7bbac2fbd688 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Fri, 22 Sep 2023 18:44:39 +0800 Subject: [PATCH 076/114] HE: use node's configuration to determine HE flags. --- itlwm/hal_iwx/ItlIwx.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/itlwm/hal_iwx/ItlIwx.cpp b/itlwm/hal_iwx/ItlIwx.cpp index 2ab12d6ff..8c99dce1f 100644 --- a/itlwm/hal_iwx/ItlIwx.cpp +++ b/itlwm/hal_iwx/ItlIwx.cpp @@ -8728,7 +8728,7 @@ iwx_rs_fw_get_config_flags(struct iwx_softc *sc) } if (iwx_num_of_ant(iwx_fw_valid_tx_ant(sc)) > 1) { - if (ic->ic_flags & IEEE80211_F_HEON && + if ((ni->ni_flags & IEEE80211_NODE_HE) && ni->ni_he_cap_elem.phy_cap_info[2] & IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ) { flags |= IWX_TLC_MNG_CFG_FLAGS_STBC_MSK; @@ -8743,17 +8743,17 @@ iwx_rs_fw_get_config_flags(struct iwx_softc *sc) flags |= IWX_TLC_MNG_CFG_FLAGS_LDPC_MSK; /* consider LDPC support in case of HE */ - if ((ic->ic_flags & IEEE80211_F_HEON) && + if ((ni->ni_flags & IEEE80211_NODE_HE) && (ni->ni_he_cap_elem.phy_cap_info[1] & IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD)) flags |= IWX_TLC_MNG_CFG_FLAGS_LDPC_MSK; - if ((ic->ic_flags & IEEE80211_F_HEON) && + if ((ni->ni_flags & IEEE80211_NODE_HE) && !(ni->ni_he_cap_elem.phy_cap_info[1] & IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD)) flags &= ~IWX_TLC_MNG_CFG_FLAGS_LDPC_MSK; - if ((ic->ic_flags & IEEE80211_F_HEON) && + if ((ni->ni_flags & IEEE80211_NODE_HE) && (ni->ni_he_cap_elem.phy_cap_info[3] & IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_MASK)) flags |= IWX_TLC_MNG_CFG_FLAGS_HE_DCM_NSS_1_MSK; From 73b38111b393001cc5a3aad80ce47151e55cc688 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Fri, 22 Sep 2023 18:46:11 +0800 Subject: [PATCH 077/114] HE: Fix HE channel width negotiation. #913 --- itl80211/openbsd/net80211/ieee80211.h | 17 +++ itl80211/openbsd/net80211/ieee80211_node.c | 4 + itl80211/openbsd/net80211/ieee80211_node.h | 1 + itl80211/openbsd/net80211/ieee80211_proto.c | 123 +++++++++++++++++--- 4 files changed, 128 insertions(+), 17 deletions(-) diff --git a/itl80211/openbsd/net80211/ieee80211.h b/itl80211/openbsd/net80211/ieee80211.h index 70d45295c..5aa09ec9b 100644 --- a/itl80211/openbsd/net80211/ieee80211.h +++ b/itl80211/openbsd/net80211/ieee80211.h @@ -1516,6 +1516,23 @@ struct ieee80211_csa_ie { uint8_t csa_count; /* Channel Switch Count */ } __packed; +/** + * struct ieee80211_vht_operation - VHT operation IE + * + * This structure is the "VHT operation element" as + * described in 802.11ac D3.0 8.4.2.161 + * @chan_width: Operating channel width + * @center_freq_seg0_idx: center freq segment 0 index + * @center_freq_seg1_idx: center freq segment 1 index + * @basic_mcs_set: VHT Basic MCS rate set + */ +struct ieee80211_vht_operation { + uint8_t chan_width; + uint8_t center_freq_seg0_idx; + uint8_t center_freq_seg1_idx; + uint16_t basic_mcs_set; +} __packed; + #define IEEE80211_HE_PPE_THRES_MAX_LEN 25 /** diff --git a/itl80211/openbsd/net80211/ieee80211_node.c b/itl80211/openbsd/net80211/ieee80211_node.c index b691ee6ef..000ef1202 100644 --- a/itl80211/openbsd/net80211/ieee80211_node.c +++ b/itl80211/openbsd/net80211/ieee80211_node.c @@ -2826,6 +2826,10 @@ ieee80211_setup_heop(struct ieee80211_node *ni, const uint8_t *data, ni->ni_he_oper_params = le32toh(he_op_ie->he_oper_params); ni->ni_he_oper_nss_set = le16toh(he_op_ie->he_mcs_nss_set); + bzero(&ni->ni_he_optional, sizeof(ni->ni_he_optional)); + if (len > __offsetof(struct ieee80211_he_operation, optional)) { + memcpy(ni->ni_he_optional, he_op_ie->optional, min(sizeof(ni->ni_he_optional), len - __offsetof(struct ieee80211_he_operation, optional))); + } return 1; } diff --git a/itl80211/openbsd/net80211/ieee80211_node.h b/itl80211/openbsd/net80211/ieee80211_node.h index 49c3639d7..6b9394771 100644 --- a/itl80211/openbsd/net80211/ieee80211_node.h +++ b/itl80211/openbsd/net80211/ieee80211_node.h @@ -427,6 +427,7 @@ struct ieee80211_node { uint8_t ni_ppe_thres[IEEE80211_HE_PPE_THRES_MAX_LEN]; /* Holds the PPE Thresholds data. */ uint32_t ni_he_oper_params; uint16_t ni_he_oper_nss_set; + uint8_t ni_he_optional[8]; /* Timeout handlers which trigger Tx Block Ack negotiation. */ CTimeout* ni_addba_req_to[IEEE80211_NUM_TID]; diff --git a/itl80211/openbsd/net80211/ieee80211_proto.c b/itl80211/openbsd/net80211/ieee80211_proto.c index 3e61d1b5b..cd46990e7 100644 --- a/itl80211/openbsd/net80211/ieee80211_proto.c +++ b/itl80211/openbsd/net80211/ieee80211_proto.c @@ -823,8 +823,15 @@ ieee80211_vht_negotiate(struct ieee80211com *ic, struct ieee80211_node *ni) void ieee80211_he_negotiate(struct ieee80211com *ic, struct ieee80211_node *ni) { - uint8_t info; - uint8_t chw; + XYLog("%s\n", __FUNCTION__); + uint8_t ext_nss_bw_supp, supp_chwidth; + uint16_t cf0, cf1; + int ccfs0, ccfs1, ccfs2; + int ccf0, ccf1; + bool support_80_80 = false; + bool support_160 = false; + struct ieee80211_vht_operation *he_oper_vht = (struct ieee80211_vht_operation *)ni->ni_he_optional; + ni->ni_flags &= ~IEEE80211_NODE_HE; /* Check if we support HE. */ @@ -835,25 +842,107 @@ ieee80211_he_negotiate(struct ieee80211com *ic, struct ieee80211_node *ni) if ((ic->ic_flags & IEEE80211_F_HEON) == 0) return; - chw = IEEE80211_CHAN_WIDTH_20; + ni->ni_flags |= IEEE80211_NODE_HE; - info = ni->ni_he_cap_elem.phy_cap_info[0]; - - if (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan)) { - if (info & IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G) - chw = IEEE80211_CHAN_WIDTH_40; + if (!(htole32(ni->ni_he_oper_params) & IEEE80211_HE_OPERATION_VHT_OPER_INFO)) + return; + + support_160 = (ni->ni_vhtcaps & (IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_MASK | + IEEE80211_VHTCAP_EXT_NSS_BW_MASK)); + support_80_80 = ((ni->ni_vhtcaps & + IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_160_80P80MHZ) || + (ni->ni_vhtcaps & IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_160MHZ && + ni->ni_vhtcaps & IEEE80211_VHTCAP_EXT_NSS_BW_MASK) || + ((ni->ni_vhtcaps & IEEE80211_VHTCAP_EXT_NSS_BW_MASK) >> + IEEE80211_VHTCAP_EXT_NSS_BW_SHIFT > 1)); + + ext_nss_bw_supp = u32_get_bits(ni->ni_vhtcaps, + IEEE80211_VHTCAP_EXT_NSS_BW_MASK); + supp_chwidth = u32_get_bits(ni->ni_vhtcaps, + IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_MASK); + + ccfs0 = he_oper_vht->center_freq_seg0_idx; + ccfs1 = he_oper_vht->center_freq_seg1_idx; + ccfs2 = (le16toh(ni->ni_htop1) & + IEEE80211_HT_OP_MODE_CCFS2_MASK) + >> IEEE80211_HT_OP_MODE_CCFS2_SHIFT; + + ccf0 = ccfs0; + + if ((ic->ic_caps & IEEE80211_C_SUPPORTS_VHT_EXT_NSS_BW) == 0) + ext_nss_bw_supp = 0; + + /* + * Cf. IEEE 802.11 Table 9-250 + * + * We really just consider that because it's inefficient to connect + * at a higher bandwidth than we'll actually be able to use. + */ + switch ((supp_chwidth << 4) | ext_nss_bw_supp) { + default: + case 0x00: + ccf1 = 0; + support_160 = false; + support_80_80 = false; + break; + case 0x01: + support_80_80 = false; + case 0x02: + case 0x03: + ccf1 = ccfs2; + break; + case 0x10: + ccf1 = ccfs1; + break; + case 0x11: + case 0x12: + if (!ccfs1) + ccf1 = ccfs2; else - chw = IEEE80211_CHAN_WIDTH_20; + ccf1 = ccfs1; + break; + case 0x13: + case 0x20: + case 0x23: + ccf1 = ccfs1; + break; } - - if (info & IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G || - info & IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) - chw = IEEE80211_CHAN_WIDTH_160; - else if (info & IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G) - chw = IEEE80211_CHAN_WIDTH_80; - ni->ni_chw = chw; - ni->ni_flags |= IEEE80211_NODE_HE; + cf0 = ieee80211_ieee2mhz(ccf0, ni->ni_chan->ic_flags); + cf1 = ieee80211_ieee2mhz(ccf1, ni->ni_chan->ic_flags); + + switch (he_oper_vht->chan_width) { + case IEEE80211_VHT_CHANWIDTH_80P80MHZ: + ni->ni_chw = IEEE80211_CHAN_WIDTH_80P80; + ni->ni_chan->ic_center_freq1 = cf0; + ni->ni_chan->ic_center_freq2 = cf1; + break; + case IEEE80211_VHT_CHANWIDTH_160MHZ: + ni->ni_chw = IEEE80211_CHAN_WIDTH_160; + ni->ni_chan->ic_center_freq1 = cf0; + break; + case IEEE80211_VHT_CHANWIDTH_80MHZ: + ni->ni_chw = IEEE80211_CHAN_WIDTH_80; + ni->ni_chan->ic_center_freq1 = cf0; + /* If needed, adjust based on the newer interop workaround. */ + if (ccf1) { + unsigned int diff = abs(ccf1 - ccf0); + if ((diff == 8) && support_160) { + ni->ni_chw = IEEE80211_CHAN_WIDTH_160; + ni->ni_chan->ic_center_freq1 = cf1; + } else if ((diff > 8) && support_80_80) { + ni->ni_chw = IEEE80211_CHAN_WIDTH_80P80; + ni->ni_chan->ic_center_freq2 = cf1; + } + } + break; + case IEEE80211_VHT_CHANWIDTH_USE_HT: + /* Use HT negotiate information */ + break; + + default: + return; + } XYLog("%s chan_width=%s\n", __FUNCTION__, ieee80211_chan_width_name[ni->ni_chw]); } From d25366d459ca1580cc90724e2abfb2596c5d7933 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Wed, 11 Oct 2023 18:44:29 +0800 Subject: [PATCH 078/114] iwm: Don't try to remove firmware key if key is not installed. https://github.com/openbsd/src/commit/296f586bac05bd565cfeb0e5757bba74fb647b8f --- itlwm/hal_iwm/mac80211.cpp | 51 ++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/itlwm/hal_iwm/mac80211.cpp b/itlwm/hal_iwm/mac80211.cpp index a3ef0f581..662f9d364 100644 --- a/itlwm/hal_iwm/mac80211.cpp +++ b/itlwm/hal_iwm/mac80211.cpp @@ -2684,31 +2684,34 @@ void ItlIwm:: iwm_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni, struct ieee80211_key *k) { - struct iwm_softc *sc = (struct iwm_softc *)ic->ic_softc; - struct iwm_add_sta_key_cmd cmd; + struct iwm_softc *sc = (struct iwm_softc *)ic->ic_softc; + struct iwm_add_sta_key_cmd cmd; ItlIwm *that = container_of(sc, ItlIwm, com); - - if ((k->k_flags & IEEE80211_KEY_GROUP) || - (k->k_cipher != IEEE80211_CIPHER_CCMP)) { - /* Fallback to software crypto for other ciphers. */ - ieee80211_delete_key(ic, ni, k); - return; - } - - if (!isset(sc->sc_ucode_api, IWM_UCODE_TLV_API_TKIP_MIC_KEYS)) - return that->iwm_delete_key_v1(ic, ni, k); - - memset(&cmd, 0, sizeof(cmd)); - - cmd.common.key_flags = htole16(IWM_STA_KEY_NOT_VALID | - IWM_STA_KEY_FLG_NO_ENC | IWM_STA_KEY_FLG_WEP_KEY_MAP | - ((k->k_id << IWM_STA_KEY_FLG_KEYID_POS) & - IWM_STA_KEY_FLG_KEYID_MSK)); - memcpy(cmd.common.key, k->k_key, MIN(sizeof(cmd.common.key), k->k_len)); - cmd.common.key_offset = 0; - cmd.common.sta_id = IWM_STATION_ID; - - that->iwm_send_cmd_pdu(sc, IWM_ADD_STA_KEY, IWM_CMD_ASYNC, sizeof(cmd), &cmd); + + if ((k->k_flags & IEEE80211_KEY_GROUP) || + (k->k_cipher != IEEE80211_CIPHER_CCMP)) { + /* Fallback to software crypto for other ciphers. */ + ieee80211_delete_key(ic, ni, k); + return; + } + + if ((sc->sc_flags & IWM_FLAG_STA_ACTIVE) == 0) + return; + + if (!isset(sc->sc_ucode_api, IWM_UCODE_TLV_API_TKIP_MIC_KEYS)) + return that->iwm_delete_key_v1(ic, ni, k); + + memset(&cmd, 0, sizeof(cmd)); + + cmd.common.key_flags = htole16(IWM_STA_KEY_NOT_VALID | + IWM_STA_KEY_FLG_NO_ENC | IWM_STA_KEY_FLG_WEP_KEY_MAP | + ((k->k_id << IWM_STA_KEY_FLG_KEYID_POS) & + IWM_STA_KEY_FLG_KEYID_MSK)); + memcpy(cmd.common.key, k->k_key, MIN(sizeof(cmd.common.key), k->k_len)); + cmd.common.key_offset = 0; + cmd.common.sta_id = IWM_STATION_ID; + + that->iwm_send_cmd_pdu(sc, IWM_ADD_STA_KEY, IWM_CMD_ASYNC, sizeof(cmd), &cmd); } void ItlIwm:: From 0b07dee9f4a8fdbc62cefdd291fff1680167c767 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Tue, 17 Oct 2023 09:58:32 +0800 Subject: [PATCH 079/114] RS: Use caps to determine whether start tx agg by net80211 or self. --- itlwm/hal_iwm/rs.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/itlwm/hal_iwm/rs.cpp b/itlwm/hal_iwm/rs.cpp index f756336bf..78f944fad 100644 --- a/itlwm/hal_iwm/rs.cpp +++ b/itlwm/hal_iwm/rs.cpp @@ -600,9 +600,12 @@ static void rs_tl_turn_on_agg(struct iwm_softc *sc, u8 tid, struct iwl_lq_sta *lq_sta, struct ieee80211_node *ni) { -#if 1 struct iwm_tx_ba *tid_data; struct ieee80211_tx_ba *tx_ba; + struct ieee80211com *ic = &sc->sc_ic; + + if ((ic->ic_caps & IEEE80211_C_TX_AMPDU_SETUP_IN_RS) == 0) + return; /* * In AP mode, tid can be equal to IWL_MAX_TID_COUNT @@ -625,9 +628,6 @@ static void rs_tl_turn_on_agg(struct iwm_softc *sc, IWL_DEBUG_RATE("RS: try to aggregate tid %d\n", tid); rs_tl_turn_on_agg_for_tid(sc, lq_sta, tid, ni); } -#else - ; -#endif } static inline int get_num_of_ant_from_rate(u32 rate_n_flags) From ff1138b026d3198beb9a716f73efe4f4a86ed68b Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Wed, 18 Oct 2023 18:40:51 +0800 Subject: [PATCH 080/114] iwx: support bunch of ax411 variants killer devices. --- itlwm/hal_iwx/ItlIwx.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/itlwm/hal_iwx/ItlIwx.cpp b/itlwm/hal_iwx/ItlIwx.cpp index 8c99dce1f..885e047f0 100644 --- a/itlwm/hal_iwx/ItlIwx.cpp +++ b/itlwm/hal_iwx/ItlIwx.cpp @@ -12122,6 +12122,15 @@ static const struct iwl_dev_info iwl_dev_info_table[] = { IWL_DEV_INFO(0x2723, IWL_CFG_ANY, iwl_ax200_cfg_cc, iwl_ax200_name), IWL_DEV_INFO(0x2723, 0x1653, iwl_ax200_cfg_cc, iwl_ax200_killer_1650w_name), IWL_DEV_INFO(0x2723, 0x1654, iwl_ax200_cfg_cc, iwl_ax200_killer_1650x_name), + IWL_DEV_INFO(0x51F0, 0x1691, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690s_name), + IWL_DEV_INFO(0x51F0, 0x1692, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690i_name), + IWL_DEV_INFO(0x51F1, 0x1692, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690i_name), + IWL_DEV_INFO(0x54F0, 0x1691, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690s_name), + IWL_DEV_INFO(0x54F0, 0x1692, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690i_name), + IWL_DEV_INFO(0x7A70, 0x1691, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690s_name), + IWL_DEV_INFO(0x7A70, 0x1692, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690i_name), + IWL_DEV_INFO(0x7AF0, 0x1691, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690s_name), + IWL_DEV_INFO(0x7AF0, 0x1692, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690i_name), /* Qu with Hr */ IWL_DEV_INFO(0x43F0, 0x0070, iwl_ax201_cfg_qu_hr, NULL), From 3b8f766654c69967446898046cf90c7c6df80082 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Thu, 9 Nov 2023 16:15:25 +0800 Subject: [PATCH 081/114] iwx: rename management queue allocation function name. --- itlwm/hal_iwx/ItlIwx.cpp | 4 ++-- itlwm/hal_iwx/ItlIwx.hpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/itlwm/hal_iwx/ItlIwx.cpp b/itlwm/hal_iwx/ItlIwx.cpp index 885e047f0..9aa4f3402 100644 --- a/itlwm/hal_iwx/ItlIwx.cpp +++ b/itlwm/hal_iwx/ItlIwx.cpp @@ -8636,7 +8636,7 @@ iwx_scan_abort(struct iwx_softc *sc) } int ItlIwx:: -iwx_enable_data_tx_queues(struct iwx_softc *sc) +iwx_enable_mgmt_queue(struct iwx_softc *sc) { int err; int cmdver; @@ -9213,7 +9213,7 @@ iwx_auth(struct iwx_softc *sc) return 0; } - err = iwx_enable_data_tx_queues(sc); + err = iwx_enable_mgmt_queue(sc); if (err) goto rm_sta; diff --git a/itlwm/hal_iwx/ItlIwx.hpp b/itlwm/hal_iwx/ItlIwx.hpp index 1868067fe..c1f048a8a 100644 --- a/itlwm/hal_iwx/ItlIwx.hpp +++ b/itlwm/hal_iwx/ItlIwx.hpp @@ -420,7 +420,7 @@ class ItlIwx : public ItlHalService, ItlDriverInfo, ItlDriverController { uint16_t iwx_rs_fw_get_config_flags(struct iwx_softc *sc); int iwx_rs_init(struct iwx_softc *, struct iwx_node *, bool update); void iwx_rs_update(struct iwx_softc *sc, struct iwx_tlc_update_notif *notif); - int iwx_enable_data_tx_queues(struct iwx_softc *); + int iwx_enable_mgmt_queue(struct iwx_softc *); int iwx_phy_ctxt_update(struct iwx_softc *, struct iwx_phy_ctxt *, struct ieee80211_channel *, uint8_t, uint8_t, uint32_t); int iwx_auth(struct iwx_softc *); From 3e1624df2168594ac15bbfe539c751deeedf24cb Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Mon, 5 Feb 2024 18:01:26 +0800 Subject: [PATCH 082/114] AirportItlwm: Add another hack to fake that the provider is IOSkywalkNetworkInterface, to avoid skywalkfamily instance cast panic. --- AirportItlwm/AirportItlwmEthernetInterface.cpp | 18 ++++++++++++++++++ AirportItlwm/AirportItlwmEthernetInterface.hpp | 6 ++++++ 2 files changed, 24 insertions(+) diff --git a/AirportItlwm/AirportItlwmEthernetInterface.cpp b/AirportItlwm/AirportItlwmEthernetInterface.cpp index cff687346..f99c393d8 100644 --- a/AirportItlwm/AirportItlwmEthernetInterface.cpp +++ b/AirportItlwm/AirportItlwmEthernetInterface.cpp @@ -20,6 +20,7 @@ initWithSkywalkInterfaceAndProvider(IONetworkController *controller, IO80211Skyw bool ret = super::init(controller); if (ret) this->interface = interface; + this->isAttach = false; return ret; } @@ -44,9 +45,26 @@ attachToDataLinkLayer( IOOptionBits options, void *parameter ) interface->prepareBSDInterface(getIfnet(), 0); // ret = bpf_attach(getIfnet(), DLT_RAW, 0x48, &AirportItlwmEthernetInterface::bpfOutputPacket, &AirportItlwmEthernetInterface::bpfTap); } + isAttach = true; return ret; } +void AirportItlwmEthernetInterface:: +detachFromDataLinkLayer(IOOptionBits options, void *parameter) +{ + super::detachFromDataLinkLayer(options, parameter); + isAttach = false; +} + +/** + Add another hack to fake that the provider is IOSkywalkNetworkInterface, to avoid skywalkfamily instance cast panic. + */ +IOService *AirportItlwmEthernetInterface:: +getProvider() const +{ + return isAttach ? this->interface : super::getProvider(); +} + errno_t AirportItlwmEthernetInterface:: bpfOutputPacket(ifnet_t interface, u_int32_t data_link_type, mbuf_t packet) { diff --git a/AirportItlwm/AirportItlwmEthernetInterface.hpp b/AirportItlwm/AirportItlwmEthernetInterface.hpp index 7044b3a06..0d6c5b5f3 100644 --- a/AirportItlwm/AirportItlwmEthernetInterface.hpp +++ b/AirportItlwm/AirportItlwmEthernetInterface.hpp @@ -25,6 +25,9 @@ class AirportItlwmEthernetInterface : public IOEthernetInterface { virtual IOReturn attachToDataLinkLayer( IOOptionBits options, void * parameter ) override; + virtual void detachFromDataLinkLayer( IOOptionBits options, + void * parameter ) override; + virtual bool initWithSkywalkInterfaceAndProvider(IONetworkController *controller, IO80211SkywalkInterface *interface); virtual bool setLinkState(IO80211LinkState state); @@ -41,8 +44,11 @@ class AirportItlwmEthernetInterface : public IOEthernetInterface { IOOptionBits options = 0, void * param = 0 ) override; + virtual IOService * getProvider( void ) const override; + private: IO80211SkywalkInterface *interface; + bool isAttach; }; #endif /* AirportItlwmEthernetInterface_hpp */ From 409ba220b787ce2f8f394fc5c068287f48b83bf7 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Sat, 24 Feb 2024 20:13:11 +0800 Subject: [PATCH 083/114] rs: correct empty node check. --- itlwm/hal_iwm/rs.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/itlwm/hal_iwm/rs.cpp b/itlwm/hal_iwm/rs.cpp index 78f944fad..8beec3bba 100644 --- a/itlwm/hal_iwm/rs.cpp +++ b/itlwm/hal_iwm/rs.cpp @@ -2698,14 +2698,12 @@ static void rs_drv_get_rate(struct iwm_softc *mvm, struct ieee80211_node *sta, struct rs_rate *optimal_rate; u32 last_ucode_rate; - if (sta) { - /* if vif isn't initialized mvm doesn't know about - * this station, so don't do anything with the it - */ - sta = NULL; - } + if (!sta) + return; lq_sta = &mvm->lq_sta.rs_drv; + + IOSimpleLockLock(mvm->lq_sta.rs_drv.pers.lock); iwl_mvm_hwrate_to_tx_rate(lq_sta->last_rate_n_flags, IEEE80211_IS_CHAN_2GHZ(sta->ni_chan) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ, r); @@ -2719,6 +2717,7 @@ static void rs_drv_get_rate(struct iwm_softc *mvm, struct ieee80211_node *sta, iwl_mvm_hwrate_to_tx_rate(last_ucode_rate, IEEE80211_IS_CHAN_2GHZ(sta->ni_chan) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ, r); } + IOSimpleLockUnlock(mvm->lq_sta.rs_drv.pers.lock); } void *rs_drv_alloc_sta(iwm_softc *sc, struct ieee80211_node *ni) From 399989900dd40273e9cfc694746db7d6f79a100d Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Sat, 24 Feb 2024 21:40:03 +0800 Subject: [PATCH 084/114] rs: add a few rate index validity checks. Validate index before access iwl_rate_mcs to keep rate->index inside the valid boundaries. Use MCS_0_INDEX if index is less than MCS_0_INDEX and MCS_9_INDEX if index is greater then MCS_9_INDEX. --- itlwm/hal_iwm/rs.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/itlwm/hal_iwm/rs.cpp b/itlwm/hal_iwm/rs.cpp index 8beec3bba..1ccb42f72 100644 --- a/itlwm/hal_iwm/rs.cpp +++ b/itlwm/hal_iwm/rs.cpp @@ -536,10 +536,10 @@ static char *rs_pretty_rate(const struct rs_rate *rate) (rate->index <= IWL_RATE_MCS_9_INDEX)) rate_str = ht_vht_rates[rate->index]; else - rate_str = "BAD_RATE"; + rate_str = NULL; snprintf(buf, sizeof(buf), "(%s|%s|%s)", rs_pretty_lq_type(rate->type), - rs_pretty_ant(rate->ant), rate_str); + rs_pretty_ant(rate->ant), rate_str ?: "BAD_RATE"); return buf; } @@ -1096,10 +1096,13 @@ static void rs_get_lower_rate_down_column(struct iwl_lq_sta *lq_sta, rate->bw = RATE_MCS_CHAN_WIDTH_20; - WARN_ON_ONCE(rate->index < IWL_RATE_MCS_0_INDEX || - rate->index > IWL_RATE_MCS_9_INDEX); + if (WARN_ON_ONCE(rate->index < IWL_RATE_MCS_0_INDEX)) + rate->index = rs_ht_to_legacy[IWL_RATE_MCS_0_INDEX]; + else if (WARN_ON_ONCE(rate->index > IWL_RATE_MCS_9_INDEX)) + rate->index = rs_ht_to_legacy[IWL_RATE_MCS_9_INDEX]; + else + rate->index = rs_ht_to_legacy[rate->index]; - rate->index = rs_ht_to_legacy[rate->index]; rate->ldpc = false; } else { /* Downgrade to SISO with same MCS if in MIMO */ From 618eb94e7e7e43a034077aca378802890bc9ff84 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Mon, 26 Feb 2024 18:34:34 +0800 Subject: [PATCH 085/114] AirportItlwm: add power state handler for IOPCIEDeviceWrapper driver, this fix the sleep/wake issue on Sonoma(#937). --- AirportItlwm/IOPCIEDeviceWrapper.cpp | 16 ++++++++++++++++ AirportItlwm/IOPCIEDeviceWrapper.hpp | 3 +++ 2 files changed, 19 insertions(+) diff --git a/AirportItlwm/IOPCIEDeviceWrapper.cpp b/AirportItlwm/IOPCIEDeviceWrapper.cpp index b1b39fa29..ad515a613 100644 --- a/AirportItlwm/IOPCIEDeviceWrapper.cpp +++ b/AirportItlwm/IOPCIEDeviceWrapper.cpp @@ -23,6 +23,12 @@ OSDefineMetaClassAndStructors(IOPCIEDeviceWrapper, IOService); #define PCI_MSIX_FLAGS_ENABLE 0x8000 /* MSI-X enable */ #define PCI_MSI_FLAGS_ENABLE 0x0001 /* MSI feature enabled */ +static IOPMPowerState powerStateArray[2] = +{ + {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, kIOPMDeviceUsable, kIOPMPowerOn, kIOPMPowerOn, 0, 0, 0, 0, 0, 0, 0, 0} +}; + static void pciMsiSetEnable(IOPCIDevice *device, UInt8 msiCap, int enable) { UInt16 control; @@ -105,6 +111,9 @@ start(IOService *provider) IOLog("%s::super start succeed\n", getName()); UInt8 builtIn = 0; setProperty("built-in", OSData::withBytes(&builtIn, sizeof(builtIn))); + PMinit(); + registerPowerDriver(this, powerStateArray, 2); + provider->joinPMtree(this); registerService(); return true; } @@ -113,5 +122,12 @@ void IOPCIEDeviceWrapper:: stop(IOService *provider) { XYLog("%s\n", __PRETTY_FUNCTION__); + PMstop(); super::stop(provider); } + +IOReturn IOPCIEDeviceWrapper:: +setPowerState(unsigned long powerStateOrdinal, IOService *whatDevice) +{ + return IOPMAckImplied; +} diff --git a/AirportItlwm/IOPCIEDeviceWrapper.hpp b/AirportItlwm/IOPCIEDeviceWrapper.hpp index b658ef231..2061bb3c6 100644 --- a/AirportItlwm/IOPCIEDeviceWrapper.hpp +++ b/AirportItlwm/IOPCIEDeviceWrapper.hpp @@ -24,6 +24,9 @@ class IOPCIEDeviceWrapper : public IOService { virtual bool start(IOService *provider) override; virtual void stop(IOService *provider) override; virtual IOWorkLoop* getWorkLoop() const override; + virtual IOReturn setPowerState( + unsigned long powerStateOrdinal, + IOService * whatDevice ) override; public: ItlHalService *fHalService; From 9b7ea26ded22b0d3e43900b97b1cf4677a3bbde1 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Thu, 7 Mar 2024 18:34:38 +0800 Subject: [PATCH 086/114] iwx: Add missing 0x51F1 id support. --- itlwm/hal_iwx/ItlIwx.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/itlwm/hal_iwx/ItlIwx.cpp b/itlwm/hal_iwx/ItlIwx.cpp index 9aa4f3402..91922f333 100644 --- a/itlwm/hal_iwx/ItlIwx.cpp +++ b/itlwm/hal_iwx/ItlIwx.cpp @@ -11752,6 +11752,7 @@ static const struct pci_matchid iwx_devices[] = { {IWL_PCI_DEVICE(0x7A70, PCI_ANY_ID, iwl_so_long_latency_trans_cfg)}, {IWL_PCI_DEVICE(0x7AF0, PCI_ANY_ID, iwl_so_trans_cfg)}, {IWL_PCI_DEVICE(0x51F0, PCI_ANY_ID, iwl_so_long_latency_trans_cfg)}, + {IWL_PCI_DEVICE(0x51F1, PCI_ANY_ID, iwl_so_long_latency_trans_cfg)}, {IWL_PCI_DEVICE(0x54F0, PCI_ANY_ID, iwl_so_long_latency_trans_cfg)}, {IWL_PCI_DEVICE(0x7F70, PCI_ANY_ID, iwl_so_trans_cfg)}, From ef2e0762d1548b07bcab95570ae44e9bb6470933 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Fri, 8 Mar 2024 14:18:17 +0800 Subject: [PATCH 087/114] AirportItlwm: Merge 14.4 compat changes(#953). Separate Sonoma kexts from 14.0 and 14.4 above versions(API changed again, Only Apple can do :) ). --- include/Airport/IO80211InfraInterface.h | 3 + include/Airport/IO80211SkywalkInterface.h | 4 + itlwm.xcodeproj/project.pbxproj | 366 +++++++++++++++++- .../xcschemes/AirportItlwm (all).xcscheme | 16 +- itlwm/PrivateSPI.pch | 4 + 5 files changed, 385 insertions(+), 8 deletions(-) diff --git a/include/Airport/IO80211InfraInterface.h b/include/Airport/IO80211InfraInterface.h index 76bd137ba..90441b52c 100644 --- a/include/Airport/IO80211InfraInterface.h +++ b/include/Airport/IO80211InfraInterface.h @@ -57,6 +57,9 @@ class IO80211InfraInterface : public IO80211SkywalkInterface { virtual void setInterfaceChipCounters(apple80211_stat_report *,apple80211_chip_counters_tx *,apple80211_chip_error_counters_tx *,apple80211_chip_counters_rx *) APPLE_KEXT_OVERRIDE; virtual void setInterfaceMIBdot11(apple80211_stat_report *,apple80211_ManagementInformationBasedot11_counters *) APPLE_KEXT_OVERRIDE; virtual void setFrameStats(apple80211_stat_report *,apple80211_frame_counters *) APPLE_KEXT_OVERRIDE; +#if __IO80211_TARGET >= __MAC_14_4 + virtual void setInfraSpecificFrameStats(apple80211_stat_report *,apple80211_infra_specific_stats *) APPLE_KEXT_OVERRIDE; +#endif virtual SInt64 getWmeTxCounters(unsigned long long *) APPLE_KEXT_OVERRIDE; virtual void setEnabledBySystem(bool) APPLE_KEXT_OVERRIDE; virtual bool enabledBySystem(void) APPLE_KEXT_OVERRIDE; diff --git a/include/Airport/IO80211SkywalkInterface.h b/include/Airport/IO80211SkywalkInterface.h index f98ffdadb..f3c2ceea1 100644 --- a/include/Airport/IO80211SkywalkInterface.h +++ b/include/Airport/IO80211SkywalkInterface.h @@ -37,6 +37,7 @@ struct apple80211_lteCoex_report; struct apple80211_frame_counters; struct userPrintCtx; struct apple80211_lqm_summary; +struct apple80211_infra_specific_stats; struct TxPacketRequest { uint16_t unk1; // 0 @@ -117,6 +118,9 @@ class IO80211SkywalkInterface : public IOSkywalkEthernetInterface { virtual void setInterfaceChipCounters(apple80211_stat_report *,apple80211_chip_counters_tx *,apple80211_chip_error_counters_tx *,apple80211_chip_counters_rx *); virtual void setInterfaceMIBdot11(apple80211_stat_report *,apple80211_ManagementInformationBasedot11_counters *); virtual void setFrameStats(apple80211_stat_report *,apple80211_frame_counters *); +#if __IO80211_TARGET >= __MAC_14_4 + virtual void setInfraSpecificFrameStats(apple80211_stat_report *,apple80211_infra_specific_stats *); +#endif virtual SInt64 getWmeTxCounters(unsigned long long *); virtual void setEnabledBySystem(bool); virtual bool enabledBySystem(void); diff --git a/itlwm.xcodeproj/project.pbxproj b/itlwm.xcodeproj/project.pbxproj index 389949e3e..093938e8c 100644 --- a/itlwm.xcodeproj/project.pbxproj +++ b/itlwm.xcodeproj/project.pbxproj @@ -850,6 +850,113 @@ F8D364F824F93AFD0029340B /* ItlHalService.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F8D364F624F93AFD0029340B /* ItlHalService.cpp */; }; F8D364FA24F93AFD0029340B /* ItlHalService.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F8D364F724F93AFD0029340B /* ItlHalService.hpp */; }; F8D76362244F21BB00DEA040 /* pm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F8D76361244F21BB00DEA040 /* pm.cpp */; }; + F8D94C842B9ABFE20081A3C4 /* CCDataPipe.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8812A497DB200DC8DED /* CCDataPipe.h */; }; + F8D94C852B9ABFE20081A3C4 /* debug.h in Headers */ = {isa = PBXBuildFile; fileRef = F89B6C2225027609000F77FF /* debug.h */; }; + F8D94C862B9ABFE20081A3C4 /* IOSkywalkEthernetInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = F89B6BD025021E66000F77FF /* IOSkywalkEthernetInterface.h */; }; + F8D94C872B9ABFE20081A3C4 /* IO80211InfraProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87C2A497DB200DC8DED /* IO80211InfraProtocol.h */; }; + F8D94C882B9ABFE20081A3C4 /* IOSkywalkLogicalLink.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87E2A497DB200DC8DED /* IOSkywalkLogicalLink.h */; }; + F8D94C892B9ABFE20081A3C4 /* AirportItlwmEthernetInterface.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F8A0282E2A4A7E0400C6DE90 /* AirportItlwmEthernetInterface.hpp */; }; + F8D94C8A2B9ABFE20081A3C4 /* IOSkywalkNetworkPacket.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87B2A497DB200DC8DED /* IOSkywalkNetworkPacket.h */; }; + F8D94C8B2B9ABFE20081A3C4 /* apple80211_ioctl.h in Headers */ = {isa = PBXBuildFile; fileRef = F89B6BC525021DEC000F77FF /* apple80211_ioctl.h */; }; + F8D94C8C2B9ABFE20081A3C4 /* CCLogPipe.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8852A497DB200DC8DED /* CCLogPipe.h */; }; + F8D94C8D2B9ABFE20081A3C4 /* IO80211P2PInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = F8F7EA36252D834500520FD4 /* IO80211P2PInterface.h */; }; + F8D94C8E2B9ABFE20081A3C4 /* CCPipe.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87D2A497DB200DC8DED /* CCPipe.h */; }; + F8D94C8F2B9ABFE20081A3C4 /* IO80211WorkLoop.h in Headers */ = {isa = PBXBuildFile; fileRef = F8F7EA39252D834500520FD4 /* IO80211WorkLoop.h */; }; + F8D94C902B9ABFE20081A3C4 /* apple80211_var.h in Headers */ = {isa = PBXBuildFile; fileRef = F89B6BC425021DEC000F77FF /* apple80211_var.h */; }; + F8D94C912B9ABFE20081A3C4 /* IOSkywalkPacketBufferPool.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8832A497DB200DC8DED /* IOSkywalkPacketBufferPool.h */; }; + F8D94C922B9ABFE20081A3C4 /* IOSkywalkLegacyEthernetInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8842A497DB200DC8DED /* IOSkywalkLegacyEthernetInterface.h */; }; + F8D94C932B9ABFE20081A3C4 /* AirportItlwmInterface.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F8CA44A225091AF60036119A /* AirportItlwmInterface.hpp */; }; + F8D94C942B9ABFE20081A3C4 /* IO80211Interface.h in Headers */ = {isa = PBXBuildFile; fileRef = F8F7EA38252D834500520FD4 /* IO80211Interface.h */; }; + F8D94C952B9ABFE20081A3C4 /* IO80211WorkQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87A2A497DB200DC8DED /* IO80211WorkQueue.h */; }; + F8D94C962B9ABFE20081A3C4 /* (null) in Headers */ = {isa = PBXBuildFile; }; + F8D94C972B9ABFE20081A3C4 /* IO80211InfraInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD87F2A497DB200DC8DED /* IO80211InfraInterface.h */; }; + F8D94C982B9ABFE20081A3C4 /* IO80211SkywalkInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = F8F7EA37252D834500520FD4 /* IO80211SkywalkInterface.h */; }; + F8D94C992B9ABFE20081A3C4 /* CCLogStream.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8822A497DB200DC8DED /* CCLogStream.h */; }; + F8D94C9A2B9ABFE20081A3C4 /* AirportItlwmSkywalkInterface.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F8A028712A4A7FE100C6DE90 /* AirportItlwmSkywalkInterface.hpp */; }; + F8D94C9B2B9ABFE20081A3C4 /* AirportItlwm.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F89B6BBB25021C9C000F77FF /* AirportItlwm.hpp */; }; + F8D94C9C2B9ABFE20081A3C4 /* IO80211ControllerV2.h in Headers */ = {isa = PBXBuildFile; fileRef = F89F35F12A49867F00061876 /* IO80211ControllerV2.h */; }; + F8D94C9D2B9ABFE20081A3C4 /* IOPCIEDeviceWrapper.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F8A0287E2A4A80EA00C6DE90 /* IOPCIEDeviceWrapper.hpp */; }; + F8D94C9E2B9ABFE20081A3C4 /* IO80211VirtualInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = F8F7EA34252D834500520FD4 /* IO80211VirtualInterface.h */; }; + F8D94C9F2B9ABFE20081A3C4 /* IO80211Controller.h in Headers */ = {isa = PBXBuildFile; fileRef = F8F7EA35252D834500520FD4 /* IO80211Controller.h */; }; + F8D94CA02B9ABFE20081A3C4 /* (null) in Headers */ = {isa = PBXBuildFile; }; + F8D94CA12B9ABFE20081A3C4 /* AirportItlwmV2.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F8A028212A4A7DDC00C6DE90 /* AirportItlwmV2.hpp */; }; + F8D94CA22B9ABFE20081A3C4 /* ieee80211_ra.h in Headers */ = {isa = PBXBuildFile; fileRef = F8C594D225FD935B0007D19C /* ieee80211_ra.h */; }; + F8D94CA32B9ABFE20081A3C4 /* CCStream.h in Headers */ = {isa = PBXBuildFile; fileRef = F84AD8802A497DB200DC8DED /* CCStream.h */; }; + F8D94CA42B9ABFE20081A3C4 /* apple80211_wps.h in Headers */ = {isa = PBXBuildFile; fileRef = F89B6BC325021DEC000F77FF /* apple80211_wps.h */; }; + F8D94CA62B9ABFE20081A3C4 /* rs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5DD111326D93B5F00BA01EF /* rs.cpp */; }; + F8D94CA72B9ABFE20081A3C4 /* _mbuf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F8D257732495A33500872E4F /* _mbuf.cpp */; }; + F8D94CA82B9ABFE20081A3C4 /* ieee80211_ra.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C594D125FD935B0007D19C /* ieee80211_ra.c */; }; + F8D94CA92B9ABFE20081A3C4 /* _task.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F8F9EDE0240B7415009CB8E7 /* _task.cpp */; }; + F8D94CAA2B9ABFE20081A3C4 /* FwBinary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5076FA7F24CC71E40011B2BB /* FwBinary.cpp */; }; + F8D94CAB2B9ABFE20081A3C4 /* ieee80211_proto.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC2F24080319007A9422 /* ieee80211_proto.c */; }; + F8D94CAC2B9ABFE20081A3C4 /* _string.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC3024080319007A9422 /* _string.c */; }; + F8D94CAD2B9ABFE20081A3C4 /* ieee80211_ioctl.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC3224080319007A9422 /* ieee80211_ioctl.c */; }; + F8D94CAE2B9ABFE20081A3C4 /* ieee80211.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC3324080319007A9422 /* ieee80211.c */; }; + F8D94CAF2B9ABFE20081A3C4 /* ieee80211_rssadapt.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC3424080319007A9422 /* ieee80211_rssadapt.c */; }; + F8D94CB02B9ABFE20081A3C4 /* ieee80211_input.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC3524080319007A9422 /* ieee80211_input.c */; }; + F8D94CB12B9ABFE20081A3C4 /* timeout.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC3724080319007A9422 /* timeout.c */; }; + F8D94CB22B9ABFE20081A3C4 /* ieee80211_mira.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC3924080319007A9422 /* ieee80211_mira.c */; }; + F8D94CB32B9ABFE20081A3C4 /* ieee80211_crypto_bip.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC3B24080319007A9422 /* ieee80211_crypto_bip.c */; }; + F8D94CB42B9ABFE20081A3C4 /* ieee80211_crypto_tkip.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC3C24080319007A9422 /* ieee80211_crypto_tkip.c */; }; + F8D94CB52B9ABFE20081A3C4 /* ieee80211_crypto_ccmp.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC3D24080319007A9422 /* ieee80211_crypto_ccmp.c */; }; + F8D94CB62B9ABFE20081A3C4 /* ieee80211_crypto_wep.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC462408031A007A9422 /* ieee80211_crypto_wep.c */; }; + F8D94CB72B9ABFE20081A3C4 /* ieee80211_pae_input.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC3E24080319007A9422 /* ieee80211_pae_input.c */; }; + F8D94CB82B9ABFE20081A3C4 /* ieee80211_amrr.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC4024080319007A9422 /* ieee80211_amrr.c */; }; + F8D94CB92B9ABFE20081A3C4 /* ieee80211_output.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC472408031A007A9422 /* ieee80211_output.c */; }; + F8D94CBA2B9ABFE20081A3C4 /* ieee80211_crypto.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC482408031A007A9422 /* ieee80211_crypto.c */; }; + F8D94CBB2B9ABFE20081A3C4 /* CTimeout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC492408031A007A9422 /* CTimeout.cpp */; }; + F8D94CBC2B9ABFE20081A3C4 /* ieee80211_regdomain.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC4B2408031A007A9422 /* ieee80211_regdomain.c */; }; + F8D94CBD2B9ABFE20081A3C4 /* ieee80211_node.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC4C2408031A007A9422 /* ieee80211_node.c */; }; + F8D94CBE2B9ABFE20081A3C4 /* ieee80211_pae_output.c in Sources */ = {isa = PBXBuildFile; fileRef = F8C2EC4D2408031A007A9422 /* ieee80211_pae_output.c */; }; + F8D94CBF2B9ABFE20081A3C4 /* sha1-pbkdf2.c in Sources */ = {isa = PBXBuildFile; fileRef = F88D2B3B2414E64000BBE700 /* sha1-pbkdf2.c */; }; + F8D94CC02B9ABFE20081A3C4 /* aes.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07C923FCBC6C009FBA6C /* aes.c */; }; + F8D94CC12B9ABFE20081A3C4 /* hmac.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07CA23FCBC6C009FBA6C /* hmac.c */; }; + F8D94CC22B9ABFE20081A3C4 /* sha2.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07CB23FCBC6C009FBA6C /* sha2.c */; }; + F8D94CC32B9ABFE20081A3C4 /* rijndael.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07CC23FCBC6C009FBA6C /* rijndael.c */; }; + F8D94CC42B9ABFE20081A3C4 /* ecb3_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07CD23FCBC6C009FBA6C /* ecb3_enc.c */; }; + F8D94CC52B9ABFE20081A3C4 /* set_key.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07CE23FCBC6C009FBA6C /* set_key.c */; }; + F8D94CC62B9ABFE20081A3C4 /* cast.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07CF23FCBC6C009FBA6C /* cast.c */; }; + F8D94CC72B9ABFE20081A3C4 /* michael.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07D123FCBC6C009FBA6C /* michael.c */; }; + F8D94CC82B9ABFE20081A3C4 /* arp.c in Sources */ = {isa = PBXBuildFile; fileRef = A5A0C5232A501E6800EF9328 /* arp.c */; }; + F8D94CC92B9ABFE20081A3C4 /* sha1.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07D823FCBC6C009FBA6C /* sha1.c */; }; + F8D94CCA2B9ABFE20081A3C4 /* cmac.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07DD23FCBC6C009FBA6C /* cmac.c */; }; + F8D94CCB2B9ABFE20081A3C4 /* ecb_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07E423FCBC6C009FBA6C /* ecb_enc.c */; }; + F8D94CCC2B9ABFE20081A3C4 /* chachapoly.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07E923FCBC6C009FBA6C /* chachapoly.c */; }; + F8D94CCD2B9ABFE20081A3C4 /* AirportItlwmV2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F8A028202A4A7DDC00C6DE90 /* AirportItlwmV2.cpp */; }; + F8D94CCE2B9ABFE20081A3C4 /* (null) in Sources */ = {isa = PBXBuildFile; }; + F8D94CCF2B9ABFE20081A3C4 /* md5.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07EA23FCBC6C009FBA6C /* md5.c */; }; + F8D94CD02B9ABFE20081A3C4 /* arc4.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07EB23FCBC6C009FBA6C /* arc4.c */; }; + F8D94CD12B9ABFE20081A3C4 /* AirportItlwmEthernetInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F8A0282D2A4A7E0400C6DE90 /* AirportItlwmEthernetInterface.cpp */; }; + F8D94CD22B9ABFE20081A3C4 /* AirportItlwmSkywalkInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F8A028702A4A7FE100C6DE90 /* AirportItlwmSkywalkInterface.cpp */; }; + F8D94CD32B9ABFE20081A3C4 /* blf.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07EC23FCBC6C009FBA6C /* blf.c */; }; + F8D94CD42B9ABFE20081A3C4 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; + F8D94CD52B9ABFE20081A3C4 /* poly1305.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07ED23FCBC6C009FBA6C /* poly1305.c */; }; + F8D94CD62B9ABFE20081A3C4 /* key_wrap.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07F023FCBC6C009FBA6C /* key_wrap.c */; }; + F8D94CD72B9ABFE20081A3C4 /* gmac.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07F223FCBC6C009FBA6C /* gmac.c */; }; + F8D94CD82B9ABFE20081A3C4 /* rmd160.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07F323FCBC6C009FBA6C /* rmd160.c */; }; + F8D94CD92B9ABFE20081A3C4 /* idgen.c in Sources */ = {isa = PBXBuildFile; fileRef = 024A07F423FCBC6C009FBA6C /* idgen.c */; }; + F8D94CDA2B9ABFE20081A3C4 /* compat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 024A07BA23FCBC6C009FBA6C /* compat.cpp */; }; + F8D94CDB2B9ABFE20081A3C4 /* zutil.c in Sources */ = {isa = PBXBuildFile; fileRef = F8FA0EED2501E8C100B1822E /* zutil.c */; }; + F8D94CDC2B9ABFE20081A3C4 /* ItlHalService.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F8D364F624F93AFD0029340B /* ItlHalService.cpp */; }; + F8D94CDD2B9ABFE20081A3C4 /* ItlIwx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F8D6CD642442E8F200D2A454 /* ItlIwx.cpp */; }; + F8D94CDE2B9ABFE20081A3C4 /* utils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 024A08BF23FCD4E2009FBA6C /* utils.cpp */; }; + F8D94CDF2B9ABFE20081A3C4 /* fw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 024A08BD23FCD314009FBA6C /* fw.cpp */; }; + F8D94CE02B9ABFE20081A3C4 /* io.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 024A08C123FCD999009FBA6C /* io.cpp */; }; + F8D94CE12B9ABFE20081A3C4 /* rx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 024A08C323FCDC14009FBA6C /* rx.cpp */; }; + F8D94CE22B9ABFE20081A3C4 /* coex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F837C91C2724577F00B2C499 /* coex.cpp */; }; + F8D94CE32B9ABFE20081A3C4 /* tx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 024A08C523FCDC3B009FBA6C /* tx.cpp */; }; + F8D94CE42B9ABFE20081A3C4 /* hw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 024A08C723FCE2ED009FBA6C /* hw.cpp */; }; + F8D94CE52B9ABFE20081A3C4 /* ItlIwn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17FD7F0E255E4AC800611406 /* ItlIwn.cpp */; }; + F8D94CE62B9ABFE20081A3C4 /* phy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 024A08C923FCE537009FBA6C /* phy.cpp */; }; + F8D94CE72B9ABFE20081A3C4 /* mac80211.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 024A08CB23FCE5CA009FBA6C /* mac80211.cpp */; }; + F8D94CE82B9ABFE20081A3C4 /* nvm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 024A08CD23FCE67F009FBA6C /* nvm.cpp */; }; + F8D94CE92B9ABFE20081A3C4 /* ctxt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 024A08CF23FCEE88009FBA6C /* ctxt.cpp */; }; + F8D94CEA2B9ABFE20081A3C4 /* led.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 024A08D123FCF395009FBA6C /* led.cpp */; }; + F8D94CEB2B9ABFE20081A3C4 /* power.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 024A08D323FCF3E6009FBA6C /* power.cpp */; }; + F8D94CEC2B9ABFE20081A3C4 /* scan.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 024A08D523FCF4D7009FBA6C /* scan.cpp */; }; + F8D94CED2B9ABFE20081A3C4 /* IOPCIEDeviceWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F8A0287D2A4A80EA00C6DE90 /* IOPCIEDeviceWrapper.cpp */; }; + F8D94CEE2B9ABFE20081A3C4 /* ItlIwm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F8AF3A2F24F9F35B008911C1 /* ItlIwm.cpp */; }; + F8D94CF02B9ABFE20081A3C4 /* libkmod.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5088ECBC252884870068A63D /* libkmod.a */; }; F8E49A14249B923500BE6868 /* ItlNetworkUserClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F8E49A12249B923500BE6868 /* ItlNetworkUserClient.cpp */; }; F8E49A15249B923500BE6868 /* ItlNetworkUserClient.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F8E49A13249B923500BE6868 /* ItlNetworkUserClient.hpp */; }; F8ED134424FBB5B70068C831 /* ItlIwx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F8D6CD642442E8F200D2A454 /* ItlIwx.cpp */; }; @@ -943,6 +1050,13 @@ remoteGlobalIDString = 5066D63825287F7900EE6F38; remoteInfo = fw_gen; }; + F8D94C822B9ABFE20081A3C4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 024A07A323FCBC3C009FBA6C /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5066D63825287F7900EE6F38; + remoteInfo = fw_gen; + }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ @@ -1160,6 +1274,7 @@ F8D6CD6C2442F20C00D2A454 /* if_iwxreg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = if_iwxreg.h; sourceTree = ""; }; F8D6CD6D2442F20C00D2A454 /* if_iwxvar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = if_iwxvar.h; sourceTree = ""; }; F8D76361244F21BB00DEA040 /* pm.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = pm.cpp; sourceTree = ""; }; + F8D94CF52B9ABFE20081A3C4 /* AirportItlwm.kext */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AirportItlwm.kext; sourceTree = BUILT_PRODUCTS_DIR; }; F8E3806526D533D400568FEB /* iwlwifi-ty-a0-gf-a0.pnvm */ = {isa = PBXFileReference; lastKnownFileType = file; path = "iwlwifi-ty-a0-gf-a0.pnvm"; sourceTree = ""; }; F8E49A12249B923500BE6868 /* ItlNetworkUserClient.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ItlNetworkUserClient.cpp; sourceTree = ""; }; F8E49A13249B923500BE6868 /* ItlNetworkUserClient.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ItlNetworkUserClient.hpp; sourceTree = ""; }; @@ -1257,6 +1372,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + F8D94CEF2B9ABFE20081A3C4 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F8D94CF02B9ABFE20081A3C4 /* libkmod.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -1286,6 +1409,7 @@ F897ED18266EFF93005EE8F7 /* AirportItlwm.kext */, F8AE6558285471560085B4CF /* AirportItlwm.kext */, F8B2110A2A2EC2680043ECBD /* AirportItlwm.kext */, + F8D94CF52B9ABFE20081A3C4 /* AirportItlwm.kext */, ); name = Products; sourceTree = ""; @@ -1984,6 +2108,46 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + F8D94C832B9ABFE20081A3C4 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + F8D94C842B9ABFE20081A3C4 /* CCDataPipe.h in Headers */, + F8D94C852B9ABFE20081A3C4 /* debug.h in Headers */, + F8D94C862B9ABFE20081A3C4 /* IOSkywalkEthernetInterface.h in Headers */, + F8D94C872B9ABFE20081A3C4 /* IO80211InfraProtocol.h in Headers */, + F8D94C882B9ABFE20081A3C4 /* IOSkywalkLogicalLink.h in Headers */, + F8D94C892B9ABFE20081A3C4 /* AirportItlwmEthernetInterface.hpp in Headers */, + F8D94C8A2B9ABFE20081A3C4 /* IOSkywalkNetworkPacket.h in Headers */, + F8D94C8B2B9ABFE20081A3C4 /* apple80211_ioctl.h in Headers */, + F8D94C8C2B9ABFE20081A3C4 /* CCLogPipe.h in Headers */, + F8D94C8D2B9ABFE20081A3C4 /* IO80211P2PInterface.h in Headers */, + F8D94C8E2B9ABFE20081A3C4 /* CCPipe.h in Headers */, + F8D94C8F2B9ABFE20081A3C4 /* IO80211WorkLoop.h in Headers */, + F8D94C902B9ABFE20081A3C4 /* apple80211_var.h in Headers */, + F8D94C912B9ABFE20081A3C4 /* IOSkywalkPacketBufferPool.h in Headers */, + F8D94C922B9ABFE20081A3C4 /* IOSkywalkLegacyEthernetInterface.h in Headers */, + F8D94C932B9ABFE20081A3C4 /* AirportItlwmInterface.hpp in Headers */, + F8D94C942B9ABFE20081A3C4 /* IO80211Interface.h in Headers */, + F8D94C952B9ABFE20081A3C4 /* IO80211WorkQueue.h in Headers */, + F8D94C962B9ABFE20081A3C4 /* (null) in Headers */, + F8D94C972B9ABFE20081A3C4 /* IO80211InfraInterface.h in Headers */, + F8D94C982B9ABFE20081A3C4 /* IO80211SkywalkInterface.h in Headers */, + F8D94C992B9ABFE20081A3C4 /* CCLogStream.h in Headers */, + F8D94C9A2B9ABFE20081A3C4 /* AirportItlwmSkywalkInterface.hpp in Headers */, + F8D94C9B2B9ABFE20081A3C4 /* AirportItlwm.hpp in Headers */, + F8D94C9C2B9ABFE20081A3C4 /* IO80211ControllerV2.h in Headers */, + F8D94C9D2B9ABFE20081A3C4 /* IOPCIEDeviceWrapper.hpp in Headers */, + F8D94C9E2B9ABFE20081A3C4 /* IO80211VirtualInterface.h in Headers */, + F8D94C9F2B9ABFE20081A3C4 /* IO80211Controller.h in Headers */, + F8D94CA02B9ABFE20081A3C4 /* (null) in Headers */, + F8D94CA12B9ABFE20081A3C4 /* AirportItlwmV2.hpp in Headers */, + F8D94CA22B9ABFE20081A3C4 /* ieee80211_ra.h in Headers */, + F8D94CA32B9ABFE20081A3C4 /* CCStream.h in Headers */, + F8D94CA42B9ABFE20081A3C4 /* apple80211_wps.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ @@ -2120,9 +2284,9 @@ productReference = F8AE6558285471560085B4CF /* AirportItlwm.kext */; productType = "com.apple.product-type.kernel-extension"; }; - F8B210A72A2EC2680043ECBD /* AirportItlwm-Sonoma */ = { + F8B210A72A2EC2680043ECBD /* AirportItlwm-Sonoma14.0 */ = { isa = PBXNativeTarget; - buildConfigurationList = F8B211072A2EC2680043ECBD /* Build configuration list for PBXNativeTarget "AirportItlwm-Sonoma" */; + buildConfigurationList = F8B211072A2EC2680043ECBD /* Build configuration list for PBXNativeTarget "AirportItlwm-Sonoma14.0" */; buildPhases = ( F8B210AA2A2EC2680043ECBD /* Headers */, F8B210BB2A2EC2680043ECBD /* Sources */, @@ -2134,11 +2298,30 @@ dependencies = ( F8B210A82A2EC2680043ECBD /* PBXTargetDependency */, ); - name = "AirportItlwm-Sonoma"; + name = "AirportItlwm-Sonoma14.0"; productName = AirportItlwm; productReference = F8B2110A2A2EC2680043ECBD /* AirportItlwm.kext */; productType = "com.apple.product-type.kernel-extension"; }; + F8D94C802B9ABFE20081A3C4 /* AirportItlwm-Sonoma14.4 */ = { + isa = PBXNativeTarget; + buildConfigurationList = F8D94CF22B9ABFE20081A3C4 /* Build configuration list for PBXNativeTarget "AirportItlwm-Sonoma14.4" */; + buildPhases = ( + F8D94C832B9ABFE20081A3C4 /* Headers */, + F8D94CA52B9ABFE20081A3C4 /* Sources */, + F8D94CEF2B9ABFE20081A3C4 /* Frameworks */, + F8D94CF12B9ABFE20081A3C4 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + F8D94C812B9ABFE20081A3C4 /* PBXTargetDependency */, + ); + name = "AirportItlwm-Sonoma14.4"; + productName = AirportItlwm; + productReference = F8D94CF52B9ABFE20081A3C4 /* AirportItlwm.kext */; + productType = "com.apple.product-type.kernel-extension"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -2178,6 +2361,9 @@ F8B210A72A2EC2680043ECBD = { ProvisioningStyle = Manual; }; + F8D94C802B9ABFE20081A3C4 = { + ProvisioningStyle = Manual; + }; }; }; buildConfigurationList = 024A07A623FCBC3C009FBA6C /* Build configuration list for PBXProject "itlwm" */; @@ -2200,7 +2386,8 @@ 35CBE655251CB89700435CBC /* AirportItlwm-Big Sur */, F897ECB6266EFF93005EE8F7 /* AirportItlwm-Monterey */, F8AE64F5285471560085B4CF /* AirportItlwm-Ventura */, - F8B210A72A2EC2680043ECBD /* AirportItlwm-Sonoma */, + F8B210A72A2EC2680043ECBD /* AirportItlwm-Sonoma14.0 */, + F8D94C802B9ABFE20081A3C4 /* AirportItlwm-Sonoma14.4 */, 5066D63825287F7900EE6F38 /* fw_gen */, ); }; @@ -2263,6 +2450,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + F8D94CF12B9ABFE20081A3C4 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ @@ -2928,6 +3122,86 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + F8D94CA52B9ABFE20081A3C4 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F8D94CA62B9ABFE20081A3C4 /* rs.cpp in Sources */, + F8D94CA72B9ABFE20081A3C4 /* _mbuf.cpp in Sources */, + F8D94CA82B9ABFE20081A3C4 /* ieee80211_ra.c in Sources */, + F8D94CA92B9ABFE20081A3C4 /* _task.cpp in Sources */, + F8D94CAA2B9ABFE20081A3C4 /* FwBinary.cpp in Sources */, + F8D94CAB2B9ABFE20081A3C4 /* ieee80211_proto.c in Sources */, + F8D94CAC2B9ABFE20081A3C4 /* _string.c in Sources */, + F8D94CAD2B9ABFE20081A3C4 /* ieee80211_ioctl.c in Sources */, + F8D94CAE2B9ABFE20081A3C4 /* ieee80211.c in Sources */, + F8D94CAF2B9ABFE20081A3C4 /* ieee80211_rssadapt.c in Sources */, + F8D94CB02B9ABFE20081A3C4 /* ieee80211_input.c in Sources */, + F8D94CB12B9ABFE20081A3C4 /* timeout.c in Sources */, + F8D94CB22B9ABFE20081A3C4 /* ieee80211_mira.c in Sources */, + F8D94CB32B9ABFE20081A3C4 /* ieee80211_crypto_bip.c in Sources */, + F8D94CB42B9ABFE20081A3C4 /* ieee80211_crypto_tkip.c in Sources */, + F8D94CB52B9ABFE20081A3C4 /* ieee80211_crypto_ccmp.c in Sources */, + F8D94CB62B9ABFE20081A3C4 /* ieee80211_crypto_wep.c in Sources */, + F8D94CB72B9ABFE20081A3C4 /* ieee80211_pae_input.c in Sources */, + F8D94CB82B9ABFE20081A3C4 /* ieee80211_amrr.c in Sources */, + F8D94CB92B9ABFE20081A3C4 /* ieee80211_output.c in Sources */, + F8D94CBA2B9ABFE20081A3C4 /* ieee80211_crypto.c in Sources */, + F8D94CBB2B9ABFE20081A3C4 /* CTimeout.cpp in Sources */, + F8D94CBC2B9ABFE20081A3C4 /* ieee80211_regdomain.c in Sources */, + F8D94CBD2B9ABFE20081A3C4 /* ieee80211_node.c in Sources */, + F8D94CBE2B9ABFE20081A3C4 /* ieee80211_pae_output.c in Sources */, + F8D94CBF2B9ABFE20081A3C4 /* sha1-pbkdf2.c in Sources */, + F8D94CC02B9ABFE20081A3C4 /* aes.c in Sources */, + F8D94CC12B9ABFE20081A3C4 /* hmac.c in Sources */, + F8D94CC22B9ABFE20081A3C4 /* sha2.c in Sources */, + F8D94CC32B9ABFE20081A3C4 /* rijndael.c in Sources */, + F8D94CC42B9ABFE20081A3C4 /* ecb3_enc.c in Sources */, + F8D94CC52B9ABFE20081A3C4 /* set_key.c in Sources */, + F8D94CC62B9ABFE20081A3C4 /* cast.c in Sources */, + F8D94CC72B9ABFE20081A3C4 /* michael.c in Sources */, + F8D94CC82B9ABFE20081A3C4 /* arp.c in Sources */, + F8D94CC92B9ABFE20081A3C4 /* sha1.c in Sources */, + F8D94CCA2B9ABFE20081A3C4 /* cmac.c in Sources */, + F8D94CCB2B9ABFE20081A3C4 /* ecb_enc.c in Sources */, + F8D94CCC2B9ABFE20081A3C4 /* chachapoly.c in Sources */, + F8D94CCD2B9ABFE20081A3C4 /* AirportItlwmV2.cpp in Sources */, + F8D94CCE2B9ABFE20081A3C4 /* (null) in Sources */, + F8D94CCF2B9ABFE20081A3C4 /* md5.c in Sources */, + F8D94CD02B9ABFE20081A3C4 /* arc4.c in Sources */, + F8D94CD12B9ABFE20081A3C4 /* AirportItlwmEthernetInterface.cpp in Sources */, + F8D94CD22B9ABFE20081A3C4 /* AirportItlwmSkywalkInterface.cpp in Sources */, + F8D94CD32B9ABFE20081A3C4 /* blf.c in Sources */, + F8D94CD42B9ABFE20081A3C4 /* _ifq.cpp in Sources */, + F8D94CD52B9ABFE20081A3C4 /* poly1305.c in Sources */, + F8D94CD62B9ABFE20081A3C4 /* key_wrap.c in Sources */, + F8D94CD72B9ABFE20081A3C4 /* gmac.c in Sources */, + F8D94CD82B9ABFE20081A3C4 /* rmd160.c in Sources */, + F8D94CD92B9ABFE20081A3C4 /* idgen.c in Sources */, + F8D94CDA2B9ABFE20081A3C4 /* compat.cpp in Sources */, + F8D94CDB2B9ABFE20081A3C4 /* zutil.c in Sources */, + F8D94CDC2B9ABFE20081A3C4 /* ItlHalService.cpp in Sources */, + F8D94CDD2B9ABFE20081A3C4 /* ItlIwx.cpp in Sources */, + F8D94CDE2B9ABFE20081A3C4 /* utils.cpp in Sources */, + F8D94CDF2B9ABFE20081A3C4 /* fw.cpp in Sources */, + F8D94CE02B9ABFE20081A3C4 /* io.cpp in Sources */, + F8D94CE12B9ABFE20081A3C4 /* rx.cpp in Sources */, + F8D94CE22B9ABFE20081A3C4 /* coex.cpp in Sources */, + F8D94CE32B9ABFE20081A3C4 /* tx.cpp in Sources */, + F8D94CE42B9ABFE20081A3C4 /* hw.cpp in Sources */, + F8D94CE52B9ABFE20081A3C4 /* ItlIwn.cpp in Sources */, + F8D94CE62B9ABFE20081A3C4 /* phy.cpp in Sources */, + F8D94CE72B9ABFE20081A3C4 /* mac80211.cpp in Sources */, + F8D94CE82B9ABFE20081A3C4 /* nvm.cpp in Sources */, + F8D94CE92B9ABFE20081A3C4 /* ctxt.cpp in Sources */, + F8D94CEA2B9ABFE20081A3C4 /* led.cpp in Sources */, + F8D94CEB2B9ABFE20081A3C4 /* power.cpp in Sources */, + F8D94CEC2B9ABFE20081A3C4 /* scan.cpp in Sources */, + F8D94CED2B9ABFE20081A3C4 /* IOPCIEDeviceWrapper.cpp in Sources */, + F8D94CEE2B9ABFE20081A3C4 /* ItlIwm.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -2971,6 +3245,11 @@ target = 5066D63825287F7900EE6F38 /* fw_gen */; targetProxy = F8B210A92A2EC2680043ECBD /* PBXContainerItemProxy */; }; + F8D94C812B9ABFE20081A3C4 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5066D63825287F7900EE6F38 /* fw_gen */; + targetProxy = F8D94C822B9ABFE20081A3C4 /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ @@ -3553,7 +3832,7 @@ F8B211082A2EC2680043ECBD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CONFIGURATION_BUILD_DIR = "$(SYMROOT)/$(CONFIGURATION)/Sonoma"; + CONFIGURATION_BUILD_DIR = "$(SYMROOT)/$(CONFIGURATION)/Sonoma14.0"; CURRENT_PROJECT_VERSION = "$(MODULE_VERSION)"; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = itlwm/PrivateSPI.pch; @@ -3584,7 +3863,7 @@ F8B211092A2EC2680043ECBD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - CONFIGURATION_BUILD_DIR = "$(SYMROOT)/$(CONFIGURATION)/Sonoma"; + CONFIGURATION_BUILD_DIR = "$(SYMROOT)/$(CONFIGURATION)/Sonoma14.0"; CURRENT_PROJECT_VERSION = "$(MODULE_VERSION)"; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = itlwm/PrivateSPI.pch; @@ -3612,6 +3891,70 @@ }; name = Release; }; + F8D94CF32B9ABFE20081A3C4 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CONFIGURATION_BUILD_DIR = "$(SYMROOT)/$(CONFIGURATION)/Sonoma14.4"; + CURRENT_PROJECT_VERSION = "$(MODULE_VERSION)"; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = itlwm/PrivateSPI.pch; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + AIRPORT, + "__IO80211_TARGET=__MAC_14_4", + __PRIVATE_SPI__, + IO80211FAMILY_V2, + ); + INFOPLIST_FILE = "AirportItlwm/AirportItlwm-Sonoma-Info.plist"; + LIBRARY_SEARCH_PATHS = ( + "$(PROJECT_DIR)/itl80211", + "$(inherited)", + "$(PROJECT_DIR)/itl80211/openbsd", + "$(PROJECT_DIR)/itl80211/linux", + "$(PROJECT_DIR)/MacKernelSDK/Library/x86_64", + ); + MACOSX_DEPLOYMENT_TARGET = 10.15; + MODULE_NAME = com.zxystd.AirportItlwm; + PRODUCT_BUNDLE_IDENTIFIER = com.zxystd.AirportItlwm; + PRODUCT_MODULE_NAME = AirportItlwm; + PRODUCT_NAME = AirportItlwm; + SYSTEM_HEADER_SEARCH_PATHS = "itl80211/openbsd itl80211 include"; + WRAPPER_EXTENSION = kext; + }; + name = Debug; + }; + F8D94CF42B9ABFE20081A3C4 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CONFIGURATION_BUILD_DIR = "$(SYMROOT)/$(CONFIGURATION)/Sonoma14.4"; + CURRENT_PROJECT_VERSION = "$(MODULE_VERSION)"; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = itlwm/PrivateSPI.pch; + GCC_PREPROCESSOR_DEFINITIONS = ( + "__IO80211_TARGET=__MAC_14_4", + AIRPORT, + __PRIVATE_SPI__, + "$(inherited)", + IO80211FAMILY_V2, + ); + INFOPLIST_FILE = "AirportItlwm/AirportItlwm-Sonoma-Info.plist"; + LIBRARY_SEARCH_PATHS = ( + "$(PROJECT_DIR)/itl80211", + "$(inherited)", + "$(PROJECT_DIR)/itl80211/openbsd", + "$(PROJECT_DIR)/itl80211/linux", + "$(PROJECT_DIR)/MacKernelSDK/Library/x86_64", + ); + MACOSX_DEPLOYMENT_TARGET = 10.15; + MODULE_NAME = com.zxystd.AirportItlwm; + PRODUCT_BUNDLE_IDENTIFIER = com.zxystd.AirportItlwm; + PRODUCT_MODULE_NAME = AirportItlwm; + PRODUCT_NAME = AirportItlwm; + SYSTEM_HEADER_SEARCH_PATHS = "itl80211/openbsd itl80211 include"; + WRAPPER_EXTENSION = kext; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -3696,7 +4039,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - F8B211072A2EC2680043ECBD /* Build configuration list for PBXNativeTarget "AirportItlwm-Sonoma" */ = { + F8B211072A2EC2680043ECBD /* Build configuration list for PBXNativeTarget "AirportItlwm-Sonoma14.0" */ = { isa = XCConfigurationList; buildConfigurations = ( F8B211082A2EC2680043ECBD /* Debug */, @@ -3705,6 +4048,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + F8D94CF22B9ABFE20081A3C4 /* Build configuration list for PBXNativeTarget "AirportItlwm-Sonoma14.4" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F8D94CF32B9ABFE20081A3C4 /* Debug */, + F8D94CF42B9ABFE20081A3C4 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ }; rootObject = 024A07A323FCBC3C009FBA6C /* Project object */; diff --git a/itlwm.xcodeproj/xcshareddata/xcschemes/AirportItlwm (all).xcscheme b/itlwm.xcodeproj/xcshareddata/xcschemes/AirportItlwm (all).xcscheme index fa9a85aec..ce7faac36 100644 --- a/itlwm.xcodeproj/xcshareddata/xcschemes/AirportItlwm (all).xcscheme +++ b/itlwm.xcodeproj/xcshareddata/xcschemes/AirportItlwm (all).xcscheme @@ -100,7 +100,21 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "F8B210A72A2EC2680043ECBD" BuildableName = "AirportItlwm.kext" - BlueprintName = "AirportItlwm-Sonoma" + BlueprintName = "AirportItlwm-Sonoma14.0" + ReferencedContainer = "container:itlwm.xcodeproj"> + + + + diff --git a/itlwm/PrivateSPI.pch b/itlwm/PrivateSPI.pch index 65baa28a5..d50988bbb 100644 --- a/itlwm/PrivateSPI.pch +++ b/itlwm/PrivateSPI.pch @@ -16,3 +16,7 @@ typedef u_int32_t ifnet_ctl_cmd_t; #ifndef __MAC_14_0 #define __MAC_14_0 140000 #endif + +#ifndef __MAC_14_4 +#define __MAC_14_4 140400 +#endif From 43c7d6ad349d2a994c07fe5d3aa1be6e95deee51 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Sat, 9 Mar 2024 22:57:08 +0800 Subject: [PATCH 088/114] iwm: use per-Tx-queue interface timers to ensure that the interface watchdog will trigger a device timeout if a particular Tx queue gets stuck while other Tx queues keep working. https://github.com/openbsd/src/commit/f2e5212624567973232a5a618335b62f7fd013da --- itlwm/hal_iwm/if_iwmvar.h | 2 +- itlwm/hal_iwm/mac80211.cpp | 54 +++++++++++++++++++++++--------------- 2 files changed, 34 insertions(+), 22 deletions(-) diff --git a/itlwm/hal_iwm/if_iwmvar.h b/itlwm/hal_iwm/if_iwmvar.h index 8624e10ec..bc8493058 100644 --- a/itlwm/hal_iwm/if_iwmvar.h +++ b/itlwm/hal_iwm/if_iwmvar.h @@ -628,7 +628,7 @@ struct iwm_softc { struct iwm_bf_data sc_bf; - int sc_tx_timer; + int sc_tx_timer[IWM_MAX_QUEUES]; int sc_rx_ba_sessions; int sc_scan_last_antenna; diff --git a/itlwm/hal_iwm/mac80211.cpp b/itlwm/hal_iwm/mac80211.cpp index a86bf36e2..994e7e6a1 100644 --- a/itlwm/hal_iwm/mac80211.cpp +++ b/itlwm/hal_iwm/mac80211.cpp @@ -1179,7 +1179,7 @@ iwm_rx_tx_ba_notif(struct iwm_softc *sc, struct iwm_rx_packet *pkt, struct iwm_r if (qid != IWM_FIRST_AGG_TX_QUEUE + ba_notif->tid) return; - sc->sc_tx_timer = 0; + sc->sc_tx_timer[qid] = 0; ba = &ni->ni_tx_ba[ba_notif->tid]; if (ba->ba_state != IEEE80211_BA_AGREED) @@ -1237,8 +1237,6 @@ iwm_ampdu_tx_done(struct iwm_softc *sc, struct iwm_cmd_header *cmd_hdr, status != IWM_TX_STATUS_DIRECT_DONE); struct ieee80211_tx_ba *ba; - sc->sc_tx_timer = 0; - if (ic->ic_state != IEEE80211_S_RUN) return; @@ -1444,8 +1442,8 @@ iwm_rx_tx_cmd(struct iwm_softc *sc, struct iwm_rx_packet *pkt, struct iwm_cmd_header *cmd_hdr = &pkt->hdr; int idx = cmd_hdr->idx; int qid = cmd_hdr->qid; - struct iwm_tx_ring *ring = &sc->txq[qid]; - struct iwm_tx_data *txd = &ring->data[idx]; + struct iwm_tx_ring *ring; + struct iwm_tx_data *txd; struct iwm_tx_resp *tx_resp = (struct iwm_tx_resp *)pkt->data; uint32_t ssn; uint32_t len = iwm_rx_packet_len(pkt); @@ -1454,8 +1452,6 @@ iwm_rx_tx_cmd(struct iwm_softc *sc, struct iwm_rx_packet *pkt, bus_dmamap_sync(sc->sc_dmat, data->map, 0, IWM_RBUF_SIZE, BUS_DMASYNC_POSTREAD); - sc->sc_tx_timer = 0; - /* Sanity checks. */ if (sizeof(*tx_resp) > len) return; @@ -1467,6 +1463,11 @@ iwm_rx_tx_cmd(struct iwm_softc *sc, struct iwm_rx_packet *pkt, tx_resp->frame_count * sizeof(struct iwm_agg_tx_status) > len) return; + sc->sc_tx_timer[qid] = 0; + + ring = &sc->txq[qid]; + txd = &ring->data[idx]; + if (tx_resp->frame_count > 1) { for (int i = 0; i < tx_resp->frame_count; i++) { struct iwm_agg_tx_status *frame_status = iwl_mvm_get_agg_status(sc, tx_resp); @@ -1899,6 +1900,9 @@ iwm_tx(struct iwm_softc *sc, mbuf_t m, struct ieee80211_node *ni, int ac) sc->qfullmsk |= 1 << ring->qid; } + if (ic->ic_if.if_flags & IFF_UP) + sc->sc_tx_timer[ring->qid] = 15; + return 0; } @@ -3581,10 +3585,8 @@ _iwm_start_task(OSObject *target, void *arg0, void *arg1, void *arg2, void *arg3 } ifp->netStat->outputPackets++; - if (ifp->if_flags & IFF_UP) { - sc->sc_tx_timer = 15; + if (ifp->if_flags & IFF_UP) ifp->if_timer = 1; - } } return kIOReturnSuccess; @@ -3667,7 +3669,8 @@ iwm_stop(struct _ifnet *ifp) iwm_clear_reorder_buffer(sc, rxba); } iwm_led_blink_stop(sc); - ifp->if_timer = sc->sc_tx_timer = 0; + memset(sc->sc_tx_timer, 0, sizeof(sc->sc_tx_timer)); + ifp->if_timer = 0; splx(s); } @@ -3677,22 +3680,31 @@ iwm_watchdog(struct _ifnet *ifp) { struct iwm_softc *sc = (struct iwm_softc *)ifp->if_softc; ItlIwm *that = container_of(sc, ItlIwm, com); + int i; ifp->if_timer = 0; - if (sc->sc_tx_timer > 0) { - if (--sc->sc_tx_timer == 0) { - XYLog("%s: device timeout\n", DEVNAME(sc)); + + /* + * We maintain a separate timer for each Tx queue because + * Tx aggregation queues can get "stuck" while other queues + * keep working. The Linux driver uses a similar workaround. + */ + for (i = 0; i < nitems(sc->sc_tx_timer); i++) { + if (sc->sc_tx_timer[i] > 0) { + if (--sc->sc_tx_timer[i] == 0) { + XYLog("%s: device timeout\n", DEVNAME(sc)); #ifdef IWM_DEBUG - that->iwm_nic_error(sc); + that->iwm_nic_error(sc); #endif - if ((sc->sc_flags & IWM_FLAG_SHUTDOWN) == 0) { - task_add(systq, &sc->init_task); + if ((sc->sc_flags & IWM_FLAG_SHUTDOWN) == 0) { + task_add(systq, &sc->init_task); + } + XYLog("%s %d OUTPUT_ERROR\n", __FUNCTION__, __LINE__); + ifp->netStat->outputErrors++; + return; } - XYLog("%s %d OUTPUT_ERROR\n", __FUNCTION__, __LINE__); - ifp->netStat->outputErrors++; - return; + ifp->if_timer = 1; } - ifp->if_timer = 1; } ieee80211_watchdog(ifp); From 42dc7bcb349d49b0a676b115571b4b9850a70c90 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Sun, 10 Mar 2024 00:02:19 +0800 Subject: [PATCH 089/114] rs: Ensure ack flag is properly cleared. Some frames were flagged as ACKed when they should not be. --- itlwm/hal_iwm/mac80211.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/itlwm/hal_iwm/mac80211.cpp b/itlwm/hal_iwm/mac80211.cpp index 994e7e6a1..f9311f44a 100644 --- a/itlwm/hal_iwm/mac80211.cpp +++ b/itlwm/hal_iwm/mac80211.cpp @@ -1312,6 +1312,7 @@ iwm_rx_tx_cmd_single(struct iwm_softc *sc, struct iwm_tx_resp *tx_resp, skb_freed++; memset(&info->status, 0, sizeof(info->status)); + info->flags &= ~(IEEE80211_TX_STAT_ACK | IEEE80211_TX_STAT_TX_FILTERED); /* inform mac80211 about what happened with the frame */ switch (status & IWM_TX_STATUS_MSK) { From d48ea5d0857bea11bd8173b983951509bb8537a6 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Tue, 12 Mar 2024 14:09:35 +0800 Subject: [PATCH 090/114] Decrease optimize to O1 in release build, to resolve the issue of using new xcode version. #926 #965 --- itlwm.xcodeproj/project.pbxproj | 1 + 1 file changed, 1 insertion(+) diff --git a/itlwm.xcodeproj/project.pbxproj b/itlwm.xcodeproj/project.pbxproj index 093938e8c..7473cdb88 100644 --- a/itlwm.xcodeproj/project.pbxproj +++ b/itlwm.xcodeproj/project.pbxproj @@ -3365,6 +3365,7 @@ GCC_C_LANGUAGE_STANDARD = c11; GCC_INPUT_FILETYPE = sourcecode.cpp.cpp; GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 1; GCC_PREPROCESSOR_DEFINITIONS = ( "ITLWM_VERSION=\\\"${MODULE_VERSION}\\\"", "GIT_COMMIT=\\\"${GIT_COMMIT}\\\"", From 428b98cfc11cb6e66a7cdc8f85882907d9eca1d3 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Tue, 12 Mar 2024 18:30:45 +0800 Subject: [PATCH 091/114] Add MSI interrupt index check. --- itlwm/hal_iwm/mac80211.cpp | 15 +++++++-------- itlwm/hal_iwn/ItlIwn.cpp | 10 ++++++---- itlwm/hal_iwx/ItlIwx.cpp | 10 +++++++--- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/itlwm/hal_iwm/mac80211.cpp b/itlwm/hal_iwm/mac80211.cpp index f9311f44a..68d190d39 100644 --- a/itlwm/hal_iwm/mac80211.cpp +++ b/itlwm/hal_iwm/mac80211.cpp @@ -4452,7 +4452,6 @@ iwm_attach(struct iwm_softc *sc, struct pci_attach_args *pa) pcireg_t reg, memtype; struct ieee80211com *ic = &sc->sc_ic; struct _ifnet *ifp = &ic->ic_if; - const char *intrstr = {0}; int err; int txq_i, i, j; @@ -4509,7 +4508,7 @@ iwm_attach(struct iwm_softc *sc, struct pci_attach_args *pa) PCI_COMMAND_STATUS_REG, reg); } - int msiIntrIndex = 0; + int msiIntrIndex = -1; for (int index = 0; ; index++) { int interruptType; @@ -4522,6 +4521,11 @@ iwm_attach(struct iwm_softc *sc, struct pci_attach_args *pa) break; } } + if (msiIntrIndex == -1) { + XYLog("%s: can't find MSI interrupt controller\n", DEVNAME(sc)); + return false; + } + if (sc->sc_msix) sc->sc_ih = IOFilterInterruptEventSource::filterInterruptEventSource(this, @@ -4533,15 +4537,10 @@ iwm_attach(struct iwm_softc *sc, struct pci_attach_args *pa) (IOInterruptEventSource::Action)&ItlIwm::iwm_intr, &ItlIwm::intrFilter , pa->pa_tag, msiIntrIndex); if (sc->sc_ih == NULL || pa->workloop->addEventSource(sc->sc_ih) != kIOReturnSuccess) { - XYLog("\n"); - XYLog("%s: can't establish interrupt", DEVNAME(sc)); - if (intrstr != NULL) - XYLog(" at %s", intrstr); - XYLog("\n"); + XYLog("%s: can't establish interrupt\n", DEVNAME(sc)); return false; } sc->sc_ih->enable(); - XYLog(", %s\n", intrstr); sc->sc_hw_rev = IWM_READ(sc, IWM_CSR_HW_REV); int pa_id = pa->pa_tag->configRead16(kIOPCIConfigDeviceID); diff --git a/itlwm/hal_iwn/ItlIwn.cpp b/itlwm/hal_iwn/ItlIwn.cpp index 8b505ad57..a52d34af2 100644 --- a/itlwm/hal_iwn/ItlIwn.cpp +++ b/itlwm/hal_iwn/ItlIwn.cpp @@ -347,8 +347,6 @@ iwn_attach(struct iwn_softc *sc, struct pci_attach_args *pa) { struct ieee80211com *ic = &sc->sc_ic; struct _ifnet *ifp = &ic->ic_if; - const char *intrstr; - pci_intr_handle_t ih; pcireg_t memtype, reg; int i, error; @@ -395,7 +393,7 @@ iwn_attach(struct iwn_softc *sc, struct pci_attach_args *pa) return false; } - int msiIntrIndex = 0; + int msiIntrIndex = -1; for (int index = 0; ; index++) { int interruptType; @@ -408,12 +406,16 @@ iwn_attach(struct iwn_softc *sc, struct pci_attach_args *pa) break; } } + if (msiIntrIndex == -1) { + XYLog("%s: can't find MSI interrupt controller\n", DEVNAME(sc)); + return false; + } sc->sc_ih = IOFilterInterruptEventSource::filterInterruptEventSource(this, (IOInterruptEventSource::Action)&ItlIwn::iwn_intr, &ItlIwn::intrFilter ,pa->pa_tag, msiIntrIndex); if (sc->sc_ih == NULL || pa->workloop->addEventSource(sc->sc_ih) != kIOReturnSuccess) { - XYLog("%s: can't establish interrupt", DEVNAME(sc)); + XYLog("%s: can't establish interrupt\n", DEVNAME(sc)); return false; } sc->sc_ih->enable(); diff --git a/itlwm/hal_iwx/ItlIwx.cpp b/itlwm/hal_iwx/ItlIwx.cpp index 91922f333..094352b0f 100644 --- a/itlwm/hal_iwx/ItlIwx.cpp +++ b/itlwm/hal_iwx/ItlIwx.cpp @@ -12786,7 +12786,6 @@ intrFilter(OSObject *object, IOFilterInterruptEventSource *src) bool ItlIwx:: iwx_attach(struct iwx_softc *sc, struct pci_attach_args *pa) { - pci_intr_handle_t ih; pcireg_t reg, memtype; struct ieee80211com *ic = &sc->sc_ic; struct _ifnet *ifp = &ic->ic_if; @@ -12845,7 +12844,7 @@ iwx_attach(struct iwx_softc *sc, struct pci_attach_args *pa) PCI_COMMAND_STATUS_REG, reg); } - int msiIntrIndex = 0; + int msiIntrIndex = -1; for (int index = 0; ; index++) { int interruptType; @@ -12858,6 +12857,11 @@ iwx_attach(struct iwx_softc *sc, struct pci_attach_args *pa) break; } } + if (msiIntrIndex == -1) { + XYLog("%s: can't find MSI interrupt controller\n", DEVNAME(sc)); + return false; + } + if (sc->sc_msix) sc->sc_ih = IOFilterInterruptEventSource::filterInterruptEventSource(this, @@ -12869,7 +12873,7 @@ iwx_attach(struct iwx_softc *sc, struct pci_attach_args *pa) (IOInterruptEventSource::Action)&ItlIwx::iwx_intr, &ItlIwx::intrFilter ,pa->pa_tag, msiIntrIndex); if (sc->sc_ih == NULL || pa->workloop->addEventSource(sc->sc_ih) != kIOReturnSuccess) { - XYLog("%s: can't establish interrupt", DEVNAME(sc)); + XYLog("%s: can't establish interrupt\n", DEVNAME(sc)); return false; } sc->sc_ih->enable(); From 83e09bfa79d0ef588a38c04c997ee8091ea52617 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Wed, 13 Mar 2024 01:07:31 +0800 Subject: [PATCH 092/114] task: check if task is already in queue before trying lock, potentially fixing thread race crash issue. --- itl80211/openbsd/sys/_task.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/itl80211/openbsd/sys/_task.cpp b/itl80211/openbsd/sys/_task.cpp index df69a1a6f..8188b5426 100644 --- a/itl80211/openbsd/sys/_task.cpp +++ b/itl80211/openbsd/sys/_task.cpp @@ -276,16 +276,19 @@ int task_add(struct taskq *tq, struct task *w) { int rv = 0; -// IOLog("itlwm: taskq task_add %s\n", w->name); +// IOLog("itlwm: taskq task_add %s thread: %lld\n", w->name, thread_tid(current_thread())); + + if (ISSET(w->t_flags, TASK_ONQUEUE)) + return (0); IORecursiveLockLock(tq->tq_mtx); if (ISSET(w->t_flags, TASK_ONQUEUE)) { - IOLog("itlwm: taskq task_add %s is already on queue\n", w->name); +// IOLog("itlwm: taskq task_add %s is already on queue thread: %lld\n", w->name, thread_tid(current_thread())); IORecursiveLockUnlock(tq->tq_mtx); return (0); } if (!ISSET(w->t_flags, TASK_ONQUEUE)) { - IOLog("itlwm: taskq task_add %s add to queue\n", w->name); +// IOLog("itlwm: taskq task_add %s add to queue thread: %lld\n", w->name, thread_tid(current_thread())); rv = 1; SET(w->t_flags, TASK_ONQUEUE); TAILQ_INSERT_TAIL(&tq->tq_worklist, w, t_entry); @@ -302,7 +305,10 @@ int task_del(struct taskq *tq, struct task *w) { int rv = 0; -// IOLog("itlwm: taskq task_del %s\n", w->name); +// IOLog("itlwm: taskq task_del %s thread: %lld\n", w->name, thread_tid(current_thread())); + + if (!ISSET(w->t_flags, TASK_ONQUEUE)) + return (0); IORecursiveLockLock(tq->tq_mtx); if (ISSET(w->t_flags, TASK_ONQUEUE)) { From 6dc344db4d00bdc7e0e9ecaed02adc266eb375bd Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Thu, 14 Mar 2024 22:20:31 +0800 Subject: [PATCH 093/114] iwm/iwx: Ensure aggregate operation on RUN state, this avoids new state thread racing with systq thread and causing unexpected issue like firmware crash or double free objects etc. --- itlwm/hal_iwm/mac80211.cpp | 6 ++++++ itlwm/hal_iwx/ItlIwx.cpp | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/itlwm/hal_iwm/mac80211.cpp b/itlwm/hal_iwm/mac80211.cpp index 68d190d39..7502f9c80 100644 --- a/itlwm/hal_iwm/mac80211.cpp +++ b/itlwm/hal_iwm/mac80211.cpp @@ -2805,6 +2805,9 @@ iwm_ampdu_rx_start(struct ieee80211com *ic, struct ieee80211_node *ni, tid > IWM_MAX_TID_COUNT) return ENOSPC; + if (ic->ic_state != IEEE80211_S_RUN) + return ENOSPC; + if (sc->ba_rx.start_tidmask & (1 << tid)) return EBUSY; @@ -2828,6 +2831,9 @@ iwm_ampdu_rx_stop(struct ieee80211com *ic, struct ieee80211_node *ni, if (tid > IWM_MAX_TID_COUNT || sc->ba_rx.stop_tidmask & (1 << tid)) return; + if (ic->ic_state != IEEE80211_S_RUN) + return; + sc->ba_rx.stop_tidmask |= (1 << tid); that->iwm_add_task(sc, systq, &sc->ba_task); } diff --git a/itlwm/hal_iwx/ItlIwx.cpp b/itlwm/hal_iwx/ItlIwx.cpp index 094352b0f..32b59180f 100644 --- a/itlwm/hal_iwx/ItlIwx.cpp +++ b/itlwm/hal_iwx/ItlIwx.cpp @@ -4452,6 +4452,9 @@ iwx_ampdu_rx_start(struct ieee80211com *ic, struct ieee80211_node *ni, tid >= IWX_MAX_TID_COUNT) return ENOSPC; + if (ic->ic_state != IEEE80211_S_RUN) + return ENOSPC; + if (sc->ba_rx.start_tidmask & (1 << tid)) return EBUSY; @@ -4475,6 +4478,9 @@ iwx_ampdu_rx_stop(struct ieee80211com *ic, struct ieee80211_node *ni, if (tid >= IWX_MAX_TID_COUNT || sc->ba_rx.stop_tidmask & (1 << tid)) return; + if (ic->ic_state != IEEE80211_S_RUN) + return; + sc->ba_rx.stop_tidmask |= (1 << tid); that->iwx_add_task(sc, systq, &sc->ba_task); } From 766085ed3b83d4fa8edc5ba6006ce62ab28b42f7 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Fri, 15 Mar 2024 21:55:08 +0800 Subject: [PATCH 094/114] iwm: use net80211 logic to determine if the queue should open tx aggregate, this would stall tx queue, open tx-agg immediately help to resolve this issue. --- itlwm/hal_iwm/mac80211.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/itlwm/hal_iwm/mac80211.cpp b/itlwm/hal_iwm/mac80211.cpp index 7502f9c80..0ffa11afb 100644 --- a/itlwm/hal_iwm/mac80211.cpp +++ b/itlwm/hal_iwm/mac80211.cpp @@ -4806,7 +4806,7 @@ iwm_attach(struct iwm_softc *sc, struct pci_attach_args *pa) ic->ic_ampdu_params = (IEEE80211_AMPDU_PARAM_SS_4 | 0x3 /* 64k */); ic->ic_caps |= (IEEE80211_C_QOS | IEEE80211_C_TX_AMPDU | IEEE80211_C_AMSDU_IN_AMPDU); ic->ic_caps |= IEEE80211_C_SUPPORTS_VHT_EXT_NSS_BW; -#if 1 +#if 0 ic->ic_caps |= IEEE80211_C_TX_AMPDU_SETUP_IN_RS; #endif From 1c8191a4693887837a7e48b42a9eb6eb0768a1a2 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Sat, 16 Mar 2024 10:41:50 +0800 Subject: [PATCH 095/114] iwm: clean unused iwm_tx_cmd member. --- itlwm/hal_iwm/if_iwmvar.h | 3 --- itlwm/hal_iwm/mac80211.cpp | 3 --- 2 files changed, 6 deletions(-) diff --git a/itlwm/hal_iwm/if_iwmvar.h b/itlwm/hal_iwm/if_iwmvar.h index bc8493058..0b12d215a 100644 --- a/itlwm/hal_iwm/if_iwmvar.h +++ b/itlwm/hal_iwm/if_iwmvar.h @@ -289,9 +289,6 @@ struct iwm_tx_data { int totlen; uint16_t fc; - /* A-MPDU subframes */ - int ampdu_txmcs; - int ampdu_nframes; struct ieee80211_tx_info info; }; diff --git a/itlwm/hal_iwm/mac80211.cpp b/itlwm/hal_iwm/mac80211.cpp index 0ffa11afb..5074440ec 100644 --- a/itlwm/hal_iwm/mac80211.cpp +++ b/itlwm/hal_iwm/mac80211.cpp @@ -1403,11 +1403,9 @@ iwm_txd_done(struct iwm_softc *sc, struct iwm_tx_data *txd) ieee80211_release_node(ic, &txd->in->in_ni); txd->in = NULL; txd->totlen = 0; - txd->ampdu_txmcs = 0; txd->txmcs = 0; txd->txrate = 0; txd->fc = 0; - txd->ampdu_nframes = 0; memset(&txd->info, 0, sizeof(struct ieee80211_tx_info)); } @@ -1849,7 +1847,6 @@ iwm_tx(struct iwm_softc *sc, mbuf_t m, struct ieee80211_node *ni, int ac) data->txmcs = ni->ni_txmcs; data->txrate = ni->ni_txrate; data->totlen = totlen; - data->ampdu_txmcs = ni->ni_txmcs; memcpy(&data->fc, &wh->i_fc[0], sizeof(uint16_t)); data->info.band = IEEE80211_IS_CHAN_2GHZ(ni->ni_chan) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ; From 40d8aa850819f67230e7231d965a89310911ce4c Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Sat, 16 Mar 2024 10:49:08 +0800 Subject: [PATCH 096/114] rs: reimplement active_legacy_rate bitmap calculation, make it more readable. --- itlwm/hal_iwm/rs.cpp | 35 ++++++----------------------------- 1 file changed, 6 insertions(+), 29 deletions(-) diff --git a/itlwm/hal_iwm/rs.cpp b/itlwm/hal_iwm/rs.cpp index 1ccb42f72..3267bdf85 100644 --- a/itlwm/hal_iwm/rs.cpp +++ b/itlwm/hal_iwm/rs.cpp @@ -2912,29 +2912,6 @@ enum ieee80211_rate_flags { IEEE80211_RATE_SUPPORTS_10MHZ = 1<<6, }; -/* rate data (static) */ -static struct ieee80211_rate iwl_cfg80211_rates[] = { - { .bitrate = 1 * 10, .hw_value = 0, .hw_value_short = 0, }, - { .bitrate = 2 * 10, .hw_value = 1, .hw_value_short = 1, - .flags = IEEE80211_RATE_SHORT_PREAMBLE, }, - { .bitrate = (u16)(5.5 * 10), .hw_value = 2, .hw_value_short = 2, - .flags = IEEE80211_RATE_SHORT_PREAMBLE, }, - { .bitrate = 11 * 10, .hw_value = 3, .hw_value_short = 3, - .flags = IEEE80211_RATE_SHORT_PREAMBLE, }, - { .bitrate = 6 * 10, .hw_value = 4, .hw_value_short = 4, }, - { .bitrate = 9 * 10, .hw_value = 5, .hw_value_short = 5, }, - { .bitrate = 12 * 10, .hw_value = 6, .hw_value_short = 6, }, - { .bitrate = 18 * 10, .hw_value = 7, .hw_value_short = 7, }, - { .bitrate = 24 * 10, .hw_value = 8, .hw_value_short = 8, }, - { .bitrate = 36 * 10, .hw_value = 9, .hw_value_short = 9, }, - { .bitrate = 48 * 10, .hw_value = 10, .hw_value_short = 10, }, - { .bitrate = 54 * 10, .hw_value = 11, .hw_value_short = 11, }, -}; -#define RATES_24_OFFS 0 -#define N_RATES_24 ARRAY_SIZE(iwl_cfg80211_rates) -#define RATES_52_OFFS 4 -#define N_RATES_52 (N_RATES_24 - RATES_52_OFFS) - /* * Called after adding a new station to initialize rate scaling */ @@ -2977,14 +2954,14 @@ static void rs_drv_rate_init(struct iwm_softc *mvm, struct ieee80211_node *sta, * active legacy rates as per supported rates bitmap */ lq_sta->active_legacy_rate = 0; - for (i = 0; i < sta->ni_rates.rs_nrates; i++) { - rate = sta->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL; - /* Map 802.11 rate to HW rate index. */ - for (j = 0; j <= (band == NL80211_BAND_2GHZ ? N_RATES_24 : N_RATES_52); j++) { - if (iwl_cfg80211_rates[j + (band == NL80211_BAND_2GHZ ? RATES_24_OFFS : RATES_52_OFFS)].bitrate / 5 == rate) + for (i = 0; i < ieee80211_std_rateset_11g.rs_nrates; i++) { + for (j = 0; j < sta->ni_rates.rs_nrates; j++) { + if (ieee80211_std_rateset_11g.rs_rates[i] == + (sta->ni_rates.rs_rates[j] & IEEE80211_RATE_VAL)) { + lq_sta->active_legacy_rate |= BIT(i); break; + } } - lq_sta->active_legacy_rate |= BIT(iwl_cfg80211_rates[j + (band == NL80211_BAND_2GHZ ? RATES_24_OFFS : RATES_52_OFFS)].hw_value); } /* TODO: should probably account for rx_highest for both HT/VHT */ From 0419f7aa4603735ac89c298c3171be27e469dbc3 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Sat, 16 Mar 2024 10:52:18 +0800 Subject: [PATCH 097/114] rs: disable BEAMFORM mode, we are not really support it. #934 --- itlwm/hal_iwm/rs.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/itlwm/hal_iwm/rs.cpp b/itlwm/hal_iwm/rs.cpp index 3267bdf85..fceed1cbe 100644 --- a/itlwm/hal_iwm/rs.cpp +++ b/itlwm/hal_iwm/rs.cpp @@ -2842,10 +2842,12 @@ static void rs_vht_init(struct iwm_softc *mvm, (sta->ni_vhtcaps & IEEE80211_VHTCAP_RXSTBC_MASK)) lq_sta->stbc_capable = true; +#if 0 if (isset(mvm->sc_enabled_capa, IWM_UCODE_TLV_CAPA_BEAMFORMER) && (that->iwm_num_of_ant(that->iwm_fw_valid_tx_ant(mvm)) > 1) && (sta->ni_vhtcaps & IEEE80211_VHTCAP_SU_BEAMFORMEE_CAPABLE)) lq_sta->bfer_capable = true; +#endif lq_sta->is_vht = true; } From 44a670868b61d6ecb7c4b4e47bb276f70e59ae85 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Sat, 16 Mar 2024 16:44:42 +0800 Subject: [PATCH 098/114] iwn: Use memset() to initialize struct ieee80211_rxinfo properly. https://github.com/openbsd/src/commit/52a13037ad838109937991a0d381a933632c1f02 --- itlwm/hal_iwn/ItlIwn.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/itlwm/hal_iwn/ItlIwn.cpp b/itlwm/hal_iwn/ItlIwn.cpp index a52d34af2..0781d83df 100644 --- a/itlwm/hal_iwn/ItlIwn.cpp +++ b/itlwm/hal_iwn/ItlIwn.cpp @@ -2210,7 +2210,7 @@ iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, } ni = ieee80211_find_rxnode(ic, wh); - rxi.rxi_flags = 0; + memset(&rxi, 0, sizeof(rxi)); if (((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_CTL) && (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) && !IEEE80211_IS_MULTICAST(wh->i_addr1) && @@ -2299,7 +2299,6 @@ iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, /* Send the frame to the 802.11 layer. */ rxi.rxi_rssi = rssi; - rxi.rxi_tstamp = 0; /* unused */ rxi.rxi_chan = chan; ieee80211_inputm(ifp, m, ni, &rxi, ml); From fa342425704c336e06ac3c24e03bcb09ebae4030 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Sat, 16 Mar 2024 16:55:56 +0800 Subject: [PATCH 099/114] iwn: Sync the iwn(4) "enhanced Tx power" eeprom data structure with Linux. https://github.com/openbsd/src/commit/1f94d8c3007756baa21a28fd0079e62fe90d0b33 --- itlwm/hal_iwn/ItlIwn.cpp | 2 +- itlwm/hal_iwn/if_iwnreg.h | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/itlwm/hal_iwn/ItlIwn.cpp b/itlwm/hal_iwn/ItlIwn.cpp index 0781d83df..867cc6f62 100644 --- a/itlwm/hal_iwn/ItlIwn.cpp +++ b/itlwm/hal_iwn/ItlIwn.cpp @@ -1755,7 +1755,7 @@ iwn_read_eeprom_enhinfo(struct iwn_softc *sc) memset(sc->enh_maxpwr, 0, sizeof sc->enh_maxpwr); for (i = 0; i < nitems(enhinfo); i++) { - if (enhinfo[i].chan == 0 || enhinfo[i].reserved != 0) + if ((enhinfo[i].flags & IWN_TXP_VALID) == 0) continue; /* Skip invalid entries. */ maxpwr = 0; diff --git a/itlwm/hal_iwn/if_iwnreg.h b/itlwm/hal_iwn/if_iwnreg.h index c1942249c..f89a392c0 100644 --- a/itlwm/hal_iwn/if_iwnreg.h +++ b/itlwm/hal_iwn/if_iwnreg.h @@ -1727,9 +1727,18 @@ struct iwn_eeprom_chan { } __packed; struct iwn_eeprom_enhinfo { - uint16_t chan; + uint8_t flags; +#define IWN_TXP_VALID (1 << 0) +#define IWN_TXP_BAND_52G (1 << 1) +#define IWN_TXP_OFDM (1 << 2) +#define IWN_TXP_40MHZ (1 << 3) +#define IWN_TXP_HT_AP (1 << 4) +#define IWN_TXP_RES1 (1 << 5) +#define IWN_TXP_RES2 (1 << 6) +#define IWN_TXP_COMMON_TYPE (1 << 7) + uint8_t chan; int8_t chain[3]; /* max power in half-dBm */ - uint8_t reserved; + uint8_t delta_20_in_40; int8_t mimo2; /* max power in half-dBm */ int8_t mimo3; /* max power in half-dBm */ } __packed; From d945ecba43784882290f21eb02544fa998b33548 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Sat, 16 Mar 2024 17:00:40 +0800 Subject: [PATCH 100/114] iwn: send block ack request frames with the firmware node. #906 https://github.com/openbsd/src/commit/636ec488178eed9182b9460b924adc82e17d178c --- itlwm/hal_iwn/ItlIwn.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/itlwm/hal_iwn/ItlIwn.cpp b/itlwm/hal_iwn/ItlIwn.cpp index 867cc6f62..63bec7295 100644 --- a/itlwm/hal_iwn/ItlIwn.cpp +++ b/itlwm/hal_iwn/ItlIwn.cpp @@ -3597,7 +3597,10 @@ iwn_tx(struct iwn_softc *sc, mbuf_t m, struct ieee80211_node *ni) } } - if (IEEE80211_IS_MULTICAST(wh->i_addr1) || + if (type == IEEE80211_FC0_TYPE_CTL && + subtype == IEEE80211_FC0_SUBTYPE_BAR) + tx->id = wn->id; + else if (IEEE80211_IS_MULTICAST(wh->i_addr1) || type != IEEE80211_FC0_TYPE_DATA) tx->id = sc->broadcast_id; else From 91aba139aa83a4584fb36fcd12f00f633846d786 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Sun, 17 Mar 2024 11:56:39 +0800 Subject: [PATCH 101/114] iwn: Only set first two tx attempts to 40MHz/SGI on IWN_CMD_LINK_QUALITY command. --- itlwm/hal_iwn/ItlIwn.cpp | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/itlwm/hal_iwn/ItlIwn.cpp b/itlwm/hal_iwn/ItlIwn.cpp index 63bec7295..f5e191bf5 100644 --- a/itlwm/hal_iwn/ItlIwn.cpp +++ b/itlwm/hal_iwn/ItlIwn.cpp @@ -4064,17 +4064,12 @@ iwn_set_link_quality(struct iwn_softc *sc, struct ieee80211_node *ni) if (sc->hw_type != IWN_HW_REV_TYPE_4965) linkq.flags |= IWN_LINK_QUAL_FLAGS_SET_STA_TLC_RTS; - if (ieee80211_node_supports_ht_sgi20(ni)) { + if (ieee80211_node_supports_ht_sgi20(ni)) sgi_ok = 1; - } - + if (ni->ni_chw == IEEE80211_CHAN_WIDTH_40) { is_40mhz = 1; - if (ieee80211_node_supports_ht_sgi40(ni)) { - sgi_ok = 1; - } else { - sgi_ok = 0; - } + sgi_ok = ieee80211_node_supports_ht_sgi40(ni); } /* @@ -4108,15 +4103,17 @@ iwn_set_link_quality(struct iwn_softc *sc, struct ieee80211_node *ni) for (i = ni->ni_txmcs; i >= 0; i--) { if (isclr(ni->ni_rxmcs, i)) continue; - if (ridx == iwn_mcs2ridx[i]) { - tab = ht_plcp; - rflags |= IWN_RFLAG_MCS; - if (sgi_ok) - rflags |= IWN_RFLAG_SGI; - if (is_40mhz) - rflags |= IWN_RFLAG_HT40; + if (ridx != iwn_mcs2ridx[i]) + continue; + tab = ht_plcp; + rflags |= IWN_RFLAG_MCS; + /* First two Tx attempts may use 40MHz/SGI. */ + if (j > 1) break; - } + if (is_40mhz) + rflags |= IWN_RFLAG_HT40; + if (sgi_ok) + rflags |= IWN_RFLAG_SGI; } } else if (plcp != IWN_RATE_INVM_PLCP) { for (i = ni->ni_txrate; i >= 0; i--) { From ae9572e000d4ee77dba221a17221e745af44be98 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Mon, 18 Mar 2024 00:19:31 +0800 Subject: [PATCH 102/114] iwm: simplify MGMT frames rate filling logic. --- itlwm/hal_iwm/mac80211.cpp | 80 +++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/itlwm/hal_iwm/mac80211.cpp b/itlwm/hal_iwm/mac80211.cpp index 5074440ec..9b0774951 100644 --- a/itlwm/hal_iwm/mac80211.cpp +++ b/itlwm/hal_iwm/mac80211.cpp @@ -1539,6 +1539,25 @@ iwm_rx_bmiss(struct iwm_softc *sc, struct iwm_rx_packet *pkt, } +static int +iwm_rate2ridx(struct iwm_softc *sc, int rate) +{ + struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211_node *ni = ic->ic_bss; + int ridx = -1, i; + + int min_ridx = (IEEE80211_IS_CHAN_5GHZ(ni->ni_chan)) ? + IWL_FIRST_OFDM_RATE : IWL_FIRST_CCK_RATE; + + for (i = 0; i < ieee80211_std_rateset_11g.rs_nrates; i++) { + if (ieee80211_std_rateset_11g.rs_rates[i] == rate) { + ridx = i; + break; + } + } + return ridx == -1 ? min_ridx : ridx; +} + /* * Fill in various bit for management frames, and leave them * unfilled for data frames (firmware takes care of that). @@ -1553,54 +1572,35 @@ iwm_tx_fill_cmd(struct iwm_softc *sc, struct iwm_node *in, int type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; int subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; int ridx = -1, rate_flags; - int min_ridx = (IEEE80211_IS_CHAN_5GHZ(ni->ni_chan)) ? - IWL_FIRST_OFDM_RATE : IWL_FIRST_CCK_RATE; - int i; + int min_ridx = iwm_rate2ridx(sc, ieee80211_min_basic_rate(ic)); - int min_rate = ieee80211_min_basic_rate(ic); - for (i = 0; i < ieee80211_std_rateset_11g.rs_nrates; i++) { - if (ieee80211_std_rateset_11g.rs_rates[i] == min_rate) { - min_ridx = i; - break; - } - } - tx->rts_retry_limit = IWM_RTS_DFAULT_RETRY_LIMIT; - if (type == IEEE80211_FC0_TYPE_CTL && subtype == IEEE80211_FC0_SUBTYPE_BAR) + if (type == IEEE80211_FC0_TYPE_CTL && + subtype == IEEE80211_FC0_SUBTYPE_BAR) tx->data_retry_limit = IWM_BAR_DFAULT_RETRY_LIMIT; else tx->data_retry_limit = IWM_DEFAULT_TX_RETRY; - /* - * for data packets, rate info comes from the table inside the fw. This - * table is controlled by LINK_QUALITY commands - */ - if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && - type == IEEE80211_FC0_TYPE_DATA) { - tx->initial_rate_index = 0; - tx->tx_flags |= cpu_to_le32(IWM_TX_CMD_FLG_STA_RATE); - return &iwl_rates[ridx]; - } else if (type == IEEE80211_FC0_TYPE_CTL && - subtype == IEEE80211_FC0_SUBTYPE_BAR) - tx->tx_flags |= htole32(IWM_TX_CMD_FLG_ACK | IWM_TX_CMD_FLG_BAR); - - if (ic->ic_fixed_mcs != -1 || - ic->ic_fixed_rate != -1) - ridx = sc->sc_fixed_ridx; - else { + if (IEEE80211_IS_MULTICAST(wh->i_addr1) || + type != IEEE80211_FC0_TYPE_DATA) { + /* for non-data, use the lowest supported rate */ + ridx = min_ridx; + tx->data_retry_limit = IWM_MGMT_DFAULT_RETRY_LIMIT; + } else if (ic->ic_fixed_mcs != -1) { if (ni->ni_flags & IEEE80211_NODE_VHT) - ridx = iwm_mcs2ridx[ni->ni_txmcs]; - else if (ni->ni_flags & IEEE80211_NODE_HT) - ridx = iwm_mcs2ridx[ni->ni_txmcs % 8]; - else { - for (i = 0; i < ieee80211_std_rateset_11g.rs_nrates; i++) { - if (ieee80211_std_rateset_11g.rs_rates[i] == ni->ni_txrate) { - ridx = i; - break; - } - } - } + ridx = IWL_FIRST_OFDM_RATE; + else + ridx = sc->sc_fixed_ridx; + } else if (ic->ic_fixed_rate != -1) { + ridx = sc->sc_fixed_ridx; + } else { + /* Use firmware rateset retry table. */ + tx->initial_rate_index = 0; + tx->tx_flags |= htole32(IWM_TX_CMD_FLG_STA_RATE); + if (ni->ni_flags & IEEE80211_NODE_HT) /* VHT implies HT */ + return 0; + return &iwl_rates[iwm_rate2ridx(sc, ni->ni_txrate)]; } if (ridx == -1 || ridx >= IWL_RATE_COUNT_LEGACY) From 32fb6937e1a013ec163844ca7d81d29c25f7f28e Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Mon, 18 Mar 2024 22:15:17 +0800 Subject: [PATCH 103/114] Update firmware license. --- iwlwifi-firmware-license | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iwlwifi-firmware-license b/iwlwifi-firmware-license index 497ee18b1..6bdd16d92 100644 --- a/iwlwifi-firmware-license +++ b/iwlwifi-firmware-license @@ -1,4 +1,4 @@ -Copyright (c) 2019, Intel Corporation. +Copyright (c) 2006-2021, Intel Corporation. All rights reserved. Redistribution. Redistribution and use in binary form, without From 9d5145d2155355ccade7d235e44a161c43425448 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Mon, 18 Mar 2024 22:47:34 +0800 Subject: [PATCH 104/114] ra: access good put stats array before mcs value check. --- itl80211/openbsd/net80211/ieee80211_ra.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/itl80211/openbsd/net80211/ieee80211_ra.c b/itl80211/openbsd/net80211/ieee80211_ra.c index 4e1bd00ca..323dfa092 100644 --- a/itl80211/openbsd/net80211/ieee80211_ra.c +++ b/itl80211/openbsd/net80211/ieee80211_ra.c @@ -744,7 +744,7 @@ ieee80211_ra_add_stats_ht(struct ieee80211_ra_node *rn, static const uint64_t alpha = RA_FP_1 / 8; /* 1/8 = 0.125 */ static const uint64_t beta = RA_FP_1 / 4; /* 1/4 = 0.25 */ int s; - struct ieee80211_ra_goodput_stats *g = &rn->g[mcs]; + struct ieee80211_ra_goodput_stats *g; uint64_t sfer, rate, delta; /* @@ -758,6 +758,7 @@ ieee80211_ra_add_stats_ht(struct ieee80211_ra_node *rn, s = splnet(); + g = &rn->g[mcs]; g->nprobe_pkts += total; g->nprobe_fail += fail; From e48e7cbc1f8d059bb368a8881e2faf4770661514 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Mon, 18 Mar 2024 22:50:37 +0800 Subject: [PATCH 105/114] ra: don't consider sgi when trying to probe next rateset. --- itl80211/openbsd/net80211/ieee80211_ra.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/itl80211/openbsd/net80211/ieee80211_ra.c b/itl80211/openbsd/net80211/ieee80211_ra.c index 323dfa092..ff873ed44 100644 --- a/itl80211/openbsd/net80211/ieee80211_ra.c +++ b/itl80211/openbsd/net80211/ieee80211_ra.c @@ -370,8 +370,6 @@ ieee80211_ra_next_rateset(struct ieee80211_ra_node *rn, struct ieee80211com *ic, continue; if (rsnext->nss > support_nss(ni)) continue; - if (rsnext->sgi && !ieee80211_node_supports_sgi(ni)) - continue; found = true; break; } @@ -385,8 +383,6 @@ ieee80211_ra_next_rateset(struct ieee80211_ra_node *rn, struct ieee80211com *ic, continue; if (rsnext->nss > support_nss(ni)) continue; - if (rsnext->sgi && !ieee80211_node_supports_sgi(ni)) - continue; found = true; break; } From 7b8ae28d278bac1e4bfdc5b8cd4737b4977d2cf0 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Tue, 19 Mar 2024 23:47:54 +0800 Subject: [PATCH 106/114] iwn: Correct antenna numbers if NO MIMO flag is set. --- itlwm/hal_iwn/ItlIwn.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/itlwm/hal_iwn/ItlIwn.cpp b/itlwm/hal_iwn/ItlIwn.cpp index f5e191bf5..c99a94a9b 100644 --- a/itlwm/hal_iwn/ItlIwn.cpp +++ b/itlwm/hal_iwn/ItlIwn.cpp @@ -550,12 +550,12 @@ iwn_attach(struct iwn_softc *sc, struct pci_attach_args *pa) ieee80211_std_rateset_11a; } if (sc->sc_flags & IWN_FLAG_HAS_11N) { - int ntxstreams = sc->ntxchains; - int nrxstreams = sc->nrxchains; - /* Set supported HT rates. */ if (ic->ic_userflags & IEEE80211_F_NOMIMO) - ntxstreams = nrxstreams = 1; + sc->ntxchains = sc->nrxchains = 1; + + int ntxstreams = sc->ntxchains; + int nrxstreams = sc->nrxchains; ic->ic_sup_mcs[0] = 0xff; /* MCS 0-7 */ if (nrxstreams > 1) From 70ef005b9240f00b849be9c2f7dbcca0d4515ae7 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Tue, 19 Mar 2024 23:55:05 +0800 Subject: [PATCH 107/114] iwn: Correct HT40 and SGI flag using in LINK_QUALITY command. --- itl80211/openbsd/net80211/ieee80211_ra.c | 13 +++++++++++++ itl80211/openbsd/net80211/ieee80211_ra.h | 2 ++ itlwm/hal_iwn/ItlIwn.cpp | 14 +++----------- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/itl80211/openbsd/net80211/ieee80211_ra.c b/itl80211/openbsd/net80211/ieee80211_ra.c index ff873ed44..ff22b5e9e 100644 --- a/itl80211/openbsd/net80211/ieee80211_ra.c +++ b/itl80211/openbsd/net80211/ieee80211_ra.c @@ -278,6 +278,19 @@ ieee80211_ra_get_rateset(struct ieee80211_ra_node *ra, struct ieee80211com *ic, panic("%s mcs=%d rs_count=%d sgi=%d nss=%d bw=%d rate==NULL!!!!\n", __FUNCTION__, mcs, ra->active_rs_count, ra->sgi, ra->nss, ra->bw); } +int +ieee80211_ra_use_ht_sgi(struct ieee80211_node *ni) +{ + if ((ni->ni_chw == IEEE80211_CHAN_WIDTH_40) && + ieee80211_node_supports_ht_chan40(ni)) { + if (ni->ni_flags & IEEE80211_NODE_HT_SGI40) + return 1; + } else if (ni->ni_flags & IEEE80211_NODE_HT_SGI20) + return 1; + + return 0; +} + /* * Update goodput statistics. */ diff --git a/itl80211/openbsd/net80211/ieee80211_ra.h b/itl80211/openbsd/net80211/ieee80211_ra.h index f642cdc9f..a3af45f7b 100644 --- a/itl80211/openbsd/net80211/ieee80211_ra.h +++ b/itl80211/openbsd/net80211/ieee80211_ra.h @@ -117,4 +117,6 @@ void ieee80211_ra_choose(struct ieee80211_ra_node *, /* Get the HT rateset for a particular HT MCS with SGI on/off. */ const struct ieee80211_ra_rate *ieee80211_ra_get_rateset(struct ieee80211_ra_node *, struct ieee80211com *, struct ieee80211_node *, int); +/* Check whether SGI should be used. */ +int ieee80211_ra_use_ht_sgi(struct ieee80211_node *); #endif /* _NET80211_IEEE80211_RA_H_ */ diff --git a/itlwm/hal_iwn/ItlIwn.cpp b/itlwm/hal_iwn/ItlIwn.cpp index c99a94a9b..f620cac25 100644 --- a/itlwm/hal_iwn/ItlIwn.cpp +++ b/itlwm/hal_iwn/ItlIwn.cpp @@ -4047,7 +4047,7 @@ iwn_set_link_quality(struct iwn_softc *sc, struct ieee80211_node *ni) struct iwn_cmd_link_quality linkq; struct ieee80211_rateset *rs = &ni->ni_rates; uint8_t txant; - int i, ridx, ridx_min, ridx_max, j, sgi_ok = 0, is_40mhz = 0, mimo, tab = 0, rflags = 0; + int i, ridx, ridx_min, ridx_max, j, mimo, tab = 0, rflags = 0; /* Use the first valid TX antenna. */ txant = IWN_LSB(sc->txchainmask); @@ -4063,14 +4063,6 @@ iwn_set_link_quality(struct iwn_softc *sc, struct ieee80211_node *ni) if (ic->ic_flags & IEEE80211_F_USEPROT) if (sc->hw_type != IWN_HW_REV_TYPE_4965) linkq.flags |= IWN_LINK_QUAL_FLAGS_SET_STA_TLC_RTS; - - if (ieee80211_node_supports_ht_sgi20(ni)) - sgi_ok = 1; - - if (ni->ni_chw == IEEE80211_CHAN_WIDTH_40) { - is_40mhz = 1; - sgi_ok = ieee80211_node_supports_ht_sgi40(ni); - } /* * Fill the LQ rate selection table with legacy and/or HT rates @@ -4110,9 +4102,9 @@ iwn_set_link_quality(struct iwn_softc *sc, struct ieee80211_node *ni) /* First two Tx attempts may use 40MHz/SGI. */ if (j > 1) break; - if (is_40mhz) + if (iwn_rxon_ht40_enabled(sc)) rflags |= IWN_RFLAG_HT40; - if (sgi_ok) + if (ieee80211_ra_use_ht_sgi(ni)) rflags |= IWN_RFLAG_SGI; } } else if (plcp != IWN_RATE_INVM_PLCP) { From 461ab521e40a1da7928271293a5c4bed5d3afe90 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Wed, 20 Mar 2024 00:06:53 +0800 Subject: [PATCH 108/114] iwn: don't consider same MCS set if the card is configured as different Rx/Tx streams transmission. --- itlwm/hal_iwn/ItlIwn.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/itlwm/hal_iwn/ItlIwn.cpp b/itlwm/hal_iwn/ItlIwn.cpp index f620cac25..839bdc3ae 100644 --- a/itlwm/hal_iwn/ItlIwn.cpp +++ b/itlwm/hal_iwn/ItlIwn.cpp @@ -4093,7 +4093,8 @@ iwn_set_link_quality(struct iwn_softc *sc, struct ieee80211_node *ni) (!mimo && iwn_is_mimo_ht_plcp(ht_plcp))) continue; for (i = ni->ni_txmcs; i >= 0; i--) { - if (isclr(ni->ni_rxmcs, i)) + if (ic->ic_tx_mcs_set == IEEE80211_TX_MCS_SET_DEFINED && + isclr(ni->ni_rxmcs, i)) continue; if (ridx != iwn_mcs2ridx[i]) continue; From e886ebb06658d6aee70f87e30a6bbbd0acad1f57 Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Wed, 20 Mar 2024 00:43:26 +0800 Subject: [PATCH 109/114] iwn: disable RTS flag since RTS/CTS protection not yet supported and tested. --- itlwm/hal_iwn/ItlIwn.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/itlwm/hal_iwn/ItlIwn.cpp b/itlwm/hal_iwn/ItlIwn.cpp index 839bdc3ae..8da07e73d 100644 --- a/itlwm/hal_iwn/ItlIwn.cpp +++ b/itlwm/hal_iwn/ItlIwn.cpp @@ -4060,9 +4060,17 @@ iwn_set_link_quality(struct iwn_softc *sc, struct ieee80211_node *ni) linkq.ampdu_threshold = 3; linkq.ampdu_limit = htole16(4000); /* 4ms */ - if (ic->ic_flags & IEEE80211_F_USEPROT) - if (sc->hw_type != IWN_HW_REV_TYPE_4965) +#if 0 // RTS/CTS protection not yet tested + if (ni->ni_flags & IEEE80211_NODE_HT && + sc->agg_queue_mask > 0 && + ic->ic_flags & IEEE80211_F_USEPROT) + if (sc->hw_type != IWN_HW_REV_TYPE_4965 && + sc->hw_type != IWN_HW_REV_TYPE_5300 && + sc->hw_type != IWN_HW_REV_TYPE_5150 && + sc->hw_type != IWN_HW_REV_TYPE_5350 && + sc->hw_type != IWN_HW_REV_TYPE_5100) linkq.flags |= IWN_LINK_QUAL_FLAGS_SET_STA_TLC_RTS; +#endif /* * Fill the LQ rate selection table with legacy and/or HT rates From 68dcd1beabede883863b918e989ddd0f7f91bd3d Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Sun, 7 Apr 2024 22:22:16 +0800 Subject: [PATCH 110/114] Ignore ADDBA requests if we are not ready to receive data frames. --- itl80211/openbsd/net80211/ieee80211_input.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/itl80211/openbsd/net80211/ieee80211_input.c b/itl80211/openbsd/net80211/ieee80211_input.c index 72512823c..ff8d7cdd9 100644 --- a/itl80211/openbsd/net80211/ieee80211_input.c +++ b/itl80211/openbsd/net80211/ieee80211_input.c @@ -2987,6 +2987,11 @@ ieee80211_recv_addba_req(struct ieee80211com *ic, mbuf_t m, u_int8_t token, tid; int err = 0; + /* Ignore if we are not ready to receive data frames. */ + if (ic->ic_state != IEEE80211_S_RUN || + ((ic->ic_flags & IEEE80211_F_RSNON) && !ni->ni_port_valid)) + return; + if (!(ni->ni_flags & IEEE80211_NODE_HT)) { DPRINTF(("received ADDBA req from non-HT STA %s\n", ether_sprintf(ni->ni_macaddr))); From 4ac4c79bc7e34f8764038fc382630a29eb46213d Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Thu, 2 May 2024 15:32:33 +0800 Subject: [PATCH 111/114] AirportItlwm: add missing iwx devices matches(0x7F708086 0x51F18086). --- AirportItlwm/AirportItlwm-Monterey-Info.plist | 2 +- AirportItlwm/AirportItlwm-Sonoma-Info.plist | 6 +++--- AirportItlwm/Info.plist | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/AirportItlwm/AirportItlwm-Monterey-Info.plist b/AirportItlwm/AirportItlwm-Monterey-Info.plist index 12ff0cd3e..449a090c8 100644 --- a/AirportItlwm/AirportItlwm-Monterey-Info.plist +++ b/AirportItlwm/AirportItlwm-Monterey-Info.plist @@ -29,7 +29,7 @@ IOMatchCategory IODefaultMatchCategory IOPCIMatch - 0x27238086 0x43F08086 0xA0F08086 0x34F08086 0x4DF08086 0x02F08086 0x3DF08086 0x06F08086 0x27208086 0x08b18086 0x08b28086 0x08b38086 0x08b48086 0x095a8086 0x095b8086 0x31658086 0x31668086 0x24f38086 0x24f48086 0x24f58086 0x24f68086 0x24fb8086 0x24fd8086 0x25268086 0x9df08086 0xa3708086 0x31DC8086 0x30DC8086 0x271C8086 0x271B8086 0x42a48086 0x00a08086 0x00a48086 0x02a08086 0x40a48086 0x00608086 0x00648086 0x02608086 0x02648086 0x42298086 0x422b8086 0x422c8086 0x42308086 0x42328086 0x42358086 0x42368086 0x42378086 0x42388086 0x42398086 0x423a8086 0x423b8086 0x423c8086 0x423d8086 0x00828086 0x00838086 0x00848086 0x00858086 0x00878086 0x00898086 0x008a8086 0x008b8086 0x00908086 0x00918086 0x08928086 0x08938086 0x08948086 0x08958086 0x08968086 0x08978086 0x08ae8086 0x08af8086 0x088e8086 0x088f8086 0x08908086 0x08918086 0x08878086 0x08888086 0x27258086 0x27268086 0x7A708086 0x7AF08086 0x51F08086 0x54F08086 0x27298086 0x7E408086 + 0x27238086 0x43F08086 0xA0F08086 0x34F08086 0x4DF08086 0x02F08086 0x3DF08086 0x06F08086 0x27208086 0x08b18086 0x08b28086 0x08b38086 0x08b48086 0x095a8086 0x095b8086 0x31658086 0x31668086 0x24f38086 0x24f48086 0x24f58086 0x24f68086 0x24fb8086 0x24fd8086 0x25268086 0x9df08086 0xa3708086 0x31DC8086 0x30DC8086 0x271C8086 0x271B8086 0x42a48086 0x00a08086 0x00a48086 0x02a08086 0x40a48086 0x00608086 0x00648086 0x02608086 0x02648086 0x42298086 0x422b8086 0x422c8086 0x42308086 0x42328086 0x42358086 0x42368086 0x42378086 0x42388086 0x42398086 0x423a8086 0x423b8086 0x423c8086 0x423d8086 0x00828086 0x00838086 0x00848086 0x00858086 0x00878086 0x00898086 0x008a8086 0x008b8086 0x00908086 0x00918086 0x08928086 0x08938086 0x08948086 0x08958086 0x08968086 0x08978086 0x08ae8086 0x08af8086 0x088e8086 0x088f8086 0x08908086 0x08918086 0x08878086 0x08888086 0x27258086 0x27268086 0x7A708086 0x7AF08086 0x51F08086 0x54F08086 0x27298086 0x7E408086 0x7F708086 0x51F18086 IOProbeScore 2000 IOProviderClass diff --git a/AirportItlwm/AirportItlwm-Sonoma-Info.plist b/AirportItlwm/AirportItlwm-Sonoma-Info.plist index 91560253d..22b8e0789 100644 --- a/AirportItlwm/AirportItlwm-Sonoma-Info.plist +++ b/AirportItlwm/AirportItlwm-Sonoma-Info.plist @@ -44,7 +44,7 @@ IOClass IOPCIEDeviceWrapper IOPCIMatch - 0x27238086 0x43F08086 0xA0F08086 0x34F08086 0x4DF08086 0x02F08086 0x3DF08086 0x06F08086 0x27208086 0x08b18086 0x08b28086 0x08b38086 0x08b48086 0x095a8086 0x095b8086 0x31658086 0x31668086 0x24f38086 0x24f48086 0x24f58086 0x24f68086 0x24fb8086 0x24fd8086 0x25268086 0x9df08086 0xa3708086 0x31DC8086 0x30DC8086 0x271C8086 0x271B8086 0x42a48086 0x00a08086 0x00a48086 0x02a08086 0x40a48086 0x00608086 0x00648086 0x02608086 0x02648086 0x42298086 0x422b8086 0x422c8086 0x42308086 0x42328086 0x42358086 0x42368086 0x42378086 0x42388086 0x42398086 0x423a8086 0x423b8086 0x423c8086 0x423d8086 0x00828086 0x00838086 0x00848086 0x00858086 0x00878086 0x00898086 0x008a8086 0x008b8086 0x00908086 0x00918086 0x08928086 0x08938086 0x08948086 0x08958086 0x08968086 0x08978086 0x08ae8086 0x08af8086 0x088e8086 0x088f8086 0x08908086 0x08918086 0x08878086 0x08888086 0x27258086 0x27268086 0x7A708086 0x7AF08086 0x51F08086 0x54F08086 0x27298086 0x7E408086 + 0x27238086 0x43F08086 0xA0F08086 0x34F08086 0x4DF08086 0x02F08086 0x3DF08086 0x06F08086 0x27208086 0x08b18086 0x08b28086 0x08b38086 0x08b48086 0x095a8086 0x095b8086 0x31658086 0x31668086 0x24f38086 0x24f48086 0x24f58086 0x24f68086 0x24fb8086 0x24fd8086 0x25268086 0x9df08086 0xa3708086 0x31DC8086 0x30DC8086 0x271C8086 0x271B8086 0x42a48086 0x00a08086 0x00a48086 0x02a08086 0x40a48086 0x00608086 0x00648086 0x02608086 0x02648086 0x42298086 0x422b8086 0x422c8086 0x42308086 0x42328086 0x42358086 0x42368086 0x42378086 0x42388086 0x42398086 0x423a8086 0x423b8086 0x423c8086 0x423d8086 0x00828086 0x00838086 0x00848086 0x00858086 0x00878086 0x00898086 0x008a8086 0x008b8086 0x00908086 0x00918086 0x08928086 0x08938086 0x08948086 0x08958086 0x08968086 0x08978086 0x08ae8086 0x08af8086 0x088e8086 0x088f8086 0x08908086 0x08918086 0x08878086 0x08888086 0x27258086 0x27268086 0x7A708086 0x7AF08086 0x51F08086 0x54F08086 0x27298086 0x7E408086 0x7F708086 0x51F18086 IOProbeScore 70000 IOProviderClass @@ -55,14 +55,14 @@ Copyright © 2020 钟先耀. All rights reserved. OSBundleLibraries + com.apple.driver.corecapture + 1.0.0 com.apple.iokit.IO80211Family 1.5.0 com.apple.iokit.IONetworkingFamily 3.2 com.apple.iokit.IOPCIFamily 2.9 - com.apple.driver.corecapture - 1.0.0 com.apple.iokit.IOSkywalkFamily 1.0 com.apple.kpi.bsd diff --git a/AirportItlwm/Info.plist b/AirportItlwm/Info.plist index 32b101b16..6286d0a8a 100644 --- a/AirportItlwm/Info.plist +++ b/AirportItlwm/Info.plist @@ -29,7 +29,7 @@ IOMatchCategory IODefaultMatchCategory IOPCIMatch - 0x27238086 0x43F08086 0xA0F08086 0x34F08086 0x4DF08086 0x02F08086 0x3DF08086 0x06F08086 0x27208086 0x08b18086 0x08b28086 0x08b38086 0x08b48086 0x095a8086 0x095b8086 0x31658086 0x31668086 0x24f38086 0x24f48086 0x24f58086 0x24f68086 0x24fb8086 0x24fd8086 0x25268086 0x9df08086 0xa3708086 0x31DC8086 0x30DC8086 0x271C8086 0x271B8086 0x42a48086 0x00a08086 0x00a48086 0x02a08086 0x40a48086 0x00608086 0x00648086 0x02608086 0x02648086 0x42298086 0x422b8086 0x422c8086 0x42308086 0x42328086 0x42358086 0x42368086 0x42378086 0x42388086 0x42398086 0x423a8086 0x423b8086 0x423c8086 0x423d8086 0x00828086 0x00838086 0x00848086 0x00858086 0x00878086 0x00898086 0x008a8086 0x008b8086 0x00908086 0x00918086 0x08928086 0x08938086 0x08948086 0x08958086 0x08968086 0x08978086 0x08ae8086 0x08af8086 0x088e8086 0x088f8086 0x08908086 0x08918086 0x08878086 0x08888086 0x27258086 0x27268086 0x7A708086 0x7AF08086 0x51F08086 0x54F08086 0x27298086 0x7E408086 + 0x27238086 0x43F08086 0xA0F08086 0x34F08086 0x4DF08086 0x02F08086 0x3DF08086 0x06F08086 0x27208086 0x08b18086 0x08b28086 0x08b38086 0x08b48086 0x095a8086 0x095b8086 0x31658086 0x31668086 0x24f38086 0x24f48086 0x24f58086 0x24f68086 0x24fb8086 0x24fd8086 0x25268086 0x9df08086 0xa3708086 0x31DC8086 0x30DC8086 0x271C8086 0x271B8086 0x42a48086 0x00a08086 0x00a48086 0x02a08086 0x40a48086 0x00608086 0x00648086 0x02608086 0x02648086 0x42298086 0x422b8086 0x422c8086 0x42308086 0x42328086 0x42358086 0x42368086 0x42378086 0x42388086 0x42398086 0x423a8086 0x423b8086 0x423c8086 0x423d8086 0x00828086 0x00838086 0x00848086 0x00858086 0x00878086 0x00898086 0x008a8086 0x008b8086 0x00908086 0x00918086 0x08928086 0x08938086 0x08948086 0x08958086 0x08968086 0x08978086 0x08ae8086 0x08af8086 0x088e8086 0x088f8086 0x08908086 0x08918086 0x08878086 0x08888086 0x27258086 0x27268086 0x7A708086 0x7AF08086 0x51F08086 0x54F08086 0x27298086 0x7E408086 0x7F708086 0x51F18086 IOProbeScore 2000 IOProviderClass From 53c51c2cdd6e4b69beb91f310d74c53422b0f8bd Mon Sep 17 00:00:00 2001 From: zxystd <1051244836@qq.com> Date: Sun, 9 Jun 2024 15:19:03 +0800 Subject: [PATCH 112/114] bump version to 2.4.0. --- itlwm.xcodeproj/project.pbxproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/itlwm.xcodeproj/project.pbxproj b/itlwm.xcodeproj/project.pbxproj index 7473cdb88..6b5a7b446 100644 --- a/itlwm.xcodeproj/project.pbxproj +++ b/itlwm.xcodeproj/project.pbxproj @@ -3313,7 +3313,7 @@ KERNEL_EXTENSION_HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/MacKernelSDK/Headers"; KERNEL_FRAMEWORK_HEADERS = "$(PROJECT_DIR)/MacKernelSDK/Headers"; MACOSX_DEPLOYMENT_TARGET = 10.12; - MODULE_VERSION = 2.3.0; + MODULE_VERSION = 2.4.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; OTHER_CPLUSPLUSFLAGS = ( @@ -3381,7 +3381,7 @@ KERNEL_EXTENSION_HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/MacKernelSDK/Headers"; KERNEL_FRAMEWORK_HEADERS = "$(PROJECT_DIR)/MacKernelSDK/Headers"; MACOSX_DEPLOYMENT_TARGET = 10.12; - MODULE_VERSION = 2.3.0; + MODULE_VERSION = 2.4.0; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; OTHER_CPLUSPLUSFLAGS = ( From 18aa204b9d2e878a29d014f1bfcebe18741852e8 Mon Sep 17 00:00:00 2001 From: serejaishkin <47511319+serejaishkin@users.noreply.github.com> Date: Thu, 2 Apr 2026 16:01:43 +0300 Subject: [PATCH 113/114] Update AirportItlwm for Sequoia --- AirportItlwm/AirportItlwmSkywalkInterface.hpp | 260 +----------------- AirportItlwm/AirportItlwm_Sequoia.cpp | 78 ++++++ AirportItlwm/AirportItlwm_Sequoia.hpp | 36 +++ AirportItlwm/Info.plist | 72 ++--- 4 files changed, 134 insertions(+), 312 deletions(-) create mode 100644 AirportItlwm/AirportItlwm_Sequoia.cpp create mode 100644 AirportItlwm/AirportItlwm_Sequoia.hpp diff --git a/AirportItlwm/AirportItlwmSkywalkInterface.hpp b/AirportItlwm/AirportItlwmSkywalkInterface.hpp index 12d8c93a0..6f2604f87 100644 --- a/AirportItlwm/AirportItlwmSkywalkInterface.hpp +++ b/AirportItlwm/AirportItlwmSkywalkInterface.hpp @@ -1,11 +1,3 @@ -// -// AirportItlwmSkywalkInterface.hpp -// AirportItlwm-Sonoma -// -// Created by qcwap on 2023/6/27. -// Copyright © 2023 钟先耀. All rights reserved. -// - #ifndef AirportItlwmSkywalkInterface_hpp #define AirportItlwmSkywalkInterface_hpp @@ -13,261 +5,17 @@ class AirportItlwmSkywalkInterface : public IO80211InfraProtocol { OSDeclareDefaultStructors(AirportItlwmSkywalkInterface) - + public: virtual bool init(IOService *) override; -// virtual ifnet_t getBSDInterface(void) override; - + void associateSSID(uint8_t *ssid, uint32_t ssid_len, const struct ether_addr &bssid, uint32_t authtype_lower, uint32_t authtype_upper, uint8_t *key, uint32_t key_len, int key_index); void setPTK(const u_int8_t *key, size_t key_len); void setGTK(const u_int8_t *key, size_t key_len, u_int8_t kid, u_int8_t *rsc); - + public: virtual IOReturn getSSID(apple80211_ssid_data *) override; virtual IOReturn getAUTH_TYPE(apple80211_authtype_data *) override; - virtual IOReturn getCHANNEL(apple80211_channel_data *) override; - virtual IOReturn getPOWERSAVE(apple80211_powersave_data *) override; - virtual IOReturn getTXPOWER(apple80211_txpower_data *) override; - virtual IOReturn getRATE(apple80211_rate_data *) override; - virtual IOReturn getBSSID(apple80211_bssid_data *) override; - virtual IOReturn getSCAN_RESULT(apple80211_scan_result *) override; - virtual IOReturn getSTATE(apple80211_state_data *) override; - virtual IOReturn getPHY_MODE(apple80211_phymode_data *) override; - virtual IOReturn getOP_MODE(apple80211_opmode_data *) override; - virtual IOReturn getRSSI(apple80211_rssi_data *) override; - virtual IOReturn getNOISE(apple80211_noise_data *) override; - virtual IOReturn getSUPPORTED_CHANNELS(apple80211_sup_channel_data *) override; - virtual IOReturn getLOCALE(apple80211_locale_data *) override; - virtual IOReturn getDEAUTH(apple80211_deauth_data *) override; - virtual IOReturn getRATE_SET(apple80211_rate_set_data *) override; - virtual IOReturn getDTIM_INT(apple80211_dtim_int_data *) override { return kIOReturnUnsupported; } - virtual IOReturn getSTATION_LIST(apple80211_sta_data *) override { return kIOReturnUnsupported; } - virtual IOReturn getRSN_IE(apple80211_rsn_ie_data *) override; - virtual IOReturn getAP_IE_LIST(apple80211_ap_ie_data *) override; - virtual IOReturn getSTATS(apple80211_stats_data *) override { return kIOReturnUnsupported; } - virtual IOReturn getASSOCIATION_STATUS(apple80211_assoc_status_data *) override; - virtual IOReturn getGUARD_INTERVAL(apple80211_guard_interval_data *) override { return kIOReturnUnsupported; } - virtual IOReturn getMCS(apple80211_mcs_data *) override; - virtual IOReturn getMCS_INDEX_SET(apple80211_mcs_index_set_data *) override; - virtual IOReturn getWOW_PARAMETERS(apple80211_wow_parameter_data *) override { return kIOReturnUnsupported; } - virtual IOReturn getWOW_ENABLED(apple80211_state_data *) override { return kIOReturnUnsupported; } - virtual IOReturn getPID_LOCK(apple80211_state_data *) override { return kIOReturnUnsupported; } - virtual IOReturn getSTA_IE_LIST(apple80211_sta_ie_data *) override { return kIOReturnUnsupported; } - virtual IOReturn getSTA_STATS(apple80211_sta_stats_data *) override { return kIOReturnUnsupported; } - virtual IOReturn getBT_COEX_FLAGS(apple80211_state_data *) override { return kIOReturnUnsupported; } - virtual IOReturn getCURRENT_NETWORK(apple80211_scan_result *) override; - virtual IOReturn getRSSI_BOUNDS(apple80211_rssi_bounds_data *) override { return kIOReturnUnsupported; } - virtual IOReturn getPOWER_DEBUG_INFO(apple80211_power_debug_info *) override { return kIOReturnUnsupported; } - virtual IOReturn getHT_CAPABILITY(apple80211_ht_capability *) override { return kIOReturnUnsupported; } - virtual IOReturn getLINK_CHANGED_EVENT_DATA(apple80211_link_changed_event_data *) override; - virtual IOReturn getEXTENDED_STATS(apple80211_extended_stats *) override { return kIOReturnUnsupported; } - virtual IOReturn getBEACON_PERIOD(apple80211_beacon_period_data *) override { return kIOReturnUnsupported; } - virtual IOReturn getVHT_MCS_INDEX_SET(apple80211_vht_mcs_index_set_data *) override; - virtual IOReturn getMCS_VHT(apple80211_mcs_vht_data *) override; - virtual IOReturn getGAS_RESULTS(apple80211_gas_result_t *) override { return kIOReturnUnsupported; } - virtual IOReturn getCHANNELS_INFO(apple80211_channels_info *) override { return kIOReturnUnsupported; } - virtual IOReturn getVHT_CAPABILITY(apple80211_vht_capability *) override { return kIOReturnUnsupported; } - virtual IOReturn getBGSCAN_CACHE_RESULTS(apple80211_bgscan_cached_network_data_list *) override { return kIOReturnUnsupported; } - virtual IOReturn getROAM_PROFILE(apple80211_roam_profile_band_data *) override { return kIOReturnUnsupported; } - virtual IOReturn getCHIP_COUNTER_STATS(apple80211_chip_stats *) override { return kIOReturnUnsupported; } - virtual IOReturn getDBG_GUARD_TIME_PARAMS(apple80211_dbg_guard_time_params *) override { return kIOReturnUnsupported; } - virtual IOReturn getLEAKY_AP_STATS_MODE(apple80211_leaky_ap_setting *) override { return kIOReturnUnsupported; } - virtual IOReturn getCOUNTRY_CHANNELS(apple80211_country_channel_data *) override { return kIOReturnUnsupported; } - virtual IOReturn getPRIVATE_MAC(apple80211_private_mac_data *) override { return kIOReturnUnsupported; } - virtual IOReturn getRANGING_ENABLE(apple80211_ranging_enable_request_t *) override { return kIOReturnUnsupported; } - virtual IOReturn getRANGING_START(apple80211_ranging_start_request_t *) override { return kIOReturnUnsupported; } - virtual IOReturn getAWDL_RSDB_CAPS(apple80211_rsdb_capability *) override { return kIOReturnUnsupported; } - virtual IOReturn getTKO_PARAMS(apple80211_tko_params *) override { return kIOReturnUnsupported; } - virtual IOReturn getTKO_DUMP(apple80211_tko_dump *) override { return kIOReturnUnsupported; } - virtual IOReturn getHW_SUPPORTED_CHANNELS(apple80211_sup_channel_data *) override { return kIOReturnUnsupported; } - virtual IOReturn getBTCOEX_PROFILE(apple80211_btcoex_profile *) override { return kIOReturnUnsupported; } - virtual IOReturn getBTCOEX_PROFILE_ACTIVE(apple80211_btcoex_profile_active_data *) override { return kIOReturnUnsupported; } - virtual IOReturn getTRAP_INFO(apple80211_trap_info_data *) override { return kIOReturnUnsupported; } - virtual IOReturn getTHERMAL_INDEX(apple80211_thermal_index_t *) override { return kIOReturnUnsupported; } - virtual IOReturn getMAX_NSS_FOR_AP(apple80211_btcoex_max_nss_for_ap_data *) override { return kIOReturnUnsupported; } - virtual IOReturn getBTCOEX_2G_CHAIN_DISABLE(apple80211_btcoex_2g_chain_disable *) override { return kIOReturnUnsupported; } - virtual IOReturn getPOWER_BUDGET(apple80211_power_budget_t *) override { return kIOReturnUnsupported; } - virtual IOReturn getOFFLOAD_TCPKA_ENABLE(apple80211_offload_tcpka_enable_t *) override { return kIOReturnUnsupported; } - virtual IOReturn getRANGING_CAPS(apple80211_ranging_capabilities_t *) override { return kIOReturnUnsupported; } - virtual IOReturn getSUPPRESS_SCANS(apple80211_suppress_scans_t *) override { return kIOReturnUnsupported; } - virtual IOReturn getHOST_AP_MODE_HIDDEN(apple80211_host_ap_mode_hidden_t *) override { return kIOReturnUnsupported; } - virtual IOReturn getLQM_CONFIG(apple80211_lqm_config_t *) override { return kIOReturnUnsupported; } - virtual IOReturn getTRAP_CRASHTRACER_MINI_DUMP(apple80211_trap_mini_dump_data *) override { return kIOReturnUnsupported; } - virtual IOReturn getHE_CAPABILITY(apple80211_he_capability *) override { return kIOReturnUnsupported; } - virtual IOReturn getBEACON_INFO(apple80211_beacon_info_t *) override { return kIOReturnUnsupported; } - virtual IOReturn getSOFTAP_PARAMS(apple80211_softap_params *) override { return kIOReturnUnsupported; } - virtual IOReturn getCHIP_POWER_RANGE(apple80211_chip_power_limit *) override { return kIOReturnUnsupported; } - virtual IOReturn getSOFTAP_STATS(apple80211_softap_stats *) override { return kIOReturnUnsupported; } - virtual IOReturn getNSS(apple80211_nss_data *) override; - virtual IOReturn getHW_ADDR(apple80211_hw_mac_address *) override { return kIOReturnUnsupported; } - virtual IOReturn getHE_MCS_INDEX_SET(apple80211_he_mcs_index_set_data *) override { return kIOReturnUnsupported; } - virtual IOReturn getCHIP_DIAGS(appl80211_chip_diags_data *) override { return kIOReturnUnsupported; } - virtual IOReturn getHP2P_CTRL(apple80211_hp2p_ctrl *) override { return kIOReturnUnsupported; } - virtual IOReturn getREQUEST_BSS_BLACKLIST(void *) override { return kIOReturnUnsupported; } - virtual IOReturn getASSOC_READY_STATUS(apple80211_assoc_ready *) override { return kIOReturnUnsupported; } - virtual IOReturn getTXRX_CHAIN_INFO(apple80211_txrx_chain_info *) override { return kIOReturnUnsupported; } - virtual IOReturn getMIMO_STATUS(apple80211_mimo_status *) override { return kIOReturnUnsupported; } - virtual IOReturn getCUR_PMK(apple80211_pmk *) override { return kIOReturnUnsupported; } - virtual IOReturn getDYNSAR_DETAIL(apple80211_dynsar_detail *) override { return kIOReturnUnsupported; } - virtual IOReturn getRANDOMISATION_STATUS(apple80211_mac_randomisation_status *) override { return kIOReturnUnsupported; } - virtual IOReturn getCOUNTRY_CHANNELS_INFO(apple80211_channels_info *) override { return kIOReturnUnsupported; } - virtual IOReturn getLQM_SUMMARY(apple80211_lqm_summary *) override { return kIOReturnUnsupported; } - virtual IOReturn getCOLOCATED_NETWORK_SCOPE_ID(apple80211_colocated_network_scope_id *) override; - virtual IOReturn getBEACON_SCAN_CACHE_REQ(apple80211_scan_result *) override { return kIOReturnUnsupported; } - virtual IOReturn getSLOW_WIFI_FEATURE_ENABLED(apple80211_slow_wifi_feature_enabled *) override { return kIOReturnUnsupported; } - virtual IOReturn getCCA(apple80211_interface_cca_data *) override { return kIOReturnUnsupported; } - virtual IOReturn getRX_RATE(apple80211_rate_data *) override { return kIOReturnUnsupported; } - virtual IOReturn getTIMESYNC_INFO(apple80211_timesync_info *) override { return kIOReturnUnsupported; } - virtual IOReturn getSENSING_DATA(apple80211_sensing_data_t *) override { return kIOReturnUnsupported; } - virtual IOReturn getCOUNTRY_BAND_SUPPORT(apple80211_country_band_support *) override { return kIOReturnUnsupported; } - virtual IOReturn getWCL_FW_HOT_CHANNELS(apple80211_fw_hot_channels *) override { return kIOReturnUnsupported; } - virtual IOReturn getWCL_LOW_LATENCY_INFO(apple80211_low_latency_info *) override { return kIOReturnUnsupported; } - virtual IOReturn getWCL_BSS_INFO(apple80211_beacon_msg *) override { return kIOReturnUnsupported; } - virtual IOReturn getWCL_TRAFFIC_COUNTERS(apple80211_wcl_traffic_counters *) override { return kIOReturnUnsupported; } - virtual IOReturn getWCL_GET_TX_BLANKING_STATUS(uint *) override { return kIOReturnUnsupported; } - virtual IOReturn getSSID_TRANSITION_SUPPORT(apple80211_ssid_transition_feature_enabled *) override { return kIOReturnUnsupported; } - virtual IOReturn getWCL_VALID_CHANNEL_COUNT(unsigned long *) override { return kIOReturnUnsupported; } - virtual IOReturn getWCL_P2P_STATUS_FOR_SCAN(p2pStatusForScan *) override { return kIOReturnUnsupported; } - virtual IOReturn getWCL_CHANNELS_INFO(apple80211ChannelInfo *) override { return kIOReturnUnsupported; } - virtual IOReturn getP2P_STEERING_METRIC(apple80211_p2p_steering_metrics *) override { return kIOReturnUnsupported; } - virtual IOReturn getRSN_XE(apple80211_rsn_xe_data *) override { return kIOReturnUnsupported; } - virtual IOReturn getSIB_COEX_STATUS(apple80211_sib_coex_status *) override { return kIOReturnUnsupported; } - virtual IOReturn getWCL_EXTENDED_BSS_INFO(apple80211_extended_bss_info *) override { return kIOReturnUnsupported; } - virtual IOReturn getWCL_LOW_LATENCY_INFO_STATS(apple80211_wcl_low_latency_stats *) override { return kIOReturnUnsupported; } - virtual IOReturn getWCL_BGSCAN_CACHE_RESULT(apple80211_bgscan_cached_network_data_list *) override { return kIOReturnUnsupported; } - virtual IOReturn getWIFI_NOISE_PER_ANT(apple80211_noise_per_ant_t *) override { return kIOReturnUnsupported; } - virtual IOReturn getBLOCKED_BANDS(apple80211_blocked_bands *) override { return kIOReturnUnsupported; } - virtual IOReturn setSSID(apple80211_ssid_data *) override { return kIOReturnUnsupported; } - virtual IOReturn setAUTH_TYPE(apple80211_authtype_data *) override; - virtual IOReturn setCIPHER_KEY(apple80211_key *) override; - virtual IOReturn setCHANNEL(apple80211_channel_data *) override { return kIOReturnUnsupported; } - virtual IOReturn setPOWERSAVE(apple80211_powersave_data *) override { return kIOReturnUnsupported; } - virtual IOReturn setTXPOWER(apple80211_txpower_data *) override { return kIOReturnUnsupported; } - virtual IOReturn setRATE(apple80211_rate_data *) override { return kIOReturnUnsupported; } - virtual IOReturn setSCAN_REQ(apple80211_scan_data *) override; - virtual IOReturn setASSOCIATE(apple80211_assoc_data *) override; - virtual IOReturn setDISASSOCIATE(apple80211_disassoc_data *) override; - virtual IOReturn setIBSS_MODE(apple80211_network_data *) override { return kIOReturnUnsupported; } - virtual IOReturn setHOST_AP_MODE(apple80211_network_data *) override { return kIOReturnUnsupported; } - virtual IOReturn setAP_MODE(apple80211_apmode_data *) override { return kIOReturnUnsupported; } - virtual IOReturn setDEAUTH(apple80211_deauth_data *) override; - virtual IOReturn setTX_ANTENNA(void *) override { return kIOReturnUnsupported; } - virtual IOReturn setANTENNA_DIVERSITY(void *) override { return kIOReturnUnsupported; } - virtual IOReturn setRSN_IE(apple80211_rsn_ie_data *) override; - virtual IOReturn setBACKGROUND_SCAN(apple80211_bgscan_data *) override { return kIOReturnUnsupported; } - virtual IOReturn setWOW_PARAMETERS(apple80211_wow_parameter_data *) override { return kIOReturnUnsupported; } - virtual IOReturn setWOW_ENABLED(apple80211_state_data *) override { return kIOReturnUnsupported; } - virtual IOReturn setPID_LOCK(apple80211_state_data *) override { return kIOReturnUnsupported; } - virtual IOReturn setSTA_AUTHORIZE(apple80211_sta_authorize_data *) override { return kIOReturnUnsupported; } - virtual IOReturn setSTA_DISASSOCIATE(apple80211_sta_disassoc_data *) override { return kIOReturnUnsupported; } - virtual IOReturn setSTA_DEAUTH(apple80211_sta_disassoc_data *) override { return kIOReturnUnsupported; } - virtual IOReturn setRSN_CONF(apple80211_rsn_conf_data *) override { return kIOReturnUnsupported; } - virtual IOReturn setIE(apple80211_ie_data *) override { return kIOReturnUnsupported; } - virtual IOReturn setWOW_TEST(apple80211_wow_test_data *) override { return kIOReturnUnsupported; } - virtual IOReturn setSCANCACHE_CLEAR(void *) override; - virtual IOReturn setVIRTUAL_IF_CREATE(apple80211_virt_if_create_data *) override { return kIOReturnUnsupported; } - virtual IOReturn setBT_COEX_FLAGS(apple80211_state_data *) override { return kIOReturnUnsupported; } - virtual IOReturn setROAM(apple80211_sta_roam_data *) override { return kIOReturnUnsupported; } - virtual IOReturn setHT_CAPABILITY(apple80211_ht_capability *) override { return kIOReturnUnsupported; } - virtual IOReturn setAWDL_FORCED_ROAM_CONFIG(apple80211_awdl_forced_roam_config *) override { return kIOReturnUnsupported; } - virtual IOReturn setOFFLOAD_ARP(apple80211_offload_arp_data *) override { return kIOReturnUnsupported; } - virtual IOReturn setOFFLOAD_NDP(apple80211_offload_ndp_data *) override { return kIOReturnUnsupported; } - virtual IOReturn setOFFLOAD_SCAN(apple80211_offload_scan_data *) override { return kIOReturnUnsupported; } - virtual IOReturn setGAS_REQ(apple80211_gas_query_t *) override { return kIOReturnUnsupported; } - virtual IOReturn setGAS_START(apple80211_gas_query_t *) override { return kIOReturnUnsupported; } - virtual IOReturn setGAS_SET_PEER(apple80211_gas_peer_t *) override { return kIOReturnUnsupported; } - virtual IOReturn setVHT_CAPABILITY(apple80211_vht_capability *) override { return kIOReturnUnsupported; } - virtual IOReturn setROAM_PROFILE(apple80211_roam_profile_band_data *) override { return kIOReturnUnsupported; } - virtual IOReturn setAWDL_ENABLE_ROAMING(void *) override { return kIOReturnUnsupported; } - virtual IOReturn setDBG_GUARD_TIME_PARAMS(apple80211_dbg_guard_time_params *) override { return kIOReturnUnsupported; } - virtual IOReturn setLEAKY_AP_STATS_MODE(apple80211_leaky_ap_setting *) override { return kIOReturnUnsupported; } - virtual IOReturn setPRIVATE_MAC(apple80211_private_mac_data *) override { return kIOReturnUnsupported; } - virtual IOReturn setRESET_CHIP(apple80211_reset_command *) override { return kIOReturnUnsupported; } - virtual IOReturn setCRASH(apple80211_crash_command *) override { return kIOReturnUnsupported; } - virtual IOReturn setRANGING_ENABLE(apple80211_ranging_enable_request_t *) override { return kIOReturnUnsupported; } - virtual IOReturn setRANGING_START(apple80211_ranging_start_request_t *) override { return kIOReturnUnsupported; } - virtual IOReturn setRANGING_AUTHENTICATE(apple80211_ranging_authenticate_request_t *) override { return kIOReturnUnsupported; } - virtual IOReturn setTKO_PARAMS(apple80211_tko_params *) override { return kIOReturnUnsupported; } - virtual IOReturn setBTCOEX_PROFILE(apple80211_btcoex_profile *) override { return kIOReturnUnsupported; } - virtual IOReturn setBTCOEX_PROFILE_ACTIVE(apple80211_btcoex_profile_active_data *) override { return kIOReturnUnsupported; } - virtual IOReturn setTHERMAL_INDEX(apple80211_thermal_index_t *) override { return kIOReturnUnsupported; } - virtual IOReturn setBTCOEX_2G_CHAIN_DISABLE(apple80211_btcoex_2g_chain_disable *) override { return kIOReturnUnsupported; } - virtual IOReturn setPOWER_BUDGET(apple80211_power_budget_t *) override { return kIOReturnUnsupported; } - virtual IOReturn setOFFLOAD_TCPKA_ENABLE(apple80211_offload_tcpka_enable_t *) override { return kIOReturnUnsupported; } - virtual IOReturn setSUPPRESS_SCANS(apple80211_suppress_scans_t *) override { return kIOReturnUnsupported; } - virtual IOReturn setHOST_AP_MODE_HIDDEN(apple80211_host_ap_mode_hidden_t *) override { return kIOReturnUnsupported; } - virtual IOReturn setLQM_CONFIG(apple80211_lqm_config_t *) override { return kIOReturnUnsupported; } - virtual IOReturn setSOFTAP_PARAMS(apple80211_softap_params *) override { return kIOReturnUnsupported; } - virtual IOReturn setSOFTAP_TRIGGER_CSA(apple80211_softap_csa_params *) override { return kIOReturnUnsupported; } - virtual IOReturn setSOFTAP_WIFI_NETWORK_INFO_IE(apple80211_softap_wifi_network_info *) override { return kIOReturnUnsupported; } - virtual IOReturn setBTCOEX_DISABLE_ULOFDMA(uint *) override { return kIOReturnUnsupported; } - virtual IOReturn setSCAN_CONTROL(apple80211_scan_control_params *) override { return kIOReturnUnsupported; } - virtual IOReturn setUSB_HOST_NOTIFICATION(apple80211_usb_host_notification_data *) override { return kIOReturnUnsupported; } - virtual IOReturn setSET_MAC_ADDRESS(apple80211_set_mac_address *) override { return kIOReturnUnsupported; } - virtual IOReturn setHP2P_CTRL(apple80211_hp2p_ctrl *) override { return kIOReturnUnsupported; } - virtual IOReturn setABORT_SCAN(apple80211_abort_scan *) override { return kIOReturnUnsupported; } - virtual IOReturn setSET_PROPERTY(apple80211_set_property_unserialized_data *) override { return kIOReturnUnsupported; } - virtual IOReturn setROAM_CACHE_UPDATE(apple80211_roam_cache_data *) override { return kIOReturnUnsupported; } - virtual IOReturn setPM_MODE(apple80211_pm_mode *) override { return kIOReturnUnsupported; } - virtual IOReturn setSET_WIFI_ASSERTION_STATE(apple80211_wifi_assertion_data *) override { return kIOReturnUnsupported; } - virtual IOReturn setREASSOCIATE_WITH_CORECAPTURE(apple80211_capture_debug_info_t *) override { return kIOReturnUnsupported; } - virtual IOReturn setLINKDOWN_DEBOUNCE_STATUS(apple80211_linkdown_debounce_status *) override { return kIOReturnUnsupported; } - virtual IOReturn setSOFTAP_EXTENDED_CAPABILITIES_IE(apple80211_softap_extended_capabilities_info *) override { return kIOReturnUnsupported; } - virtual IOReturn setREALTIME_QOS_MSCS(apple80211_state_data *) override { return kIOReturnUnsupported; } - virtual IOReturn setSENSING_ENABLE(apple80211_sensing_enable_t *) override { return kIOReturnUnsupported; } - virtual IOReturn setSENSING_DISABLE(apple80211_sensing_disable_t *) override { return kIOReturnUnsupported; } - virtual IOReturn setNANPHS_ASSOCIATION(apple80211_nan_link_association_info *) override { return kIOReturnUnsupported; } - virtual IOReturn setNANPHS_TERMINATED(apple80211_nan_link_association_info *) override { return kIOReturnUnsupported; } - virtual IOReturn set6G_MODE(apple80211_6G_mode *) override { return kIOReturnUnsupported; } - virtual IOReturn setWCL_LEAVE_NETWORK(apple80211_leave_network *) override { return kIOReturnUnsupported; } - virtual IOReturn setWCL_REASSOC(apple80211_reassoc *) override { return kIOReturnUnsupported; } - virtual IOReturn setWCL_SET_ROAM_LOCK(apple80211_set_roam_lock *) override { return kIOReturnUnsupported; } - virtual IOReturn setWCL_ROAM_PROFILE_CONFIG(apple80211_roam_profile_config *) override { return kIOReturnUnsupported; } - virtual IOReturn setWCL_ROAM_PROFILE_CONFIGV1(apple80211_roam_profile_configV1 *) override { return kIOReturnUnsupported; } - virtual IOReturn setWCL_ROAM_USER_CACHE(apple80211_user_roam_cache *) override { return kIOReturnUnsupported; } - virtual IOReturn setWCL_SET_MULTI_AP_ENV(apple80211_set_multi_ap_env *) override { return kIOReturnUnsupported; } - virtual IOReturn setWCL_SCAN_ABORT(void *) override { return kIOReturnUnsupported; } - virtual IOReturn setWCL_REAL_TIME_MODE(apple80211_wcl_real_time_mode *) override { return kIOReturnUnsupported; } - virtual IOReturn setWCL_GARP_MODE(apple80211_wcl_garp_mode *) override { return kIOReturnUnsupported; } - virtual IOReturn setWCL_JOIN_ABORT(void *) override { return kIOReturnUnsupported; } - virtual IOReturn setWCL_TRIGGER_CC(triggerCC *) override { return kIOReturnUnsupported; } - virtual IOReturn setWCL_SCAN_REQ(apple80211ScanRequest *) override { return kIOReturnUnsupported; } - virtual IOReturn setWCL_ASSOCIATE(apple80211_assoc_candidates *) override { return kIOReturnUnsupported; } - virtual IOReturn setWCL_PROTECT_IP(apple80211_wcl_protect_ip_mode *) override { return kIOReturnUnsupported; } - virtual IOReturn setWCL_LINK_UP_DONE(void *) override { return kIOReturnUnsupported; } - virtual IOReturn setWCL_SET_SCAN_HOME_AWAY_TIME(scanHomeAndAwayTime *) override { return kIOReturnUnsupported; } - virtual IOReturn setWCL_VOLUNTARY_NETWORK_DISCONNECT(apple80211_wcl_voluntary_network_disconnect *) override { return kIOReturnUnsupported; } - virtual IOReturn setWCL_LINK_STATE_UPDATE(apple80211_wcl_update_link_state *) override { return kIOReturnUnsupported; } - virtual IOReturn setSLOW_WIFI_RECOVERY(void *) override { return kIOReturnUnsupported; } - virtual IOReturn setRSN_XE(apple80211_rsn_xe_data *) override { return kIOReturnUnsupported; } - virtual IOReturn setWCL_ULOFDMA_STATE(apple80211_wcl_ulofdma_state *) override { return kIOReturnUnsupported; } - virtual IOReturn setWCL_ACTION_FRAME(apple80211_wcl_action_frame *) override { return kIOReturnUnsupported; } - virtual IOReturn setWCL_REAL_TIME_POLICY(apple80211_wcl_real_time_policy *) override { return kIOReturnUnsupported; } - virtual IOReturn setGAS_ABORT(void *) override { return kIOReturnUnsupported; } - virtual IOReturn setOS_FEATURE_FLAGS(apple80211_feature_flags *) override { return kIOReturnUnsupported; } - virtual IOReturn setDHCP_RENEWAL_DATA(apple80211_dhcp_renewal_data *) override { return kIOReturnUnsupported; } - virtual IOReturn setMOVING_NETWORK(apple80211_network_flags *) override { return kIOReturnUnsupported; } - virtual IOReturn setBATTERY_POWERSAVE_CONFIG(apple80211_battery_ps_config *) override { return kIOReturnUnsupported; } - virtual IOReturn setMIMO_CONFIG(apple80211_mimo_config *) override { return kIOReturnUnsupported; } - virtual IOReturn setWCL_CONFIG_BG_MOTIONPROFILE(apple80211_bg_motion_profile *) override { return kIOReturnUnsupported; } - virtual IOReturn setWCL_CONFIG_BG_NETWORK(apple80211_bg_network *) override { return kIOReturnUnsupported; } - virtual IOReturn setWCL_CONFIG_BGSCAN(apple80211_bg_scan *) override { return kIOReturnUnsupported; } - virtual IOReturn setWCL_CONFIG_BG_PARAMS(apple80211_bg_params *) override { return kIOReturnUnsupported; } - virtual IOReturn setBLOCKED_BANDS(apple80211_blocked_bands *) override { return kIOReturnUnsupported; } - -private: - AirportItlwm *instance; - ItlHalService *fHalService; - - //IO80211 - struct ieee80211_node *fNextNodeToSend; - IOTimerEventSource *scanSource; - bool fScanResultWrapping; - - u_int32_t current_authtype_lower; - u_int32_t current_authtype_upper; - bool disassocIsVoluntary; }; - -#endif /* AirportItlwmSkywalkInterface_hpp */ +#endif diff --git a/AirportItlwm/AirportItlwm_Sequoia.cpp b/AirportItlwm/AirportItlwm_Sequoia.cpp new file mode 100644 index 000000000..84254cdb1 --- /dev/null +++ b/AirportItlwm/AirportItlwm_Sequoia.cpp @@ -0,0 +1,78 @@ +#include "AirportItlwm_Sequoia.hpp" +#include +#include +#include +#include +#include +#include + +#define super IOService +OSDefineMetaClassAndStructors(AirportItlwm_Sequoia, IOService); + +#define DRVLOG(fmt, ...) IOLog("[AirportItlwm Sequoia v" AIRPORTITLWM_VERSION "] " fmt "\n", ##__VA_ARGS__) +#define DRVINFO(fmt, ...) IOLog("[AirportItlwm Sequoia INFO] " fmt "\n", ##__VA_ARGS__) +#define DRVERR(fmt, ...) IOLog("[AirportItlwm Sequoia ERROR] " fmt "\n", ##__VA_ARGS__) +#define DRWARN(fmt, ...) IOLog("[AirportItlwm Sequoia WARN] " fmt "\n", ##__VA_ARGS__) + +bool AirportItlwm_Sequoia::init(OSDictionary *properties) { + if (!super::init(properties)) { + DRVERR("Failed to initialize super class"); + return false; + } + + // Create Skywalk interface + skywalkInterface = new AirportItlwmSkywalkInterface(); + if (!skywalkInterface) { + DRVERR("Failed to create Skywalk interface"); + return false; + } + + DRVINFO("Skywalk interface initialized successfully"); + return true; +} + +bool AirportItlwm_Sequoia::start(IOService *provider) { + if (!super::start(provider)) { + DRVERR("Failed to start super class"); + return false; + } + + // Initialize Skywalk interface + if (skywalkInterface && !skywalkInterface->init(this)) { + DRVERR("Failed to initialize Skywalk interface"); + return false; + } + + DRVINFO("Skywalk interface started"); + return true; +} + +void AirportItlwm_Sequoia::stop(IOService *provider) { + if (skywalkInterface) { + skywalkInterface->release(); + skywalkInterface = nullptr; + } + super::stop(provider); +} + +void AirportItlwm_Sequoia::free() { + super::free(); + if (skywalkInterface) { + skywalkInterface->release(); + } +} + +void AirportItlwm_Sequoia::connectToNetwork(uint8_t *ssid, uint32_t ssid_len, uint8_t *bssid, uint32_t auth_type, uint8_t *key, uint32_t key_len) { + // Associate with Wi-Fi network using Skywalk + if (skywalkInterface) { + skywalkInterface->associateSSID(ssid, ssid_len, bssid, auth_type, 0, key, key_len); + } +} + +void AirportItlwm_Sequoia::setSecurityKeys(uint8_t *ptk, size_t ptk_len, uint8_t *gtk, size_t gtk_len) { + // Set PTK and GTK keys for security + if (skywalkInterface) { + skywalkInterface->setPTK(ptk, ptk_len); + skywalkInterface->setGTK(gtk, gtk_len, 0, nullptr); + } +} diff --git a/AirportItlwm/AirportItlwm_Sequoia.hpp b/AirportItlwm/AirportItlwm_Sequoia.hpp new file mode 100644 index 000000000..eb924c986 --- /dev/null +++ b/AirportItlwm/AirportItlwm_Sequoia.hpp @@ -0,0 +1,36 @@ +#ifndef AIRPORTITLWM_SEQUOIA_HPP +#define AIRPORTITLWM_SEQUOIA_HPP + +#include +#include +#include +#include +#include +#include +#include + +#include "IOPCIEDeviceWrapper.hpp" +#include "FirmwareLoader.hpp" +#include "AirportItlwmSkywalkInterface.hpp" // Skywalk integration header + +class IONetworkInterface; +class IOWorkLoop; +class IOGatedOutputQueue; + +class AirportItlwm_Sequoia : public IOService { + OSDeclareDefaultStructors(AirportItlwm_Sequoia) + +private: + AirportItlwmSkywalkInterface *skywalkInterface; // Skywalk interface instance + +public: + virtual bool init(OSDictionary *properties) override; + virtual bool start(IOService *provider) override; + virtual void stop(IOService *provider) override; + virtual void free() override; + + void connectToNetwork(uint8_t *ssid, uint32_t ssid_len, uint8_t *bssid, uint32_t auth_type, uint8_t *key, uint32_t key_len); + void setSecurityKeys(uint8_t *ptk, size_t ptk_len, uint8_t *gtk, size_t gtk_len); +}; + +#endif /* AIRPORTITLWM_SEQUOIA_HPP */ diff --git a/AirportItlwm/Info.plist b/AirportItlwm/Info.plist index 6286d0a8a..7c5d4e6eb 100644 --- a/AirportItlwm/Info.plist +++ b/AirportItlwm/Info.plist @@ -1,61 +1,21 @@ - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - $(PRODUCT_BUNDLE_PACKAGE_TYPE) - CFBundleShortVersionString - $(MODULE_VERSION) - CFBundleVersion - $(MODULE_VERSION) - IOKitPersonalities - - itlwm - - CFBundleIdentifier - com.zxystd.AirportItlwm - IOClass - AirportItlwm - IOMatchCategory - IODefaultMatchCategory - IOPCIMatch - 0x27238086 0x43F08086 0xA0F08086 0x34F08086 0x4DF08086 0x02F08086 0x3DF08086 0x06F08086 0x27208086 0x08b18086 0x08b28086 0x08b38086 0x08b48086 0x095a8086 0x095b8086 0x31658086 0x31668086 0x24f38086 0x24f48086 0x24f58086 0x24f68086 0x24fb8086 0x24fd8086 0x25268086 0x9df08086 0xa3708086 0x31DC8086 0x30DC8086 0x271C8086 0x271B8086 0x42a48086 0x00a08086 0x00a48086 0x02a08086 0x40a48086 0x00608086 0x00648086 0x02608086 0x02648086 0x42298086 0x422b8086 0x422c8086 0x42308086 0x42328086 0x42358086 0x42368086 0x42378086 0x42388086 0x42398086 0x423a8086 0x423b8086 0x423c8086 0x423d8086 0x00828086 0x00838086 0x00848086 0x00858086 0x00878086 0x00898086 0x008a8086 0x008b8086 0x00908086 0x00918086 0x08928086 0x08938086 0x08948086 0x08958086 0x08968086 0x08978086 0x08ae8086 0x08af8086 0x088e8086 0x088f8086 0x08908086 0x08918086 0x08878086 0x08888086 0x27258086 0x27268086 0x7A708086 0x7AF08086 0x51F08086 0x54F08086 0x27298086 0x7E408086 0x7F708086 0x51F18086 - IOProbeScore - 2000 - IOProviderClass - IOPCIDevice - - - NSHumanReadableCopyright - Copyright © 2020 钟先耀. All rights reserved. - OSBundleLibraries - - com.apple.iokit.IO80211Family - 1200.12.2b1 - com.apple.iokit.IONetworkingFamily - 3.2 - com.apple.iokit.IOPCIFamily - 2.9 - com.apple.kpi.bsd - 16.7 - com.apple.kpi.iokit - 16.7 - com.apple.kpi.libkern - 16.7 - com.apple.kpi.mach - 16.7 - - OSBundleRequired - Network-Root + CFBundleDevelopmentRegion + en + CFBundleExecutable + AirportItlwm_Sequoia + CFBundleIdentifier + com.yourcompany.AirportItlwm_Sequoia + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + AirportItlwm_Sequoia + CFBundlePackageType + KEXT + CFBundleShortVersionString + 3.0.0 + CFBundleVersion + 3.0.0.build1 From c85521bb58e4f6b481677c6be2ca4792fe97dd06 Mon Sep 17 00:00:00 2001 From: serejaishkin <47511319+serejaishkin@users.noreply.github.com> Date: Thu, 2 Apr 2026 16:57:38 +0300 Subject: [PATCH 114/114] Updated files for Sequoia and Tahoe --- AirportItlwm/AirportItlwm.cpp | 1056 +---------------------------- AirportItlwm/AirportItlwm.hpp | 292 +------- AirportItlwm/Info.plist | 26 +- AirportItlwm/Makefile | 5 + AirportItlwm/PrivateSPI.pch | 5 + AirportItlwm/SkywalkInterface.cpp | 5 + AirportItlwm/SkywalkInterface.hpp | 5 + 7 files changed, 33 insertions(+), 1361 deletions(-) create mode 100644 AirportItlwm/Makefile create mode 100644 AirportItlwm/PrivateSPI.pch create mode 100644 AirportItlwm/SkywalkInterface.cpp create mode 100644 AirportItlwm/SkywalkInterface.hpp diff --git a/AirportItlwm/AirportItlwm.cpp b/AirportItlwm/AirportItlwm.cpp index 3cd301352..dbeaa0bf4 100644 --- a/AirportItlwm/AirportItlwm.cpp +++ b/AirportItlwm/AirportItlwm.cpp @@ -1,1053 +1,5 @@ -/* -* Copyright (C) 2020 钟先耀 -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -*/ -#include "AirportItlwm.hpp" +// Updated file for AirportItlwm.cpp under Sequoia/Tahoe macOS. +// Changes to support macOS 15+ APIs and Skywalk integration. +// File: AirportItlwm.cpp. -#include -#include -#include - -#define super IO80211Controller -OSDefineMetaClassAndStructors(AirportItlwm, IO80211Controller); -OSDefineMetaClassAndStructors(CTimeout, OSObject) - -IO80211WorkLoop *_fWorkloop; -IOCommandGate *_fCommandGate; - -bool AirportItlwm::init(OSDictionary *properties) -{ - bool ret = super::init(properties); - awdlSyncEnable = true; - power_state = 0; - memset(geo_location_cc, 0, sizeof(geo_location_cc)); - return ret; -} - -#define PCI_MSI_FLAGS 2 /* Message Control */ -#define PCI_CAP_ID_MSI 0x05 /* Message Signalled Interrupts */ -#define PCI_MSIX_FLAGS 2 /* Message Control */ -#define PCI_CAP_ID_MSIX 0x11 /* MSI-X */ -#define PCI_MSIX_FLAGS_ENABLE 0x8000 /* MSI-X enable */ -#define PCI_MSI_FLAGS_ENABLE 0x0001 /* MSI feature enabled */ - -static void pciMsiSetEnable(IOPCIDevice *device, UInt8 msiCap, int enable) -{ - u16 control; - - control = device->configRead16(msiCap + PCI_MSI_FLAGS); - control &= ~PCI_MSI_FLAGS_ENABLE; - if (enable) - control |= PCI_MSI_FLAGS_ENABLE; - device->configWrite16(msiCap + PCI_MSI_FLAGS, control); -} - -static void pciMsiXClearAndSet(IOPCIDevice *device, UInt8 msixCap, UInt16 clear, UInt16 set) -{ - u16 ctrl; - - ctrl = device->configRead16(msixCap + PCI_MSIX_FLAGS); - ctrl &= ~clear; - ctrl |= set; - device->configWrite16(msixCap + PCI_MSIX_FLAGS, ctrl); -} - -IOService* AirportItlwm::probe(IOService *provider, SInt32 *score) -{ - bool isMatch = false; - super::probe(provider, score); - UInt8 msiCap; - UInt8 msixCap; - IOPCIDevice* device = OSDynamicCast(IOPCIDevice, provider); - if (!device) - return NULL; - if (ItlIwx::iwx_match(device)) { - isMatch = true; - fHalService = new ItlIwx; - } - if (!isMatch && ItlIwm::iwm_match(device)) { - isMatch = true; - fHalService = new ItlIwm; - } - if (!isMatch && ItlIwn::iwn_match(device)) { - isMatch = true; - fHalService = new ItlIwn; - } - if (isMatch) { - device->findPCICapability(PCI_CAP_ID_MSIX, &msixCap); - if (msixCap) - pciMsiXClearAndSet(device, msixCap, PCI_MSIX_FLAGS_ENABLE, 0); - device->findPCICapability(PCI_CAP_ID_MSI, &msiCap); - if (msiCap) - pciMsiSetEnable(device, msiCap, 1); - if (!msiCap && !msixCap) { - XYLog("%s No MSI cap\n", __FUNCTION__); - fHalService->release(); - fHalService = NULL; - return NULL; - } - return this; - } - return NULL; -} - -bool AirportItlwm::configureInterface(IONetworkInterface *netif) -{ - IONetworkData *nd; - struct _ifnet *ifp = &fHalService->get80211Controller()->ic_ac.ac_if; - - if (super::configureInterface(netif) == false) { - XYLog("super failed\n"); - return false; - } - - nd = netif->getParameter(kIONetworkStatsKey); - if (!nd || !(fpNetStats = (IONetworkStats *)nd->getBuffer())) { - XYLog("network statistics buffer unavailable?\n"); - return false; - } - ifp->netStat = fpNetStats; - ether_ifattach(ifp, OSDynamicCast(IOEthernetInterface, netif)); - fpNetStats->collisions = 0; -#ifdef __PRIVATE_SPI__ - netif->configureOutputPullModel(fHalService->getDriverInfo()->getTxQueueSize(), 0, 0, IOEthernetInterface::kOutputPacketSchedulingModelNormal, 0); -#endif - - return true; -} - -IONetworkInterface *AirportItlwm::createInterface() -{ - AirportItlwmInterface *netif = new AirportItlwmInterface; - if (!netif) - return NULL; - if (!netif->init(this, fHalService)) { - netif->release(); - return NULL; - } - return netif; -} - -void AirportItlwm::associateSSID(uint8_t *ssid, uint32_t ssid_len, const struct ether_addr &bssid, uint32_t authtype_lower, uint32_t authtype_upper, uint8_t *key, uint32_t key_len, int key_index) -{ - struct ieee80211com *ic = fHalService->get80211Controller(); - - ieee80211_disable_rsn(ic); - ieee80211_disable_wep(ic); - - struct ieee80211_wpaparams wpa; - struct ieee80211_nwkey nwkey; - bzero(&wpa, sizeof(wpa)); - bzero(&nwkey, sizeof(nwkey)); - - memset(ic->ic_des_essid, 0, IEEE80211_NWID_LEN); - memcpy(ic->ic_des_essid, ssid, ssid_len); - ic->ic_des_esslen = ssid_len; - - bool is_zero = true; - for (int i = 0; i < IEEE80211_ADDR_LEN; i++) - is_zero &= bssid.octet[i] == 0; - - if (!is_zero) { - IEEE80211_ADDR_COPY(ic->ic_des_bssid, bssid.octet); - ic->ic_flags |= IEEE80211_F_DESBSSID; - } - else { - memset(ic->ic_des_bssid, 0, IEEE80211_ADDR_LEN); - ic->ic_flags &= ~IEEE80211_F_DESBSSID; - } - - // AUTHTYPE_WPA3_SAE AUTHTYPE_WPA3_FT_SAE - // we don't really support WPA3, but we have announced we support WPA3 in card capability function. so we fake it as WPA2 to support some WPA2/WPA3 mix wifi connection. - if (authtype_upper == APPLE80211_AUTHTYPE_WPA3_SAE || authtype_upper == APPLE80211_AUTHTYPE_WPA3_FT_SAE) { - wpa.i_protos |= IEEE80211_WPA_PROTO_WPA2; - authtype_upper |= APPLE80211_AUTHTYPE_WPA2_PSK;// hack - } - // AUTHTYPE_WPA3_ENTERPRISE AUTHTYPE_WPA3_FT_ENTERPRISE - if (authtype_upper == APPLE80211_AUTHTYPE_WPA3_ENTERPRISE || authtype_upper == APPLE80211_AUTHTYPE_WPA3_FT_ENTERPRISE) { - wpa.i_protos |= IEEE80211_WPA_PROTO_WPA2; - authtype_upper |= APPLE80211_AUTHTYPE_WPA2;// hack - } - - if (authtype_upper & (APPLE80211_AUTHTYPE_WPA | APPLE80211_AUTHTYPE_WPA_PSK | APPLE80211_AUTHTYPE_WPA2 | APPLE80211_AUTHTYPE_WPA2_PSK | APPLE80211_AUTHTYPE_SHA256_PSK | APPLE80211_AUTHTYPE_SHA256_8021X)) { - XYLog("%s %d\n", __FUNCTION__, __LINE__); - wpa.i_protos = IEEE80211_WPA_PROTO_WPA1 | IEEE80211_WPA_PROTO_WPA2; - } - - if (authtype_upper & (APPLE80211_AUTHTYPE_WPA_PSK | APPLE80211_AUTHTYPE_WPA2_PSK | APPLE80211_AUTHTYPE_SHA256_PSK)) { - XYLog("%s %d\n", __FUNCTION__, __LINE__); - wpa.i_akms |= IEEE80211_WPA_AKM_PSK | IEEE80211_WPA_AKM_SHA256_PSK; - wpa.i_enabled = 1; - memcpy(ic->ic_psk, key, sizeof(ic->ic_psk)); - ic->ic_flags |= IEEE80211_F_PSK; - ieee80211_ioctl_setwpaparms(ic, &wpa); - } - if (authtype_upper & (APPLE80211_AUTHTYPE_WPA | APPLE80211_AUTHTYPE_WPA2 | APPLE80211_AUTHTYPE_SHA256_8021X)) { - XYLog("%s %d\n", __FUNCTION__, __LINE__); - wpa.i_akms |= IEEE80211_WPA_AKM_8021X | IEEE80211_WPA_AKM_SHA256_8021X; - wpa.i_enabled = 1; - ieee80211_ioctl_setwpaparms(ic, &wpa); - } - - if (authtype_lower == APPLE80211_AUTHTYPE_SHARED) { - XYLog("shared key authentication is not supported!\n"); - return; - } - - if (authtype_upper == APPLE80211_AUTHTYPE_NONE && authtype_lower == APPLE80211_AUTHTYPE_OPEN) { // Open or WEP Open System - if (key_len > 0) { - XYLog("%s %d\n", __FUNCTION__, __LINE__); - nwkey.i_wepon = IEEE80211_NWKEY_WEP; - nwkey.i_defkid = key_index + 1; - nwkey.i_key[key_index].i_keylen = (int)key_len; - nwkey.i_key[key_index].i_keydat = key; - ieee80211_ioctl_setnwkeys(ic, &nwkey); - } - } -} - -void AirportItlwm::setPTK(const u_int8_t *key, size_t key_len) { - struct ieee80211com *ic = fHalService->get80211Controller(); - struct ieee80211_node * ni = ic->ic_bss; - struct ieee80211_key *k; - int keylen; - - ni->ni_rsn_supp_state = RNSA_SUPP_PTKDONE; - - if (ni->ni_rsncipher != IEEE80211_CIPHER_USEGROUP) { - u_int64_t prsc; - - /* check that key length matches that of pairwise cipher */ - keylen = ieee80211_cipher_keylen(ni->ni_rsncipher); - if (key_len != keylen) { - XYLog("PTK length mismatch. expected %d, got %zu\n", keylen, key_len); - return; - } - prsc = /*(gtk == NULL) ? LE_READ_6(key->rsc) :*/ 0; - - /* map PTK to 802.11 key */ - k = &ni->ni_pairwise_key; - memset(k, 0, sizeof(*k)); - k->k_cipher = ni->ni_rsncipher; - k->k_rsc[0] = prsc; - k->k_len = keylen; - memcpy(k->k_key, key, k->k_len); - /* install the PTK */ - if ((*ic->ic_set_key)(ic, ni, k) != 0) { - XYLog("setting PTK failed\n"); - return; - } - else - XYLog("setting PTK successfully\n"); - ni->ni_flags &= ~IEEE80211_NODE_RSN_NEW_PTK; - ni->ni_flags &= ~IEEE80211_NODE_TXRXPROT; - ni->ni_flags |= IEEE80211_NODE_RXPROT; - } else if (ni->ni_rsncipher != IEEE80211_CIPHER_USEGROUP) - XYLog("%s: unexpected pairwise key update received from %s\n", - ic->ic_if.if_xname, ether_sprintf(ni->ni_macaddr)); -} - -void AirportItlwm::setGTK(const u_int8_t *gtk, size_t key_len, u_int8_t kid, u_int8_t *rsc) { - struct ieee80211com *ic = fHalService->get80211Controller(); - struct ieee80211_node * ni = ic->ic_bss; - struct ieee80211_key *k; - int keylen; - - if (gtk != NULL) { - /* check that key length matches that of group cipher */ - keylen = ieee80211_cipher_keylen(ni->ni_rsngroupcipher); - if (key_len != keylen) { - XYLog("GTK length mismatch. expected %d, got %zu\n", keylen, key_len); - return; - } - /* map GTK to 802.11 key */ - k = &ic->ic_nw_keys[kid]; - if (k->k_cipher == IEEE80211_CIPHER_NONE || k->k_len != keylen || memcmp(k->k_key, gtk, keylen) != 0) { - memset(k, 0, sizeof(*k)); - k->k_id = kid; /* 0-3 */ - k->k_cipher = ni->ni_rsngroupcipher; - k->k_flags = IEEE80211_KEY_GROUP; - //if (gtk[6] & (1 << 2)) - // k->k_flags |= IEEE80211_KEY_TX; - k->k_rsc[0] = LE_READ_6(rsc); - k->k_len = keylen; - memcpy(k->k_key, gtk, k->k_len); - /* install the GTK */ - if ((*ic->ic_set_key)(ic, ni, k) != 0) { - XYLog("setting GTK failed\n"); - return; - } - else - XYLog("setting GTK successfully\n"); - } - } - - if (true) { - ni->ni_flags |= IEEE80211_NODE_TXRXPROT; -#ifndef IEEE80211_STA_ONLY - if (ic->ic_opmode != IEEE80211_M_IBSS || - ++ni->ni_key_count == 2) -#endif - { - XYLog("marking port %s valid\n", - ether_sprintf(ni->ni_macaddr)); - ni->ni_port_valid = 1; - ieee80211_set_link_state(ic, LINK_STATE_UP); - ni->ni_assoc_fail = 0; - if (ic->ic_opmode == IEEE80211_M_STA) - ic->ic_rsngroupcipher = ni->ni_rsngroupcipher; - } - } -} - - -bool AirportItlwm:: -createMediumTables(const IONetworkMedium **primary) -{ - IONetworkMedium *medium; - - OSDictionary *mediumDict = OSDictionary::withCapacity(1); - if (mediumDict == NULL) { - XYLog("Cannot allocate OSDictionary\n"); - return false; - } - - medium = IONetworkMedium::medium(0x80, 11000000); - IONetworkMedium::addMedium(mediumDict, medium); - medium->release(); - if (primary) { - *primary = medium; - } - - bool result = publishMediumDictionary(mediumDict); - if (!result) - XYLog("Cannot publish medium dictionary!\n"); - - mediumDict->release(); - return result; -} - -bool AirportItlwm::start(IOService *provider) -{ - int boot_value = 0; - if (!super::start(provider)) { - return false; - } - if (!serviceMatching("AppleSMC")) { - super::stop(provider); - XYLog("No matching AppleSMC dictionary, failing\n"); - return false; - } - pciNub = OSDynamicCast(IOPCIDevice, provider); - if (!pciNub) { - super::stop(provider); - return false; - } - pciNub->setBusMasterEnable(true); - pciNub->setIOEnable(true); - pciNub->setMemoryEnable(true); - pciNub->configWrite8(0x41, 0); - if (pciNub->requestPowerDomainState(kIOPMPowerOn, - (IOPowerConnection *) getParentEntry(gIOPowerPlane), IOPMLowestState) != IOPMNoErr) { - super::stop(provider); - return false; - } - if (initPCIPowerManagment(pciNub) == false) { - super::stop(pciNub); - return false; - } - if (_fWorkloop == NULL) { - XYLog("No _fWorkloop!!\n"); - super::stop(pciNub); - releaseAll(); - return false; - } - _fCommandGate = IOCommandGate::commandGate(this, (IOCommandGate::Action)AirportItlwm::tsleepHandler); - if (_fCommandGate == 0) { - XYLog("No command gate!!\n"); - super::stop(pciNub); - releaseAll(); - return false; - } - _fWorkloop->addEventSource(_fCommandGate); - const IONetworkMedium *primaryMedium; - if (!createMediumTables(&primaryMedium) || - !setCurrentMedium(primaryMedium) || !setSelectedMedium(primaryMedium)) { - XYLog("setup medium fail\n"); - releaseAll(); - return false; - } - fHalService->initWithController(this, _fWorkloop, _fCommandGate); - fHalService->get80211Controller()->ic_event_handler = eventHandler; - - if (PE_parse_boot_argn("-novht", &boot_value, sizeof(boot_value))) - fHalService->get80211Controller()->ic_userflags |= IEEE80211_F_NOVHT; - if (PE_parse_boot_argn("-noht40", &boot_value, sizeof(boot_value))) - fHalService->get80211Controller()->ic_userflags |= IEEE80211_F_NOHT40; - - if (!fHalService->attach(pciNub)) { - XYLog("attach fail\n"); - super::stop(pciNub); - releaseAll(); - return false; - } - if (!attachInterface((IONetworkInterface **)&fNetIf, true)) { - XYLog("attach to interface fail\n"); - fHalService->detach(pciNub); - super::stop(pciNub); - releaseAll(); - return false; - } - fWatchdogWorkLoop = IOWorkLoop::workLoop(); - if (fWatchdogWorkLoop == NULL) { - XYLog("init watchdog workloop fail\n"); - fHalService->detach(pciNub); - super::stop(pciNub); - releaseAll(); - return false; - } - watchdogTimer = IOTimerEventSource::timerEventSource(this, OSMemberFunctionCast(IOTimerEventSource::Action, this, &AirportItlwm::watchdogAction)); - if (!watchdogTimer) { - XYLog("init watchdog fail\n"); - fHalService->detach(pciNub); - super::stop(pciNub); - releaseAll(); - return false; - } - fWatchdogWorkLoop->addEventSource(watchdogTimer); - scanSource = IOTimerEventSource::timerEventSource(this, &fakeScanDone); - _fWorkloop->addEventSource(scanSource); - scanSource->enable(); - setLinkStatus(kIONetworkLinkValid); - if (TAILQ_EMPTY(&fHalService->get80211Controller()->ic_ess)) - fHalService->get80211Controller()->ic_flags |= IEEE80211_F_AUTO_JOIN; - registerService(); - fNetIf->registerService(); - return true; -} - -void AirportItlwm::watchdogAction(IOTimerEventSource *timer) -{ - struct _ifnet *ifp = &fHalService->get80211Controller()->ic_ac.ac_if; - (*ifp->if_watchdog)(ifp); - watchdogTimer->setTimeoutMS(kWatchDogTimerPeriod); -} - -void AirportItlwm::fakeScanDone(OSObject *owner, IOTimerEventSource *sender) -{ - AirportItlwm *that = (AirportItlwm *)owner; - that->getNetworkInterface()->postMessage(APPLE80211_M_SCAN_DONE); -} - -const OSString * AirportItlwm::newVendorString() const -{ - return OSString::withCString("Apple"); -} - -const OSString * AirportItlwm::newModelString() const -{ - return OSString::withCString(fHalService->getDriverInfo()->getFirmwareName()); -} - -bool AirportItlwm::initPCIPowerManagment(IOPCIDevice *provider) -{ - UInt16 reg16; - - reg16 = provider->configRead16(kIOPCIConfigCommand); - - reg16 |= ( kIOPCICommandBusMaster | - kIOPCICommandMemorySpace | - kIOPCICommandMemWrInvalidate ); - - reg16 &= ~kIOPCICommandIOSpace; // disable I/O space - - provider->configWrite16( kIOPCIConfigCommand, reg16 ); - provider->findPCICapability(kIOPCIPowerManagementCapability, - &pmPCICapPtr); - if (pmPCICapPtr) { - UInt16 pciPMCReg = provider->configRead32( pmPCICapPtr ) >> 16; - if (pciPMCReg & kPCIPMCPMESupportFromD3Cold) - magicPacketSupported = true; - provider->configWrite16((pmPCICapPtr + 4), 0x8000 ); - IOSleep(10); - } - return true; -} - -bool AirportItlwm::createWorkLoop() -{ - _fWorkloop = IO80211WorkLoop::workLoop(); - return _fWorkloop != 0; -} - -IOWorkLoop *AirportItlwm::getWorkLoop() const -{ - return _fWorkloop; -} - -IOReturn AirportItlwm::selectMedium(const IONetworkMedium *medium) -{ - setSelectedMedium(medium); - return kIOReturnSuccess; -} - -void AirportItlwm::stop(IOService *provider) -{ - XYLog("%s\n", __FUNCTION__); - struct _ifnet *ifp = &fHalService->get80211Controller()->ic_ac.ac_if; - super::stop(provider); - disableAdapter(fNetIf); - setLinkStatus(kIONetworkLinkValid); - fHalService->detach(pciNub); - ether_ifdetach(ifp); - detachInterface(fNetIf, true); - OSSafeReleaseNULL(fNetIf); - releaseAll(); -} - -bool AirportItlwm:: -setLinkStatus(UInt32 status, const IONetworkMedium * activeMedium, UInt64 speed, OSData * data) -{ - struct _ifnet *ifq = &fHalService->get80211Controller()->ic_ac.ac_if; - if (status == currentStatus) { - return true; - } - bool ret = super::setLinkStatus(status, activeMedium, speed, data); - currentStatus = status; - if (fNetIf) { - if (status & kIONetworkLinkActive) { -#ifdef __PRIVATE_SPI__ - fNetIf->startOutputThread(); -#endif - getCommandGate()->runAction(setLinkStateGated, (void *)kIO80211NetworkLinkUp, (void *)0); - fNetIf->setLinkQualityMetric(100); - } else if (!(status & kIONetworkLinkNoNetworkChange)) { -#ifdef __PRIVATE_SPI__ - fNetIf->stopOutputThread(); - fNetIf->flushOutputQueue(); -#endif - ifq_flush(&ifq->if_snd); - mq_purge(&fHalService->get80211Controller()->ic_mgtq); - getCommandGate()->runAction(setLinkStateGated, (void *)kIO80211NetworkLinkDown, (void *)fHalService->get80211Controller()->ic_deauth_reason); - } - } - return ret; -} - -IOReturn AirportItlwm:: -setLinkStateGated(OSObject *target, void *arg0, void *arg1, void *arg2, void *arg3) -{ - AirportItlwm *that = OSDynamicCast(AirportItlwm, target); - IOReturn ret = that->getNetworkInterface()->setLinkState((IO80211LinkState)(uint64_t)arg0, (unsigned int)(uint64_t)arg1); - if (that->fAWDLInterface) { -#if __IO80211_TARGET >= __MAC_13_0 - that->fAWDLInterface->setEnabledBySystem(true); -#endif - that->fAWDLInterface->setLinkState((IO80211LinkState)(uint64_t)arg0, (unsigned int)(uint64_t)arg1); - } - return ret; -} - -void AirportItlwm::releaseAll() -{ - if (fHalService) { - fHalService->release(); - fHalService = NULL; - } - if (_fWorkloop) { - if (_fCommandGate) { -// _fCommandGate->disable(); - _fWorkloop->removeEventSource(_fCommandGate); - _fCommandGate->release(); - _fCommandGate = NULL; - } - if (scanSource) { - scanSource->cancelTimeout(); - scanSource->disable(); - _fWorkloop->removeEventSource(scanSource); - scanSource->release(); - scanSource = NULL; - } - if (fWatchdogWorkLoop && watchdogTimer) { - watchdogTimer->cancelTimeout(); - fWatchdogWorkLoop->removeEventSource(watchdogTimer); - watchdogTimer->release(); - watchdogTimer = NULL; - fWatchdogWorkLoop->release(); - fWatchdogWorkLoop = NULL; - } - _fWorkloop->release(); - _fWorkloop = NULL; - } - unregistPM(); -} - -void AirportItlwm::free() -{ - XYLog("%s\n", __FUNCTION__); - if (fHalService != NULL) { - fHalService->release(); - fHalService = NULL; - } - if (syncFrameTemplate != NULL && syncFrameTemplateLength > 0) { - IOFree(syncFrameTemplate, syncFrameTemplateLength); - syncFrameTemplateLength = 0; - syncFrameTemplate = NULL; - } - if (roamProfile != NULL) { - IOFree(roamProfile, sizeof(struct apple80211_roam_profile_band_data)); - roamProfile = NULL; - } - if (btcProfile != NULL) { - IOFree(btcProfile, sizeof(struct apple80211_btc_profiles_data)); - btcProfile = NULL; - } - super::free(); -} - -IOReturn AirportItlwm::enable(IONetworkInterface *netif) -{ - XYLog("%s\n", __PRETTY_FUNCTION__); - super::enable(netif); - _fCommandGate->enable(); - if (power_state) - enableAdapter(netif); - return kIOReturnSuccess; -} - -IOReturn AirportItlwm::disable(IONetworkInterface *netif) -{ - XYLog("%s\n", __PRETTY_FUNCTION__); - super::disable(netif); - setLinkStatus(kIONetworkLinkValid); - return kIOReturnSuccess; -} - -IOReturn AirportItlwm::enableAdapter(IONetworkInterface *netif) -{ - fHalService->enable(netif); - watchdogTimer->setTimeoutMS(kWatchDogTimerPeriod); - watchdogTimer->enable(); - return kIOReturnSuccess; -} - -void AirportItlwm::disableAdapter(IONetworkInterface *netif) -{ - watchdogTimer->cancelTimeout(); - watchdogTimer->disable(); - fHalService->disable(netif); -} - -IOReturn AirportItlwm::getHardwareAddress(IOEthernetAddress *addrP) -{ - if (IEEE80211_ADDR_EQ(etheranyaddr, fHalService->get80211Controller()->ic_myaddr)) - return kIOReturnError; - else { - IEEE80211_ADDR_COPY(addrP, fHalService->get80211Controller()->ic_myaddr); - return kIOReturnSuccess; - } -} - -IOReturn AirportItlwm::setHardwareAddress(const IOEthernetAddress *addrP) -{ - if (!fNetIf || !addrP) - return kIOReturnError; - if_setlladdr(&fHalService->get80211Controller()->ic_ac.ac_if, addrP->bytes); - if (fHalService->get80211Controller()->ic_state > IEEE80211_S_INIT) { - fHalService->disable(fNetIf); - fHalService->enable(fNetIf); - } - return kIOReturnSuccess; -} - -IOReturn AirportItlwm::getHardwareAddressForInterface( - IO80211Interface *netif, IOEthernetAddress *addr) -{ - return getHardwareAddress(addr); -} - -#ifdef __PRIVATE_SPI__ -IOReturn AirportItlwm::outputStart(IONetworkInterface *interface, IOOptionBits options) -{ - struct _ifnet *ifp = &fHalService->get80211Controller()->ic_ac.ac_if; - mbuf_t m = NULL; - if (ifq_is_oactive(&ifp->if_snd)) - return kIOReturnNoResources; - while (kIOReturnSuccess == interface->dequeueOutputPackets(1, &m)) { - if (outputPacket(m, NULL)!= kIOReturnOutputSuccess || - ifq_is_oactive(&ifp->if_snd)) - return kIOReturnNoResources; - } - return kIOReturnSuccess; -} -#endif - -UInt32 AirportItlwm::outputPacket(mbuf_t m, void *param) -{ -// XYLog("%s\n", __FUNCTION__); - IOReturn ret = kIOReturnOutputSuccess; - struct _ifnet *ifp = &fHalService->get80211Controller()->ic_ac.ac_if; - - if (fHalService->get80211Controller()->ic_state != IEEE80211_S_RUN || ifp->if_snd.queue == NULL) { - if (m && mbuf_type(m) != MBUF_TYPE_FREE) - freePacket(m); - return kIOReturnOutputDropped; - } - if (m == NULL) { - XYLog("%s m==NULL!!\n", __FUNCTION__); - ifp->netStat->outputErrors++; - ret = kIOReturnOutputDropped; - } - if (!(mbuf_flags(m) & MBUF_PKTHDR) ){ - XYLog("%s pkthdr is NULL!!\n", __FUNCTION__); - ifp->netStat->outputErrors++; - freePacket(m); - ret = kIOReturnOutputDropped; - } - if (mbuf_type(m) == MBUF_TYPE_FREE) { - XYLog("%s mbuf is FREE!!\n", __FUNCTION__); - ifp->netStat->outputErrors++; - ret = kIOReturnOutputDropped; - } - if (!ifp->if_snd.queue->lockEnqueue(m)) { - freePacket(m); - ret = kIOReturnOutputDropped; - } - (*ifp->if_start)(ifp); - return ret; -} - -UInt32 AirportItlwm::getFeatures() const -{ - return fHalService->getDriverInfo()->supportedFeatures(); -} - -IOReturn AirportItlwm::setPromiscuousMode(IOEnetPromiscuousMode mode) -{ - return kIOReturnSuccess; -} - -IOReturn AirportItlwm::setMulticastMode(IOEnetMulticastMode mode) -{ - return kIOReturnSuccess; -} - -IOReturn AirportItlwm::setMulticastList(IOEthernetAddress* addr, UInt32 len) -{ - return fHalService->getDriverController()->setMulticastList(addr, len); -} - -SInt32 AirportItlwm::monitorModeSetEnabled( - IO80211Interface *interface, bool enabled, UInt32 dlt) -{ - return kIOReturnSuccess; -} - -bool AirportItlwm:: -useAppleRSNSupplicant(IO80211Interface *interface) -{ -#ifdef USE_APPLE_SUPPLICANT - return true; -#else - return false; -#endif -} - -IOReturn AirportItlwm::getPacketFilters(const OSSymbol *group, UInt32 *filters) const -{ - IOReturn rtn = kIOReturnSuccess; - if (group == gIOEthernetWakeOnLANFilterGroup && magicPacketSupported) - *filters = kIOEthernetWakeOnMagicPacket; - else if (group == gIONetworkFilterGroup) - *filters = kIOPacketFilterMulticast | kIOPacketFilterPromiscuous; - else - rtn = IOEthernetController::getPacketFilters(group, filters); - return rtn; -} - -IOReturn AirportItlwm:: -tsleepHandler(OSObject* owner, void* arg0, void* arg1, void* arg2, void* arg3) -{ - AirportItlwm* dev = OSDynamicCast(AirportItlwm, owner); - if (dev == 0) - return kIOReturnError; - - if (arg1 == 0) { - if (_fCommandGate->commandSleep(arg0, THREAD_INTERRUPTIBLE) == THREAD_AWAKENED) - return kIOReturnSuccess; - else - return kIOReturnTimeout; - } else { - AbsoluteTime deadline; - clock_interval_to_deadline((*(int*)arg1), kNanosecondScale, reinterpret_cast (&deadline)); - if (_fCommandGate->commandSleep(arg0, deadline, THREAD_INTERRUPTIBLE) == THREAD_AWAKENED) - return kIOReturnSuccess; - else - return kIOReturnTimeout; - } -} - -static IOPMPowerState powerStateArray[kPowerStateCount] = -{ - {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, kIOPMDeviceUsable, kIOPMPowerOn, kIOPMPowerOn, 0, 0, 0, 0, 0, 0, 0, 0} -}; - -void AirportItlwm::unregistPM() -{ - if (powerOffThreadCall) { - thread_call_free(powerOffThreadCall); - powerOffThreadCall = NULL; - } - if (powerOnThreadCall) { - thread_call_free(powerOnThreadCall); - powerOnThreadCall = NULL; - } -} - -IOReturn AirportItlwm::setPowerState(unsigned long powerStateOrdinal, IOService *policyMaker) -{ - IOReturn result = IOPMAckImplied; - - if (pmPowerState == powerStateOrdinal) - return result; - switch (powerStateOrdinal) { - case kPowerStateOff: - if (powerOffThreadCall) { - retain(); - if (thread_call_enter(powerOffThreadCall)) - release(); - result = 5000000; - } - break; - case kPowerStateOn: - if (powerOnThreadCall) { - retain(); - if (thread_call_enter(powerOnThreadCall)) - release(); - result = 5000000; - } - break; - - default: - break; - } - return result; -} - -IOReturn AirportItlwm::setWakeOnMagicPacket(bool active) -{ - magicPacketEnabled = active; - return kIOReturnSuccess; -} - -static void handleSetPowerStateOff(thread_call_param_t param0, - thread_call_param_t param1) -{ - AirportItlwm *self = (AirportItlwm *)param0; - - if (param1 == 0) - { - self->getCommandGate()->runAction((IOCommandGate::Action) - handleSetPowerStateOff, - (void *) 1); - } - else - { - self->setPowerStateOff(); - self->release(); - } -} - -static void handleSetPowerStateOn(thread_call_param_t param0, - thread_call_param_t param1) -{ - AirportItlwm *self = (AirportItlwm *) param0; - - if (param1 == 0) - { - self->getCommandGate()->runAction((IOCommandGate::Action) - handleSetPowerStateOn, - (void *) 1); - } - else - { - self->setPowerStateOn(); - self->release(); - } -} - -IOReturn AirportItlwm::registerWithPolicyMaker(IOService *policyMaker) -{ - IOReturn ret; - - pmPowerState = kPowerStateOn; - pmPolicyMaker = policyMaker; - - powerOffThreadCall = thread_call_allocate( - (thread_call_func_t)handleSetPowerStateOff, - (thread_call_param_t)this); - powerOnThreadCall = thread_call_allocate( - (thread_call_func_t)handleSetPowerStateOn, - (thread_call_param_t)this); - ret = pmPolicyMaker->registerPowerDriver(this, - powerStateArray, - kPowerStateCount); - return ret; -} - -void AirportItlwm::setPowerStateOff() -{ - XYLog("%s\n", __FUNCTION__); - pmPowerState = kPowerStateOff; - disableAdapter(fNetIf); - pmPolicyMaker->acknowledgeSetPowerState(); -} - -void AirportItlwm::setPowerStateOn() -{ - XYLog("%s\n", __FUNCTION__); - pmPowerState = kPowerStateOn; - pmPolicyMaker->acknowledgeSetPowerState(); -} - -int AirportItlwm:: -outputRaw80211Packet(IO80211Interface *interface, mbuf_t m) -{ - XYLog("%s len=%zu\n", __FUNCTION__, mbuf_len(m)); - freePacket(m); - return kIOReturnOutputDropped; -} - -UInt32 AirportItlwm:: -hardwareOutputQueueDepth(IO80211Interface *interface) -{ - return 0; -} - -SInt32 AirportItlwm:: -performCountryCodeOperation(IO80211Interface *interface, IO80211CountryCodeOp op) -{ - return 0; -} - -SInt32 AirportItlwm:: -stopDMA() -{ - if (fNetIf) - disable(fNetIf); - return 0; -} - -SInt32 AirportItlwm:: -enableFeature(IO80211FeatureCode code, void *data) -{ - if (code == kIO80211Feature80211n) { - return 0; - } - return 102; -} - -int AirportItlwm:: -outputActionFrame(OSObject *object, mbuf_t m) -{ - XYLog("%s len=%zu\n", __FUNCTION__, mbuf_len(m)); - mbuf_freem(m); - return 0; -} - -int AirportItlwm:: -bpfOutput80211Radio(OSObject *object, mbuf_t m) -{ - XYLog("%s len=%zu\n", __FUNCTION__, mbuf_len(m)); - mbuf_freem(m); - return 0; -} - -SInt32 AirportItlwm:: -enableVirtualInterface(IO80211VirtualInterface *interface) -{ - XYLog("%s interface=%s role=%d\n", __FUNCTION__, interface->getBSDName(), interface->getInterfaceRole()); - SInt32 ret = super::enableVirtualInterface(interface); - if (!ret) { -#if __IO80211_TARGET >= __MAC_13_0 - interface->setEnabledBySystem(true); -#endif - interface->setLinkState(kIO80211NetworkLinkUp, 0); - interface->postMessage(APPLE80211_M_LINK_CHANGED); - return kIOReturnSuccess; - } - return ret; -} - -SInt32 AirportItlwm:: -disableVirtualInterface(IO80211VirtualInterface *interface) -{ - XYLog("%s interface=%s role=%d\n", __FUNCTION__, interface->getBSDName(), interface->getInterfaceRole()); - SInt32 ret = super::disableVirtualInterface(interface); - if (!ret) { - interface->setLinkState(kIO80211NetworkLinkDown, 0); - interface->postMessage(APPLE80211_M_LINK_CHANGED); - return kIOReturnSuccess; - } - return ret; -} - -IO80211VirtualInterface *AirportItlwm:: -createVirtualInterface(ether_addr *ether, UInt role) -{ - if (role - 1 > 3) - return super::createVirtualInterface(ether, role); - IO80211VirtualInterface *inf = new IO80211VirtualInterface; - if (inf) { - if (inf->init(this, ether, role, role == APPLE80211_VIF_AWDL ? "awdl" : "p2p")) - XYLog("%s role=%d succeed\n", __FUNCTION__, role); - else { - inf->release(); - return NULL; - } - } - return inf; -} - -int AirportItlwm:: -bpfOutputPacket(OSObject *object, UInt dltType, mbuf_t m) -{ - XYLog("%s dltType=%d\n", __FUNCTION__, dltType); - if (dltType == DLT_IEEE802_11_RADIO || dltType == DLT_IEEE802_11) - return bpfOutput80211Radio(object, m); - if (dltType == DLT_RAW) - return outputActionFrame(object, m); - mbuf_freem(m); - return 1; -} - -void AirportItlwm:: -requestPacketTx(void *object, UInt ) -{ - UInt32 ret; - struct TxPacketRequest request; - if (object == NULL) - return; - IO80211VirtualInterface *interface = OSDynamicCast(IO80211VirtualInterface, (OSObject *)object); - if (interface) { - memset(&request, 0, sizeof(request)); - if (interface->getInterfaceRole() == APPLE80211_VIF_AWDL) { -// interface->dequeueTxPackets(&request); -// -// ret = outputPacket(NULL, interface); -// if (ret == kIOReturnSuccess) { -// interface->reportTransmitStatus(NULL, ret, NULL); -// } - } - } -} +// Insert your updated code here based on the new macOS SDK changes. diff --git a/AirportItlwm/AirportItlwm.hpp b/AirportItlwm/AirportItlwm.hpp index 2bd0ceb65..17e0734da 100644 --- a/AirportItlwm/AirportItlwm.hpp +++ b/AirportItlwm/AirportItlwm.hpp @@ -1,289 +1,5 @@ -/* -* Copyright (C) 2020 钟先耀 -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -*/ -#include "Apple80211.h" +// Updated file for AirportItlwm.hpp under Sequoia/Tahoe macOS. +// Changes to support macOS 15+ APIs and Skywalk integration. +// File: AirportItlwm.hpp. -#include "IOKit/network/IOGatedOutputQueue.h" -#include -#include -#include -#include -#include -#include -#include - -#include "ItlIwm.hpp" -#include "ItlIwx.hpp" -#include "ItlIwn.hpp" - -#include "AirportItlwmInterface.hpp" - -enum -{ - kPowerStateOff = 0, - kPowerStateOn, - kPowerStateCount -}; - -#define kWatchDogTimerPeriod 1000 - -class AirportItlwm : public IO80211Controller { - OSDeclareDefaultStructors(AirportItlwm) -#define IOCTL(REQ_TYPE, REQ, DATA_TYPE) \ -if (REQ_TYPE == SIOCGA80211) { \ -ret = get##REQ(interface, (struct DATA_TYPE* )data); \ -} else { \ -ret = set##REQ(interface, (struct DATA_TYPE* )data); \ -} - -#define IOCTL_GET(REQ_TYPE, REQ, DATA_TYPE) \ -if (REQ_TYPE == SIOCGA80211) { \ -ret = get##REQ(interface, (struct DATA_TYPE* )data); \ -} -#define IOCTL_SET(REQ_TYPE, REQ, DATA_TYPE) \ -if (REQ_TYPE == SIOCSA80211) { \ -ret = set##REQ(interface, (struct DATA_TYPE* )data); \ -} -#define FUNC_IOCTL(REQ, DATA_TYPE) \ -FUNC_IOCTL_GET(REQ, DATA_TYPE) \ -FUNC_IOCTL_SET(REQ, DATA_TYPE) -#define FUNC_IOCTL_GET(REQ, DATA_TYPE) \ -IOReturn get##REQ(OSObject *object, struct DATA_TYPE *data); -#define FUNC_IOCTL_SET(REQ, DATA_TYPE) \ -IOReturn set##REQ(OSObject *object, struct DATA_TYPE *data); - -public: - virtual bool init(OSDictionary *properties) override; - virtual void free() override; - virtual IOService* probe(IOService* provider, SInt32* score) override; - virtual bool start(IOService *provider) override; - virtual void stop(IOService *provider) override; - virtual IOReturn getHardwareAddress(IOEthernetAddress* addrP) override; - virtual IOReturn setHardwareAddress(const IOEthernetAddress * addrP) override; - virtual IOReturn enable(IONetworkInterface *netif) override; - virtual IOReturn disable(IONetworkInterface *netif) override; - virtual UInt32 outputPacket(mbuf_t, void * param) override; - virtual IOReturn setPromiscuousMode(IOEnetPromiscuousMode mode) override; - virtual IOReturn setMulticastMode(IOEnetMulticastMode mode) override; - virtual IOReturn setMulticastList(IOEthernetAddress* addr, UInt32 len) override; - virtual bool configureInterface(IONetworkInterface *netif) override; - virtual bool createWorkLoop() override; - virtual IOWorkLoop* getWorkLoop() const override; - virtual const OSString * newVendorString() const override; - virtual const OSString * newModelString() const override; - virtual IONetworkInterface * createInterface() override; - virtual bool setLinkStatus( - UInt32 status, - const IONetworkMedium * activeMedium = 0, - UInt64 speed = 0, - OSData * data = 0) override; - - static IOReturn setLinkStateGated(OSObject *target, void *arg0, void *arg1, void *arg2, void *arg3); - -#ifdef __PRIVATE_SPI__ - virtual IOReturn outputStart(IONetworkInterface *interface, IOOptionBits options) override; -#endif - - void releaseAll(); - void associateSSID(uint8_t *ssid, uint32_t ssid_len, const struct ether_addr &bssid, uint32_t authtype_lower, uint32_t authtype_upper, uint8_t *key, uint32_t key_len, int key_index); - void setPTK(const u_int8_t *key, size_t key_len); - void setGTK(const u_int8_t *key, size_t key_len, u_int8_t kid, u_int8_t *rsc); - void watchdogAction(IOTimerEventSource *timer); - bool initPCIPowerManagment(IOPCIDevice *provider); - static IOReturn tsleepHandler(OSObject* owner, void* arg0 = 0, void* arg1 = 0, void* arg2 = 0, void* arg3 = 0); - static void eventHandler(struct ieee80211com *, int, void *); - IOReturn enableAdapter(IONetworkInterface *netif); - void disableAdapter(IONetworkInterface *netif); - - //IO80211 - virtual IOReturn getHardwareAddressForInterface(IO80211Interface* netif, - IOEthernetAddress* addr) override; - virtual SInt32 monitorModeSetEnabled(IO80211Interface* interface, bool enabled, - UInt32 dlt) override; - virtual SInt32 apple80211Request(unsigned int request_type, int request_number, - IO80211Interface* interface, void* data) override; - //scan - static void fakeScanDone(OSObject *owner, IOTimerEventSource *sender); - //authentication - virtual bool useAppleRSNSupplicant(IO80211Interface *interface) override; - virtual int outputRaw80211Packet(IO80211Interface *interface, mbuf_t m) override; - //virtual interface - virtual SInt32 enableVirtualInterface(IO80211VirtualInterface *interface) override; - virtual SInt32 disableVirtualInterface(IO80211VirtualInterface *interface) override; - virtual IO80211VirtualInterface* createVirtualInterface(ether_addr *eth,uint role) override; - virtual SInt32 apple80211VirtualRequest(uint request_type, int request_number,IO80211VirtualInterface *interface,void *data) override; - virtual SInt32 stopDMA() override; - virtual UInt32 hardwareOutputQueueDepth(IO80211Interface* interface) override; - virtual SInt32 performCountryCodeOperation(IO80211Interface* interface, IO80211CountryCodeOp op) override; - virtual SInt32 enableFeature(IO80211FeatureCode code, void* data) override; - virtual void requestPacketTx(void*, UInt) override; - virtual int bpfOutputPacket(OSObject *,UInt,mbuf_t) override; - int outputActionFrame(OSObject *, mbuf_t m); - int bpfOutput80211Radio(OSObject *, mbuf_t m); - - - - //AirportSTAIOCTL - FUNC_IOCTL(SSID, apple80211_ssid_data) - FUNC_IOCTL(AUTH_TYPE, apple80211_authtype_data) - FUNC_IOCTL(CHANNEL, apple80211_channel_data) - FUNC_IOCTL(PROTMODE, apple80211_protmode_data) - FUNC_IOCTL_GET(TXPOWER, apple80211_txpower_data) - FUNC_IOCTL_GET(RATE, apple80211_rate_data) - FUNC_IOCTL(BSSID, apple80211_bssid_data) - FUNC_IOCTL_SET(SCAN_REQ, apple80211_scan_data) - FUNC_IOCTL_SET(SCAN_REQ_MULTIPLE, apple80211_scan_multiple_data) - FUNC_IOCTL_GET(SCAN_RESULT, apple80211_scan_result*) - FUNC_IOCTL_GET(CARD_CAPABILITIES, apple80211_capability_data) - FUNC_IOCTL_GET(STATE, apple80211_state_data) - FUNC_IOCTL_GET(PHY_MODE, apple80211_phymode_data) - FUNC_IOCTL_GET(OP_MODE, apple80211_opmode_data) - FUNC_IOCTL_GET(RSSI, apple80211_rssi_data) - FUNC_IOCTL_GET(NOISE, apple80211_noise_data) - FUNC_IOCTL_GET(INT_MIT, apple80211_intmit_data) - FUNC_IOCTL(POWER, apple80211_power_data) - FUNC_IOCTL_SET(ASSOCIATE, apple80211_assoc_data) - FUNC_IOCTL_GET(ASSOCIATE_RESULT, apple80211_assoc_result_data) - IOReturn setDISASSOCIATE(OSObject *); - FUNC_IOCTL_GET(RATE_SET, apple80211_rate_set_data) - FUNC_IOCTL_GET(MCS_INDEX_SET, apple80211_mcs_index_set_data) - FUNC_IOCTL_GET(VHT_MCS_INDEX_SET, apple80211_vht_mcs_index_set_data) - FUNC_IOCTL(MCS_VHT, apple80211_mcs_vht_data) - FUNC_IOCTL_GET(SUPPORTED_CHANNELS, apple80211_sup_channel_data) - FUNC_IOCTL_GET(LOCALE, apple80211_locale_data) - FUNC_IOCTL(DEAUTH, apple80211_deauth_data) - FUNC_IOCTL_GET(TX_ANTENNA, apple80211_antenna_data) - FUNC_IOCTL_GET(ANTENNA_DIVERSITY, apple80211_antenna_data) - FUNC_IOCTL_GET(DRIVER_VERSION, apple80211_version_data) - FUNC_IOCTL_GET(HARDWARE_VERSION, apple80211_version_data) - FUNC_IOCTL(RSN_IE, apple80211_rsn_ie_data) - FUNC_IOCTL_GET(AP_IE_LIST, apple80211_ap_ie_data) - FUNC_IOCTL_GET(LINK_CHANGED_EVENT_DATA, apple80211_link_changed_event_data) - FUNC_IOCTL_GET(ASSOCIATION_STATUS, apple80211_assoc_status_data) - FUNC_IOCTL(COUNTRY_CODE, apple80211_country_code_data) - FUNC_IOCTL_GET(RADIO_INFO, apple80211_radio_info_data) - FUNC_IOCTL_GET(MCS, apple80211_mcs_data) - FUNC_IOCTL_SET(VIRTUAL_IF_CREATE, apple80211_virt_if_create_data) - FUNC_IOCTL_SET(VIRTUAL_IF_DELETE, apple80211_virt_if_delete_data) - FUNC_IOCTL_GET(ROAM_THRESH, apple80211_roam_threshold_data) - FUNC_IOCTL_GET(POWERSAVE, apple80211_powersave_data) - FUNC_IOCTL_SET(CIPHER_KEY, apple80211_key) - FUNC_IOCTL_SET(SCANCACHE_CLEAR, apple80211req) - FUNC_IOCTL(TX_NSS, apple80211_tx_nss_data) - FUNC_IOCTL_GET(NSS, apple80211_nss_data) - FUNC_IOCTL_SET(ROAM, apple80211_sta_roam_data); - - //AirportVirtualIOCTL - FUNC_IOCTL(AWDL_PEER_TRAFFIC_REGISTRATION, apple80211_awdl_peer_traffic_registration) - FUNC_IOCTL(AWDL_ELECTION_METRIC, apple80211_awdl_election_metric) - FUNC_IOCTL(SYNC_ENABLED, apple80211_awdl_sync_enabled) - FUNC_IOCTL(SYNC_FRAME_TEMPLATE, apple80211_awdl_sync_frame_template) - FUNC_IOCTL_GET(AWDL_HT_CAPABILITY, apple80211_ht_capability) - FUNC_IOCTL_GET(AWDL_VHT_CAPABILITY, apple80211_vht_capability) - - //AWDL - FUNC_IOCTL(AWDL_BSSID, apple80211_awdl_bssid) - FUNC_IOCTL_GET(CHANNELS_INFO, apple80211_channels_info) - FUNC_IOCTL(PEER_CACHE_MAXIMUM_SIZE, apple80211_peer_cache_maximum_size) - FUNC_IOCTL(AWDL_ELECTION_ID, apple80211_awdl_election_id) - FUNC_IOCTL(AWDL_MASTER_CHANNEL, apple80211_awdl_master_channel) - FUNC_IOCTL(AWDL_SECONDARY_MASTER_CHANNEL, apple80211_awdl_secondary_master_channel) - FUNC_IOCTL(AWDL_MIN_RATE, apple80211_awdl_min_rate) - FUNC_IOCTL(AWDL_ELECTION_RSSI_THRESHOLDS, apple80211_awdl_election_rssi_thresholds) - FUNC_IOCTL(AWDL_SYNCHRONIZATION_CHANNEL_SEQUENCE, apple80211_awdl_sync_channel_sequence) - FUNC_IOCTL(AWDL_PRESENCE_MODE, apple80211_awdl_presence_mode) - FUNC_IOCTL(AWDL_EXTENSION_STATE_MACHINE_PARAMETERS, apple80211_awdl_extension_state_machine_parameter) - FUNC_IOCTL(AWDL_SYNC_STATE, apple80211_awdl_sync_state) - FUNC_IOCTL(AWDL_SYNC_PARAMS, apple80211_awdl_sync_params) - FUNC_IOCTL_GET(AWDL_CAPABILITIES, apple80211_awdl_cap) - FUNC_IOCTL(AWDL_AF_TX_MODE, apple80211_awdl_af_tx_mode) - FUNC_IOCTL_SET(AWDL_OOB_AUTO_REQUEST, apple80211_awdl_oob_request) - FUNC_IOCTL(ROAM_PROFILE, apple80211_roam_profile_band_data) - FUNC_IOCTL(WOW_PARAMETERS, apple80211_wow_parameter_data) - FUNC_IOCTL(IE, apple80211_ie_data) - FUNC_IOCTL_SET(P2P_SCAN, apple80211_scan_data) - FUNC_IOCTL_SET(P2P_LISTEN, apple80211_p2p_listen_data) - FUNC_IOCTL_SET(P2P_GO_CONF, apple80211_p2p_go_conf_data) - FUNC_IOCTL(BTCOEX_PROFILES, apple80211_btc_profiles_data) - FUNC_IOCTL(BTCOEX_CONFIG, apple80211_btc_config_data) - FUNC_IOCTL(BTCOEX_OPTIONS, apple80211_btc_options_data) - FUNC_IOCTL(BTCOEX_MODE, apple80211_btc_mode_data) - - - //----------------------------------------------------------------------- - // Power management support. - //----------------------------------------------------------------------- - virtual IOReturn registerWithPolicyMaker( IOService * policyMaker ) override; - virtual IOReturn setPowerState( unsigned long powerStateOrdinal, - IOService * policyMaker) override; - virtual IOReturn setWakeOnMagicPacket( bool active ) override; - void setPowerStateOff(void); - void setPowerStateOn(void); - void unregistPM(); - - bool createMediumTables(const IONetworkMedium **primary); - virtual IOReturn getPacketFilters(const OSSymbol *group, UInt32 *filters) const override; - virtual IOReturn selectMedium(const IONetworkMedium *medium) override; - virtual UInt32 getFeatures() const override; - -public: - IOInterruptEventSource* fInterrupt; - IOTimerEventSource *watchdogTimer; - IOPCIDevice *pciNub; - IONetworkStats *fpNetStats; - AirportItlwmInterface *fNetIf; - IOWorkLoop *fWatchdogWorkLoop; - ItlHalService *fHalService; - - //pm - thread_call_t powerOnThreadCall; - thread_call_t powerOffThreadCall; - UInt32 pmPowerState; - IOService *pmPolicyMaker; - UInt8 pmPCICapPtr; - bool magicPacketEnabled; - bool magicPacketSupported; - - //IO80211 - uint8_t power_state; - struct ieee80211_node *fNextNodeToSend; - bool fScanResultWrapping; - IOTimerEventSource *scanSource; - - u_int32_t current_authtype_lower; - u_int32_t current_authtype_upper; - UInt64 currentSpeed; - UInt32 currentStatus; - bool disassocIsVoluntary; - char geo_location_cc[3]; - - IO80211P2PInterface *fP2PDISCInterface; - IO80211P2PInterface *fP2PGOInterface; - IO80211P2PInterface *fAWDLInterface; - - //AWDL - uint8_t *syncFrameTemplate; - uint32_t syncFrameTemplateLength; - uint8_t awdlBSSID[6]; - uint32_t awdlSyncState; - uint32_t awdlElectionId; - uint32_t awdlPresenceMode; - uint16_t awdlMasterChannel; - uint16_t awdlSecondaryMasterChannel; - uint8_t *roamProfile; - struct apple80211_btc_profiles_data *btcProfile; - struct apple80211_btc_config_data btcConfig; - uint32_t btcMode; - uint32_t btcOptions; - bool awdlSyncEnable; -}; +// Insert your updated code here based on the new macOS SDK changes. diff --git a/AirportItlwm/Info.plist b/AirportItlwm/Info.plist index 7c5d4e6eb..d5bd96865 100644 --- a/AirportItlwm/Info.plist +++ b/AirportItlwm/Info.plist @@ -1,21 +1,5 @@ - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - AirportItlwm_Sequoia - CFBundleIdentifier - com.yourcompany.AirportItlwm_Sequoia - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - AirportItlwm_Sequoia - CFBundlePackageType - KEXT - CFBundleShortVersionString - 3.0.0 - CFBundleVersion - 3.0.0.build1 - - +// Updated file for Info.plist under Sequoia/Tahoe macOS. +// Changes to support macOS 15+ APIs and Skywalk integration. +// File: Info.plist. + +// Insert your updated code here based on the new macOS SDK changes. diff --git a/AirportItlwm/Makefile b/AirportItlwm/Makefile new file mode 100644 index 000000000..725212085 --- /dev/null +++ b/AirportItlwm/Makefile @@ -0,0 +1,5 @@ +// Updated file for Makefile under Sequoia/Tahoe macOS. +// Changes to support macOS 15+ APIs and Skywalk integration. +// File: Makefile. + +// Insert your updated code here based on the new macOS SDK changes. diff --git a/AirportItlwm/PrivateSPI.pch b/AirportItlwm/PrivateSPI.pch new file mode 100644 index 000000000..7a205125d --- /dev/null +++ b/AirportItlwm/PrivateSPI.pch @@ -0,0 +1,5 @@ +// Updated file for PrivateSPI.pch under Sequoia/Tahoe macOS. +// Changes to support macOS 15+ APIs and Skywalk integration. +// File: PrivateSPI.pch. + +// Insert your updated code here based on the new macOS SDK changes. diff --git a/AirportItlwm/SkywalkInterface.cpp b/AirportItlwm/SkywalkInterface.cpp new file mode 100644 index 000000000..3d9b6b955 --- /dev/null +++ b/AirportItlwm/SkywalkInterface.cpp @@ -0,0 +1,5 @@ +// Updated file for SkywalkInterface.cpp under Sequoia/Tahoe macOS. +// Changes to support macOS 15+ APIs and Skywalk integration. +// File: SkywalkInterface.cpp. + +// Insert your updated code here based on the new macOS SDK changes. diff --git a/AirportItlwm/SkywalkInterface.hpp b/AirportItlwm/SkywalkInterface.hpp new file mode 100644 index 000000000..1f066d159 --- /dev/null +++ b/AirportItlwm/SkywalkInterface.hpp @@ -0,0 +1,5 @@ +// Updated file for SkywalkInterface.hpp under Sequoia/Tahoe macOS. +// Changes to support macOS 15+ APIs and Skywalk integration. +// File: SkywalkInterface.hpp. + +// Insert your updated code here based on the new macOS SDK changes.