1 /* 2 * ISHTP client logic 3 * 4 * Copyright (c) 2003-2016, Intel Corporation. 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms and conditions of the GNU General Public License, 8 * version 2, as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 * more details. 14 */ 15 16 #ifndef _ISHTP_CLIENT_H_ 17 #define _ISHTP_CLIENT_H_ 18 19 #include <linux/types.h> 20 #include "ishtp-dev.h" 21 22 /* Tx and Rx ring size */ 23 #define CL_DEF_RX_RING_SIZE 2 24 #define CL_DEF_TX_RING_SIZE 2 25 #define CL_MAX_RX_RING_SIZE 32 26 #define CL_MAX_TX_RING_SIZE 32 27 28 #define DMA_SLOT_SIZE 4096 29 /* Number of IPC fragments after which it's worth sending via DMA */ 30 #define DMA_WORTH_THRESHOLD 3 31 32 /* DMA/IPC Tx paths. Other the default means enforcement */ 33 #define CL_TX_PATH_DEFAULT 0 34 #define CL_TX_PATH_IPC 1 35 #define CL_TX_PATH_DMA 2 36 37 /* Client Tx buffer list entry */ 38 struct ishtp_cl_tx_ring { 39 struct list_head list; 40 struct ishtp_msg_data send_buf; 41 }; 42 43 /* ISHTP client instance */ 44 struct ishtp_cl { 45 struct list_head link; 46 struct ishtp_device *dev; 47 enum cl_state state; 48 int status; 49 50 /* Link to ISHTP bus device */ 51 struct ishtp_cl_device *device; 52 53 /* ID of client connected */ 54 uint8_t host_client_id; 55 uint8_t fw_client_id; 56 uint8_t ishtp_flow_ctrl_creds; 57 uint8_t out_flow_ctrl_creds; 58 59 /* dma */ 60 int last_tx_path; 61 /* 0: ack wasn't received,1:ack was received */ 62 int last_dma_acked; 63 unsigned char *last_dma_addr; 64 /* 0: ack wasn't received,1:ack was received */ 65 int last_ipc_acked; 66 67 /* Rx ring buffer pool */ 68 unsigned int rx_ring_size; 69 struct ishtp_cl_rb free_rb_list; 70 spinlock_t free_list_spinlock; 71 /* Rx in-process list */ 72 struct ishtp_cl_rb in_process_list; 73 spinlock_t in_process_spinlock; 74 75 /* Client Tx buffers list */ 76 unsigned int tx_ring_size; 77 struct ishtp_cl_tx_ring tx_list, tx_free_list; 78 int tx_ring_free_size; 79 spinlock_t tx_list_spinlock; 80 spinlock_t tx_free_list_spinlock; 81 size_t tx_offs; /* Offset in buffer at head of 'tx_list' */ 82 83 /** 84 * if we get a FC, and the list is not empty, we must know whether we 85 * are at the middle of sending. 86 * if so -need to increase FC counter, otherwise, need to start sending 87 * the first msg in list 88 * (!)This is for counting-FC implementation only. Within single-FC the 89 * other party may NOT send FC until it receives complete message 90 */ 91 int sending; 92 93 /* Send FC spinlock */ 94 spinlock_t fc_spinlock; 95 96 /* wait queue for connect and disconnect response from FW */ 97 wait_queue_head_t wait_ctrl_res; 98 99 /* Error stats */ 100 unsigned int err_send_msg; 101 unsigned int err_send_fc; 102 103 /* Send/recv stats */ 104 unsigned int send_msg_cnt_ipc; 105 unsigned int send_msg_cnt_dma; 106 unsigned int recv_msg_cnt_ipc; 107 unsigned int recv_msg_cnt_dma; 108 unsigned int recv_msg_num_frags; 109 unsigned int ishtp_flow_ctrl_cnt; 110 unsigned int out_flow_ctrl_cnt; 111 112 /* Rx msg ... out FC timing */ 113 ktime_t ts_rx; 114 ktime_t ts_out_fc; 115 ktime_t ts_max_fc_delay; 116 void *client_data; 117 }; 118 119 /* Client connection managenment internal functions */ 120 int ishtp_can_client_connect(struct ishtp_device *ishtp_dev, guid_t *uuid); 121 int ishtp_fw_cl_by_id(struct ishtp_device *dev, uint8_t client_id); 122 void ishtp_cl_send_msg(struct ishtp_device *dev, struct ishtp_cl *cl); 123 void recv_ishtp_cl_msg(struct ishtp_device *dev, 124 struct ishtp_msg_hdr *ishtp_hdr); 125 int ishtp_cl_read_start(struct ishtp_cl *cl); 126 127 /* Ring Buffer I/F */ 128 int ishtp_cl_alloc_rx_ring(struct ishtp_cl *cl); 129 int ishtp_cl_alloc_tx_ring(struct ishtp_cl *cl); 130 void ishtp_cl_free_rx_ring(struct ishtp_cl *cl); 131 void ishtp_cl_free_tx_ring(struct ishtp_cl *cl); 132 int ishtp_cl_get_tx_free_buffer_size(struct ishtp_cl *cl); 133 int ishtp_cl_get_tx_free_rings(struct ishtp_cl *cl); 134 135 /* DMA I/F functions */ 136 void recv_ishtp_cl_msg_dma(struct ishtp_device *dev, void *msg, 137 struct dma_xfer_hbm *hbm); 138 void ishtp_cl_alloc_dma_buf(struct ishtp_device *dev); 139 void ishtp_cl_free_dma_buf(struct ishtp_device *dev); 140 void *ishtp_cl_get_dma_send_buf(struct ishtp_device *dev, 141 uint32_t size); 142 void ishtp_cl_release_dma_acked_mem(struct ishtp_device *dev, 143 void *msg_addr, 144 uint8_t size); 145 146 /* Request blocks alloc/free I/F */ 147 struct ishtp_cl_rb *ishtp_io_rb_init(struct ishtp_cl *cl); 148 void ishtp_io_rb_free(struct ishtp_cl_rb *priv_rb); 149 int ishtp_io_rb_alloc_buf(struct ishtp_cl_rb *rb, size_t length); 150 151 /** 152 * ishtp_cl_cmp_id - tells if file private data have same id 153 * returns true - if ids are the same and not NULL 154 */ 155 static inline bool ishtp_cl_cmp_id(const struct ishtp_cl *cl1, 156 const struct ishtp_cl *cl2) 157 { 158 return cl1 && cl2 && 159 (cl1->host_client_id == cl2->host_client_id) && 160 (cl1->fw_client_id == cl2->fw_client_id); 161 } 162 163 #endif /* _ISHTP_CLIENT_H_ */ 164