blob: 61831a59552f298b532abc19862872a08ee2055d [file] [log] [blame]
/*
* 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>
/* Reserved codes for T=1 devices. */
#define TEQ1_ERROR_HARD_FAIL 0
#define TEQ1_ERROR_ABORT 1
#define TEQ1_ERROR_DEVICE_RESET 2
enum pcb_type {
kPcbTypeInfo0 = 0x0,
kPcbTypeInfo1 = 0x1,
kPcbTypeReceiveReady = 0x2,
kPcbTypeSupervisory = 0x3,
kPcbTypeMax,
};
enum super_type {
kSuperTypeResync = 0x0,
kSuperTypeIFS = 0x1,
kSuperTypeAbort = 0x2,
kSuperTypeWTX = 0x3,
};
struct PCB {
union {
/* Info bits */
struct {
uint8_t reserved:5; /* Should be 0. */
uint8_t more_data:1;
uint8_t send_seq:1;
uint8_t bit8:1; /* Must be 0 for I-blocks. */
} I; /* Information Block */
/* receive bits */
struct {
uint8_t parity_err:1; /* char parity or redundancy code err */
uint8_t other_err:1; /* any other errors */
uint8_t unused_1:2;
uint8_t next_seq:1; /* If the same seq as last frame, then err even if other bits are 0. */
uint8_t unused_0:1;
uint8_t pcb_type:2; /* Always (1, 0)=2 for R */
} R; /* Receive ready block */
struct {
uint8_t type:2;
uint8_t unused_0:3;
uint8_t response:1;
uint8_t pcb_type:2;
} S; /* Supervisory block */
struct {
uint8_t data:6;
uint8_t type:2; /* I = 0|1, R = 2, S = 3 */
}; /* Bit7-8 access for block type access. */
/* Bitwise access */
struct {
uint8_t bit0:1; /* lsb */
uint8_t bit1:1;
uint8_t bit2:1;
uint8_t bit3:1;
uint8_t bit4:1;
uint8_t bit5:1;
uint8_t bit6:1;
uint8_t bit7:1; /* msb */
} bits;
uint8_t val;
};
};
struct Teq1Header {
uint8_t NAD;
struct PCB PCB;
uint8_t LEN;
} __attribute__((packed));
#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. */
};
/* uint8_t LRC; If CRC was supported, it would be uint16_t. */
};
};
} __attribute__((packed));
/*
* 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;
};
/* I-block bits */
#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)
size_t teq1_transceive(struct EseInterface *ese,
const uint8_t *const tx_buf, size_t tx_len,
uint8_t *rx_buf, size_t rx_max);
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_ */