Will Drewry | d4ae528 | 2017-01-03 22:06:26 -0600 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2017 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | #ifndef ESE_HW_API_H_ |
| 18 | #define ESE_HW_API_H_ 1 |
| 19 | |
Will Drewry | 8f367fc | 2017-03-30 22:07:48 -0500 | [diff] [blame] | 20 | #include "ese_sg.h" |
Will Drewry | de2cad7 | 2017-03-10 15:53:34 -0600 | [diff] [blame] | 21 | #include "../../../libese-sysdeps/include/ese/sysdeps.h" |
Will Drewry | d4ae528 | 2017-01-03 22:06:26 -0600 | [diff] [blame] | 22 | |
| 23 | #ifdef __cplusplus |
| 24 | extern "C" { |
| 25 | #endif |
| 26 | /* |
| 27 | * Pulls the hardware declarations in to scope for the current file |
| 28 | * to make use of. |
| 29 | */ |
| 30 | #define __ESE_INCLUDE_HW(name) \ |
Will Drewry | de2cad7 | 2017-03-10 15:53:34 -0600 | [diff] [blame] | 31 | extern const struct EseOperations * name## _ops |
Will Drewry | d4ae528 | 2017-01-03 22:06:26 -0600 | [diff] [blame] | 32 | |
| 33 | |
| 34 | struct EseInterface; |
Will Drewry | de2cad7 | 2017-03-10 15:53:34 -0600 | [diff] [blame] | 35 | |
| 36 | /* ese_hw_receive_op_t: receives a buffer from the hardware. |
| 37 | * Args: |
| 38 | * - struct EseInterface *: session handle. |
| 39 | * - uint8_t *: pointer to the buffer to receive data into. |
| 40 | * - uint32_t: maximum length of the data to receive. |
| 41 | * - int: 1 or 0 indicating if it is a complete transaction. This allows the underlying |
| 42 | * implementation to batch reads if needed by the underlying wire protocol or if |
| 43 | * the hardware needs to be signalled explicitly. |
Will Drewry | d4ae528 | 2017-01-03 22:06:26 -0600 | [diff] [blame] | 44 | * |
Will Drewry | de2cad7 | 2017-03-10 15:53:34 -0600 | [diff] [blame] | 45 | * Returns: |
| 46 | * - uint32_t: bytes received. |
Will Drewry | ed4a7a7 | 2017-03-10 11:03:59 -0600 | [diff] [blame] | 47 | */ |
Will Drewry | de2cad7 | 2017-03-10 15:53:34 -0600 | [diff] [blame] | 48 | typedef uint32_t (ese_hw_receive_op_t)(struct EseInterface *, uint8_t *, uint32_t, int); |
| 49 | /* ese_hw_transmit_op_t: transmits a buffer over the hardware. |
| 50 | * Args: |
| 51 | * - struct EseInterface *: session handle. |
| 52 | * - uint8_t *: pointer to the buffer to transmit. |
| 53 | * - uint32_t: length of the data to transmit. |
| 54 | * - int: 1 or 0 indicating if it is a complete transaction. |
| 55 | * |
| 56 | * Returns: |
| 57 | * - uint32_t: bytes transmitted. |
| 58 | */ |
| 59 | typedef uint32_t (ese_hw_transmit_op_t)(struct EseInterface *, const uint8_t *, uint32_t, int); |
| 60 | /* ese_hw_reset_op_t: resets the hardware in case of communication desynchronization. |
| 61 | * Args: |
| 62 | * - struct EseInterface *: session handle. |
| 63 | * |
| 64 | * Returns: |
| 65 | * - int: -1 on error, 0 on success. |
| 66 | */ |
Will Drewry | d4ae528 | 2017-01-03 22:06:26 -0600 | [diff] [blame] | 67 | typedef int (ese_hw_reset_op_t)(struct EseInterface *); |
Will Drewry | 8f367fc | 2017-03-30 22:07:48 -0500 | [diff] [blame] | 68 | /* ese_transceive_sg_op_t: fully contained transmission and receive operation. |
Will Drewry | de2cad7 | 2017-03-10 15:53:34 -0600 | [diff] [blame] | 69 | * |
| 70 | * Must provide an implementation of the wire protocol necessary to transmit |
| 71 | * and receive an application payload to and from the eSE. Normally, this |
| 72 | * implementation is built on the hw_{receive,transmit} operations also |
| 73 | * provided and often requires the poll operation below. |
| 74 | * |
| 75 | * Args: |
| 76 | * - struct EseInterface *: session handle. |
Will Drewry | 8f367fc | 2017-03-30 22:07:48 -0500 | [diff] [blame] | 77 | * - const EseSgBuffer *: array of buffers to transmit |
| 78 | * - uint32_t: number of buffers to send |
| 79 | * - const EseSgBuffer *: array of buffers to receive into |
| 80 | * - uint32_t: number of buffers to receive to |
Will Drewry | de2cad7 | 2017-03-10 15:53:34 -0600 | [diff] [blame] | 81 | * |
| 82 | * Returns: |
| 83 | * - uint32_t: bytes received. |
| 84 | */ |
Will Drewry | 8f367fc | 2017-03-30 22:07:48 -0500 | [diff] [blame] | 85 | typedef uint32_t (ese_transceive_op_t)( |
| 86 | struct EseInterface *, const struct EseSgBuffer *, uint32_t, struct EseSgBuffer *, uint32_t); |
Will Drewry | de2cad7 | 2017-03-10 15:53:34 -0600 | [diff] [blame] | 87 | /* ese_poll_op_t: waits for the hardware to be ready to send data. |
| 88 | * |
| 89 | * Args: |
| 90 | * - struct EseInterface *: session handle. |
| 91 | * - uint8_t: byte to wait for. E.g., a start of frame byte. |
| 92 | * - float: time in seconds to wait. |
| 93 | * - int: whether to complete a transaction when polling іs complete. |
| 94 | * |
| 95 | * Returns: |
| 96 | * - int: On error or timeout, -1. |
| 97 | * On success, 1 or 0 depending on if the found byte was consumed. |
| 98 | */ |
Will Drewry | d4ae528 | 2017-01-03 22:06:26 -0600 | [diff] [blame] | 99 | typedef int (ese_poll_op_t)(struct EseInterface *, uint8_t, float, int); |
Will Drewry | de2cad7 | 2017-03-10 15:53:34 -0600 | [diff] [blame] | 100 | /* ese_hw_open_op_t: prepares the hardware for use. |
| 101 | * |
| 102 | * This function should prepare the hardware for use and attach |
| 103 | * any implementation specific state to the EseInterface handle such |
| 104 | * that it is accessible in the other calls. |
| 105 | * |
| 106 | * Args: |
| 107 | * - struct EseInterface *: freshly initialized session handle. |
| 108 | * - void *: implementation specific pointer from the libese client. |
| 109 | * |
| 110 | * Returns: |
| 111 | * - int: < 0 on error, 0 on success. |
| 112 | */ |
Will Drewry | d4ae528 | 2017-01-03 22:06:26 -0600 | [diff] [blame] | 113 | typedef int (ese_open_op_t)(struct EseInterface *, void *); |
Will Drewry | de2cad7 | 2017-03-10 15:53:34 -0600 | [diff] [blame] | 114 | /* ese_hw_close_op_t: releases the hardware in use. |
| 115 | * |
| 116 | * This function should free any dynamic memory and release |
| 117 | * the claimed hardware. |
| 118 | * |
| 119 | * Args: |
| 120 | * - struct EseInterface *: freshly initialized session handle. |
| 121 | * |
| 122 | * Returns: |
| 123 | * - Nothing. |
| 124 | */ |
| 125 | typedef void (ese_close_op_t)(struct EseInterface *); |
Will Drewry | d4ae528 | 2017-01-03 22:06:26 -0600 | [diff] [blame] | 126 | |
| 127 | #define __ESE_INITIALIZER(TYPE) \ |
| 128 | { \ |
| 129 | .ops = TYPE## _ops, \ |
Will Drewry | 92973c7 | 2017-04-02 15:04:32 -0500 | [diff] [blame] | 130 | .error = { \ |
| 131 | .is_err = false, \ |
| 132 | .code = 0, \ |
| 133 | .message = NULL, \ |
| 134 | }, \ |
Will Drewry | d4ae528 | 2017-01-03 22:06:26 -0600 | [diff] [blame] | 135 | .pad = { 0 }, \ |
| 136 | } |
| 137 | |
| 138 | #define __ese_init(_ptr, TYPE) {\ |
Will Drewry | 92973c7 | 2017-04-02 15:04:32 -0500 | [diff] [blame] | 139 | (_ptr)->ops = TYPE## _ops; \ |
| 140 | (_ptr)->pad[0] = 0; \ |
| 141 | (_ptr)->error.is_err = false; \ |
| 142 | (_ptr)->error.code = 0; \ |
| 143 | (_ptr)->error.message = (const char *)NULL; \ |
Will Drewry | d4ae528 | 2017-01-03 22:06:26 -0600 | [diff] [blame] | 144 | } |
| 145 | |
| 146 | struct EseOperations { |
Will Drewry | 92973c7 | 2017-04-02 15:04:32 -0500 | [diff] [blame] | 147 | const char *name; |
Will Drewry | d4ae528 | 2017-01-03 22:06:26 -0600 | [diff] [blame] | 148 | /* Used to prepare any implementation specific internal data and |
| 149 | * state needed for robust communication. |
| 150 | */ |
Will Drewry | 92973c7 | 2017-04-02 15:04:32 -0500 | [diff] [blame] | 151 | ese_open_op_t *open; |
Will Drewry | d4ae528 | 2017-01-03 22:06:26 -0600 | [diff] [blame] | 152 | /* Used to receive raw data from the ese. */ |
Will Drewry | 92973c7 | 2017-04-02 15:04:32 -0500 | [diff] [blame] | 153 | ese_hw_receive_op_t *hw_receive; |
Will Drewry | d4ae528 | 2017-01-03 22:06:26 -0600 | [diff] [blame] | 154 | /* Used to transmit raw data to the ese. */ |
Will Drewry | 92973c7 | 2017-04-02 15:04:32 -0500 | [diff] [blame] | 155 | ese_hw_transmit_op_t *hw_transmit; |
Will Drewry | d4ae528 | 2017-01-03 22:06:26 -0600 | [diff] [blame] | 156 | /* Used to perform a power reset on the device. */ |
Will Drewry | 92973c7 | 2017-04-02 15:04:32 -0500 | [diff] [blame] | 157 | ese_hw_reset_op_t *hw_reset; |
Will Drewry | d4ae528 | 2017-01-03 22:06:26 -0600 | [diff] [blame] | 158 | /* Wire-specific protocol polling for readiness. */ |
Will Drewry | 92973c7 | 2017-04-02 15:04:32 -0500 | [diff] [blame] | 159 | ese_poll_op_t *poll; |
Will Drewry | d4ae528 | 2017-01-03 22:06:26 -0600 | [diff] [blame] | 160 | /* Wire-specific protocol for transmitting and receiving |
| 161 | * application data to the eSE. By default, this may point to |
| 162 | * a generic implementation, like teq1_transceive, which uses |
| 163 | * the hw_* ops above. |
| 164 | */ |
Will Drewry | 92973c7 | 2017-04-02 15:04:32 -0500 | [diff] [blame] | 165 | ese_transceive_op_t *transceive; |
Will Drewry | d4ae528 | 2017-01-03 22:06:26 -0600 | [diff] [blame] | 166 | /* Cleans up any required state: file descriptors or heap allocations. */ |
Will Drewry | 92973c7 | 2017-04-02 15:04:32 -0500 | [diff] [blame] | 167 | ese_close_op_t *close; |
Will Drewry | d4ae528 | 2017-01-03 22:06:26 -0600 | [diff] [blame] | 168 | |
| 169 | /* Operational options */ |
Will Drewry | 92973c7 | 2017-04-02 15:04:32 -0500 | [diff] [blame] | 170 | const void *opts; |
Will Drewry | de2cad7 | 2017-03-10 15:53:34 -0600 | [diff] [blame] | 171 | |
| 172 | /* Operation error messages. */ |
| 173 | const char **errors; |
Will Drewry | 92973c7 | 2017-04-02 15:04:32 -0500 | [diff] [blame] | 174 | uint32_t errors_count; |
Will Drewry | d4ae528 | 2017-01-03 22:06:26 -0600 | [diff] [blame] | 175 | }; |
| 176 | |
| 177 | /* Maximum private stack storage on the interface instance. */ |
| 178 | #define ESE_INTERFACE_STATE_PAD 16 |
| 179 | struct EseInterface { |
| 180 | const struct EseOperations * ops; |
| 181 | struct { |
Will Drewry | de2cad7 | 2017-03-10 15:53:34 -0600 | [diff] [blame] | 182 | bool is_err; |
Will Drewry | d4ae528 | 2017-01-03 22:06:26 -0600 | [diff] [blame] | 183 | int code; |
| 184 | const char *message; |
| 185 | } error; |
Will Drewry | d4ae528 | 2017-01-03 22:06:26 -0600 | [diff] [blame] | 186 | /* Reserved to avoid heap allocation requirement. */ |
| 187 | uint8_t pad[ESE_INTERFACE_STATE_PAD]; |
| 188 | }; |
| 189 | |
Will Drewry | de2cad7 | 2017-03-10 15:53:34 -0600 | [diff] [blame] | 190 | /* |
| 191 | * Provided by libese to manage exposing usable errors up the stack to the |
| 192 | * libese user. |
| 193 | */ |
| 194 | void ese_set_error(struct EseInterface *ese, int code); |
Will Drewry | d4ae528 | 2017-01-03 22:06:26 -0600 | [diff] [blame] | 195 | |
Will Drewry | de2cad7 | 2017-03-10 15:53:34 -0600 | [diff] [blame] | 196 | /* |
| 197 | * Global error enums. |
| 198 | */ |
| 199 | enum EseGlobalError { |
| 200 | kEseGlobalErrorNoTransceive = -1, |
| 201 | kEseGlobalErrorPollTimedOut = -2, |
| 202 | }; |
Will Drewry | d4ae528 | 2017-01-03 22:06:26 -0600 | [diff] [blame] | 203 | |
| 204 | #define ESE_DEFINE_HW_OPS(name, obj) \ |
| 205 | const struct EseOperations * name##_ops = &obj |
| 206 | |
Will Drewry | de2cad7 | 2017-03-10 15:53:34 -0600 | [diff] [blame] | 207 | |
Will Drewry | d4ae528 | 2017-01-03 22:06:26 -0600 | [diff] [blame] | 208 | #ifdef __cplusplus |
| 209 | } /* extern "C" */ |
| 210 | #endif |
| 211 | #endif /* ESE_HW_API_H_ */ |