1 /* 2 * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for 5 * any purpose with or without fee is hereby granted, provided that the 6 * above copyright notice and this permission notice appear in all 7 * copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 /** 20 * @file ol_tx.h 21 * @brief Internal definitions for the high-level tx module. 22 */ 23 #ifndef _OL_TX__H_ 24 #define _OL_TX__H_ 25 26 #include <qdf_nbuf.h> /* qdf_nbuf_t */ 27 #include <qdf_lock.h> 28 #include <cdp_txrx_cmn.h> /* ol_txrx_vdev_t, etc. */ 29 #include <cdp_txrx_misc.h> /* ol_tx_spec */ 30 #include <cdp_txrx_handle.h> 31 #include <ol_txrx_types.h> /* ol_tx_desc_t, ol_txrx_msdu_info_t */ 32 #include <hif.h> 33 34 #ifdef IPA_OFFLOAD 35 /** 36 * ol_tx_send_ipa_data_frame() - send IPA data frame 37 * @vdev: vdev 38 * @skb: skb 39 * 40 * Return: skb/ NULL is for success 41 */ 42 qdf_nbuf_t ol_tx_send_ipa_data_frame(struct cdp_vdev *vdev, qdf_nbuf_t skb); 43 #endif 44 45 #ifdef CONFIG_LL_DP_SUPPORT 46 struct ol_tx_desc_t * 47 ol_tx_prepare_ll(ol_txrx_vdev_handle vdev, 48 qdf_nbuf_t msdu, 49 struct ol_txrx_msdu_info_t *msdu_info); 50 #endif 51 52 qdf_nbuf_t ol_tx_ll_wrapper(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list); 53 #ifdef WLAN_FEATURE_FASTPATH 54 qdf_nbuf_t ol_tx_ll_fast(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list); 55 56 void ol_tx_setup_fastpath_ce_handles(struct hif_opaque_softc *osc, 57 struct ol_txrx_pdev_t *pdev); 58 #else 59 static inline 60 void ol_tx_setup_fastpath_ce_handles(struct hif_opaque_softc *osc, 61 struct ol_txrx_pdev_t *pdev) 62 { } 63 64 qdf_nbuf_t ol_tx_ll(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list); 65 #endif 66 67 qdf_nbuf_t ol_tx_ll_queue(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list); 68 69 #ifdef CONFIG_HL_SUPPORT 70 #define OL_TX_SEND ol_tx_hl 71 #else 72 #define OL_TX_SEND OL_TX_LL 73 #endif 74 75 #ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL 76 #define OL_TX_LL ol_tx_ll_queue 77 #else 78 #define OL_TX_LL ol_tx_ll_wrapper 79 #endif 80 81 #ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL 82 void ol_tx_vdev_ll_pause_queue_send(void *context); 83 void ol_tx_pdev_ll_pause_queue_send_all(struct ol_txrx_pdev_t *pdev); 84 #else 85 static inline void ol_tx_vdev_ll_pause_queue_send(void *context) 86 { 87 } 88 static inline 89 void ol_tx_pdev_ll_pause_queue_send_all(struct ol_txrx_pdev_t *pdev) 90 { 91 } 92 #endif 93 94 static inline 95 int ol_txrx_tx_is_raw(enum ol_tx_spec tx_spec) 96 { 97 return tx_spec & 98 (OL_TX_SPEC_RAW | OL_TX_SPEC_NO_AGGR | OL_TX_SPEC_NO_ENCRYPT); 99 } 100 101 static inline 102 uint8_t ol_txrx_tx_raw_subtype(enum ol_tx_spec tx_spec) 103 { 104 uint8_t sub_type = 0x1; /* 802.11 MAC header present */ 105 106 if (tx_spec & OL_TX_SPEC_NO_AGGR) 107 sub_type |= 0x1 << HTT_TX_MSDU_DESC_RAW_SUBTYPE_NO_AGGR_S; 108 if (tx_spec & OL_TX_SPEC_NO_ENCRYPT) 109 sub_type |= 0x1 << HTT_TX_MSDU_DESC_RAW_SUBTYPE_NO_ENCRYPT_S; 110 if (tx_spec & OL_TX_SPEC_NWIFI_NO_ENCRYPT) 111 sub_type |= 0x1 << HTT_TX_MSDU_DESC_RAW_SUBTYPE_NO_ENCRYPT_S; 112 return sub_type; 113 } 114 115 /** 116 * ol_tx_hl() - transmit tx frames for a HL system. 117 * @vdev: the virtual device transmit the data 118 * @msdu_list: the tx frames to send 119 * 120 * Return: NULL if all MSDUs are accepted 121 */ 122 qdf_nbuf_t 123 ol_tx_hl(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list); 124 125 /** 126 * ol_tx_non_std() - Allow the control-path SW to send data frames 127 * @data_vdev: which vdev should transmit the tx data frames 128 * @tx_spec: what non-standard handling to apply to the tx data frames 129 * @msdu_list: NULL-terminated list of tx MSDUs 130 * 131 * Generally, all tx data frames come from the OS shim into the txrx layer. 132 * However, there are rare cases such as TDLS messaging where the UMAC 133 * control-path SW creates tx data frames. 134 * This UMAC SW can call this function to provide the tx data frames to 135 * the txrx layer. 136 * The UMAC SW can request a callback for these data frames after their 137 * transmission completes, by using the ol_txrx_data_tx_cb_set function 138 * to register a tx completion callback, and by specifying 139 * ol_tx_spec_no_free as the tx_spec arg when giving the frames to 140 * ol_tx_non_std. 141 * The MSDUs need to have the appropriate L2 header type (802.3 vs. 802.11), 142 * as specified by ol_cfg_frame_type(). 143 * 144 * Return: null - success, skb - failure 145 */ 146 #ifdef CONFIG_HL_SUPPORT 147 qdf_nbuf_t ol_tx_non_std_hl(struct ol_txrx_vdev_t *vdev, 148 enum ol_tx_spec tx_spec, 149 qdf_nbuf_t msdu_list); 150 151 static inline qdf_nbuf_t 152 ol_tx_non_std(struct cdp_vdev *pvdev, 153 enum ol_tx_spec tx_spec, qdf_nbuf_t msdu_list) 154 { 155 struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev; 156 157 return ol_tx_non_std_hl(vdev, tx_spec, msdu_list); 158 } 159 #else 160 qdf_nbuf_t ol_tx_non_std_ll(struct ol_txrx_vdev_t *vdev, 161 enum ol_tx_spec tx_spec, qdf_nbuf_t msdu_list); 162 163 static inline qdf_nbuf_t 164 ol_tx_non_std(struct cdp_vdev *pvdev, 165 enum ol_tx_spec tx_spec, qdf_nbuf_t msdu_list) 166 { 167 struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev; 168 169 return ol_tx_non_std_ll(vdev, tx_spec, msdu_list); 170 } 171 #endif 172 173 void ol_txrx_mgmt_tx_complete(void *ctxt, qdf_nbuf_t netbuf, int err); 174 175 /** 176 * ol_txrx_mgmt_tx_cb_set() - Store a callback for delivery 177 * notifications for management frames. 178 * @ppdev: the data physical device object 179 * @type: the type of mgmt frame the callback is used for 180 * @download_cb: the callback for notification of delivery to the target 181 * @ota_ack_cb: the callback for notification of delivery to the peer 182 * @ctxt: context to use with the callback 183 * 184 * When the txrx SW receives notifications from the target that a tx frame 185 * has been delivered to its recipient, it will check if the tx frame 186 * is a management frame. If so, the txrx SW will check the management 187 * frame type specified when the frame was submitted for transmission. 188 * If there is a callback function registered for the type of management 189 * frame in question, the txrx code will invoke the callback to inform 190 * the management + control SW that the mgmt frame was delivered. 191 * This function is used by the control SW to store a callback pointer 192 * for a given type of management frame. 193 */ 194 void 195 ol_txrx_mgmt_tx_cb_set(struct cdp_pdev *ppdev, uint8_t type, 196 ol_txrx_mgmt_tx_cb download_cb, 197 ol_txrx_mgmt_tx_cb ota_ack_cb, void *ctxt); 198 199 /** 200 * ol_txrx_mgmt_send_ext() - Transmit a management frame 201 * @pvdev: virtual device transmitting the frame 202 * @tx_mgmt_frm: management frame to transmit 203 * @type: the type of management frame (determines what callback to use) 204 * @use_6mbps: specify whether management frame to transmit should 205 * use 6 Mbps rather than 1 Mbps min rate(for 5GHz band or P2P) 206 * @chanfreq: channel to transmit the frame on 207 * 208 * Send the specified management frame from the specified virtual device. 209 * The type is used for determining whether to invoke a callback to inform 210 * the sender that the tx mgmt frame was delivered, and if so, which 211 * callback to use. 212 * 213 * Return: 0 - the frame is accepted for transmission 214 * 1 - the frame was not accepted 215 */ 216 int 217 ol_txrx_mgmt_send_ext(struct cdp_vdev *pvdev, 218 qdf_nbuf_t tx_mgmt_frm, 219 uint8_t type, uint8_t use_6mbps, uint16_t chanfreq); 220 221 qdf_nbuf_t 222 ol_tx_reinject(struct ol_txrx_vdev_t *vdev, qdf_nbuf_t msdu, uint16_t peer_id); 223 224 #if defined(FEATURE_TSO) 225 void ol_tso_seg_list_init(struct ol_txrx_pdev_t *pdev, uint32_t num_seg); 226 void ol_tso_seg_list_deinit(struct ol_txrx_pdev_t *pdev); 227 void ol_tso_num_seg_list_init(struct ol_txrx_pdev_t *pdev, uint32_t num_seg); 228 void ol_tso_num_seg_list_deinit(struct ol_txrx_pdev_t *pdev); 229 uint32_t ol_tx_tso_get_stats_idx(struct ol_txrx_pdev_t *pdev); 230 uint8_t ol_tx_prepare_tso(ol_txrx_vdev_handle vdev, 231 qdf_nbuf_t msdu, 232 struct ol_txrx_msdu_info_t *msdu_info); 233 void ol_tx_tso_update_stats(struct ol_txrx_pdev_t *pdev, 234 struct qdf_tso_info_t *tso_info, qdf_nbuf_t msdu, 235 uint32_t tso_msdu_idx); 236 #else 237 static inline uint32_t ol_tx_tso_get_stats_idx(struct ol_txrx_pdev_t *pdev) 238 { 239 return 0; 240 } 241 242 static inline void ol_tso_seg_list_init(struct ol_txrx_pdev_t *pdev, 243 uint32_t num_seg) 244 { 245 } 246 247 static inline void ol_tso_seg_list_deinit(struct ol_txrx_pdev_t *pdev) 248 { 249 } 250 251 static inline void ol_tso_num_seg_list_init(struct ol_txrx_pdev_t *pdev, 252 uint32_t num_seg) 253 { 254 } 255 256 static inline void ol_tso_num_seg_list_deinit(struct ol_txrx_pdev_t *pdev) 257 { 258 } 259 260 static inline uint8_t ol_tx_prepare_tso(ol_txrx_vdev_handle vdev, 261 qdf_nbuf_t msdu, 262 struct ol_txrx_msdu_info_t *msdu_info) 263 { 264 return 0; 265 } 266 267 static inline void ol_tx_tso_update_stats(struct ol_txrx_pdev_t *pdev, 268 struct qdf_tso_info_t *tso_info, 269 qdf_nbuf_t msdu, 270 uint32_t tso_msdu_idx) 271 { 272 } 273 #endif 274 275 #ifdef QCA_HL_NETDEV_FLOW_CONTROL 276 bool ol_tx_desc_is_high_prio(qdf_nbuf_t msdu); 277 #endif 278 279 #if defined(HELIUMPLUS) 280 void ol_txrx_dump_frag_desc(char *msg, struct ol_tx_desc_t *tx_desc); 281 #else 282 static inline 283 void ol_txrx_dump_frag_desc(char *msg, struct ol_tx_desc_t *tx_desc) 284 { 285 } 286 #endif 287 288 #endif /* _OL_TX__H_ */ 289