linux/drivers/net/wireless/ath/ath10k/htc.h
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2005-2011 Atheros Communications Inc.
   3 * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
   4 *
   5 * Permission to use, copy, modify, and/or distribute this software for any
   6 * purpose with or without fee is hereby granted, provided that the above
   7 * copyright notice and this permission notice appear in all copies.
   8 *
   9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16 */
  17
  18#ifndef _HTC_H_
  19#define _HTC_H_
  20
  21#include <linux/kernel.h>
  22#include <linux/list.h>
  23#include <linux/bug.h>
  24#include <linux/skbuff.h>
  25#include <linux/timer.h>
  26
  27struct ath10k;
  28
  29/****************/
  30/* HTC protocol */
  31/****************/
  32
  33/*
  34 * HTC - host-target control protocol
  35 *
  36 * tx packets are generally <htc_hdr><payload>
  37 * rx packets are more complex: <htc_hdr><payload><trailer>
  38 *
  39 * The payload + trailer length is stored in len.
  40 * To get payload-only length one needs to payload - trailer_len.
  41 *
  42 * Trailer contains (possibly) multiple <htc_record>.
  43 * Each record is a id-len-value.
  44 *
  45 * HTC header flags, control_byte0, control_byte1
  46 * have different meaning depending whether its tx
  47 * or rx.
  48 *
  49 * Alignment: htc_hdr, payload and trailer are
  50 * 4-byte aligned.
  51 */
  52
  53#define HTC_HOST_MAX_MSG_PER_BUNDLE        8
  54
  55enum ath10k_htc_tx_flags {
  56        ATH10K_HTC_FLAG_NEED_CREDIT_UPDATE = 0x01,
  57        ATH10K_HTC_FLAG_SEND_BUNDLE        = 0x02
  58};
  59
  60enum ath10k_htc_rx_flags {
  61        ATH10K_HTC_FLAG_TRAILER_PRESENT = 0x02,
  62        ATH10K_HTC_FLAG_BUNDLE_MASK     = 0xF0
  63};
  64
  65struct ath10k_htc_hdr {
  66        u8 eid; /* @enum ath10k_htc_ep_id */
  67        u8 flags; /* @enum ath10k_htc_tx_flags, ath10k_htc_rx_flags */
  68        __le16 len;
  69        union {
  70                u8 trailer_len; /* for rx */
  71                u8 control_byte0;
  72        } __packed;
  73        union {
  74                u8 seq_no; /* for tx */
  75                u8 control_byte1;
  76        } __packed;
  77        u8 pad0;
  78        u8 pad1;
  79} __packed __aligned(4);
  80
  81enum ath10k_ath10k_htc_msg_id {
  82        ATH10K_HTC_MSG_READY_ID                = 1,
  83        ATH10K_HTC_MSG_CONNECT_SERVICE_ID      = 2,
  84        ATH10K_HTC_MSG_CONNECT_SERVICE_RESP_ID = 3,
  85        ATH10K_HTC_MSG_SETUP_COMPLETE_ID       = 4,
  86        ATH10K_HTC_MSG_SETUP_COMPLETE_EX_ID    = 5,
  87        ATH10K_HTC_MSG_SEND_SUSPEND_COMPLETE   = 6
  88};
  89
  90enum ath10k_htc_version {
  91        ATH10K_HTC_VERSION_2P0 = 0x00, /* 2.0 */
  92        ATH10K_HTC_VERSION_2P1 = 0x01, /* 2.1 */
  93};
  94
  95enum ath10k_htc_conn_flags {
  96        ATH10K_HTC_CONN_FLAGS_THRESHOLD_LEVEL_ONE_FOURTH    = 0x0,
  97        ATH10K_HTC_CONN_FLAGS_THRESHOLD_LEVEL_ONE_HALF      = 0x1,
  98        ATH10K_HTC_CONN_FLAGS_THRESHOLD_LEVEL_THREE_FOURTHS = 0x2,
  99        ATH10K_HTC_CONN_FLAGS_THRESHOLD_LEVEL_UNITY         = 0x3,
 100#define ATH10K_HTC_CONN_FLAGS_THRESHOLD_LEVEL_MASK 0x3
 101        ATH10K_HTC_CONN_FLAGS_REDUCE_CREDIT_DRIBBLE    = 1 << 2,
 102        ATH10K_HTC_CONN_FLAGS_DISABLE_CREDIT_FLOW_CTRL = 1 << 3
 103#define ATH10K_HTC_CONN_FLAGS_RECV_ALLOC_MASK 0xFF00
 104#define ATH10K_HTC_CONN_FLAGS_RECV_ALLOC_LSB  8
 105};
 106
 107enum ath10k_htc_conn_svc_status {
 108        ATH10K_HTC_CONN_SVC_STATUS_SUCCESS      = 0,
 109        ATH10K_HTC_CONN_SVC_STATUS_NOT_FOUND    = 1,
 110        ATH10K_HTC_CONN_SVC_STATUS_FAILED       = 2,
 111        ATH10K_HTC_CONN_SVC_STATUS_NO_RESOURCES = 3,
 112        ATH10K_HTC_CONN_SVC_STATUS_NO_MORE_EP   = 4
 113};
 114
 115enum ath10k_htc_setup_complete_flags {
 116        ATH10K_HTC_SETUP_COMPLETE_FLAGS_RX_BNDL_EN = 1
 117};
 118
 119struct ath10k_ath10k_htc_msg_hdr {
 120        __le16 message_id; /* @enum htc_message_id */
 121} __packed;
 122
 123struct ath10k_htc_unknown {
 124        u8 pad0;
 125        u8 pad1;
 126} __packed;
 127
 128struct ath10k_htc_ready {
 129        __le16 credit_count;
 130        __le16 credit_size;
 131        u8 max_endpoints;
 132        u8 pad0;
 133} __packed;
 134
 135struct ath10k_htc_ready_extended {
 136        struct ath10k_htc_ready base;
 137        u8 htc_version; /* @enum ath10k_htc_version */
 138        u8 max_msgs_per_htc_bundle;
 139        u8 pad0;
 140        u8 pad1;
 141} __packed;
 142
 143struct ath10k_htc_conn_svc {
 144        __le16 service_id;
 145        __le16 flags; /* @enum ath10k_htc_conn_flags */
 146        u8 pad0;
 147        u8 pad1;
 148} __packed;
 149
 150struct ath10k_htc_conn_svc_response {
 151        __le16 service_id;
 152        u8 status; /* @enum ath10k_htc_conn_svc_status */
 153        u8 eid;
 154        __le16 max_msg_size;
 155} __packed;
 156
 157struct ath10k_htc_setup_complete_extended {
 158        u8 pad0;
 159        u8 pad1;
 160        __le32 flags; /* @enum htc_setup_complete_flags */
 161        u8 max_msgs_per_bundled_recv;
 162        u8 pad2;
 163        u8 pad3;
 164        u8 pad4;
 165} __packed;
 166
 167struct ath10k_htc_msg {
 168        struct ath10k_ath10k_htc_msg_hdr hdr;
 169        union {
 170                /* host-to-target */
 171                struct ath10k_htc_conn_svc connect_service;
 172                struct ath10k_htc_ready ready;
 173                struct ath10k_htc_ready_extended ready_ext;
 174                struct ath10k_htc_unknown unknown;
 175                struct ath10k_htc_setup_complete_extended setup_complete_ext;
 176
 177                /* target-to-host */
 178                struct ath10k_htc_conn_svc_response connect_service_response;
 179        };
 180} __packed __aligned(4);
 181
 182enum ath10k_ath10k_htc_record_id {
 183        ATH10K_HTC_RECORD_NULL             = 0,
 184        ATH10K_HTC_RECORD_CREDITS          = 1,
 185        ATH10K_HTC_RECORD_LOOKAHEAD        = 2,
 186        ATH10K_HTC_RECORD_LOOKAHEAD_BUNDLE = 3,
 187};
 188
 189struct ath10k_ath10k_htc_record_hdr {
 190        u8 id; /* @enum ath10k_ath10k_htc_record_id */
 191        u8 len;
 192        u8 pad0;
 193        u8 pad1;
 194} __packed;
 195
 196struct ath10k_htc_credit_report {
 197        u8 eid; /* @enum ath10k_htc_ep_id */
 198        u8 credits;
 199        u8 pad0;
 200        u8 pad1;
 201} __packed;
 202
 203struct ath10k_htc_lookahead_report {
 204        u8 pre_valid;
 205        u8 pad0;
 206        u8 pad1;
 207        u8 pad2;
 208        u8 lookahead[4];
 209        u8 post_valid;
 210        u8 pad3;
 211        u8 pad4;
 212        u8 pad5;
 213} __packed;
 214
 215struct ath10k_htc_lookahead_bundle {
 216        u8 lookahead[4];
 217} __packed;
 218
 219struct ath10k_htc_record {
 220        struct ath10k_ath10k_htc_record_hdr hdr;
 221        union {
 222                struct ath10k_htc_credit_report credit_report[0];
 223                struct ath10k_htc_lookahead_report lookahead_report[0];
 224                struct ath10k_htc_lookahead_bundle lookahead_bundle[0];
 225                u8 pauload[0];
 226        };
 227} __packed __aligned(4);
 228
 229/*
 230 * note: the trailer offset is dynamic depending
 231 * on payload length. this is only a struct layout draft
 232 */
 233struct ath10k_htc_frame {
 234        struct ath10k_htc_hdr hdr;
 235        union {
 236                struct ath10k_htc_msg msg;
 237                u8 payload[0];
 238        };
 239        struct ath10k_htc_record trailer[0];
 240} __packed __aligned(4);
 241
 242/*******************/
 243/* Host-side stuff */
 244/*******************/
 245
 246enum ath10k_htc_svc_gid {
 247        ATH10K_HTC_SVC_GRP_RSVD = 0,
 248        ATH10K_HTC_SVC_GRP_WMI = 1,
 249        ATH10K_HTC_SVC_GRP_NMI = 2,
 250        ATH10K_HTC_SVC_GRP_HTT = 3,
 251
 252        ATH10K_HTC_SVC_GRP_TEST = 254,
 253        ATH10K_HTC_SVC_GRP_LAST = 255,
 254};
 255
 256#define SVC(group, idx) \
 257        (int)(((int)(group) << 8) | (int)(idx))
 258
 259enum ath10k_htc_svc_id {
 260        /* NOTE: service ID of 0x0000 is reserved and should never be used */
 261        ATH10K_HTC_SVC_ID_RESERVED      = 0x0000,
 262        ATH10K_HTC_SVC_ID_UNUSED        = ATH10K_HTC_SVC_ID_RESERVED,
 263
 264        ATH10K_HTC_SVC_ID_RSVD_CTRL     = SVC(ATH10K_HTC_SVC_GRP_RSVD, 1),
 265        ATH10K_HTC_SVC_ID_WMI_CONTROL   = SVC(ATH10K_HTC_SVC_GRP_WMI, 0),
 266        ATH10K_HTC_SVC_ID_WMI_DATA_BE   = SVC(ATH10K_HTC_SVC_GRP_WMI, 1),
 267        ATH10K_HTC_SVC_ID_WMI_DATA_BK   = SVC(ATH10K_HTC_SVC_GRP_WMI, 2),
 268        ATH10K_HTC_SVC_ID_WMI_DATA_VI   = SVC(ATH10K_HTC_SVC_GRP_WMI, 3),
 269        ATH10K_HTC_SVC_ID_WMI_DATA_VO   = SVC(ATH10K_HTC_SVC_GRP_WMI, 4),
 270
 271        ATH10K_HTC_SVC_ID_NMI_CONTROL   = SVC(ATH10K_HTC_SVC_GRP_NMI, 0),
 272        ATH10K_HTC_SVC_ID_NMI_DATA      = SVC(ATH10K_HTC_SVC_GRP_NMI, 1),
 273
 274        ATH10K_HTC_SVC_ID_HTT_DATA_MSG  = SVC(ATH10K_HTC_SVC_GRP_HTT, 0),
 275
 276        /* raw stream service (i.e. flash, tcmd, calibration apps) */
 277        ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS = SVC(ATH10K_HTC_SVC_GRP_TEST, 0),
 278};
 279
 280#undef SVC
 281
 282enum ath10k_htc_ep_id {
 283        ATH10K_HTC_EP_UNUSED = -1,
 284        ATH10K_HTC_EP_0 = 0,
 285        ATH10K_HTC_EP_1 = 1,
 286        ATH10K_HTC_EP_2,
 287        ATH10K_HTC_EP_3,
 288        ATH10K_HTC_EP_4,
 289        ATH10K_HTC_EP_5,
 290        ATH10K_HTC_EP_6,
 291        ATH10K_HTC_EP_7,
 292        ATH10K_HTC_EP_8,
 293        ATH10K_HTC_EP_COUNT,
 294};
 295
 296struct ath10k_htc_ops {
 297        void (*target_send_suspend_complete)(struct ath10k *ar);
 298};
 299
 300struct ath10k_htc_ep_ops {
 301        void (*ep_tx_complete)(struct ath10k *, struct sk_buff *);
 302        void (*ep_rx_complete)(struct ath10k *, struct sk_buff *);
 303        void (*ep_tx_credits)(struct ath10k *);
 304};
 305
 306/* service connection information */
 307struct ath10k_htc_svc_conn_req {
 308        u16 service_id;
 309        struct ath10k_htc_ep_ops ep_ops;
 310        int max_send_queue_depth;
 311};
 312
 313/* service connection response information */
 314struct ath10k_htc_svc_conn_resp {
 315        u8 buffer_len;
 316        u8 actual_len;
 317        enum ath10k_htc_ep_id eid;
 318        unsigned int max_msg_len;
 319        u8 connect_resp_code;
 320};
 321
 322#define ATH10K_NUM_CONTROL_TX_BUFFERS 2
 323#define ATH10K_HTC_MAX_LEN 4096
 324#define ATH10K_HTC_MAX_CTRL_MSG_LEN 256
 325#define ATH10K_HTC_WAIT_TIMEOUT_HZ (1 * HZ)
 326#define ATH10K_HTC_CONTROL_BUFFER_SIZE (ATH10K_HTC_MAX_CTRL_MSG_LEN + \
 327                                        sizeof(struct ath10k_htc_hdr))
 328#define ATH10K_HTC_CONN_SVC_TIMEOUT_HZ (1 * HZ)
 329
 330struct ath10k_htc_ep {
 331        struct ath10k_htc *htc;
 332        enum ath10k_htc_ep_id eid;
 333        enum ath10k_htc_svc_id service_id;
 334        struct ath10k_htc_ep_ops ep_ops;
 335
 336        int max_tx_queue_depth;
 337        int max_ep_message_len;
 338        u8 ul_pipe_id;
 339        u8 dl_pipe_id;
 340
 341        u8 seq_no; /* for debugging */
 342        int tx_credits;
 343        bool tx_credit_flow_enabled;
 344};
 345
 346struct ath10k_htc_svc_tx_credits {
 347        u16 service_id;
 348        u8  credit_allocation;
 349};
 350
 351struct ath10k_htc {
 352        struct ath10k *ar;
 353        struct ath10k_htc_ep endpoint[ATH10K_HTC_EP_COUNT];
 354
 355        /* protects endpoints */
 356        spinlock_t tx_lock;
 357
 358        struct ath10k_htc_ops htc_ops;
 359
 360        u8 control_resp_buffer[ATH10K_HTC_MAX_CTRL_MSG_LEN];
 361        int control_resp_len;
 362
 363        struct completion ctl_resp;
 364
 365        int total_transmit_credits;
 366        int target_credit_size;
 367        u8 max_msgs_per_htc_bundle;
 368};
 369
 370int ath10k_htc_init(struct ath10k *ar);
 371int ath10k_htc_wait_target(struct ath10k_htc *htc);
 372int ath10k_htc_start(struct ath10k_htc *htc);
 373int ath10k_htc_connect_service(struct ath10k_htc *htc,
 374                               struct ath10k_htc_svc_conn_req  *conn_req,
 375                               struct ath10k_htc_svc_conn_resp *conn_resp);
 376int ath10k_htc_send(struct ath10k_htc *htc, enum ath10k_htc_ep_id eid,
 377                    struct sk_buff *packet);
 378struct sk_buff *ath10k_htc_alloc_skb(struct ath10k *ar, int size);
 379void ath10k_htc_tx_completion_handler(struct ath10k *ar, struct sk_buff *skb);
 380void ath10k_htc_rx_completion_handler(struct ath10k *ar, struct sk_buff *skb);
 381void ath10k_htc_notify_tx_completion(struct ath10k_htc_ep *ep,
 382                                     struct sk_buff *skb);
 383int ath10k_htc_process_trailer(struct ath10k_htc *htc,
 384                               u8 *buffer,
 385                               int length,
 386                               enum ath10k_htc_ep_id src_eid,
 387                               void *next_lookaheads,
 388                               int *next_lookaheads_len);
 389
 390#endif
 391