Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame^] | 1 | /* |
| 2 | * Copyright (c) 2012, 2014-2015 The Linux Foundation. All rights reserved. |
| 3 | * |
| 4 | * Previously licensed under the ISC license by Qualcomm Atheros, Inc. |
| 5 | * |
| 6 | * |
| 7 | * Permission to use, copy, modify, and/or distribute this software for |
| 8 | * any purpose with or without fee is hereby granted, provided that the |
| 9 | * above copyright notice and this permission notice appear in all |
| 10 | * copies. |
| 11 | * |
| 12 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL |
| 13 | * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
| 14 | * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE |
| 15 | * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL |
| 16 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR |
| 17 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER |
| 18 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
| 19 | * PERFORMANCE OF THIS SOFTWARE. |
| 20 | */ |
| 21 | |
| 22 | /* |
| 23 | * This file was originally distributed by Qualcomm Atheros, Inc. |
| 24 | * under proprietary terms before Copyright ownership was assigned |
| 25 | * to the Linux Foundation. |
| 26 | */ |
| 27 | |
| 28 | /** |
| 29 | * @file ol_txrx_osif_api.h |
| 30 | * @brief Define the host data API functions called by the host OS shim SW. |
| 31 | */ |
| 32 | #ifndef _OL_TXRX_OSIF_API__H_ |
| 33 | #define _OL_TXRX_OSIF_API__H_ |
| 34 | |
| 35 | #include <cdf_nbuf.h> /* cdf_nbuf_t */ |
| 36 | |
| 37 | #include <ol_osif_api.h> /* ol_osif_vdev_handle */ |
| 38 | #include <ol_txrx_api.h> /* ol_txrx_pdev_handle, etc. */ |
| 39 | #include <ol_txrx_ctrl_api.h> |
| 40 | #include "cds_sched.h" |
| 41 | |
| 42 | /** |
| 43 | * struct ol_rx_cached_buf - rx cached buffer |
| 44 | * @list: linked list |
| 45 | * @buf: skb buffer |
| 46 | */ |
| 47 | struct ol_rx_cached_buf { |
| 48 | struct list_head list; |
| 49 | cdf_nbuf_t buf; |
| 50 | }; |
| 51 | |
| 52 | /** |
| 53 | * @typedef ol_txrx_rx_fp |
| 54 | * @brief receive function to hand batches of data frames from txrx to OS shim |
| 55 | */ |
| 56 | typedef void (*ol_txrx_rx_fp)(void *osif_dev, cdf_nbuf_t msdus); |
| 57 | |
| 58 | /** |
| 59 | * @typedef ol_txrx_tx_fp |
| 60 | * @brief top-level transmit function |
| 61 | */ |
| 62 | typedef cdf_nbuf_t (*ol_txrx_tx_fp)(ol_txrx_vdev_handle data_vdev, |
| 63 | cdf_nbuf_t msdu_list); |
| 64 | |
| 65 | /** |
| 66 | * @typedef ol_txrx_tx_non_std_fp |
| 67 | * @brief top-level transmit function for non-standard tx frames |
| 68 | * @details |
| 69 | * This function pointer provides an alternative to the ol_txrx_tx_fp |
| 70 | * to support non-standard transmits. In particular, this function |
| 71 | * supports transmission of: |
| 72 | * 1. "Raw" frames |
| 73 | * These raw frames already have an 802.11 header; the usual |
| 74 | * 802.11 header encapsulation by the driver does not apply. |
| 75 | * 2. TSO segments |
| 76 | * During tx completion, the txrx layer needs to reclaim the buffer |
| 77 | * that holds the ethernet/IP/TCP header created for the TSO segment. |
| 78 | * Thus, these tx frames need to be marked as TSO, to show that they |
| 79 | * need this special handling during tx completion. |
| 80 | * |
| 81 | * @param data_vdev - which virtual device should transmit the frame |
| 82 | * @param tx_spec - what non-standard operations to apply to the tx frame |
| 83 | * @param msdu_list - tx frame(s), in a null-terminated list |
| 84 | */ |
| 85 | typedef cdf_nbuf_t (*ol_txrx_tx_non_std_fp)(ol_txrx_vdev_handle data_vdev, |
| 86 | enum ol_tx_spec tx_spec, |
| 87 | cdf_nbuf_t msdu_list); |
| 88 | |
| 89 | struct txrx_rx_metainfo; |
| 90 | |
| 91 | /** |
| 92 | * @typedef ol_txrx_tx_fc_fp |
| 93 | * @brief tx flow control notification function from txrx to OS shim |
| 94 | * @param osif_dev - the virtual device's OS shim object |
| 95 | * @param tx_resume - tx os q should be resumed or not |
| 96 | */ |
| 97 | typedef void (*ol_txrx_tx_flow_control_fp)(void *osif_dev, |
| 98 | bool tx_resume); |
| 99 | |
| 100 | /** |
| 101 | * struct ol_txrx_desc_type - txrx descriptor type |
| 102 | * @sta_id: sta id |
| 103 | * @is_qos_enabled: is station qos enabled |
| 104 | * @is_wapi_supported: is station wapi supported |
| 105 | */ |
| 106 | struct ol_txrx_desc_type { |
| 107 | uint8_t sta_id; |
| 108 | uint8_t is_qos_enabled; |
| 109 | uint8_t is_wapi_supported; |
| 110 | }; |
| 111 | |
| 112 | |
| 113 | typedef CDF_STATUS (*ol_rx_callback_fp)(void *p_cds_gctx, |
| 114 | cdf_nbuf_t pDataBuff, |
| 115 | uint8_t ucSTAId); |
| 116 | |
| 117 | typedef void (*ol_tx_pause_callback_fp)(uint8_t vdev_id, |
| 118 | enum netif_action_type action, |
| 119 | enum netif_reason_type reason); |
| 120 | |
| 121 | #ifdef QCA_LL_TX_FLOW_CONTROL_V2 |
| 122 | CDF_STATUS ol_txrx_register_pause_cb(ol_tx_pause_callback_fp pause_cb); |
| 123 | #else |
| 124 | static inline |
| 125 | CDF_STATUS ol_txrx_register_pause_cb(ol_tx_pause_callback_fp pause_cb) |
| 126 | { |
| 127 | return CDF_STATUS_SUCCESS; |
| 128 | |
| 129 | } |
| 130 | #endif |
| 131 | |
| 132 | #ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL |
| 133 | |
| 134 | int ol_txrx_register_tx_flow_control (uint8_t vdev_id, |
| 135 | ol_txrx_tx_flow_control_fp flowControl, |
| 136 | void *osif_fc_ctx); |
| 137 | |
| 138 | int ol_txrx_deregister_tx_flow_control_cb(uint8_t vdev_id); |
| 139 | |
| 140 | void ol_txrx_flow_control_cb(ol_txrx_vdev_handle vdev, |
| 141 | bool tx_resume); |
| 142 | bool |
| 143 | ol_txrx_get_tx_resource(uint8_t sta_id, |
| 144 | unsigned int low_watermark, |
| 145 | unsigned int high_watermark_offset); |
| 146 | |
| 147 | int |
| 148 | ol_txrx_ll_set_tx_pause_q_depth(uint8_t vdev_id, int pause_q_depth); |
| 149 | #endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */ |
| 150 | |
| 151 | /** |
| 152 | * @typedef ol_txrx_rx_fp |
| 153 | * @brief receive function to hand batches of data frames from txrx to OS shim |
| 154 | */ |
| 155 | |
| 156 | struct ol_txrx_osif_ops { |
| 157 | /* tx function pointers - specified by txrx, stored by OS shim */ |
| 158 | struct { |
| 159 | ol_txrx_tx_fp std; |
| 160 | ol_txrx_tx_non_std_fp non_std; |
| 161 | ol_txrx_tx_flow_control_fp flow_control_cb; |
| 162 | } tx; |
| 163 | |
| 164 | /* rx function pointers - specified by OS shim, stored by txrx */ |
| 165 | struct { |
| 166 | ol_txrx_rx_fp std; |
| 167 | } rx; |
| 168 | }; |
| 169 | |
| 170 | /** |
| 171 | * @brief Link a vdev's data object with the matching OS shim vdev object. |
| 172 | * @details |
| 173 | * The data object for a virtual device is created by the function |
| 174 | * ol_txrx_vdev_attach. However, rather than fully linking the |
| 175 | * data vdev object with the vdev objects from the other subsystems |
| 176 | * that the data vdev object interacts with, the txrx_vdev_attach |
| 177 | * function focuses primarily on creating the data vdev object. |
| 178 | * After the creation of both the data vdev object and the OS shim |
| 179 | * vdev object, this txrx_osif_vdev_attach function is used to connect |
| 180 | * the two vdev objects, so the data SW can use the OS shim vdev handle |
| 181 | * when passing rx data received by a vdev up to the OS shim. |
| 182 | * |
| 183 | * @param txrx_vdev - the virtual device's data object |
| 184 | * @param osif_vdev - the virtual device's OS shim object |
| 185 | * @param txrx_ops - (pointers to) the functions used for tx and rx data xfer |
| 186 | * There are two portions of these txrx operations. |
| 187 | * The rx portion is filled in by OSIF SW before calling |
| 188 | * ol_txrx_osif_vdev_register; inside the ol_txrx_osif_vdev_register |
| 189 | * the txrx SW stores a copy of these rx function pointers, to use |
| 190 | * as it delivers rx data frames to the OSIF SW. |
| 191 | * The tx portion is filled in by the txrx SW inside |
| 192 | * ol_txrx_osif_vdev_register; when the function call returns, |
| 193 | * the OSIF SW stores a copy of these tx functions to use as it |
| 194 | * delivers tx data frames to the txrx SW. |
| 195 | * The rx function pointer inputs consist of the following: |
| 196 | * rx: the OS shim rx function to deliver rx data frames to. |
| 197 | * This can have different values for different virtual devices, |
| 198 | * e.g. so one virtual device's OS shim directly hands rx frames to |
| 199 | * the OS, but another virtual device's OS shim filters out P2P |
| 200 | * messages before sending the rx frames to the OS. |
| 201 | * The netbufs delivered to the osif_rx function are in the format |
| 202 | * specified by the OS to use for tx and rx frames (either 802.3 or |
| 203 | * native WiFi). |
| 204 | * rx_mon: the OS shim rx monitor function to deliver monitor data to |
| 205 | * Though in practice, it is probable that the same function will |
| 206 | * be used for delivering rx monitor data for all virtual devices, |
| 207 | * in theory each different virtual device can have a different |
| 208 | * OS shim function for accepting rx monitor data. |
| 209 | * The netbufs delivered to the osif_rx_mon function are in 802.11 |
| 210 | * format. Each netbuf holds a 802.11 MPDU, not an 802.11 MSDU. |
| 211 | * Depending on compile-time configuration, each netbuf may also |
| 212 | * have a monitor-mode encapsulation header such as a radiotap |
| 213 | * header added before the MPDU contents. |
| 214 | * The tx function pointer outputs consist of the following: |
| 215 | * tx: the tx function pointer for standard data frames |
| 216 | * This function pointer is set by the txrx SW to perform |
| 217 | * host-side transmit operations based on whether a HL or LL |
| 218 | * host/target interface is in use. |
| 219 | * tx_non_std: the tx function pointer for non-standard data frames, |
| 220 | * such as TSO frames, explicitly-prioritized frames, or "raw" |
| 221 | * frames which skip some of the tx operations, such as 802.11 |
| 222 | * MAC header encapsulation. |
| 223 | */ |
| 224 | void |
| 225 | ol_txrx_osif_vdev_register(ol_txrx_vdev_handle txrx_vdev, |
| 226 | void *osif_vdev, struct ol_txrx_osif_ops *txrx_ops); |
| 227 | |
| 228 | /** |
| 229 | * @brief Divide a jumbo TCP frame into smaller segments. |
| 230 | * @details |
| 231 | * For efficiency, the protocol stack above the WLAN driver may operate |
| 232 | * on jumbo tx frames, which are larger than the 802.11 MTU. |
| 233 | * The OSIF SW uses this txrx API function to divide the jumbo tx TCP frame |
| 234 | * into a series of segment frames. |
| 235 | * The segments are created as clones of the input jumbo frame. |
| 236 | * The txrx SW generates a new encapsulation header (ethernet + IP + TCP) |
| 237 | * for each of the output segment frames. The exact format of this header, |
| 238 | * e.g. 802.3 vs. Ethernet II, and IPv4 vs. IPv6, is chosen to match the |
| 239 | * header format of the input jumbo frame. |
| 240 | * The input jumbo frame is not modified. |
| 241 | * After the ol_txrx_osif_tso_segment returns, the OSIF SW needs to perform |
| 242 | * DMA mapping on each of the segment network buffers, and also needs to |
| 243 | * |
| 244 | * @param txrx_vdev - which virtual device will transmit the TSO segments |
| 245 | * @param max_seg_payload_bytes - the maximum size for the TCP payload of |
| 246 | * each segment frame. |
| 247 | * This does not include the ethernet + IP + TCP header sizes. |
| 248 | * @param jumbo_tcp_frame - jumbo frame which needs to be cloned+segmented |
| 249 | * @return |
| 250 | * NULL if the segmentation fails, - OR - |
| 251 | * a NULL-terminated list of segment network buffers |
| 252 | */ |
| 253 | cdf_nbuf_t ol_txrx_osif_tso_segment(ol_txrx_vdev_handle txrx_vdev, |
| 254 | int max_seg_payload_bytes, |
| 255 | cdf_nbuf_t jumbo_tcp_frame); |
| 256 | |
| 257 | cdf_nbuf_t ol_tx_send_data_frame(uint8_t sta_id, cdf_nbuf_t skb, |
| 258 | uint8_t proto_type); |
| 259 | |
| 260 | #ifdef IPA_OFFLOAD |
| 261 | cdf_nbuf_t ol_tx_send_ipa_data_frame(void *vdev, |
| 262 | cdf_nbuf_t skb); |
| 263 | #endif |
| 264 | |
| 265 | CDF_STATUS ol_txrx_register_peer(ol_rx_callback_fp rxcb, |
| 266 | struct ol_txrx_desc_type *sta_desc); |
| 267 | |
| 268 | CDF_STATUS ol_txrx_clear_peer(uint8_t sta_id); |
| 269 | |
| 270 | CDF_STATUS ol_txrx_change_peer_state(uint8_t sta_id, |
| 271 | enum ol_txrx_peer_state sta_state, |
| 272 | bool roam_synch_in_progress); |
| 273 | |
| 274 | void ol_rx_data_process(struct ol_txrx_peer_t *peer, |
| 275 | cdf_nbuf_t rx_buf_list); |
| 276 | |
| 277 | void ol_txrx_flush_rx_frames(struct ol_txrx_peer_t *peer, |
| 278 | bool drop); |
| 279 | |
| 280 | #if defined(FEATURE_LRO) |
| 281 | void ol_register_lro_flush_cb(void (handler)(void *), void *data); |
| 282 | #endif |
| 283 | #endif /* _OL_TXRX_OSIF_API__H_ */ |