xref: /aosp_15_r20/external/libese/libese-hw/ese_hw_fake.c (revision 5c4dab75aa57366379dce576b1a9e082a44e2b3a)
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