• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 #ifndef ESE_TEQ1_H_
18 #define ESE_TEQ1_H_ 1
19 
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23 
24 #include <ese/ese.h>
25 #include <ese/bit_spec.h>
26 
27 /* Reserved codes for T=1 devices in EseOperation­>errors. */
28 enum Teq1Error {
29  kTeq1ErrorHardFail = 0,
30  kTeq1ErrorAbort,
31  kTeq1ErrorDeviceReset,
32  kTeq1ErrorMax,
33 };
34 
35 /* For use in constant initializers libese-hw errors. */
36 #define TEQ1_ERROR_MESSAGES \
37   [kTeq1ErrorHardFail] = "T=1 suffered hard failure", \
38   [kTeq1ErrorAbort] = "T=1 aborting due to errors", \
39   [kTeq1ErrorDeviceReset] = "T=1 unable to recover even after device reset"
40 
41 enum pcb_type {
42   kPcbTypeInfo0 = 0x0,
43   kPcbTypeInfo1 = 0x1,
44   kPcbTypeReceiveReady = 0x2,
45   kPcbTypeSupervisory = 0x3,
46 };
47 
48 enum super_type {
49   kSuperTypeResync = 0x0,
50   kSuperTypeIFS = 0x1,
51   kSuperTypeAbort = 0x2,
52   kSuperTypeWTX = 0x3,
53 };
54 
55 struct PcbSpec {
56   struct bit_spec type;
57   struct bit_spec data;
58   struct {
59     struct bit_spec more_data;
60     struct bit_spec send_seq;
61   } I;
62   struct {
63     struct bit_spec parity_err;
64     struct bit_spec other_err;
65     struct bit_spec next_seq;
66   } R;
67   struct {
68     struct bit_spec type;
69     struct bit_spec response;
70   } S;
71 };
72 
73 const static struct PcbSpec PCB = {
74   .type = { .value = 3, .shift = 6, },
75   .data = { .value = 63, .shift = 0, },
76   .I = {
77     .more_data = { .value = 1, .shift = 5, },
78     .send_seq = { .value = 1, .shift = 6, },
79   },
80   .R = {
81     /* char parity or redundancy code err */
82     .parity_err = { .value = 1, .shift = 0, },
83     /* any other errors */
84     .other_err = { .value = 1, .shift = 1, },
85     /* If the same seq as last frame, then err even if other bits are 0. */
86     .next_seq = { .value = 1, .shift = 4, },
87   },
88   .S = {
89     .type = { .value = 3, .shift = 0, },
90     .response = { .value = 1, .shift = 5, },
91   },
92 };
93 
94 struct Teq1Header {
95   uint8_t NAD;
96   uint8_t PCB;
97   uint8_t LEN;
98 };
99 #define TEQ1HEADER_SIZE 3
100 #define TEQ1FRAME_SIZE INF_LEN + 1 + TEQ1HEADER_SIZE
101 
102 #define INF_LEN 254
103 #define IFSC 254
104 struct Teq1Frame {
105   union {
106     uint8_t val[sizeof(struct Teq1Header) + INF_LEN + 1];
107     struct {
108       struct Teq1Header header;
109       union {
110         uint8_t INF[INF_LEN + 1]; /* Up to 254 with trailing LRC byte. */
111       };
112       /* If CRC was supported, it would be uint16_t. */
113     };
114   };
115 };
116 
117 
118 /*
119  * Required to be the header for all EseInterface pad[]s for
120  * cards implementing T=1.
121  */
122 struct Teq1CardState {
123   union {
124     struct {
125       int card:1;
126       int interface:1;
127     };
128     uint8_t seq_bits;
129   } seq;
130 };
131 
132 /* Set "last sent" to 1 so we start at 0. */
133 #define TEQ1_INIT_CARD_STATE(CARD) \
134   (CARD)->seq.card = 1; \
135   (CARD)->seq.interface = 1;
136 
137 /*
138  * Used by devices implementing T=1 to set specific options
139  * or callback behavior.
140  */
141 struct Teq1ProtocolOptions;
142 typedef int (teq1_protocol_preprocess_op_t)(const struct Teq1ProtocolOptions *const, struct Teq1Frame *, int);
143 
144 struct Teq1ProtocolOptions {
145   uint8_t host_address;  /* NAD to listen for */
146   uint8_t node_address;  /* NAD to send to */
147   float bwt;
148   float etu;
149   /*
150    * If not NULL, is called immediately before transmit (1)
151    * and immediately after receive.
152    */
153   teq1_protocol_preprocess_op_t *preprocess;
154 };
155 
156 /* PCB bits */
157 #define kTeq1PcbType (3 << 6)
158 
159 /* I-block bits */
160 #define kTeq1InfoType        (0 << 6)
161 #define kTeq1InfoMoreBit     (1 << 5)
162 #define kTeq1InfoSeqBit      (1 << 6)
163 
164 /* R-block bits */
165 #define kTeq1RrType         (1 << 7)
166 #define kTeq1RrSeqBit       (1 << 4)
167 #define kTeq1RrParityError  (1)
168 #define kTeq1RrOtherError   (1 << 1)
169 
170 /* S-block bits */
171 #define kTeq1SuperType      (3 << 6)
172 #define kTeq1SuperRequestBit (0)
173 #define kTeq1SuperResponseBit (1 << 5)
174 #define kTeq1SuperResyncBit (0)
175 #define kTeq1SuperIfsBit (1)
176 #define kTeq1SuperAbortBit (1 << 1)
177 #define kTeq1SuperWtxBit (3)
178 
179 /* I(Seq, More-bit) */
180 #define TEQ1_I(S, M) ((S) << 6) | ((M) << 5)
181 
182 /* R(Seq, Other Error, Parity Error) */
183 #define TEQ1_R(S, O, P) (kTeq1RrType | ((S) << 4) | (P) | ((O) << 1))
184 /* S_<TYPE>(response) */
185 #define TEQ1_S_RESYNC(R) (kTeq1SuperType | ((R) << 5) | kTeq1SuperResyncBit)
186 #define TEQ1_S_WTX(R)  (kTeq1SuperType | ((R) << 5) | kTeq1SuperWtxBit)
187 #define TEQ1_S_ABORT(R) (kTeq1SuperType | ((R) << 5) | kTeq1SuperAbortBit)
188 #define TEQ1_S_IFS(R) (kTeq1SuperType | ((R) << 5) | kTeq1SuperIfsBit)
189 
190 uint32_t teq1_transceive(struct EseInterface *ese,
191                          const struct Teq1ProtocolOptions *opts,
192                          const struct EseSgBuffer *tx_bufs, uint8_t tx_segs,
193                          struct EseSgBuffer *rx_bufs, uint8_t rx_segs);
194 
195 uint8_t teq1_compute_LRC(const struct Teq1Frame *frame);
196 
197 #define teq1_trace_header() ALOGI("%-20s --- %20s", "Interface", "Card")
198 #define teq1_trace_transmit(PCB, LEN) ALOGI("%-20s --> %20s [%3hhu]", teq1_pcb_to_name(PCB), "", LEN)
199 #define teq1_trace_receive(PCB, LEN) ALOGI("%-20s <-- %20s [%3hhu]", "", teq1_pcb_to_name(PCB), LEN)
200 
201 #ifdef __cplusplus
202 }  /* extern "C" */
203 #endif
204 #endif  /* ESE_TEQ1_H_ */
205