You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

205 lines
5.4 KiB

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

/*
* 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_ */