1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * Copyright (c) 2017-2026 Morse Micro 4 */ 5 6 #ifndef _MM81X_SKBQ_H_ 7 #define _MM81X_SKBQ_H_ 8 9 #include <linux/skbuff.h> 10 #include <linux/workqueue.h> 11 #include "rate_code.h" 12 13 /* Sync value of skb header to indicate a valid skb */ 14 #define MM81X_SKB_HEADER_SYNC (0xAA) 15 /* Sync value indicating that the chip owns this skb */ 16 #define MM81X_SKB_HEADER_CHIP_OWNED_SYNC (0xBB) 17 18 enum mm81x_tx_status_and_conf_flags { 19 MM81X_TX_STATUS_FLAGS_NO_ACK = BIT(0), 20 MM81X_TX_STATUS_FLAGS_NO_REPORT = BIT(1), 21 MM81X_TX_CONF_FLAGS_CTL_AMPDU = BIT(2), 22 MM81X_TX_CONF_FLAGS_HW_ENCRYPT = BIT(3), 23 MM81X_TX_CONF_FLAGS_VIF_ID = (BIT(4) | BIT(5) | BIT(6) | BIT(7) | 24 BIT(8) | BIT(9) | BIT(10) | BIT(11)), 25 MM81X_TX_CONF_FLAGS_KEY_IDX = (BIT(12) | BIT(13) | BIT(14)), 26 MM81X_TX_STATUS_FLAGS_PS_FILTERED = (BIT(15)), 27 MM81X_TX_CONF_IGNORE_TWT = (BIT(16)), 28 MM81X_TX_STATUS_PAGE_INVALID = (BIT(17)), 29 MM81X_TX_CONF_NO_PS_BUFFER = (BIT(18)), 30 MM81X_TX_STATUS_DUTY_CYCLE_CANT_SEND = (BIT(19)), 31 MM81X_TX_CONF_HAS_PV1_BPN_IN_BODY = (BIT(21)), 32 MM81X_TX_CONF_FLAGS_SEND_AFTER_DTIM = (BIT(22)), 33 MM81X_TX_STATUS_WAS_AGGREGATED = (BIT(23)), 34 MM81X_TX_CONF_FLAGS_FULLMAC_REPORT = BIT(24), 35 MM81X_TX_CONF_FLAGS_IMMEDIATE_REPORT = (BIT(31)) 36 }; 37 38 /* Getter and setter macros for vif id */ 39 #define MM81X_TX_CONF_FLAGS_VIF_ID_MASK (0xFF) 40 #define MM81X_TX_CONF_FLAGS_VIF_ID_SET(x) \ 41 (((x) & MM81X_TX_CONF_FLAGS_VIF_ID_MASK) << 4) 42 #define MM81X_TX_CONF_FLAGS_VIF_ID_GET(x) \ 43 (((x) & MM81X_TX_CONF_FLAGS_VIF_ID) >> 4) 44 45 /* Getter and setter macros for key index */ 46 #define MM81X_TX_CONF_FLAGS_KEY_IDX_SET(x) (((x) & 0x07) << 12) 47 #define MM81X_TX_CONF_FLAGS_KEY_IDX_GET(x) \ 48 (((x) & MM81X_TX_CONF_FLAGS_KEY_IDX) >> 12) 49 50 enum mm81x_rx_status_flags { 51 MM81X_RX_STATUS_FLAGS_ERROR = BIT(0), 52 MM81X_RX_STATUS_FLAGS_DECRYPTED = BIT(1), 53 MM81X_RX_STATUS_FLAGS_FCS_INCLUDED = BIT(2), 54 MM81X_RX_STATUS_FLAGS_EOF = BIT(3), 55 MM81X_RX_STATUS_FLAGS_AMPDU = BIT(4), 56 MM81X_RX_STATUS_FLAGS_NDP = BIT(7), 57 MM81X_RX_STATUS_FLAGS_UPLINK = BIT(8), 58 MM81X_RX_STATUS_FLAGS_RI = (BIT(9) | BIT(10)), 59 MM81X_RX_STATUS_FLAGS_NDP_TYPE = (BIT(11) | BIT(12) | BIT(13)), 60 MM81X_RX_STATUS_FLAGS_CRC_ERROR = BIT(14), 61 MM81X_RX_STATUS_FLAGS_VIF_ID = GENMASK(24, 17), 62 }; 63 64 /* Getter and Setter macros for vif id */ 65 #define MM81X_RX_STATUS_FLAGS_VIF_ID_MASK (0xFF) 66 #define MM81X_RX_STATUS_FLAGS_VIF_ID_SET(x) \ 67 (((x) & MM81X_RX_STATUS_FLAGS_VIF_ID_MASK) << 17) 68 #define MM81X_RX_STATUS_FLAGS_VIF_ID_GET(x) \ 69 (((x) & MM81X_RX_STATUS_FLAGS_VIF_ID) >> 17) 70 #define MM81X_RX_STATUS_FLAGS_VIF_ID_CLEAR(x) \ 71 ((x) & ~(MM81X_RX_STATUS_FLAGS_VIF_ID_MASK << 17)) 72 73 /* Getter macro for guard interval */ 74 #define MM81X_RX_STATUS_FLAGS_UPL_IND_GET(x) \ 75 (((x) & MM81X_RX_STATUS_FLAGS_UPLINK) >> 8) 76 77 /* Getter macro for response indication */ 78 #define MM81X_RX_STATUS_FLAGS_RI_GET(x) (((x) & MM81X_RX_STATUS_FLAGS_RI) >> 9) 79 80 /* Getter macro for NDP type */ 81 #define MM81X_RX_STATUS_FLAGS_NDP_TYPE_GET(x) \ 82 (((x) & MM81X_RX_STATUS_FLAGS_NDP_TYPE) >> 11) 83 84 enum mm81x_skb_channel { 85 MM81X_SKB_CHAN_DATA = 0x0, 86 MM81X_SKB_CHAN_NDP_FRAMES = 0x1, 87 MM81X_SKB_CHAN_DATA_NOACK = 0x2, 88 MM81X_SKB_CHAN_BEACON = 0x3, 89 MM81X_SKB_CHAN_MGMT = 0x4, 90 MM81X_SKB_CHAN_INTERNAL_CRIT_BEACON = 0x80, 91 MM81X_SKB_CHAN_COMMAND = 0xFE, 92 MM81X_SKB_CHAN_TX_STATUS = 0xFF 93 }; 94 95 #define MM81X_SKB_MAX_RATES (4) 96 97 struct mm81x_skb_rate_info { 98 mm81x_rate_code_t mm81x_ratecode; 99 u8 count; 100 } __packed; 101 102 struct mm81x_skb_tx_status { 103 __le32 flags; 104 __le32 pkt_id; 105 u8 tid; 106 u8 channel; 107 __le16 ampdu_info; 108 struct mm81x_skb_rate_info rates[MM81X_SKB_MAX_RATES]; 109 } __packed; 110 111 #define MM81X_TXSTS_AMPDU_INFO_GET_TAG(x) (((x) >> 10) & 0x3F) 112 #define MM81X_TXSTS_AMPDU_INFO_GET_LEN(x) (((x) >> 5) & 0x1F) 113 #define MM81X_TXSTS_AMPDU_INFO_GET_SUC(x) ((x) & 0x1F) 114 115 struct mm81x_skb_tx_info { 116 __le32 flags; 117 __le32 pkt_id; 118 u8 tid; 119 u8 tid_params; 120 u8 mmss_params; 121 u8 padding[1]; 122 struct mm81x_skb_rate_info rates[MM81X_SKB_MAX_RATES]; 123 } __packed; 124 125 #define TX_INFO_TID_PARAMS_MAX_REORDER_BUF 0x1f 126 #define TX_INFO_TID_PARAMS_AMPDU_ENABLED 0x20 127 #define TX_INFO_TID_PARAMS_AMSDU_SUPPORTED 0x40 128 #define TX_INFO_TID_PARAMS_USE_LEGACY_BA 0x80 129 130 /* Bitmap for MMSS (Minimum MPDU start spacing) parameters 131 * +-----------+-----------+ 132 * | Morse | MMSS set | 133 * | MMSS | by S1G cap| 134 * | offset | IE | 135 * |-----------|-----------| 136 * |b7|b6|b5|b4|b3|b2|b1|b0| 137 */ 138 #define TX_INFO_MMSS_PARAMS_MMSS_MASK GENMASK(3, 0) 139 #define TX_INFO_MMSS_PARAMS_MMSS_OFFSET_START 4 140 #define TX_INFO_MMSS_PARAMS_MMSS_OFFSET_MASK GENMASK(7, 4) 141 #define TX_INFO_MMSS_PARAMS_SET_MMSS(x) ((x) & TX_INFO_MMSS_PARAMS_MMSS_MASK) 142 #define TX_INFO_MMSS_PARAMS_SET_MMSS_OFFSET(x) \ 143 (((x) << TX_INFO_MMSS_PARAMS_MMSS_OFFSET_START) & \ 144 TX_INFO_MMSS_PARAMS_MMSS_OFFSET_MASK) 145 146 struct mm81x_skb_rx_status { 147 __le32 flags; 148 mm81x_rate_code_t mm81x_ratecode; 149 __le16 rssi; 150 __le16 freq_100khz; 151 u8 bss_color; 152 s8 noise_dbm; 153 /** Padding for word alignment */ 154 u8 padding[2]; 155 __le64 rx_timestamp_us; 156 } __packed; 157 158 struct mm81x_skb_hdr { 159 u8 sync; 160 u8 channel; 161 __le16 len; 162 u8 offset; 163 u8 checksum_lower; 164 __le16 checksum_upper; 165 union { 166 struct mm81x_skb_tx_info tx_info; 167 struct mm81x_skb_tx_status tx_status; 168 struct mm81x_skb_rx_status rx_status; 169 }; 170 } __packed; 171 172 #define MM81X_SKBQ_SIZE (4 * 128 * 1024) 173 174 struct mm81x; 175 176 struct mm81x_skbq { 177 struct mm81x *mors; 178 u32 pkt_seq; /* SKB sequence used in tx_status */ 179 u16 flags; 180 u32 skbq_size; /* current off loaded size */ 181 spinlock_t lock; 182 struct sk_buff_head skbq; 183 struct sk_buff_head pending; /* packets sent pending feedback */ 184 struct work_struct dispatch_work; 185 }; 186 187 void mm81x_skbq_purge(struct mm81x_skbq *mq, struct sk_buff_head *skbq); 188 void mm81x_skbq_purge_aged(struct mm81x *mors, struct mm81x_skbq *mq); 189 u32 mm81x_skbq_space(struct mm81x_skbq *mq); 190 u32 mm81x_skbq_size(struct mm81x_skbq *mq); 191 int mm81x_skbq_deq_num_skb(struct mm81x_skbq *mq, struct sk_buff_head *skbq, 192 int num_skb); 193 struct sk_buff *mm81x_skbq_alloc_skb(struct mm81x_skbq *mq, 194 unsigned int length); 195 int mm81x_skbq_skb_tx(struct mm81x_skbq *mq, struct sk_buff **skb, 196 struct mm81x_skb_tx_info *tx_info, u8 channel); 197 int mm81x_skbq_put(struct mm81x_skbq *mq, struct sk_buff *skb); 198 void mm81x_skbq_enq(struct mm81x_skbq *mq, struct sk_buff_head *skbq); 199 void mm81x_skbq_enq_prepend(struct mm81x_skbq *mq, struct sk_buff_head *skbq); 200 void mm81x_skbq_tx_complete(struct mm81x_skbq *mq, struct sk_buff_head *skbq); 201 struct sk_buff *mm81x_skbq_tx_pending(struct mm81x_skbq *mq); 202 void mm81x_skbq_init(struct mm81x *mors, struct mm81x_skbq *mq, u16 flags); 203 void mm81x_skbq_finish(struct mm81x_skbq *mq); 204 void mm81x_skbq_pull_hdr_post_tx(struct sk_buff *skb); 205 void mm81x_skbq_mon_dump(struct mm81x *mors, struct seq_file *file); 206 void mm81x_skbq_skb_finish(struct mm81x_skbq *mq, struct sk_buff *skb, 207 struct mm81x_skb_tx_status *tx_sts); 208 void mm81x_skbq_tx_flush(struct mm81x_skbq *mq); 209 int mm81x_skbq_check_for_stale_tx(struct mm81x *mors, struct mm81x_skbq *mq); 210 void mm81x_skbq_may_wake_tx_queues(struct mm81x *mors); 211 u32 mm81x_skbq_count_tx_ready(struct mm81x_skbq *mq); 212 u32 mm81x_skbq_count(struct mm81x_skbq *mq); 213 u32 mm81x_skbq_pending_count(struct mm81x_skbq *mq); 214 void mm81x_skbq_data_traffic_pause(struct mm81x *mors); 215 void mm81x_skbq_data_traffic_resume(struct mm81x *mors); 216 bool mm81x_skbq_validate_checksum(u8 *data); 217 218 #endif /* !_MM81X_SKBQ_H_ */ 219