blob: 96139ce4c2b4c0d49969a5cafd0ccc4673d5f884 [file] [log] [blame]
Will Drewryd4ae5282017-01-03 22:06:26 -06001/*
2 * Copyright (C) 2016 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 * Minimal functions that only validate arguments.
17 */
18
Will Drewryde2cad72017-03-10 15:53:34 -060019#include "../libese/include/ese/ese.h"
20
21enum EseFakeHwError {
22 kEseFakeHwErrorEarlyClose,
23 kEseFakeHwErrorReceiveDuringTransmit,
24 kEseFakeHwErrorInvalidReceiveSize,
25 kEseFakeHwErrorTransmitDuringReceive,
26 kEseFakeHwErrorInvalidTransmitSize,
27 kEseFakeHwErrorTranscieveWhileBusy,
28 kEseFakeHwErrorEmptyTransmit,
29 kEseFakeHwErrorMax,
30};
31
32static const char *kErrorMessages[] = {
33 "Interface closed without finishing transmission.",
34 "Receive called without completing transmission.",
35 "Invalid receive buffer supplied with non-zero length.",
36 "Transmit called without completing reception.",
37 "Invalid transmit buffer supplied with non-zero length.",
38 "Transceive called while other I/O in process.",
39 "Transmitted no data.", /* Can reach this by setting tx_len = 0. */
40};
Will Drewryd4ae5282017-01-03 22:06:26 -060041
42static int fake_open(struct EseInterface *ese,
43 void *hw_opts __attribute__((unused))) {
44 ese->pad[0] = 1; /* rx complete */
45 ese->pad[1] = 1; /* tx complete */
46 return 0;
47}
48
Will Drewryde2cad72017-03-10 15:53:34 -060049static void fake_close(struct EseInterface *ese) {
Will Drewryd4ae5282017-01-03 22:06:26 -060050 if (!ese->pad[0] || !ese->pad[1]) {
51 /* Set by caller. ese->error.is_error = 1; */
Will Drewryde2cad72017-03-10 15:53:34 -060052 ese_set_error(ese, kEseFakeHwErrorEarlyClose);
53 return;
Will Drewryd4ae5282017-01-03 22:06:26 -060054 }
Will Drewryd4ae5282017-01-03 22:06:26 -060055}
56
Will Drewryde2cad72017-03-10 15:53:34 -060057static uint32_t fake_receive(struct EseInterface *ese, uint8_t *buf,
58 uint32_t len, int complete) {
Will Drewryd4ae5282017-01-03 22:06:26 -060059 if (!ese->pad[1]) {
Will Drewryde2cad72017-03-10 15:53:34 -060060 ese_set_error(ese, kEseFakeHwErrorReceiveDuringTransmit);
Will Drewryd4ae5282017-01-03 22:06:26 -060061 return -1;
62 }
63 ese->pad[0] = complete;
64 if (!buf && len) {
Will Drewryde2cad72017-03-10 15:53:34 -060065 ese_set_error(ese, kEseFakeHwErrorInvalidReceiveSize);
Will Drewryd4ae5282017-01-03 22:06:26 -060066 return -1;
67 }
Will Drewryde2cad72017-03-10 15:53:34 -060068 if (!len) {
Will Drewryd4ae5282017-01-03 22:06:26 -060069 return 0;
Will Drewryde2cad72017-03-10 15:53:34 -060070 }
Will Drewryd4ae5282017-01-03 22:06:26 -060071 return len;
72}
73
Will Drewryde2cad72017-03-10 15:53:34 -060074static uint32_t fake_transmit(struct EseInterface *ese, const uint8_t *buf,
75 uint32_t len, int complete) {
Will Drewryd4ae5282017-01-03 22:06:26 -060076 if (!ese->pad[0]) {
Will Drewryde2cad72017-03-10 15:53:34 -060077 ese_set_error(ese, kEseFakeHwErrorTransmitDuringReceive);
Will Drewryd4ae5282017-01-03 22:06:26 -060078 return -1;
79 }
80 ese->pad[1] = complete;
81 if (!buf && len) {
Will Drewryde2cad72017-03-10 15:53:34 -060082 ese_set_error(ese, kEseFakeHwErrorInvalidTransmitSize);
Will Drewryd4ae5282017-01-03 22:06:26 -060083 return -1;
84 }
Will Drewryde2cad72017-03-10 15:53:34 -060085 if (!len) {
Will Drewryd4ae5282017-01-03 22:06:26 -060086 return 0;
Will Drewryde2cad72017-03-10 15:53:34 -060087 }
Will Drewryd4ae5282017-01-03 22:06:26 -060088 return len;
89}
90
91static int fake_poll(struct EseInterface *ese, uint8_t poll_for, float timeout,
92 int complete) {
93 /* Poll begins a receive-train so transmit needs to be completed. */
94 if (!ese->pad[1]) {
Will Drewryde2cad72017-03-10 15:53:34 -060095 ese_set_error(ese, kEseFakeHwErrorReceiveDuringTransmit);
Will Drewryd4ae5282017-01-03 22:06:26 -060096 return -1;
97 }
98 if (timeout == 0.0f) {
99 /* Instant timeout. */
100 return 0;
101 }
102 /* Only expect one value to work. */
103 if (poll_for == 0xad) {
104 return 1;
105 }
106 ese->pad[0] = complete;
107 return 0;
108}
109
Will Drewry8f367fc2017-03-30 22:07:48 -0500110uint32_t fake_transceive(struct EseInterface *ese,
111 const struct EseSgBuffer *tx_bufs, uint32_t tx_seg,
112 struct EseSgBuffer *rx_bufs, uint32_t rx_seg) {
Will Drewryde2cad72017-03-10 15:53:34 -0600113 uint32_t processed = 0;
Will Drewry8f367fc2017-03-30 22:07:48 -0500114 uint32_t offset = 0;
115 struct EseSgBuffer *rx_buf = rx_bufs;
116 const struct EseSgBuffer *tx_buf = tx_bufs;
117
Will Drewryd4ae5282017-01-03 22:06:26 -0600118 if (!ese->pad[0] || !ese->pad[1]) {
Will Drewryde2cad72017-03-10 15:53:34 -0600119 ese_set_error(ese, kEseFakeHwErrorTranscieveWhileBusy);
Will Drewryd4ae5282017-01-03 22:06:26 -0600120 return 0;
121 }
Will Drewry8f367fc2017-03-30 22:07:48 -0500122 while (tx_buf < tx_bufs + tx_seg) {
123 uint32_t sent =
124 fake_transmit(ese, tx_buf->base + offset, tx_buf->len - offset, 0);
125 if (sent != tx_buf->len - offset) {
126 offset = tx_buf->len - sent;
127 processed += sent;
128 continue;
129 }
Will Drewryd4ae5282017-01-03 22:06:26 -0600130 if (sent == 0) {
Will Drewryde2cad72017-03-10 15:53:34 -0600131 if (ese_error(ese)) {
Will Drewryd4ae5282017-01-03 22:06:26 -0600132 return 0;
Will Drewryde2cad72017-03-10 15:53:34 -0600133 }
134 ese_set_error(ese, kEseFakeHwErrorEmptyTransmit);
Will Drewryd4ae5282017-01-03 22:06:26 -0600135 return 0;
136 }
Will Drewry8f367fc2017-03-30 22:07:48 -0500137 tx_buf++;
138 offset = 0;
Will Drewryd4ae5282017-01-03 22:06:26 -0600139 processed += sent;
140 }
141 fake_transmit(ese, NULL, 0, 1); /* Complete. */
142 if (fake_poll(ese, 0xad, 10, 0) != 1) {
Will Drewryde2cad72017-03-10 15:53:34 -0600143 ese_set_error(ese, kEseGlobalErrorPollTimedOut);
Will Drewryd4ae5282017-01-03 22:06:26 -0600144 return 0;
145 }
Will Drewry8f367fc2017-03-30 22:07:48 -0500146 /* This reads the full RX buffer rather than a protocol specified amount. */
147 processed = 0;
148 while (rx_buf < rx_bufs + rx_seg) {
149 processed += fake_receive(ese, rx_buf->base, rx_buf->len, 1);
150 }
Will Drewryd4ae5282017-01-03 22:06:26 -0600151 return processed;
152}
153
154static const struct EseOperations ops = {
155 .name = "eSE Fake Hardware",
156 .open = &fake_open,
157 .hw_receive = &fake_receive,
158 .hw_transmit = &fake_transmit,
159 .transceive = &fake_transceive,
160 .poll = &fake_poll,
161 .close = &fake_close,
162 .opts = NULL,
Will Drewryde2cad72017-03-10 15:53:34 -0600163 .errors = kErrorMessages,
164 .errors_count = sizeof(kErrorMessages),
Will Drewryd4ae5282017-01-03 22:06:26 -0600165};
166ESE_DEFINE_HW_OPS(ESE_HW_FAKE, ops);
167