1*5c4dab75SAndroid Build Coastguard Worker /*
2*5c4dab75SAndroid Build Coastguard Worker * Copyright (C) 2016 The Android Open Source Project
3*5c4dab75SAndroid Build Coastguard Worker *
4*5c4dab75SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*5c4dab75SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*5c4dab75SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*5c4dab75SAndroid Build Coastguard Worker *
8*5c4dab75SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*5c4dab75SAndroid Build Coastguard Worker *
10*5c4dab75SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*5c4dab75SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*5c4dab75SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*5c4dab75SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*5c4dab75SAndroid Build Coastguard Worker * limitations under the License.
15*5c4dab75SAndroid Build Coastguard Worker *
16*5c4dab75SAndroid Build Coastguard Worker * Minimal functions that only validate arguments.
17*5c4dab75SAndroid Build Coastguard Worker */
18*5c4dab75SAndroid Build Coastguard Worker
19*5c4dab75SAndroid Build Coastguard Worker #include "../libese/include/ese/ese.h"
20*5c4dab75SAndroid Build Coastguard Worker
21*5c4dab75SAndroid Build Coastguard Worker enum EseFakeHwError {
22*5c4dab75SAndroid Build Coastguard Worker kEseFakeHwErrorEarlyClose,
23*5c4dab75SAndroid Build Coastguard Worker kEseFakeHwErrorReceiveDuringTransmit,
24*5c4dab75SAndroid Build Coastguard Worker kEseFakeHwErrorInvalidReceiveSize,
25*5c4dab75SAndroid Build Coastguard Worker kEseFakeHwErrorTransmitDuringReceive,
26*5c4dab75SAndroid Build Coastguard Worker kEseFakeHwErrorInvalidTransmitSize,
27*5c4dab75SAndroid Build Coastguard Worker kEseFakeHwErrorTranscieveWhileBusy,
28*5c4dab75SAndroid Build Coastguard Worker kEseFakeHwErrorEmptyTransmit,
29*5c4dab75SAndroid Build Coastguard Worker kEseFakeHwErrorMax,
30*5c4dab75SAndroid Build Coastguard Worker };
31*5c4dab75SAndroid Build Coastguard Worker
32*5c4dab75SAndroid Build Coastguard Worker static const char *kErrorMessages[] = {
33*5c4dab75SAndroid Build Coastguard Worker "Interface closed without finishing transmission.",
34*5c4dab75SAndroid Build Coastguard Worker "Receive called without completing transmission.",
35*5c4dab75SAndroid Build Coastguard Worker "Invalid receive buffer supplied with non-zero length.",
36*5c4dab75SAndroid Build Coastguard Worker "Transmit called without completing reception.",
37*5c4dab75SAndroid Build Coastguard Worker "Invalid transmit buffer supplied with non-zero length.",
38*5c4dab75SAndroid Build Coastguard Worker "Transceive called while other I/O in process.",
39*5c4dab75SAndroid Build Coastguard Worker "Transmitted no data.", /* Can reach this by setting tx_len = 0. */
40*5c4dab75SAndroid Build Coastguard Worker };
41*5c4dab75SAndroid Build Coastguard Worker
fake_open(struct EseInterface * ese,void * hw_opts)42*5c4dab75SAndroid Build Coastguard Worker static int fake_open(struct EseInterface *ese,
43*5c4dab75SAndroid Build Coastguard Worker void *hw_opts __attribute__((unused))) {
44*5c4dab75SAndroid Build Coastguard Worker ese->pad[0] = 1; /* rx complete */
45*5c4dab75SAndroid Build Coastguard Worker ese->pad[1] = 1; /* tx complete */
46*5c4dab75SAndroid Build Coastguard Worker return 0;
47*5c4dab75SAndroid Build Coastguard Worker }
48*5c4dab75SAndroid Build Coastguard Worker
fake_close(struct EseInterface * ese)49*5c4dab75SAndroid Build Coastguard Worker static void fake_close(struct EseInterface *ese) {
50*5c4dab75SAndroid Build Coastguard Worker if (!ese->pad[0] || !ese->pad[1]) {
51*5c4dab75SAndroid Build Coastguard Worker /* Set by caller. ese->error.is_error = 1; */
52*5c4dab75SAndroid Build Coastguard Worker ese_set_error(ese, kEseFakeHwErrorEarlyClose);
53*5c4dab75SAndroid Build Coastguard Worker return;
54*5c4dab75SAndroid Build Coastguard Worker }
55*5c4dab75SAndroid Build Coastguard Worker }
56*5c4dab75SAndroid Build Coastguard Worker
fake_receive(struct EseInterface * ese,uint8_t * buf,uint32_t len,int complete)57*5c4dab75SAndroid Build Coastguard Worker static uint32_t fake_receive(struct EseInterface *ese, uint8_t *buf,
58*5c4dab75SAndroid Build Coastguard Worker uint32_t len, int complete) {
59*5c4dab75SAndroid Build Coastguard Worker if (!ese->pad[1]) {
60*5c4dab75SAndroid Build Coastguard Worker ese_set_error(ese, kEseFakeHwErrorReceiveDuringTransmit);
61*5c4dab75SAndroid Build Coastguard Worker return -1;
62*5c4dab75SAndroid Build Coastguard Worker }
63*5c4dab75SAndroid Build Coastguard Worker ese->pad[0] = complete;
64*5c4dab75SAndroid Build Coastguard Worker if (!buf && len) {
65*5c4dab75SAndroid Build Coastguard Worker ese_set_error(ese, kEseFakeHwErrorInvalidReceiveSize);
66*5c4dab75SAndroid Build Coastguard Worker return -1;
67*5c4dab75SAndroid Build Coastguard Worker }
68*5c4dab75SAndroid Build Coastguard Worker if (!len) {
69*5c4dab75SAndroid Build Coastguard Worker return 0;
70*5c4dab75SAndroid Build Coastguard Worker }
71*5c4dab75SAndroid Build Coastguard Worker return len;
72*5c4dab75SAndroid Build Coastguard Worker }
73*5c4dab75SAndroid Build Coastguard Worker
fake_transmit(struct EseInterface * ese,const uint8_t * buf,uint32_t len,int complete)74*5c4dab75SAndroid Build Coastguard Worker static uint32_t fake_transmit(struct EseInterface *ese, const uint8_t *buf,
75*5c4dab75SAndroid Build Coastguard Worker uint32_t len, int complete) {
76*5c4dab75SAndroid Build Coastguard Worker if (!ese->pad[0]) {
77*5c4dab75SAndroid Build Coastguard Worker ese_set_error(ese, kEseFakeHwErrorTransmitDuringReceive);
78*5c4dab75SAndroid Build Coastguard Worker return -1;
79*5c4dab75SAndroid Build Coastguard Worker }
80*5c4dab75SAndroid Build Coastguard Worker ese->pad[1] = complete;
81*5c4dab75SAndroid Build Coastguard Worker if (!buf && len) {
82*5c4dab75SAndroid Build Coastguard Worker ese_set_error(ese, kEseFakeHwErrorInvalidTransmitSize);
83*5c4dab75SAndroid Build Coastguard Worker return -1;
84*5c4dab75SAndroid Build Coastguard Worker }
85*5c4dab75SAndroid Build Coastguard Worker if (!len) {
86*5c4dab75SAndroid Build Coastguard Worker return 0;
87*5c4dab75SAndroid Build Coastguard Worker }
88*5c4dab75SAndroid Build Coastguard Worker return len;
89*5c4dab75SAndroid Build Coastguard Worker }
90*5c4dab75SAndroid Build Coastguard Worker
fake_poll(struct EseInterface * ese,uint8_t poll_for,float timeout,int complete)91*5c4dab75SAndroid Build Coastguard Worker static int fake_poll(struct EseInterface *ese, uint8_t poll_for, float timeout,
92*5c4dab75SAndroid Build Coastguard Worker int complete) {
93*5c4dab75SAndroid Build Coastguard Worker /* Poll begins a receive-train so transmit needs to be completed. */
94*5c4dab75SAndroid Build Coastguard Worker if (!ese->pad[1]) {
95*5c4dab75SAndroid Build Coastguard Worker ese_set_error(ese, kEseFakeHwErrorReceiveDuringTransmit);
96*5c4dab75SAndroid Build Coastguard Worker return -1;
97*5c4dab75SAndroid Build Coastguard Worker }
98*5c4dab75SAndroid Build Coastguard Worker if (timeout == 0.0f) {
99*5c4dab75SAndroid Build Coastguard Worker /* Instant timeout. */
100*5c4dab75SAndroid Build Coastguard Worker return 0;
101*5c4dab75SAndroid Build Coastguard Worker }
102*5c4dab75SAndroid Build Coastguard Worker /* Only expect one value to work. */
103*5c4dab75SAndroid Build Coastguard Worker if (poll_for == 0xad) {
104*5c4dab75SAndroid Build Coastguard Worker return 1;
105*5c4dab75SAndroid Build Coastguard Worker }
106*5c4dab75SAndroid Build Coastguard Worker ese->pad[0] = complete;
107*5c4dab75SAndroid Build Coastguard Worker return 0;
108*5c4dab75SAndroid Build Coastguard Worker }
109*5c4dab75SAndroid Build Coastguard Worker
fake_transceive(struct EseInterface * ese,const struct EseSgBuffer * tx_bufs,uint32_t tx_seg,struct EseSgBuffer * rx_bufs,uint32_t rx_seg)110*5c4dab75SAndroid Build Coastguard Worker uint32_t fake_transceive(struct EseInterface *ese,
111*5c4dab75SAndroid Build Coastguard Worker const struct EseSgBuffer *tx_bufs, uint32_t tx_seg,
112*5c4dab75SAndroid Build Coastguard Worker struct EseSgBuffer *rx_bufs, uint32_t rx_seg) {
113*5c4dab75SAndroid Build Coastguard Worker uint32_t processed = 0;
114*5c4dab75SAndroid Build Coastguard Worker uint32_t offset = 0;
115*5c4dab75SAndroid Build Coastguard Worker struct EseSgBuffer *rx_buf = rx_bufs;
116*5c4dab75SAndroid Build Coastguard Worker const struct EseSgBuffer *tx_buf = tx_bufs;
117*5c4dab75SAndroid Build Coastguard Worker
118*5c4dab75SAndroid Build Coastguard Worker if (!ese->pad[0] || !ese->pad[1]) {
119*5c4dab75SAndroid Build Coastguard Worker ese_set_error(ese, kEseFakeHwErrorTranscieveWhileBusy);
120*5c4dab75SAndroid Build Coastguard Worker return 0;
121*5c4dab75SAndroid Build Coastguard Worker }
122*5c4dab75SAndroid Build Coastguard Worker while (tx_buf < tx_bufs + tx_seg) {
123*5c4dab75SAndroid Build Coastguard Worker uint32_t sent =
124*5c4dab75SAndroid Build Coastguard Worker fake_transmit(ese, tx_buf->base + offset, tx_buf->len - offset, 0);
125*5c4dab75SAndroid Build Coastguard Worker if (sent != tx_buf->len - offset) {
126*5c4dab75SAndroid Build Coastguard Worker offset = tx_buf->len - sent;
127*5c4dab75SAndroid Build Coastguard Worker processed += sent;
128*5c4dab75SAndroid Build Coastguard Worker continue;
129*5c4dab75SAndroid Build Coastguard Worker }
130*5c4dab75SAndroid Build Coastguard Worker if (sent == 0) {
131*5c4dab75SAndroid Build Coastguard Worker if (ese_error(ese)) {
132*5c4dab75SAndroid Build Coastguard Worker return 0;
133*5c4dab75SAndroid Build Coastguard Worker }
134*5c4dab75SAndroid Build Coastguard Worker ese_set_error(ese, kEseFakeHwErrorEmptyTransmit);
135*5c4dab75SAndroid Build Coastguard Worker return 0;
136*5c4dab75SAndroid Build Coastguard Worker }
137*5c4dab75SAndroid Build Coastguard Worker tx_buf++;
138*5c4dab75SAndroid Build Coastguard Worker offset = 0;
139*5c4dab75SAndroid Build Coastguard Worker processed += sent;
140*5c4dab75SAndroid Build Coastguard Worker }
141*5c4dab75SAndroid Build Coastguard Worker fake_transmit(ese, NULL, 0, 1); /* Complete. */
142*5c4dab75SAndroid Build Coastguard Worker if (fake_poll(ese, 0xad, 10, 0) != 1) {
143*5c4dab75SAndroid Build Coastguard Worker ese_set_error(ese, kEseGlobalErrorPollTimedOut);
144*5c4dab75SAndroid Build Coastguard Worker return 0;
145*5c4dab75SAndroid Build Coastguard Worker }
146*5c4dab75SAndroid Build Coastguard Worker /* This reads the full RX buffer rather than a protocol specified amount. */
147*5c4dab75SAndroid Build Coastguard Worker processed = 0;
148*5c4dab75SAndroid Build Coastguard Worker while (rx_buf < rx_bufs + rx_seg) {
149*5c4dab75SAndroid Build Coastguard Worker processed += fake_receive(ese, rx_buf->base, rx_buf->len, 1);
150*5c4dab75SAndroid Build Coastguard Worker }
151*5c4dab75SAndroid Build Coastguard Worker return processed;
152*5c4dab75SAndroid Build Coastguard Worker }
153*5c4dab75SAndroid Build Coastguard Worker
154*5c4dab75SAndroid Build Coastguard Worker static const struct EseOperations ops = {
155*5c4dab75SAndroid Build Coastguard Worker .name = "eSE Fake Hardware",
156*5c4dab75SAndroid Build Coastguard Worker .open = &fake_open,
157*5c4dab75SAndroid Build Coastguard Worker .hw_receive = &fake_receive,
158*5c4dab75SAndroid Build Coastguard Worker .hw_transmit = &fake_transmit,
159*5c4dab75SAndroid Build Coastguard Worker .transceive = &fake_transceive,
160*5c4dab75SAndroid Build Coastguard Worker .poll = &fake_poll,
161*5c4dab75SAndroid Build Coastguard Worker .close = &fake_close,
162*5c4dab75SAndroid Build Coastguard Worker .opts = NULL,
163*5c4dab75SAndroid Build Coastguard Worker .errors = kErrorMessages,
164*5c4dab75SAndroid Build Coastguard Worker .errors_count = sizeof(kErrorMessages),
165*5c4dab75SAndroid Build Coastguard Worker };
166*5c4dab75SAndroid Build Coastguard Worker ESE_DEFINE_HW_OPS(ESE_HW_FAKE, ops);
167*5c4dab75SAndroid Build Coastguard Worker
168