|
|
/*
|
|
|
* Copyright (C) 2016 The Android Open Source Project
|
|
|
*
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
* You may obtain a copy of the License at
|
|
|
*
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
*
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
* See the License for the specific language governing permissions and
|
|
|
* limitations under the License.
|
|
|
*/
|
|
|
|
|
|
#ifndef ESE_TEQ1_H_
|
|
|
#define ESE_TEQ1_H_ 1
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
extern "C" {
|
|
|
#endif
|
|
|
|
|
|
#include <ese/ese.h>
|
|
|
#include <ese/bit_spec.h>
|
|
|
|
|
|
/* Reserved codes for T=1 devices in EseOperation>errors. */
|
|
|
enum Teq1Error {
|
|
|
kTeq1ErrorHardFail = 0,
|
|
|
kTeq1ErrorAbort,
|
|
|
kTeq1ErrorDeviceReset,
|
|
|
kTeq1ErrorMax,
|
|
|
};
|
|
|
|
|
|
/* For use in constant initializers libese-hw errors. */
|
|
|
#define TEQ1_ERROR_MESSAGES \
|
|
|
[kTeq1ErrorHardFail] = "T=1 suffered hard failure", \
|
|
|
[kTeq1ErrorAbort] = "T=1 aborting due to errors", \
|
|
|
[kTeq1ErrorDeviceReset] = "T=1 unable to recover even after device reset"
|
|
|
|
|
|
enum pcb_type {
|
|
|
kPcbTypeInfo0 = 0x0,
|
|
|
kPcbTypeInfo1 = 0x1,
|
|
|
kPcbTypeReceiveReady = 0x2,
|
|
|
kPcbTypeSupervisory = 0x3,
|
|
|
};
|
|
|
|
|
|
enum super_type {
|
|
|
kSuperTypeResync = 0x0,
|
|
|
kSuperTypeIFS = 0x1,
|
|
|
kSuperTypeAbort = 0x2,
|
|
|
kSuperTypeWTX = 0x3,
|
|
|
};
|
|
|
|
|
|
struct PcbSpec {
|
|
|
struct bit_spec type;
|
|
|
struct bit_spec data;
|
|
|
struct {
|
|
|
struct bit_spec more_data;
|
|
|
struct bit_spec send_seq;
|
|
|
} I;
|
|
|
struct {
|
|
|
struct bit_spec parity_err;
|
|
|
struct bit_spec other_err;
|
|
|
struct bit_spec next_seq;
|
|
|
} R;
|
|
|
struct {
|
|
|
struct bit_spec type;
|
|
|
struct bit_spec response;
|
|
|
} S;
|
|
|
};
|
|
|
|
|
|
const static struct PcbSpec PCB = {
|
|
|
.type = { .value = 3, .shift = 6, },
|
|
|
.data = { .value = 63, .shift = 0, },
|
|
|
.I = {
|
|
|
.more_data = { .value = 1, .shift = 5, },
|
|
|
.send_seq = { .value = 1, .shift = 6, },
|
|
|
},
|
|
|
.R = {
|
|
|
/* char parity or redundancy code err */
|
|
|
.parity_err = { .value = 1, .shift = 0, },
|
|
|
/* any other errors */
|
|
|
.other_err = { .value = 1, .shift = 1, },
|
|
|
/* If the same seq as last frame, then err even if other bits are 0. */
|
|
|
.next_seq = { .value = 1, .shift = 4, },
|
|
|
},
|
|
|
.S = {
|
|
|
.type = { .value = 3, .shift = 0, },
|
|
|
.response = { .value = 1, .shift = 5, },
|
|
|
},
|
|
|
};
|
|
|
|
|
|
struct Teq1Header {
|
|
|
uint8_t NAD;
|
|
|
uint8_t PCB;
|
|
|
uint8_t LEN;
|
|
|
};
|
|
|
#define TEQ1HEADER_SIZE 3
|
|
|
#define TEQ1FRAME_SIZE INF_LEN + 1 + TEQ1HEADER_SIZE
|
|
|
|
|
|
#define INF_LEN 254
|
|
|
#define IFSC 254
|
|
|
struct Teq1Frame {
|
|
|
union {
|
|
|
uint8_t val[sizeof(struct Teq1Header) + INF_LEN + 1];
|
|
|
struct {
|
|
|
struct Teq1Header header;
|
|
|
union {
|
|
|
uint8_t INF[INF_LEN + 1]; /* Up to 254 with trailing LRC byte. */
|
|
|
};
|
|
|
/* If CRC was supported, it would be uint16_t. */
|
|
|
};
|
|
|
};
|
|
|
};
|
|
|
|
|
|
|
|
|
/*
|
|
|
* Required to be the header for all EseInterface pad[]s for
|
|
|
* cards implementing T=1.
|
|
|
*/
|
|
|
struct Teq1CardState {
|
|
|
union {
|
|
|
struct {
|
|
|
int card:1;
|
|
|
int interface:1;
|
|
|
};
|
|
|
uint8_t seq_bits;
|
|
|
} seq;
|
|
|
};
|
|
|
|
|
|
/* Set "last sent" to 1 so we start at 0. */
|
|
|
#define TEQ1_INIT_CARD_STATE(CARD) \
|
|
|
(CARD)->seq.card = 1; \
|
|
|
(CARD)->seq.interface = 1;
|
|
|
|
|
|
/*
|
|
|
* Used by devices implementing T=1 to set specific options
|
|
|
* or callback behavior.
|
|
|
*/
|
|
|
struct Teq1ProtocolOptions;
|
|
|
typedef int (teq1_protocol_preprocess_op_t)(const struct Teq1ProtocolOptions *const, struct Teq1Frame *, int);
|
|
|
|
|
|
struct Teq1ProtocolOptions {
|
|
|
uint8_t host_address; /* NAD to listen for */
|
|
|
uint8_t node_address; /* NAD to send to */
|
|
|
float bwt;
|
|
|
float etu;
|
|
|
/*
|
|
|
* If not NULL, is called immediately before transmit (1)
|
|
|
* and immediately after receive.
|
|
|
*/
|
|
|
teq1_protocol_preprocess_op_t *preprocess;
|
|
|
};
|
|
|
|
|
|
/* PCB bits */
|
|
|
#define kTeq1PcbType (3 << 6)
|
|
|
|
|
|
/* I-block bits */
|
|
|
#define kTeq1InfoType (0 << 6)
|
|
|
#define kTeq1InfoMoreBit (1 << 5)
|
|
|
#define kTeq1InfoSeqBit (1 << 6)
|
|
|
|
|
|
/* R-block bits */
|
|
|
#define kTeq1RrType (1 << 7)
|
|
|
#define kTeq1RrSeqBit (1 << 4)
|
|
|
#define kTeq1RrParityError (1)
|
|
|
#define kTeq1RrOtherError (1 << 1)
|
|
|
|
|
|
/* S-block bits */
|
|
|
#define kTeq1SuperType (3 << 6)
|
|
|
#define kTeq1SuperRequestBit (0)
|
|
|
#define kTeq1SuperResponseBit (1 << 5)
|
|
|
#define kTeq1SuperResyncBit (0)
|
|
|
#define kTeq1SuperIfsBit (1)
|
|
|
#define kTeq1SuperAbortBit (1 << 1)
|
|
|
#define kTeq1SuperWtxBit (3)
|
|
|
|
|
|
/* I(Seq, More-bit) */
|
|
|
#define TEQ1_I(S, M) ((S) << 6) | ((M) << 5)
|
|
|
|
|
|
/* R(Seq, Other Error, Parity Error) */
|
|
|
#define TEQ1_R(S, O, P) (kTeq1RrType | ((S) << 4) | (P) | ((O) << 1))
|
|
|
/* S_<TYPE>(response) */
|
|
|
#define TEQ1_S_RESYNC(R) (kTeq1SuperType | ((R) << 5) | kTeq1SuperResyncBit)
|
|
|
#define TEQ1_S_WTX(R) (kTeq1SuperType | ((R) << 5) | kTeq1SuperWtxBit)
|
|
|
#define TEQ1_S_ABORT(R) (kTeq1SuperType | ((R) << 5) | kTeq1SuperAbortBit)
|
|
|
#define TEQ1_S_IFS(R) (kTeq1SuperType | ((R) << 5) | kTeq1SuperIfsBit)
|
|
|
|
|
|
uint32_t teq1_transceive(struct EseInterface *ese,
|
|
|
const struct Teq1ProtocolOptions *opts,
|
|
|
const struct EseSgBuffer *tx_bufs, uint8_t tx_segs,
|
|
|
struct EseSgBuffer *rx_bufs, uint8_t rx_segs);
|
|
|
|
|
|
uint8_t teq1_compute_LRC(const struct Teq1Frame *frame);
|
|
|
|
|
|
#define teq1_trace_header() ALOGI("%-20s --- %20s", "Interface", "Card")
|
|
|
#define teq1_trace_transmit(PCB, LEN) ALOGI("%-20s --> %20s [%3hhu]", teq1_pcb_to_name(PCB), "", LEN)
|
|
|
#define teq1_trace_receive(PCB, LEN) ALOGI("%-20s <-- %20s [%3hhu]", "", teq1_pcb_to_name(PCB), LEN)
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
} /* extern "C" */
|
|
|
#endif
|
|
|
#endif /* ESE_TEQ1_H_ */
|