^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Sony NFC Port-100 Series driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 2013, Intel Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Partly based/Inspired by Stephen Tiedemann's nfcpy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <net/nfc/digital.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #define VERSION "0.1"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #define SONY_VENDOR_ID 0x054c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define RCS380S_PRODUCT_ID 0x06c1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define RCS380P_PRODUCT_ID 0x06c3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define PORT100_PROTOCOLS (NFC_PROTO_JEWEL_MASK | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) NFC_PROTO_MIFARE_MASK | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) NFC_PROTO_FELICA_MASK | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) NFC_PROTO_NFC_DEP_MASK | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) NFC_PROTO_ISO14443_MASK | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) NFC_PROTO_ISO14443_B_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define PORT100_CAPABILITIES (NFC_DIGITAL_DRV_CAPS_IN_CRC | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) NFC_DIGITAL_DRV_CAPS_TG_CRC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) /* Standard port100 frame definitions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define PORT100_FRAME_HEADER_LEN (sizeof(struct port100_frame) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) + 2) /* data[0] CC, data[1] SCC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define PORT100_FRAME_TAIL_LEN 2 /* data[len] DCS, data[len + 1] postamble*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define PORT100_COMM_RF_HEAD_MAX_LEN (sizeof(struct port100_tg_comm_rf_cmd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * Max extended frame payload len, excluding CC and SCC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * which are already in PORT100_FRAME_HEADER_LEN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define PORT100_FRAME_MAX_PAYLOAD_LEN 1001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define PORT100_FRAME_ACK_SIZE 6 /* Preamble (1), SoPC (2), ACK Code (2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) Postamble (1) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static u8 ack_frame[PORT100_FRAME_ACK_SIZE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) 0x00, 0x00, 0xff, 0x00, 0xff, 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define PORT100_FRAME_CHECKSUM(f) (f->data[le16_to_cpu(f->datalen)])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define PORT100_FRAME_POSTAMBLE(f) (f->data[le16_to_cpu(f->datalen) + 1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /* start of frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define PORT100_FRAME_SOF 0x00FF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define PORT100_FRAME_EXT 0xFFFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define PORT100_FRAME_ACK 0x00FF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /* Port-100 command: in or out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define PORT100_FRAME_DIRECTION(f) (f->data[0]) /* CC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define PORT100_FRAME_DIR_OUT 0xD6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define PORT100_FRAME_DIR_IN 0xD7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) /* Port-100 sub-command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define PORT100_FRAME_CMD(f) (f->data[1]) /* SCC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define PORT100_CMD_GET_FIRMWARE_VERSION 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define PORT100_CMD_GET_COMMAND_TYPE 0x28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define PORT100_CMD_SET_COMMAND_TYPE 0x2A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define PORT100_CMD_IN_SET_RF 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define PORT100_CMD_IN_SET_PROTOCOL 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define PORT100_CMD_IN_COMM_RF 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define PORT100_CMD_TG_SET_RF 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define PORT100_CMD_TG_SET_PROTOCOL 0x42
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define PORT100_CMD_TG_SET_RF_OFF 0x46
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define PORT100_CMD_TG_COMM_RF 0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define PORT100_CMD_SWITCH_RF 0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define PORT100_CMD_RESPONSE(cmd) (cmd + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define PORT100_CMD_TYPE_IS_SUPPORTED(mask, cmd_type) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) ((mask) & (0x01 << (cmd_type)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define PORT100_CMD_TYPE_0 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define PORT100_CMD_TYPE_1 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define PORT100_CMD_STATUS_OK 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define PORT100_CMD_STATUS_TIMEOUT 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define PORT100_MDAA_TGT_HAS_BEEN_ACTIVATED_MASK 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define PORT100_MDAA_TGT_WAS_ACTIVATED_MASK 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct port100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) typedef void (*port100_send_async_complete_t)(struct port100 *dev, void *arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct sk_buff *resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * Setting sets structure for in_set_rf command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * @in_*_set_number: Represent the entry indexes in the port-100 RF Base Table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * This table contains multiple RF setting sets required for RF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * communication.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * @in_*_comm_type: Theses fields set the communication type to be used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) struct port100_in_rf_setting {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) u8 in_send_set_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) u8 in_send_comm_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) u8 in_recv_set_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) u8 in_recv_comm_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #define PORT100_COMM_TYPE_IN_212F 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define PORT100_COMM_TYPE_IN_424F 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define PORT100_COMM_TYPE_IN_106A 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #define PORT100_COMM_TYPE_IN_106B 0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static const struct port100_in_rf_setting in_rf_settings[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) [NFC_DIGITAL_RF_TECH_212F] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) .in_send_set_number = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) .in_send_comm_type = PORT100_COMM_TYPE_IN_212F,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) .in_recv_set_number = 15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) .in_recv_comm_type = PORT100_COMM_TYPE_IN_212F,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) [NFC_DIGITAL_RF_TECH_424F] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) .in_send_set_number = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) .in_send_comm_type = PORT100_COMM_TYPE_IN_424F,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) .in_recv_set_number = 15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) .in_recv_comm_type = PORT100_COMM_TYPE_IN_424F,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) [NFC_DIGITAL_RF_TECH_106A] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) .in_send_set_number = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) .in_send_comm_type = PORT100_COMM_TYPE_IN_106A,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) .in_recv_set_number = 15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) .in_recv_comm_type = PORT100_COMM_TYPE_IN_106A,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) [NFC_DIGITAL_RF_TECH_106B] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) .in_send_set_number = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) .in_send_comm_type = PORT100_COMM_TYPE_IN_106B,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) .in_recv_set_number = 15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) .in_recv_comm_type = PORT100_COMM_TYPE_IN_106B,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /* Ensures the array has NFC_DIGITAL_RF_TECH_LAST elements */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) [NFC_DIGITAL_RF_TECH_LAST] = { 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * Setting sets structure for tg_set_rf command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * @tg_set_number: Represents the entry index in the port-100 RF Base Table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * This table contains multiple RF setting sets required for RF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * communication. this field is used for both send and receive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * settings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * @tg_comm_type: Sets the communication type to be used to send and receive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct port100_tg_rf_setting {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) u8 tg_set_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) u8 tg_comm_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #define PORT100_COMM_TYPE_TG_106A 0x0B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #define PORT100_COMM_TYPE_TG_212F 0x0C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #define PORT100_COMM_TYPE_TG_424F 0x0D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) static const struct port100_tg_rf_setting tg_rf_settings[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) [NFC_DIGITAL_RF_TECH_106A] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) .tg_set_number = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) .tg_comm_type = PORT100_COMM_TYPE_TG_106A,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) [NFC_DIGITAL_RF_TECH_212F] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) .tg_set_number = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) .tg_comm_type = PORT100_COMM_TYPE_TG_212F,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) [NFC_DIGITAL_RF_TECH_424F] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) .tg_set_number = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) .tg_comm_type = PORT100_COMM_TYPE_TG_424F,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) /* Ensures the array has NFC_DIGITAL_RF_TECH_LAST elements */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) [NFC_DIGITAL_RF_TECH_LAST] = { 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) #define PORT100_IN_PROT_INITIAL_GUARD_TIME 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) #define PORT100_IN_PROT_ADD_CRC 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) #define PORT100_IN_PROT_CHECK_CRC 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) #define PORT100_IN_PROT_MULTI_CARD 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) #define PORT100_IN_PROT_ADD_PARITY 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) #define PORT100_IN_PROT_CHECK_PARITY 0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) #define PORT100_IN_PROT_BITWISE_AC_RECV_MODE 0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) #define PORT100_IN_PROT_VALID_BIT_NUMBER 0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) #define PORT100_IN_PROT_CRYPTO1 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) #define PORT100_IN_PROT_ADD_SOF 0x09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) #define PORT100_IN_PROT_CHECK_SOF 0x0A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) #define PORT100_IN_PROT_ADD_EOF 0x0B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) #define PORT100_IN_PROT_CHECK_EOF 0x0C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) #define PORT100_IN_PROT_DEAF_TIME 0x0E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) #define PORT100_IN_PROT_CRM 0x0F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) #define PORT100_IN_PROT_CRM_MIN_LEN 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) #define PORT100_IN_PROT_T1_TAG_FRAME 0x11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) #define PORT100_IN_PROT_RFCA 0x12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) #define PORT100_IN_PROT_GUARD_TIME_AT_INITIATOR 0x13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) #define PORT100_IN_PROT_END 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) #define PORT100_IN_MAX_NUM_PROTOCOLS 19
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) #define PORT100_TG_PROT_TU 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) #define PORT100_TG_PROT_RF_OFF 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) #define PORT100_TG_PROT_CRM 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) #define PORT100_TG_PROT_END 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) #define PORT100_TG_MAX_NUM_PROTOCOLS 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) struct port100_protocol {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) u8 number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) u8 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) static struct port100_protocol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) in_protocols[][PORT100_IN_MAX_NUM_PROTOCOLS + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) [NFC_DIGITAL_FRAMING_NFCA_SHORT] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) { PORT100_IN_PROT_INITIAL_GUARD_TIME, 6 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) { PORT100_IN_PROT_ADD_CRC, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) { PORT100_IN_PROT_CHECK_CRC, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) { PORT100_IN_PROT_MULTI_CARD, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) { PORT100_IN_PROT_ADD_PARITY, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) { PORT100_IN_PROT_CHECK_PARITY, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) { PORT100_IN_PROT_BITWISE_AC_RECV_MODE, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) { PORT100_IN_PROT_VALID_BIT_NUMBER, 7 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) { PORT100_IN_PROT_CRYPTO1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) { PORT100_IN_PROT_ADD_SOF, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) { PORT100_IN_PROT_CHECK_SOF, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) { PORT100_IN_PROT_ADD_EOF, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) { PORT100_IN_PROT_CHECK_EOF, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) { PORT100_IN_PROT_DEAF_TIME, 4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) { PORT100_IN_PROT_CRM, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) { PORT100_IN_PROT_CRM_MIN_LEN, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) { PORT100_IN_PROT_T1_TAG_FRAME, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) { PORT100_IN_PROT_RFCA, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) { PORT100_IN_PROT_GUARD_TIME_AT_INITIATOR, 6 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) { PORT100_IN_PROT_END, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) [NFC_DIGITAL_FRAMING_NFCA_STANDARD] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) { PORT100_IN_PROT_INITIAL_GUARD_TIME, 6 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) { PORT100_IN_PROT_ADD_CRC, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) { PORT100_IN_PROT_CHECK_CRC, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) { PORT100_IN_PROT_MULTI_CARD, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) { PORT100_IN_PROT_ADD_PARITY, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) { PORT100_IN_PROT_CHECK_PARITY, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) { PORT100_IN_PROT_BITWISE_AC_RECV_MODE, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) { PORT100_IN_PROT_VALID_BIT_NUMBER, 8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) { PORT100_IN_PROT_CRYPTO1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) { PORT100_IN_PROT_ADD_SOF, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) { PORT100_IN_PROT_CHECK_SOF, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) { PORT100_IN_PROT_ADD_EOF, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) { PORT100_IN_PROT_CHECK_EOF, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) { PORT100_IN_PROT_DEAF_TIME, 4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) { PORT100_IN_PROT_CRM, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) { PORT100_IN_PROT_CRM_MIN_LEN, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) { PORT100_IN_PROT_T1_TAG_FRAME, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) { PORT100_IN_PROT_RFCA, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) { PORT100_IN_PROT_GUARD_TIME_AT_INITIATOR, 6 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) { PORT100_IN_PROT_END, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) [NFC_DIGITAL_FRAMING_NFCA_STANDARD_WITH_CRC_A] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) { PORT100_IN_PROT_INITIAL_GUARD_TIME, 6 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) { PORT100_IN_PROT_ADD_CRC, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) { PORT100_IN_PROT_CHECK_CRC, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) { PORT100_IN_PROT_MULTI_CARD, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) { PORT100_IN_PROT_ADD_PARITY, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) { PORT100_IN_PROT_CHECK_PARITY, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) { PORT100_IN_PROT_BITWISE_AC_RECV_MODE, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) { PORT100_IN_PROT_VALID_BIT_NUMBER, 8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) { PORT100_IN_PROT_CRYPTO1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) { PORT100_IN_PROT_ADD_SOF, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) { PORT100_IN_PROT_CHECK_SOF, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) { PORT100_IN_PROT_ADD_EOF, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) { PORT100_IN_PROT_CHECK_EOF, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) { PORT100_IN_PROT_DEAF_TIME, 4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) { PORT100_IN_PROT_CRM, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) { PORT100_IN_PROT_CRM_MIN_LEN, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) { PORT100_IN_PROT_T1_TAG_FRAME, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) { PORT100_IN_PROT_RFCA, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) { PORT100_IN_PROT_GUARD_TIME_AT_INITIATOR, 6 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) { PORT100_IN_PROT_END, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) [NFC_DIGITAL_FRAMING_NFCA_T1T] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) /* nfc_digital_framing_nfca_short */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) { PORT100_IN_PROT_ADD_CRC, 2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) { PORT100_IN_PROT_CHECK_CRC, 2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) { PORT100_IN_PROT_VALID_BIT_NUMBER, 8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) { PORT100_IN_PROT_T1_TAG_FRAME, 2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) { PORT100_IN_PROT_END, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) [NFC_DIGITAL_FRAMING_NFCA_T2T] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) /* nfc_digital_framing_nfca_standard */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) { PORT100_IN_PROT_ADD_CRC, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) { PORT100_IN_PROT_CHECK_CRC, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) { PORT100_IN_PROT_END, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) [NFC_DIGITAL_FRAMING_NFCA_T4T] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) /* nfc_digital_framing_nfca_standard_with_crc_a */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) { PORT100_IN_PROT_END, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) [NFC_DIGITAL_FRAMING_NFCA_NFC_DEP] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) /* nfc_digital_framing_nfca_standard */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) { PORT100_IN_PROT_END, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) [NFC_DIGITAL_FRAMING_NFCF] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) { PORT100_IN_PROT_INITIAL_GUARD_TIME, 18 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) { PORT100_IN_PROT_ADD_CRC, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) { PORT100_IN_PROT_CHECK_CRC, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) { PORT100_IN_PROT_MULTI_CARD, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) { PORT100_IN_PROT_ADD_PARITY, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) { PORT100_IN_PROT_CHECK_PARITY, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) { PORT100_IN_PROT_BITWISE_AC_RECV_MODE, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) { PORT100_IN_PROT_VALID_BIT_NUMBER, 8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) { PORT100_IN_PROT_CRYPTO1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) { PORT100_IN_PROT_ADD_SOF, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) { PORT100_IN_PROT_CHECK_SOF, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) { PORT100_IN_PROT_ADD_EOF, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) { PORT100_IN_PROT_CHECK_EOF, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) { PORT100_IN_PROT_DEAF_TIME, 4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) { PORT100_IN_PROT_CRM, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) { PORT100_IN_PROT_CRM_MIN_LEN, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) { PORT100_IN_PROT_T1_TAG_FRAME, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) { PORT100_IN_PROT_RFCA, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) { PORT100_IN_PROT_GUARD_TIME_AT_INITIATOR, 6 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) { PORT100_IN_PROT_END, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) [NFC_DIGITAL_FRAMING_NFCF_T3T] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) /* nfc_digital_framing_nfcf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) { PORT100_IN_PROT_END, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) [NFC_DIGITAL_FRAMING_NFCF_NFC_DEP] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) /* nfc_digital_framing_nfcf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) { PORT100_IN_PROT_INITIAL_GUARD_TIME, 18 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) { PORT100_IN_PROT_ADD_CRC, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) { PORT100_IN_PROT_CHECK_CRC, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) { PORT100_IN_PROT_MULTI_CARD, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) { PORT100_IN_PROT_ADD_PARITY, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) { PORT100_IN_PROT_CHECK_PARITY, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) { PORT100_IN_PROT_BITWISE_AC_RECV_MODE, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) { PORT100_IN_PROT_VALID_BIT_NUMBER, 8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) { PORT100_IN_PROT_CRYPTO1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) { PORT100_IN_PROT_ADD_SOF, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) { PORT100_IN_PROT_CHECK_SOF, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) { PORT100_IN_PROT_ADD_EOF, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) { PORT100_IN_PROT_CHECK_EOF, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) { PORT100_IN_PROT_DEAF_TIME, 4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) { PORT100_IN_PROT_CRM, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) { PORT100_IN_PROT_CRM_MIN_LEN, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) { PORT100_IN_PROT_T1_TAG_FRAME, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) { PORT100_IN_PROT_RFCA, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) { PORT100_IN_PROT_GUARD_TIME_AT_INITIATOR, 6 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) { PORT100_IN_PROT_END, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) [NFC_DIGITAL_FRAMING_NFC_DEP_ACTIVATED] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) { PORT100_IN_PROT_END, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) [NFC_DIGITAL_FRAMING_NFCB] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) { PORT100_IN_PROT_INITIAL_GUARD_TIME, 20 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) { PORT100_IN_PROT_ADD_CRC, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) { PORT100_IN_PROT_CHECK_CRC, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) { PORT100_IN_PROT_MULTI_CARD, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) { PORT100_IN_PROT_ADD_PARITY, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) { PORT100_IN_PROT_CHECK_PARITY, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) { PORT100_IN_PROT_BITWISE_AC_RECV_MODE, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) { PORT100_IN_PROT_VALID_BIT_NUMBER, 8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) { PORT100_IN_PROT_CRYPTO1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) { PORT100_IN_PROT_ADD_SOF, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) { PORT100_IN_PROT_CHECK_SOF, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) { PORT100_IN_PROT_ADD_EOF, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) { PORT100_IN_PROT_CHECK_EOF, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) { PORT100_IN_PROT_DEAF_TIME, 4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) { PORT100_IN_PROT_CRM, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) { PORT100_IN_PROT_CRM_MIN_LEN, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) { PORT100_IN_PROT_T1_TAG_FRAME, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) { PORT100_IN_PROT_RFCA, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) { PORT100_IN_PROT_GUARD_TIME_AT_INITIATOR, 6 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) { PORT100_IN_PROT_END, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) [NFC_DIGITAL_FRAMING_NFCB_T4T] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) /* nfc_digital_framing_nfcb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) { PORT100_IN_PROT_END, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) /* Ensures the array has NFC_DIGITAL_FRAMING_LAST elements */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) [NFC_DIGITAL_FRAMING_LAST] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) { PORT100_IN_PROT_END, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) static struct port100_protocol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) tg_protocols[][PORT100_TG_MAX_NUM_PROTOCOLS + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) [NFC_DIGITAL_FRAMING_NFCA_SHORT] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) { PORT100_TG_PROT_END, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) [NFC_DIGITAL_FRAMING_NFCA_STANDARD] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) { PORT100_TG_PROT_END, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) [NFC_DIGITAL_FRAMING_NFCA_STANDARD_WITH_CRC_A] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) { PORT100_TG_PROT_END, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) [NFC_DIGITAL_FRAMING_NFCA_T1T] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) { PORT100_TG_PROT_END, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) [NFC_DIGITAL_FRAMING_NFCA_T2T] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) { PORT100_TG_PROT_END, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) [NFC_DIGITAL_FRAMING_NFCA_NFC_DEP] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) { PORT100_TG_PROT_TU, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) { PORT100_TG_PROT_RF_OFF, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) { PORT100_TG_PROT_CRM, 7 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) { PORT100_TG_PROT_END, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) [NFC_DIGITAL_FRAMING_NFCF] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) { PORT100_TG_PROT_END, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) [NFC_DIGITAL_FRAMING_NFCF_T3T] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) { PORT100_TG_PROT_END, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) [NFC_DIGITAL_FRAMING_NFCF_NFC_DEP] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) { PORT100_TG_PROT_TU, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) { PORT100_TG_PROT_RF_OFF, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) { PORT100_TG_PROT_CRM, 7 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) { PORT100_TG_PROT_END, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) [NFC_DIGITAL_FRAMING_NFC_DEP_ACTIVATED] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) { PORT100_TG_PROT_RF_OFF, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) { PORT100_TG_PROT_END, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) /* Ensures the array has NFC_DIGITAL_FRAMING_LAST elements */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) [NFC_DIGITAL_FRAMING_LAST] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) { PORT100_TG_PROT_END, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) struct port100 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) struct nfc_digital_dev *nfc_digital_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) int skb_headroom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) int skb_tailroom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) struct usb_device *udev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) struct usb_interface *interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) struct urb *out_urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) struct urb *in_urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) /* This mutex protects the out_urb and avoids to submit a new command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) * through port100_send_frame_async() while the previous one is being
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) * canceled through port100_abort_cmd().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) struct mutex out_urb_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) struct work_struct cmd_complete_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) u8 cmd_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) /* The digital stack serializes commands to be sent. There is no need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) * for any queuing/locking mechanism at driver level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) struct port100_cmd *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) bool cmd_cancel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) struct completion cmd_cancel_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) struct port100_cmd {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) u8 code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) struct sk_buff *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) struct sk_buff *resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) int resp_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) port100_send_async_complete_t complete_cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) void *complete_cb_context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) struct port100_frame {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) u8 preamble;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) __be16 start_frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) __be16 extended_frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) __le16 datalen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) u8 datalen_checksum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) u8 data[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) struct port100_ack_frame {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) u8 preamble;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) __be16 start_frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) __be16 ack_frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) u8 postambule;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) struct port100_cb_arg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) nfc_digital_cmd_complete_t complete_cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) void *complete_arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) u8 mdaa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) struct port100_tg_comm_rf_cmd {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) __le16 guard_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) __le16 send_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) u8 mdaa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) u8 nfca_param[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) u8 nfcf_param[18];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) u8 mf_halted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) u8 arae_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) __le16 recv_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) u8 data[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) struct port100_tg_comm_rf_res {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) u8 comm_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) u8 ar_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) u8 target_activated;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) __le32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) u8 data[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) /* The rule: value + checksum = 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) static inline u8 port100_checksum(u16 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) return ~(((u8 *)&value)[0] + ((u8 *)&value)[1]) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) /* The rule: sum(data elements) + checksum = 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) static u8 port100_data_checksum(u8 *data, int datalen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) u8 sum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) for (i = 0; i < datalen; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) sum += data[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) return port100_checksum(sum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) static void port100_tx_frame_init(void *_frame, u8 cmd_code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) struct port100_frame *frame = _frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) frame->preamble = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) frame->start_frame = cpu_to_be16(PORT100_FRAME_SOF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) frame->extended_frame = cpu_to_be16(PORT100_FRAME_EXT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) PORT100_FRAME_DIRECTION(frame) = PORT100_FRAME_DIR_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) PORT100_FRAME_CMD(frame) = cmd_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) frame->datalen = cpu_to_le16(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) static void port100_tx_frame_finish(void *_frame)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) struct port100_frame *frame = _frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) frame->datalen_checksum = port100_checksum(le16_to_cpu(frame->datalen));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) PORT100_FRAME_CHECKSUM(frame) =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) port100_data_checksum(frame->data, le16_to_cpu(frame->datalen));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) PORT100_FRAME_POSTAMBLE(frame) = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) static void port100_tx_update_payload_len(void *_frame, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) struct port100_frame *frame = _frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) le16_add_cpu(&frame->datalen, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) static bool port100_rx_frame_is_valid(void *_frame)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) u8 checksum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) struct port100_frame *frame = _frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) if (frame->start_frame != cpu_to_be16(PORT100_FRAME_SOF) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) frame->extended_frame != cpu_to_be16(PORT100_FRAME_EXT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) checksum = port100_checksum(le16_to_cpu(frame->datalen));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) if (checksum != frame->datalen_checksum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) checksum = port100_data_checksum(frame->data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) le16_to_cpu(frame->datalen));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (checksum != PORT100_FRAME_CHECKSUM(frame))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) static bool port100_rx_frame_is_ack(struct port100_ack_frame *frame)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) return (frame->start_frame == cpu_to_be16(PORT100_FRAME_SOF) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) frame->ack_frame == cpu_to_be16(PORT100_FRAME_ACK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) static inline int port100_rx_frame_size(void *frame)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) struct port100_frame *f = frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) return sizeof(struct port100_frame) + le16_to_cpu(f->datalen) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) PORT100_FRAME_TAIL_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) static bool port100_rx_frame_is_cmd_response(struct port100 *dev, void *frame)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) struct port100_frame *f = frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) return (PORT100_FRAME_CMD(f) == PORT100_CMD_RESPONSE(dev->cmd->code));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) static void port100_recv_response(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) struct port100 *dev = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) struct port100_cmd *cmd = dev->cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) u8 *in_frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) cmd->status = urb->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) switch (urb->status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) break; /* success */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) case -ECONNRESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) case -ENOENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) nfc_err(&dev->interface->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) "The urb has been canceled (status %d)\n", urb->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) goto sched_wq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) case -ESHUTDOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) nfc_err(&dev->interface->dev, "Urb failure (status %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) urb->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) goto sched_wq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) in_frame = dev->in_urb->transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) if (!port100_rx_frame_is_valid(in_frame)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) nfc_err(&dev->interface->dev, "Received an invalid frame\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) cmd->status = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) goto sched_wq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) print_hex_dump_debug("PORT100 RX: ", DUMP_PREFIX_NONE, 16, 1, in_frame,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) port100_rx_frame_size(in_frame), false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) if (!port100_rx_frame_is_cmd_response(dev, in_frame)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) nfc_err(&dev->interface->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) "It's not the response to the last command\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) cmd->status = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) goto sched_wq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) sched_wq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) schedule_work(&dev->cmd_complete_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) static int port100_submit_urb_for_response(struct port100 *dev, gfp_t flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) dev->in_urb->complete = port100_recv_response;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) return usb_submit_urb(dev->in_urb, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) static void port100_recv_ack(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) struct port100 *dev = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) struct port100_cmd *cmd = dev->cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) struct port100_ack_frame *in_frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) cmd->status = urb->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) switch (urb->status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) break; /* success */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) case -ECONNRESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) case -ENOENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) nfc_err(&dev->interface->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) "The urb has been stopped (status %d)\n", urb->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) goto sched_wq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) case -ESHUTDOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) nfc_err(&dev->interface->dev, "Urb failure (status %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) urb->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) goto sched_wq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) in_frame = dev->in_urb->transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) if (!port100_rx_frame_is_ack(in_frame)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) nfc_err(&dev->interface->dev, "Received an invalid ack\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) cmd->status = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) goto sched_wq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) rc = port100_submit_urb_for_response(dev, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) nfc_err(&dev->interface->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) "usb_submit_urb failed with result %d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) cmd->status = rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) goto sched_wq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) sched_wq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) schedule_work(&dev->cmd_complete_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) static int port100_submit_urb_for_ack(struct port100 *dev, gfp_t flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) dev->in_urb->complete = port100_recv_ack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) return usb_submit_urb(dev->in_urb, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) static int port100_send_ack(struct port100 *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) mutex_lock(&dev->out_urb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) * If prior cancel is in-flight (dev->cmd_cancel == true), we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) * can skip to send cancel. Then this will wait the prior
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) * cancel, or merged into the next cancel rarely if next
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) * cancel was started before waiting done. In any case, this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) * will be waked up soon or later.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) if (!dev->cmd_cancel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) reinit_completion(&dev->cmd_cancel_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) usb_kill_urb(dev->out_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) dev->out_urb->transfer_buffer = ack_frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) dev->out_urb->transfer_buffer_length = sizeof(ack_frame);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) rc = usb_submit_urb(dev->out_urb, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) * Set the cmd_cancel flag only if the URB has been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) * successfully submitted. It will be reset by the out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) * URB completion callback port100_send_complete().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) dev->cmd_cancel = !rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) mutex_unlock(&dev->out_urb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) wait_for_completion(&dev->cmd_cancel_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) static int port100_send_frame_async(struct port100 *dev, struct sk_buff *out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) struct sk_buff *in, int in_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) mutex_lock(&dev->out_urb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) /* A command cancel frame as been sent through dev->out_urb. Don't try
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) * to submit a new one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) if (dev->cmd_cancel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) rc = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) dev->out_urb->transfer_buffer = out->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) dev->out_urb->transfer_buffer_length = out->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) dev->in_urb->transfer_buffer = in->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) dev->in_urb->transfer_buffer_length = in_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) print_hex_dump_debug("PORT100 TX: ", DUMP_PREFIX_NONE, 16, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) out->data, out->len, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) rc = usb_submit_urb(dev->out_urb, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) rc = port100_submit_urb_for_ack(dev, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) usb_kill_urb(dev->out_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) mutex_unlock(&dev->out_urb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) static void port100_build_cmd_frame(struct port100 *dev, u8 cmd_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) /* payload is already there, just update datalen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) int payload_len = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) skb_push(skb, PORT100_FRAME_HEADER_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) skb_put(skb, PORT100_FRAME_TAIL_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) port100_tx_frame_init(skb->data, cmd_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) port100_tx_update_payload_len(skb->data, payload_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) port100_tx_frame_finish(skb->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) static void port100_send_async_complete(struct port100 *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) struct port100_cmd *cmd = dev->cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) int status = cmd->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) struct sk_buff *req = cmd->req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) struct sk_buff *resp = cmd->resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) dev_kfree_skb(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) dev->cmd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) cmd->complete_cb(dev, cmd->complete_cb_context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) ERR_PTR(status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) dev_kfree_skb(resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) skb_put(resp, port100_rx_frame_size(resp->data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) skb_pull(resp, PORT100_FRAME_HEADER_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) skb_trim(resp, resp->len - PORT100_FRAME_TAIL_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) cmd->complete_cb(dev, cmd->complete_cb_context, resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) kfree(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) static int port100_send_cmd_async(struct port100 *dev, u8 cmd_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) struct sk_buff *req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) port100_send_async_complete_t complete_cb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) void *complete_cb_context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) struct port100_cmd *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) struct sk_buff *resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) int resp_len = PORT100_FRAME_HEADER_LEN +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) PORT100_FRAME_MAX_PAYLOAD_LEN +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) PORT100_FRAME_TAIL_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) if (dev->cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) nfc_err(&dev->interface->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) "A command is still in process\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) resp = alloc_skb(resp_len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) if (!resp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) if (!cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) dev_kfree_skb(resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) cmd->code = cmd_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) cmd->req = req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) cmd->resp = resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) cmd->resp_len = resp_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) cmd->complete_cb = complete_cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) cmd->complete_cb_context = complete_cb_context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) port100_build_cmd_frame(dev, cmd_code, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) dev->cmd = cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) rc = port100_send_frame_async(dev, req, resp, resp_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) kfree(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) dev_kfree_skb(resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) dev->cmd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) struct port100_sync_cmd_response {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) struct sk_buff *resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) struct completion done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) static void port100_wq_cmd_complete(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) struct port100 *dev = container_of(work, struct port100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) cmd_complete_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) port100_send_async_complete(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) static void port100_send_sync_complete(struct port100 *dev, void *_arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) struct sk_buff *resp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) struct port100_sync_cmd_response *arg = _arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) arg->resp = resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) complete(&arg->done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) static struct sk_buff *port100_send_cmd_sync(struct port100 *dev, u8 cmd_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) struct sk_buff *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) struct port100_sync_cmd_response arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) init_completion(&arg.done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) rc = port100_send_cmd_async(dev, cmd_code, req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) port100_send_sync_complete, &arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) dev_kfree_skb(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) return ERR_PTR(rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) wait_for_completion(&arg.done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) return arg.resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) static void port100_send_complete(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) struct port100 *dev = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) if (dev->cmd_cancel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) complete_all(&dev->cmd_cancel_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) dev->cmd_cancel = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) switch (urb->status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) break; /* success */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) case -ECONNRESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) case -ENOENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) nfc_err(&dev->interface->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) "The urb has been stopped (status %d)\n", urb->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) case -ESHUTDOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) nfc_err(&dev->interface->dev, "Urb failure (status %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) urb->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) static void port100_abort_cmd(struct nfc_digital_dev *ddev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) struct port100 *dev = nfc_digital_get_drvdata(ddev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) /* An ack will cancel the last issued command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) port100_send_ack(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) /* cancel the urb request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) usb_kill_urb(dev->in_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) static struct sk_buff *port100_alloc_skb(struct port100 *dev, unsigned int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) skb = alloc_skb(dev->skb_headroom + dev->skb_tailroom + size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) if (skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) skb_reserve(skb, dev->skb_headroom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) static int port100_set_command_type(struct port100 *dev, u8 command_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) struct sk_buff *resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) skb = port100_alloc_skb(dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) skb_put_u8(skb, command_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) resp = port100_send_cmd_sync(dev, PORT100_CMD_SET_COMMAND_TYPE, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) if (IS_ERR(resp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) return PTR_ERR(resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) rc = resp->data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) dev_kfree_skb(resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) static u64 port100_get_command_type_mask(struct port100 *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) struct sk_buff *resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) u64 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) skb = port100_alloc_skb(dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) resp = port100_send_cmd_sync(dev, PORT100_CMD_GET_COMMAND_TYPE, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) if (IS_ERR(resp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) if (resp->len < 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) mask = be64_to_cpu(*(__be64 *)resp->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) dev_kfree_skb(resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) return mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) static u16 port100_get_firmware_version(struct port100 *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) struct sk_buff *resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) u16 fw_ver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) skb = port100_alloc_skb(dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) resp = port100_send_cmd_sync(dev, PORT100_CMD_GET_FIRMWARE_VERSION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) if (IS_ERR(resp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) fw_ver = le16_to_cpu(*(__le16 *)resp->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) dev_kfree_skb(resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) return fw_ver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) static int port100_switch_rf(struct nfc_digital_dev *ddev, bool on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) struct port100 *dev = nfc_digital_get_drvdata(ddev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) struct sk_buff *skb, *resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) skb = port100_alloc_skb(dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) skb_put_u8(skb, on ? 1 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) /* Cancel the last command if the device is being switched off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) if (!on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) port100_abort_cmd(ddev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) resp = port100_send_cmd_sync(dev, PORT100_CMD_SWITCH_RF, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) if (IS_ERR(resp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) return PTR_ERR(resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) dev_kfree_skb(resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) static int port100_in_set_rf(struct nfc_digital_dev *ddev, u8 rf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) struct port100 *dev = nfc_digital_get_drvdata(ddev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) struct sk_buff *resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) if (rf >= NFC_DIGITAL_RF_TECH_LAST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) skb = port100_alloc_skb(dev, sizeof(struct port100_in_rf_setting));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) skb_put_data(skb, &in_rf_settings[rf],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) sizeof(struct port100_in_rf_setting));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) resp = port100_send_cmd_sync(dev, PORT100_CMD_IN_SET_RF, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) if (IS_ERR(resp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) return PTR_ERR(resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) rc = resp->data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) dev_kfree_skb(resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) static int port100_in_set_framing(struct nfc_digital_dev *ddev, int param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) struct port100 *dev = nfc_digital_get_drvdata(ddev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) struct port100_protocol *protocols;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) struct sk_buff *resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) int num_protocols;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) size_t size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) if (param >= NFC_DIGITAL_FRAMING_LAST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) protocols = in_protocols[param];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) num_protocols = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) while (protocols[num_protocols].number != PORT100_IN_PROT_END)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) num_protocols++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) if (!num_protocols)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) size = sizeof(struct port100_protocol) * num_protocols;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) skb = port100_alloc_skb(dev, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) skb_put_data(skb, protocols, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) resp = port100_send_cmd_sync(dev, PORT100_CMD_IN_SET_PROTOCOL, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) if (IS_ERR(resp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) return PTR_ERR(resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) rc = resp->data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) dev_kfree_skb(resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) static int port100_in_configure_hw(struct nfc_digital_dev *ddev, int type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) int param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) if (type == NFC_DIGITAL_CONFIG_RF_TECH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) return port100_in_set_rf(ddev, param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) if (type == NFC_DIGITAL_CONFIG_FRAMING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) return port100_in_set_framing(ddev, param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) static void port100_in_comm_rf_complete(struct port100 *dev, void *arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) struct sk_buff *resp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) struct port100_cb_arg *cb_arg = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) nfc_digital_cmd_complete_t cb = cb_arg->complete_cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) if (IS_ERR(resp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) rc = PTR_ERR(resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) if (resp->len < 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) nfc_err(&dev->interface->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) "Invalid packet length received\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) status = le32_to_cpu(*(__le32 *)resp->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) skb_pull(resp, sizeof(u32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) if (status == PORT100_CMD_STATUS_TIMEOUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) rc = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) if (status != PORT100_CMD_STATUS_OK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) nfc_err(&dev->interface->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) "in_comm_rf failed with status 0x%08x\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) /* Remove collision bits byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) skb_pull(resp, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) kfree_skb(resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) resp = ERR_PTR(rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) cb(dev->nfc_digital_dev, cb_arg->complete_arg, resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) kfree(cb_arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) static int port100_in_send_cmd(struct nfc_digital_dev *ddev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) struct sk_buff *skb, u16 _timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) nfc_digital_cmd_complete_t cb, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) struct port100 *dev = nfc_digital_get_drvdata(ddev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) struct port100_cb_arg *cb_arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) __le16 timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) cb_arg = kzalloc(sizeof(struct port100_cb_arg), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) if (!cb_arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) cb_arg->complete_cb = cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) cb_arg->complete_arg = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) timeout = cpu_to_le16(_timeout * 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) memcpy(skb_push(skb, sizeof(__le16)), &timeout, sizeof(__le16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) return port100_send_cmd_async(dev, PORT100_CMD_IN_COMM_RF, skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) port100_in_comm_rf_complete, cb_arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) static int port100_tg_set_rf(struct nfc_digital_dev *ddev, u8 rf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) struct port100 *dev = nfc_digital_get_drvdata(ddev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) struct sk_buff *resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) if (rf >= NFC_DIGITAL_RF_TECH_LAST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) skb = port100_alloc_skb(dev, sizeof(struct port100_tg_rf_setting));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) skb_put_data(skb, &tg_rf_settings[rf],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) sizeof(struct port100_tg_rf_setting));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) resp = port100_send_cmd_sync(dev, PORT100_CMD_TG_SET_RF, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) if (IS_ERR(resp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) return PTR_ERR(resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) rc = resp->data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) dev_kfree_skb(resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) static int port100_tg_set_framing(struct nfc_digital_dev *ddev, int param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) struct port100 *dev = nfc_digital_get_drvdata(ddev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) struct port100_protocol *protocols;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) struct sk_buff *resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) int num_protocols;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) size_t size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) if (param >= NFC_DIGITAL_FRAMING_LAST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) protocols = tg_protocols[param];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) num_protocols = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) while (protocols[num_protocols].number != PORT100_TG_PROT_END)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) num_protocols++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) if (!num_protocols)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) size = sizeof(struct port100_protocol) * num_protocols;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) skb = port100_alloc_skb(dev, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) skb_put_data(skb, protocols, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) resp = port100_send_cmd_sync(dev, PORT100_CMD_TG_SET_PROTOCOL, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) if (IS_ERR(resp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) return PTR_ERR(resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) rc = resp->data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) dev_kfree_skb(resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) static int port100_tg_configure_hw(struct nfc_digital_dev *ddev, int type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) int param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) if (type == NFC_DIGITAL_CONFIG_RF_TECH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) return port100_tg_set_rf(ddev, param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) if (type == NFC_DIGITAL_CONFIG_FRAMING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) return port100_tg_set_framing(ddev, param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) static bool port100_tg_target_activated(struct port100 *dev, u8 tgt_activated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) u8 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) switch (dev->cmd_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) case PORT100_CMD_TYPE_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) mask = PORT100_MDAA_TGT_HAS_BEEN_ACTIVATED_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) case PORT100_CMD_TYPE_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) mask = PORT100_MDAA_TGT_HAS_BEEN_ACTIVATED_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) PORT100_MDAA_TGT_WAS_ACTIVATED_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) nfc_err(&dev->interface->dev, "Unknown command type\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) return ((tgt_activated & mask) == mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) static void port100_tg_comm_rf_complete(struct port100 *dev, void *arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) struct sk_buff *resp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) struct port100_cb_arg *cb_arg = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) nfc_digital_cmd_complete_t cb = cb_arg->complete_cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) struct port100_tg_comm_rf_res *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) if (IS_ERR(resp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) hdr = (struct port100_tg_comm_rf_res *)resp->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) status = le32_to_cpu(hdr->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) if (cb_arg->mdaa &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) !port100_tg_target_activated(dev, hdr->target_activated)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) kfree_skb(resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) resp = ERR_PTR(-ETIMEDOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) skb_pull(resp, sizeof(struct port100_tg_comm_rf_res));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) if (status != PORT100_CMD_STATUS_OK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) kfree_skb(resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) if (status == PORT100_CMD_STATUS_TIMEOUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) resp = ERR_PTR(-ETIMEDOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) resp = ERR_PTR(-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) cb(dev->nfc_digital_dev, cb_arg->complete_arg, resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) kfree(cb_arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) static int port100_tg_send_cmd(struct nfc_digital_dev *ddev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) struct sk_buff *skb, u16 timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) nfc_digital_cmd_complete_t cb, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) struct port100 *dev = nfc_digital_get_drvdata(ddev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) struct port100_tg_comm_rf_cmd *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) struct port100_cb_arg *cb_arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) cb_arg = kzalloc(sizeof(struct port100_cb_arg), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) if (!cb_arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) cb_arg->complete_cb = cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) cb_arg->complete_arg = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) skb_push(skb, sizeof(struct port100_tg_comm_rf_cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) hdr = (struct port100_tg_comm_rf_cmd *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) memset(hdr, 0, sizeof(struct port100_tg_comm_rf_cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) hdr->guard_time = cpu_to_le16(500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) hdr->send_timeout = cpu_to_le16(0xFFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) hdr->recv_timeout = cpu_to_le16(timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) return port100_send_cmd_async(dev, PORT100_CMD_TG_COMM_RF, skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) port100_tg_comm_rf_complete, cb_arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) static int port100_listen_mdaa(struct nfc_digital_dev *ddev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) struct digital_tg_mdaa_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) u16 timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) nfc_digital_cmd_complete_t cb, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) struct port100 *dev = nfc_digital_get_drvdata(ddev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) struct port100_tg_comm_rf_cmd *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) struct port100_cb_arg *cb_arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) rc = port100_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) NFC_DIGITAL_RF_TECH_106A);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) rc = port100_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) NFC_DIGITAL_FRAMING_NFCA_NFC_DEP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) cb_arg = kzalloc(sizeof(struct port100_cb_arg), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) if (!cb_arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) cb_arg->complete_cb = cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) cb_arg->complete_arg = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) cb_arg->mdaa = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) skb = port100_alloc_skb(dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) if (!skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) kfree(cb_arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) skb_push(skb, sizeof(struct port100_tg_comm_rf_cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) hdr = (struct port100_tg_comm_rf_cmd *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) memset(hdr, 0, sizeof(struct port100_tg_comm_rf_cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) hdr->guard_time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) hdr->send_timeout = cpu_to_le16(0xFFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) hdr->mdaa = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) hdr->nfca_param[0] = (params->sens_res >> 8) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) hdr->nfca_param[1] = params->sens_res & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) memcpy(hdr->nfca_param + 2, params->nfcid1, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) hdr->nfca_param[5] = params->sel_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) memcpy(hdr->nfcf_param, params->nfcid2, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) hdr->nfcf_param[16] = (params->sc >> 8) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) hdr->nfcf_param[17] = params->sc & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) hdr->recv_timeout = cpu_to_le16(timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) return port100_send_cmd_async(dev, PORT100_CMD_TG_COMM_RF, skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) port100_tg_comm_rf_complete, cb_arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) static int port100_listen(struct nfc_digital_dev *ddev, u16 timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) nfc_digital_cmd_complete_t cb, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) struct port100 *dev = nfc_digital_get_drvdata(ddev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) skb = port100_alloc_skb(dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) return port100_tg_send_cmd(ddev, skb, timeout, cb, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) static struct nfc_digital_ops port100_digital_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) .in_configure_hw = port100_in_configure_hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) .in_send_cmd = port100_in_send_cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) .tg_listen_mdaa = port100_listen_mdaa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) .tg_listen = port100_listen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) .tg_configure_hw = port100_tg_configure_hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) .tg_send_cmd = port100_tg_send_cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) .switch_rf = port100_switch_rf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) .abort_cmd = port100_abort_cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) static const struct usb_device_id port100_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) { USB_DEVICE(SONY_VENDOR_ID, RCS380S_PRODUCT_ID), },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) { USB_DEVICE(SONY_VENDOR_ID, RCS380P_PRODUCT_ID), },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) MODULE_DEVICE_TABLE(usb, port100_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) static int port100_probe(struct usb_interface *interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) const struct usb_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) struct port100 *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) struct usb_host_interface *iface_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) struct usb_endpoint_descriptor *endpoint;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) int in_endpoint;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) int out_endpoint;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) u16 fw_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) u64 cmd_type_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) dev = devm_kzalloc(&interface->dev, sizeof(struct port100), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) mutex_init(&dev->out_urb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) dev->udev = usb_get_dev(interface_to_usbdev(interface));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) dev->interface = interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) usb_set_intfdata(interface, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) in_endpoint = out_endpoint = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) iface_desc = interface->cur_altsetting;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) endpoint = &iface_desc->endpoint[i].desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) if (!in_endpoint && usb_endpoint_is_bulk_in(endpoint))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) in_endpoint = endpoint->bEndpointAddress;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) if (!out_endpoint && usb_endpoint_is_bulk_out(endpoint))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) out_endpoint = endpoint->bEndpointAddress;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) if (!in_endpoint || !out_endpoint) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) nfc_err(&interface->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) "Could not find bulk-in or bulk-out endpoint\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) dev->in_urb = usb_alloc_urb(0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) dev->out_urb = usb_alloc_urb(0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) if (!dev->in_urb || !dev->out_urb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) nfc_err(&interface->dev, "Could not allocate USB URBs\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) usb_fill_bulk_urb(dev->in_urb, dev->udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) usb_rcvbulkpipe(dev->udev, in_endpoint),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) NULL, 0, NULL, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) usb_fill_bulk_urb(dev->out_urb, dev->udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) usb_sndbulkpipe(dev->udev, out_endpoint),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) NULL, 0, port100_send_complete, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) dev->out_urb->transfer_flags = URB_ZERO_PACKET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) dev->skb_headroom = PORT100_FRAME_HEADER_LEN +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) PORT100_COMM_RF_HEAD_MAX_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) dev->skb_tailroom = PORT100_FRAME_TAIL_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) init_completion(&dev->cmd_cancel_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) INIT_WORK(&dev->cmd_complete_work, port100_wq_cmd_complete);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) /* The first thing to do with the Port-100 is to set the command type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) * to be used. If supported we use command type 1. 0 otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) cmd_type_mask = port100_get_command_type_mask(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) if (!cmd_type_mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) nfc_err(&interface->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) "Could not get supported command types\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) if (PORT100_CMD_TYPE_IS_SUPPORTED(cmd_type_mask, PORT100_CMD_TYPE_1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) dev->cmd_type = PORT100_CMD_TYPE_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) dev->cmd_type = PORT100_CMD_TYPE_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) rc = port100_set_command_type(dev, dev->cmd_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) nfc_err(&interface->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) "The device does not support command type %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) dev->cmd_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) fw_version = port100_get_firmware_version(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) if (!fw_version)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) nfc_err(&interface->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) "Could not get device firmware version\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) nfc_info(&interface->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) "Sony NFC Port-100 Series attached (firmware v%x.%02x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) (fw_version & 0xFF00) >> 8, fw_version & 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) dev->nfc_digital_dev = nfc_digital_allocate_device(&port100_digital_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) PORT100_PROTOCOLS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) PORT100_CAPABILITIES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) dev->skb_headroom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) dev->skb_tailroom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) if (!dev->nfc_digital_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) nfc_err(&interface->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) "Could not allocate nfc_digital_dev\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) nfc_digital_set_parent_dev(dev->nfc_digital_dev, &interface->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) nfc_digital_set_drvdata(dev->nfc_digital_dev, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) rc = nfc_digital_register_device(dev->nfc_digital_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) nfc_err(&interface->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) "Could not register digital device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) goto free_nfc_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) free_nfc_dev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) nfc_digital_free_device(dev->nfc_digital_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) usb_kill_urb(dev->in_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) usb_free_urb(dev->in_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) usb_kill_urb(dev->out_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) usb_free_urb(dev->out_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) usb_put_dev(dev->udev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) static void port100_disconnect(struct usb_interface *interface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) struct port100 *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) dev = usb_get_intfdata(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) usb_set_intfdata(interface, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) nfc_digital_unregister_device(dev->nfc_digital_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) nfc_digital_free_device(dev->nfc_digital_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) usb_kill_urb(dev->in_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) usb_kill_urb(dev->out_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) usb_free_urb(dev->in_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) usb_free_urb(dev->out_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) usb_put_dev(dev->udev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) kfree(dev->cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) nfc_info(&interface->dev, "Sony Port-100 NFC device disconnected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) static struct usb_driver port100_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) .name = "port100",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) .probe = port100_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) .disconnect = port100_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) .id_table = port100_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) module_usb_driver(port100_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) MODULE_DESCRIPTION("NFC Port-100 series usb driver ver " VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) MODULE_VERSION(VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) MODULE_LICENSE("GPL");