text: /*
   * Copyright (c) 2012, 2014, 2017-2018 The Linux Foundation. All rights reserved.
   *
   * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
   *
   *
   * Permission to use, copy, modify, and/or distribute this software for
   * any purpose with or without fee is hereby granted, provided that the
   * above copyright notice and this permission notice appear in all
   * copies.
   *
   * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
   * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
   * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
   * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
   * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
   * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
   * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
   * PERFORMANCE OF THIS SOFTWARE.
   */
  
  /*
   * This file was originally distributed by Qualcomm Atheros, Inc.
   * under proprietary terms before Copyright ownership was assigned
   * to the Linux Foundation.
   */
  
  /**
   * @file ol_txrx_osif_api.h
   * @brief Define the host data API functions called by the host OS shim SW.
   */
  #ifndef _OL_TXRX_OSIF_API__H_
  #define _OL_TXRX_OSIF_API__H_
  
  #include <adf_nbuf.h>     /* adf_nbuf_t */
  
  #include <ol_osif_api.h> /* ol_osif_vdev_handle */
  #include <ol_txrx_api.h> /* ol_txrx_pdev_handle, etc. */
  
  /**
   * @typedef ol_txrx_tx_fp
   * @brief top-level transmit function
   */
  typedef adf_nbuf_t (*ol_txrx_tx_fp)(
      ol_txrx_vdev_handle data_vdev, adf_nbuf_t msdu_list);
  
  /**
   * @typedef ol_txrx_tx_non_std_fp
   * @brief top-level transmit function for non-standard tx frames
   * @details
   *  This function pointer provides an alternative to the ol_txrx_tx_fp
   *  to support non-standard transmits.  In particular, this function
   *  supports transmission of:
   *  1. "Raw" frames
   *     These raw frames already have an 802.11 header; the usual
   *     802.11 header encapsulation by the driver does not apply.
   *  2. TSO segments
   *     During tx completion, the txrx layer needs to reclaim the buffer
   *     that holds the ethernet/IP/TCP header created for the TSO segment.
   *     Thus, these tx frames need to be marked as TSO, to show that they
   *     need this special handling during tx completion.
   *
   * @param data_vdev - which virtual device should transmit the frame
   * @param tx_spec - what non-standard operations to apply to the tx frame
   * @param msdu_list - tx frame(s), in a null-terminated list
   */
  typedef adf_nbuf_t (*ol_txrx_tx_non_std_fp)(
      ol_txrx_vdev_handle data_vdev,
      enum ol_tx_spec tx_spec,
      adf_nbuf_t msdu_list);
  
  struct txrx_rx_metainfo;
  
  #ifdef OSIF_NEED_RX_PEER_ID
  /**
   * @typedef ol_txrx_rx_fp
   * @brief receive function to hand batches of data frames from txrx to OS shim
   * @details this version of rx callback is for the OS shim, for example CLD, which
   * depends on peer id information in data rx.
   */
  typedef void (*ol_txrx_rx_fp)(void *osif_dev, u_int16_t peer_id,
  			      adf_nbuf_t msdus);
  #else
  
  /**
   * @typedef ol_txrx_rx_fp
   * @brief receive function to hand batches of data frames from txrx to OS shim
   */
  typedef void (*ol_txrx_rx_fp)(void *osif_dev, adf_nbuf_t msdus);
  #endif /* OSIF_NEED_RX_PEER_ID */
  
  /**
   * @typedef ol_txrx_tx_fc_fp
   * @brief tx flow control notification function from txrx to OS shim
   * @param osif_dev - the virtual device's OS shim object
   * @param vdev_id - virtual device id
   * @param tx_resume - tx os q should be resumed or not
   */
  typedef void (*ol_txrx_tx_flow_control_fp)(void *osif_dev,
                                             u_int8_t vdev_id, a_bool_t tx_resume);
  /**
   * @typedef ol_txrx_vir_mon_rx_fp
   * @brief receive function to hand montior frames from txrx to OS shim
   * @param msdus - rx monitor frame(s), in a null-terminated list
   */
  typedef void (*ol_txrx_vir_mon_rx_fp)(adf_nbuf_t msdus);
  
  /**
   * @typedef ol_txrx_rx_fp
   * @brief receive function to hand batches of data frames from txrx to OS shim
   */
  
  struct ol_txrx_osif_ops {
      /* tx function pointers - specified by txrx, stored by OS shim */
      struct {
          ol_txrx_tx_fp              std;
          ol_txrx_tx_non_std_fp      non_std;
          ol_txrx_tx_flow_control_fp flow_control_cb;
      } tx;
  
      /* rx function pointers - specified by OS shim, stored by txrx */
      struct {
          ol_txrx_rx_fp         std;
      } rx;
  };
  
  /**
   * @brief Link a vdev's data object with the matching OS shim vdev object.
   * @details
   *  The data object for a virtual device is created by the function
   *  ol_txrx_vdev_attach.  However, rather than fully linking the
   *  data vdev object with the vdev objects from the other subsystems
   *  that the data vdev object interacts with, the txrx_vdev_attach
   *  function focuses primarily on creating the data vdev object.
   *  After the creation of both the data vdev object and the OS shim
   *  vdev object, this txrx_osif_vdev_attach function is used to connect
   *  the two vdev objects, so the data SW can use the OS shim vdev handle
   *  when passing rx data received by a vdev up to the OS shim.
   *
   * @param txrx_vdev - the virtual device's data object
   * @param osif_vdev - the virtual device's OS shim object
   * @param txrx_ops - (pointers to) the functions used for tx and rx data xfer
   *      There are two portions of these txrx operations.
   *      The rx portion is filled in by OSIF SW before calling
   *      ol_txrx_osif_vdev_register; inside the ol_txrx_osif_vdev_register
   *      the txrx SW stores a copy of these rx function pointers, to use
   *      as it delivers rx data frames to the OSIF SW.
   *      The tx portion is filled in by the txrx SW inside
   *      ol_txrx_osif_vdev_register; when the function call returns,
   *      the OSIF SW stores a copy of these tx functions to use as it
   *      delivers tx data frames to the txrx SW.
   *      The rx function pointer inputs consist of the following:
   *      rx: the OS shim rx function to deliver rx data frames to.
   *          This can have different values for different virtual devices,
   *          e.g. so one virtual device's OS shim directly hands rx frames to
   *          the OS, but another virtual device's OS shim filters out P2P
   *          messages before sending the rx frames to the OS.
   *          The netbufs delivered to the osif_rx function are in the format
   *          specified by the OS to use for tx and rx frames (either 802.3 or
   *          native WiFi).
   *      rx_mon: the OS shim rx monitor function to deliver monitor data to
   *          Though in practice, it is probable that the same function will
   *          be used for delivering rx monitor data for all virtual devices,
   *          in theory each different virtual device can have a different
   *          OS shim function for accepting rx monitor data.
   *          The netbufs delivered to the osif_rx_mon function are in 802.11
   *          format.  Each netbuf holds a 802.11 MPDU, not an 802.11 MSDU.
   *          Depending on compile-time configuration, each netbuf may also
   *          have a monitor-mode encapsulation header such as a radiotap
   *          header added before the MPDU contents.
   *      The tx function pointer outputs consist of the following:
   *      tx: the tx function pointer for standard data frames
   *          This function pointer is set by the txrx SW to perform
   *          host-side transmit operations based on whether a HL or LL
   *          host/target interface is in use.
   *      tx_non_std: the tx function pointer for non-standard data frames,
   *          such as TSO frames, explicitly-prioritized frames, or "raw"
   *          frames which skip some of the tx operations, such as 802.11
   *          MAC header encapsulation.
   */
  void
  ol_txrx_osif_vdev_register(
      ol_txrx_vdev_handle txrx_vdev,
      void *osif_vdev,
      struct ol_txrx_osif_ops *txrx_ops);
  
  /**
   * @brief Divide a jumbo TCP frame into smaller segments.
   * @details
   *  For efficiency, the protocol stack above the WLAN driver may operate
   *  on jumbo tx frames, which are larger than the 802.11 MTU.
   *  The OSIF SW uses this txrx API function to divide the jumbo tx TCP frame
   *  into a series of segment frames.
   *  The segments are created as clones of the input jumbo frame.
   *  The txrx SW generates a new encapsulation header (ethernet + IP + TCP)
   *  for each of the output segment frames.  The exact format of this header,
   *  e.g. 802.3 vs. Ethernet II, and IPv4 vs. IPv6, is chosen to match the
   *  header format of the input jumbo frame.
   *  The input jumbo frame is not modified.
   *  After the ol_txrx_osif_tso_segment returns, the OSIF SW needs to perform
   *  DMA mapping on each of the segment network buffers, and also needs to
   *
   * @param txrx_vdev - which virtual device will transmit the TSO segments
   * @param max_seg_payload_bytes - the maximum size for the TCP payload of
   *      each segment frame.
   *      This does not include the ethernet + IP + TCP header sizes.
   * @param jumbo_tcp_frame - jumbo frame which needs to be cloned+segmented
   * @return
   *      NULL if the segmentation fails, - OR -
   *      a NULL-terminated list of segment network buffers
   */
  adf_nbuf_t ol_txrx_osif_tso_segment(
      ol_txrx_vdev_handle txrx_vdev,
      int max_seg_payload_bytes,
      adf_nbuf_t jumbo_tcp_frame);
  
  /**
   * @brief register the TLSHIM montior callback to OL pdev context
   * @details
   * For the virtual monitor interface which real VDEV is not created case,
   * just store the TLSHIM RX montior callback into TXRX_PDEV context.
   * later when receive RX montior packets from HTT layer, call the callback
   * stored in TXRX_PDEV to deliver packets to TLSHIM.
   *
   * @param txrx_pdev - TXRX physical device context
   * @param cbk - TLSHIM montior callback to be registered
   */
  void
  ol_txrx_osif_pdev_mon_register_cbk(
  	ol_txrx_pdev_handle txrx_pdev,
  	ol_txrx_vir_mon_rx_fp cbk);
  
  #ifdef QCA_SUPPORT_TXRX_DRIVER_TCP_DEL_ACK
  void
  ol_tx_vdev_set_driver_del_ack_enable(uint8_t vdev_id, unsigned long tx_packets,
  			uint32_t time_in_ms, uint32_t high_th, uint32_t low_th);
  void
  ol_tx_pdev_reset_driver_del_ack(void *pdev);
  
  #else
  static inline void
  ol_tx_vdev_set_driver_del_ack_enable(uint8_t vdev_id, unsigned long tx_packets,
  			uint32_t time_in_ms, uint32_t high_th, uint32_t low_th)
  {
  	return;
  }
  static inline void
  ol_tx_pdev_reset_driver_del_ack(void *pdev)
  {
  	return;
  }
  
  #endif
  
  #ifdef QCA_SUPPORT_TXRX_HL_BUNDLE
  void
  ol_tx_vdev_set_bundle_require(uint8_t vdev_id, unsigned long tx_packets,
  			uint32_t time_in_ms, uint32_t high_th, uint32_t low_th);
  void
  ol_tx_pdev_reset_bundle_require(void* pdev);
  
  #else
  static inline void
  ol_tx_vdev_set_bundle_require(uint8_t vdev_id, unsigned long tx_packets,
  			uint32_t time_in_ms, uint32_t high_th, uint32_t low_th)
  {
  	return;
  }
  static inline void
  ol_tx_pdev_reset_bundle_require(void* pdev)
  {
  	return;
  }
  
  #endif
  
  #endif /* _OL_TXRX_OSIF_API__H_ */
  