summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Hong <rurumihong@google.com>2021-11-25 19:54:41 +0800
committerAlex Hong <rurumihong@google.com>2021-11-25 19:54:49 +0800
commitd75480a9fae3b4da3c77508be3aef07ecc79dabe (patch)
treedf7a03d7f7c7bf8c217207e7571ad4d69718a774
parent114cf21edc68b961c1d268f51706d1669b064f4b (diff)
parentb86fb29e205b1f3553f06fbbc635f140a54fd7a1 (diff)
downloaduwb-d75480a9fae3b4da3c77508be3aef07ecc79dabe.tar.gz
Merge android12-gs-pixel-5.10-sc-v2 into android13-gs-pixel-5.10
Bug: 199698959 Change-Id: Iff8213c278c2d725e3e2693ab26b4035cf3fb57e Signed-off-by: Alex Hong <rurumihong@google.com>
-rw-r--r--kernel/drivers/net/ieee802154/Kbuild1
-rw-r--r--kernel/drivers/net/ieee802154/dw3000.h1
-rw-r--r--kernel/drivers/net/ieee802154/dw3000_chip_d0.c4
-rw-r--r--kernel/drivers/net/ieee802154/dw3000_core.c4
-rw-r--r--kernel/drivers/net/ieee802154/dw3000_nfcc_coex.h38
-rw-r--r--kernel/drivers/net/ieee802154/dw3000_nfcc_coex_core.c10
-rw-r--r--kernel/drivers/net/ieee802154/dw3000_nfcc_coex_mcps.c27
-rw-r--r--kernel/drivers/net/ieee802154/dw3000_nfcc_coex_msg.c103
-rw-r--r--kernel/drivers/net/ieee802154/dw3000_nfcc_coex_msg.h46
-rw-r--r--kernel/drivers/net/ieee802154/dw3000_nfcc_coex_testmode.c335
-rw-r--r--kernel/drivers/net/ieee802154/dw3000_nfcc_coex_testmode.h84
-rw-r--r--kernel/drivers/net/ieee802154/dw3000_stm.c4
-rw-r--r--kernel/drivers/net/ieee802154/dw3000_testmode.c332
-rw-r--r--kernel/drivers/net/ieee802154/dw3000_testmode_nl.h11
-rw-r--r--kernel/drivers/net/ieee802154/dw3000_trc.h197
-rw-r--r--kernel/net/mcps802154/fira_trace.h41
-rw-r--r--mac/fira_access.c50
-rw-r--r--mac/fira_frame.c17
-rw-r--r--mac/fira_frame.h5
-rw-r--r--mac/fira_region.c9
-rw-r--r--mac/fira_region.h1
-rw-r--r--mac/fira_region_call.c195
-rw-r--r--mac/fira_session.c136
-rw-r--r--mac/fira_session.h23
-rw-r--r--mac/include/net/fira_region_nl.h8
-rw-r--r--mac/include/net/mcps802154.h8
26 files changed, 616 insertions, 1074 deletions
diff --git a/kernel/drivers/net/ieee802154/Kbuild b/kernel/drivers/net/ieee802154/Kbuild
index 768fdbf..b88dc40 100644
--- a/kernel/drivers/net/ieee802154/Kbuild
+++ b/kernel/drivers/net/ieee802154/Kbuild
@@ -8,7 +8,6 @@ dw3000-y := \
dw3000_nfcc_coex_buffer.o \
dw3000_nfcc_coex_msg.o \
dw3000_nfcc_coex_mcps.o \
- dw3000_nfcc_coex_testmode.o \
dw3000_calib.o \
dw3000_chip_c0.o \
dw3000_chip_d0.o \
diff --git a/kernel/drivers/net/ieee802154/dw3000.h b/kernel/drivers/net/ieee802154/dw3000.h
index 0725b97..e29ab03 100644
--- a/kernel/drivers/net/ieee802154/dw3000.h
+++ b/kernel/drivers/net/ieee802154/dw3000.h
@@ -494,7 +494,6 @@ struct dw3000_rctu_conv {
* @sp0_rx_antenna: Special rx antenna to use for SP0, -1 if deactivated
* @lna_pa_mode: LNA/PA configuration to use
* @autoack: auto-ack status, true if activated
- * @ccc: CCC related data
* @pgf_cal_running: true if pgf calibration is running
* @stm: High-priority thread state machine
* @rx: received skbuff and associated spinlock
diff --git a/kernel/drivers/net/ieee802154/dw3000_chip_d0.c b/kernel/drivers/net/ieee802154/dw3000_chip_d0.c
index cd54d62..032c3b2 100644
--- a/kernel/drivers/net/ieee802154/dw3000_chip_d0.c
+++ b/kernel/drivers/net/ieee802154/dw3000_chip_d0.c
@@ -115,8 +115,8 @@ int dw3000_d0_init(struct dw3000 *dw)
int rc = 0;
if (dw->current_operational_state != DW3000_OP_STATE_DEEP_SLEEP) {
- /* Disable CCC Mailbox only if the chip is not in deep sleep.
- * Else, on wake up, the CCC state will be not detectable. */
+ /* Disable nfcc_coex mail box only if the chip is not in deep sleep.
+ * Else, on wake up, the nfcc_coex state will be not detectable. */
rc = dw3000_nfcc_coex_disable(dw);
}
return rc;
diff --git a/kernel/drivers/net/ieee802154/dw3000_core.c b/kernel/drivers/net/ieee802154/dw3000_core.c
index 2b116ca..f840c02 100644
--- a/kernel/drivers/net/ieee802154/dw3000_core.c
+++ b/kernel/drivers/net/ieee802154/dw3000_core.c
@@ -4128,7 +4128,7 @@ static int dw3000_backup_registers(struct dw3000 *dw, bool after)
*/
void dw3000_wakeup_timer_start(struct dw3000 *dw, int delay_us)
{
- hrtimer_start(&dw->deep_sleep_timer, ns_to_ktime(delay_us * 1000),
+ hrtimer_start(&dw->deep_sleep_timer, ns_to_ktime(delay_us * 1000ull),
HRTIMER_MODE_REL);
dw->call_timer_expired = true;
trace_dw3000_wakeup_timer_start(dw, delay_us);
@@ -6626,7 +6626,7 @@ void dw3000_isr(struct dw3000 *dw)
goto spi_err;
}
- /* Handle the SPI1 Available events in CCC mode only */
+ /* Handle the SPI1 Available events in nfcc_coex mode only */
if (dw->nfcc_coex.enabled &&
(isr.dss_stat & DW3000_DSS_STAT_SPI1_AVAIL_BIT_MASK)) {
rc = dw3000_clear_dss_status(
diff --git a/kernel/drivers/net/ieee802154/dw3000_nfcc_coex.h b/kernel/drivers/net/ieee802154/dw3000_nfcc_coex.h
index 8a56882..682c7bd 100644
--- a/kernel/drivers/net/ieee802154/dw3000_nfcc_coex.h
+++ b/kernel/drivers/net/ieee802154/dw3000_nfcc_coex.h
@@ -26,10 +26,8 @@
#include <linux/module.h>
#include <net/vendor_cmd.h>
-#include "dw3000_nfcc_coex_testmode.h"
-
/* Main defines */
-#define DW3000_NFCC_COEX_VER_ID 1
+#define DW3000_NFCC_COEX_VER_ID 2
#define DW3000_NFCC_COEX_SIGNATURE_STR "QORVO"
#define DW3000_NFCC_COEX_SIGNATURE_LEN 5
#define DW3000_NFCC_COEX_MAX_NB_TLV 12
@@ -49,6 +47,9 @@
#define MSG_HEADER_LEN (DW3000_NFCC_COEX_SIGNATURE_LEN + 3)
#define MSG_LEN(x) (MSG_HEADER_LEN + (x).tlvs_len)
+#define DW3000_NFCC_COEX_UUS_PER_SYS_POWER 8 /* To use with right shift. */
+#define DW3000_NFCC_COEX_DTU_PER_UUS_POWER 4 /* To use with left shift. */
+
/**
* struct dw3000_nfcc_coex_msg - Message read/write from/to scratch memory.
*/
@@ -86,7 +87,7 @@ struct dw3000_nfcc_coex_buffer {
*/
u8 raw[DW3000_NFCC_COEX_MSG_MAX_SIZE];
/**
- * @msg: CCC Message.
+ * @msg: nfcc_coex message.
*/
struct dw3000_nfcc_coex_msg msg;
};
@@ -101,23 +102,22 @@ struct dw3000_nfcc_coex_buffer {
*/
struct dw3000_nfcc_coex_rx_msg_info {
/**
- * @next_timestamp_sys_time: Next NFCC access requested.
+ * @next_timestamp_dtu: Next NFCC access requested.
*/
- u32 next_timestamp_sys_time;
+ u32 next_timestamp_dtu;
/**
- * @next_duration_sys_time: Next NFCC duration access.
+ * @next_duration_dtu: Next NFCC duration access.
*/
- int next_duration_sys_time;
+ int next_duration_dtu;
/**
* @next_slot_found: True when first next slot is found.
*/
bool next_slot_found;
- /**
- * @slot_list: Pointer to array of slot.
- */
- const struct dw3000_nfcc_coex_tlv_slot_list *slot_list;
};
+/* Forward declaration. */
+struct dw3000;
+
/**
* typedef dw3000_nfcc_coex_spi_avail_cb - SPI available isr handler.
* @dw: Driver context.
@@ -133,10 +133,6 @@ typedef int (*dw3000_nfcc_coex_spi_avail_cb)(
*/
struct dw3000_nfcc_coex {
/**
- * @testmode_config: config with testmode enabled.
- */
- const struct dw3000_nfcc_coex_testmode_config *testmode_config;
- /**
* @access_info: Access information to provide to upper layer.
*/
struct dw3000_vendor_cmd_nfcc_coex_get_access_info access_info;
@@ -145,13 +141,13 @@ struct dw3000_nfcc_coex {
*/
dw3000_nfcc_coex_spi_avail_cb spi_avail_cb;
/**
- * @testmode_round_count: Index number of NFCC session.
- */
- u32 testmode_round_count;
+ * @session_time0_dtu: Timestamp used as reference between NFCC and AP.
+ */
+ u32 session_time0_dtu;
/**
- * @session_start_dtu: start date of nfcc session in DTU.
+ * @access_start_dtu: start date of nfcc session in DTU.
*/
- u32 session_start_dtu;
+ u32 access_start_dtu;
/**
* @prev_offset_sys_time: Previous offset between local and decawave time.
*/
diff --git a/kernel/drivers/net/ieee802154/dw3000_nfcc_coex_core.c b/kernel/drivers/net/ieee802154/dw3000_nfcc_coex_core.c
index 1004577..2fa642f 100644
--- a/kernel/drivers/net/ieee802154/dw3000_nfcc_coex_core.c
+++ b/kernel/drivers/net/ieee802154/dw3000_nfcc_coex_core.c
@@ -105,7 +105,7 @@ static int dw3000_nfcc_coex_enable_SPIxMAVAIL_interrupts(struct dw3000 *dw)
return rc;
/* Set SPI1MAVAIL and SPI2MAVAIL masks */
reg |= (DW3000_SPI_SEM_SPI1MAVAIL_BIT_MASK >> 8) |
- (DW3000_SPI_SEM_SPI2MAVAIL_BIT_MASK >> 8);
+ (DW3000_SPI_SEM_SPI2MAVAIL_BIT_MASK >> 8);
return dw3000_reg_write8(dw, DW3000_SPI_SEM_ID, 1, reg);
}
@@ -125,8 +125,8 @@ static int dw3000_nfcc_coex_disable_SPIxMAVAIL_interrupts(struct dw3000 *dw)
if (rc)
return rc;
/* Reset SPI1MAVAIL and SPI2MAVAIL masks. */
- reg = reg & ~(DW3000_SPI_SEM_SPI1MAVAIL_BIT_MASK >> 8) &
- ~(DW3000_SPI_SEM_SPI2MAVAIL_BIT_MASK >> 8);
+ reg &= ~(DW3000_SPI_SEM_SPI1MAVAIL_BIT_MASK >> 8) &
+ ~(DW3000_SPI_SEM_SPI2MAVAIL_BIT_MASK >> 8);
rc = dw3000_reg_write8(dw, DW3000_SPI_SEM_ID, 1, reg);
if (rc)
return rc;
@@ -150,7 +150,7 @@ static int dw3000_nfcc_coex_do_watchdog_timeout(struct dw3000 *dw,
dw->nfcc_coex.access_info.stop = true;
/* FIXME: The expected is a hard reset of decawave when the semaphore
* haven't been released.
- * But CCC firmware can not currently provide a message with nb_tlv=0. */
+ * But nfcc_coex firmware can not currently provide a message with nb_tlv=0. */
dw3000_nfcc_coex_disable(dw);
mcps802154_tx_done(dw->llhw);
@@ -336,7 +336,7 @@ int dw3000_nfcc_coex_disable(struct dw3000 *dw)
if (rc) {
trace_dw3000_nfcc_coex_err(
dw,
- "ccc_disable error while restoring channel");
+ "nfcc_coex_disable error while restoring channel");
return rc;
}
}
diff --git a/kernel/drivers/net/ieee802154/dw3000_nfcc_coex_mcps.c b/kernel/drivers/net/ieee802154/dw3000_nfcc_coex_mcps.c
index 74d1590..17229b9 100644
--- a/kernel/drivers/net/ieee802154/dw3000_nfcc_coex_mcps.c
+++ b/kernel/drivers/net/ieee802154/dw3000_nfcc_coex_mcps.c
@@ -38,33 +38,24 @@
static void dw3000_nfcc_coex_update_access_info(
struct dw3000 *dw, const struct dw3000_nfcc_coex_buffer *buffer)
{
- struct dw3000_nfcc_coex *nfcc_coex = &dw->nfcc_coex;
struct dw3000_vendor_cmd_nfcc_coex_get_access_info *access_info =
&dw->nfcc_coex.access_info;
struct dw3000_nfcc_coex_rx_msg_info rx_msg_info = {};
int r;
r = dw3000_nfcc_coex_message_check(dw, buffer, &rx_msg_info);
- if (r)
+ if (r) {
+ trace_dw3000_nfcc_coex_warn(dw, "message check failure");
goto failure;
+ }
/* Update access_info. */
access_info->stop = !rx_msg_info.next_slot_found;
access_info->watchdog_timeout = false;
if (rx_msg_info.next_slot_found) {
- u32 diff_sys_time;
-
- /* Build the next date with the difference, because the sys_time is
- * faster than dtu time. */
- diff_sys_time = rx_msg_info.next_timestamp_sys_time -
- dw3000_dtu_to_sys_time(
- dw, nfcc_coex->session_start_dtu);
access_info->next_timestamp_dtu =
- nfcc_coex->session_start_dtu +
- (diff_sys_time >> DW3000_DTU_PER_SYS_POWER);
- access_info->next_duration_dtu =
- rx_msg_info.next_duration_sys_time >>
- DW3000_DTU_PER_SYS_POWER;
+ rx_msg_info.next_timestamp_dtu;
+ access_info->next_duration_dtu = rx_msg_info.next_duration_dtu;
}
return;
@@ -120,15 +111,12 @@ static int dw3000_nfcc_coex_handle_access(struct dw3000 *dw, void *data,
const struct dw3000_vendor_cmd_nfcc_coex_handle_access *info = data;
struct dw3000_nfcc_coex *nfcc_coex = &dw->nfcc_coex;
const u32 dtu_per_ms = dw->llhw->dtu_freq_hz / 1000;
- u32 cur_time_dtu;
u32 diff_dtu, diff_ms;
int r;
if (!info || data_len != sizeof(*info))
return -EINVAL;
- cur_time_dtu = dw3000_get_dtu_time(dw);
-
if (timer_pending(&nfcc_coex->watchdog_timer)) {
trace_dw3000_nfcc_coex_err(dw, "watchdog timer is pending");
return -EBUSY;
@@ -141,10 +129,11 @@ static int dw3000_nfcc_coex_handle_access(struct dw3000 *dw, void *data,
return r;
}
+ trace_dw3000_nfcc_coex_handle_access(dw, info);
/* Save start session date, to retrieve MSB bits lost for next date. */
- nfcc_coex->session_start_dtu = info->timestamp_dtu;
+ nfcc_coex->access_start_dtu = info->timestamp_dtu;
/* Setup watchdog timer. */
- diff_dtu = info->timestamp_dtu - cur_time_dtu;
+ diff_dtu = info->timestamp_dtu - dw3000_get_dtu_time(dw);
diff_ms = diff_dtu / dtu_per_ms;
nfcc_coex->watchdog_timer.expires =
jiffies +
diff --git a/kernel/drivers/net/ieee802154/dw3000_nfcc_coex_msg.c b/kernel/drivers/net/ieee802154/dw3000_nfcc_coex_msg.c
index 1517678..0058f61 100644
--- a/kernel/drivers/net/ieee802154/dw3000_nfcc_coex_msg.c
+++ b/kernel/drivers/net/ieee802154/dw3000_nfcc_coex_msg.c
@@ -33,12 +33,6 @@
#define TLV_U32_LEN (4 + 1) /* u32 + ack/nack. */
#define TLV_SLOTS_LEN(nbslots) \
(1 + (8 * (nbslots)) + 1) /* nslots + slots + ack/nack. */
-
-/* Error codes for TLV_ERROR type. */
-#define CCC_ERR_LATE_SPIMAVAIL 0
-#define CCC_ERR_SLOT_CONFLICT 1
-#define CCC_ERR_CODE_SZ 2
-
#define MSG_NEXT_TLV(buffer, offset) \
(struct dw3000_nfcc_coex_tlv *)((buffer)->msg.tlvs + (offset))
@@ -70,6 +64,8 @@ void dw3000_nfcc_coex_header_put(struct dw3000 *dw,
{
struct dw3000_nfcc_coex_msg *msg = &buffer->msg;
+ trace_dw3000_nfcc_coex_header_put(dw, DW3000_NFCC_COEX_VER_ID,
+ dw->nfcc_coex.tx_seq_num);
memcpy(msg->signature, DW3000_NFCC_COEX_SIGNATURE_STR,
DW3000_NFCC_COEX_SIGNATURE_LEN);
msg->ver_id = DW3000_NFCC_COEX_VER_ID;
@@ -79,37 +75,14 @@ void dw3000_nfcc_coex_header_put(struct dw3000 *dw,
}
/**
- * dw3000_nfcc_coex_single_tlv_slot_put() - Fill buffer payload for a single TLV slot.
- * @buffer: Message buffer to fill.
- * @start: Start date of NFCC session in ms.
- * @end: End date of NFCC session in ms.
- */
-void dw3000_nfcc_coex_single_tlv_slot_put(
- struct dw3000_nfcc_coex_buffer *buffer, u32 start, u32 end)
-{
- struct dw3000_nfcc_coex_msg *msg = &buffer->msg;
- struct dw3000_nfcc_coex_tlv *tlv;
- struct dw3000_nfcc_coex_tlv_slot_list *slot_list;
-
- tlv = MSG_NEXT_TLV(buffer, buffer->tlvs_len);
- msg->nb_tlv++;
- tlv->type = TLV_SLOT_LIST;
- tlv->len = TLV_SLOTS_LEN(1);
- slot_list = (struct dw3000_nfcc_coex_tlv_slot_list *)&tlv->tlv;
- slot_list->nb_slots = 1;
- slot_list->slots[0].start_sys_time = start;
- slot_list->slots[0].end_sys_time = end;
- buffer->tlvs_len += TLV_TYPELEN_LEN + tlv->len;
-}
-
-/**
* dw3000_nfcc_coex_tlv_u32_put() - Fill buffer payload for a TLV.
* @buffer: Message buffer to fill.
* @type: Type id of the TLV.
* @value: Value of TLV.
*/
-void dw3000_nfcc_coex_tlv_u32_put(struct dw3000_nfcc_coex_buffer *buffer,
- u8 type, u32 value)
+static void dw3000_nfcc_coex_tlv_u32_put(struct dw3000_nfcc_coex_buffer *buffer,
+ enum dw3000_nfcc_coex_tlv_type type,
+ u32 value)
{
struct dw3000_nfcc_coex_msg *msg = &buffer->msg;
struct dw3000_nfcc_coex_tlv *tlv;
@@ -125,26 +98,6 @@ void dw3000_nfcc_coex_tlv_u32_put(struct dw3000_nfcc_coex_buffer *buffer,
}
/**
- * dw3000_nfcc_coex_tlv_slots_put() - Fill buffer payload for a TLV slots.
- * @buffer: Message buffer to fill.
- * @slot_list: TLV slots.
- */
-void dw3000_nfcc_coex_tlv_slots_put(
- struct dw3000_nfcc_coex_buffer *buffer,
- const struct dw3000_nfcc_coex_tlv_slot_list *slot_list)
-{
- struct dw3000_nfcc_coex_msg *msg = &buffer->msg;
- struct dw3000_nfcc_coex_tlv *tlv;
-
- tlv = MSG_NEXT_TLV(buffer, buffer->tlvs_len);
- msg->nb_tlv++;
- tlv->type = TLV_SLOT_LIST;
- tlv->len = TLV_SLOTS_LEN(slot_list->nb_slots);
- memcpy(&tlv->tlv, slot_list, sizeof(*slot_list));
- buffer->tlvs_len += TLV_TYPELEN_LEN + tlv->len;
-}
-
-/**
* dw3000_nfcc_coex_clock_sync_payload_put() - Fill clock sync frame payload.
* @dw: Driver context.
* @buffer: Buffer to set with help of handle_access.
@@ -154,12 +107,16 @@ dw3000_nfcc_coex_clock_sync_payload_put(struct dw3000 *dw,
struct dw3000_nfcc_coex_buffer *buffer)
{
u32 session_time0_sys_time =
- dw3000_dtu_to_sys_time(dw, dw->nfcc_coex.session_start_dtu);
+ dw3000_dtu_to_sys_time(dw, dw->nfcc_coex.access_start_dtu);
+ /* Update clock reference. */
+ dw->nfcc_coex.session_time0_dtu = dw->nfcc_coex.access_start_dtu;
+ /* Prepare message. */
trace_dw3000_nfcc_coex_clock_sync_payload_put(dw,
session_time0_sys_time);
dw3000_nfcc_coex_header_put(dw, buffer);
- dw3000_nfcc_coex_tlv_u32_put(buffer, TLV_SESSION_TIME0,
+ dw3000_nfcc_coex_tlv_u32_put(buffer,
+ DW3000_NFCC_COEX_TLV_TYPE_SESSION_TIME0,
session_time0_sys_time);
}
@@ -167,7 +124,7 @@ dw3000_nfcc_coex_clock_sync_payload_put(struct dw3000 *dw,
* dw3000_nfcc_coex_clock_offset_payload_put() - Fill clock offset payload.
* @dw: Driver context.
* @buffer: Buffer to set with help of handle_access.
- * @clock_offset_sys_time: Offset to add to next ccc schedule.
+ * @clock_offset_sys_time: Offset to add to next nfcc_coex schedule.
*/
static void dw3000_nfcc_coex_clock_offset_payload_put(
struct dw3000 *dw, struct dw3000_nfcc_coex_buffer *buffer,
@@ -176,7 +133,8 @@ static void dw3000_nfcc_coex_clock_offset_payload_put(
trace_dw3000_nfcc_coex_clock_offset_payload_put(dw,
clock_offset_sys_time);
dw3000_nfcc_coex_header_put(dw, buffer);
- dw3000_nfcc_coex_tlv_u32_put(buffer, TLV_UWBCNT_OFFS,
+ dw3000_nfcc_coex_tlv_u32_put(buffer,
+ DW3000_NFCC_COEX_TLV_TYPE_TLV_UWBCNT_OFFS,
clock_offset_sys_time);
}
@@ -282,35 +240,30 @@ dw3000_nfcc_coex_tlvs_check(struct dw3000 *dw,
if (tlvs_len > tlvs_len_max)
return -EINVAL;
- switch (tlv->type) {
- case TLV_SLOT_LIST:
+ trace_dw3000_nfcc_coex_tlv_check(dw, tlv->type, tlv->len,
+ tlv->tlv);
+ if (tlv->type == DW3000_NFCC_COEX_TLV_TYPE_SLOT_LIST_UUS) {
/* Reject a new TLV with same type. Behavior not defined. */
if (slot_list)
return -EINVAL;
slot_list = (const struct dw3000_nfcc_coex_tlv_slot_list
*)&tlv->tlv;
- /* Keep the pointer ref for testmode. */
- rx_msg_info->slot_list = slot_list;
/* Update rx_msg_info. */
if (slot_list->nb_slots > 0) {
const struct dw3000_nfcc_coex_tlv_slot *slot =
&slot_list->slots[0];
+ u32 next_in_session_dtu =
+ slot->t_start_uus
+ << DW3000_NFCC_COEX_DTU_PER_UUS_POWER;
rx_msg_info->next_slot_found = true;
- rx_msg_info->next_timestamp_sys_time =
- slot->start_sys_time;
- rx_msg_info->next_duration_sys_time =
- slot->end_sys_time -
- slot->start_sys_time;
+ rx_msg_info->next_timestamp_dtu =
+ dw->nfcc_coex.session_time0_dtu +
+ next_in_session_dtu;
+ rx_msg_info->next_duration_dtu =
+ (slot->t_end_uus - slot->t_start_uus)
+ << DW3000_NFCC_COEX_DTU_PER_UUS_POWER;
}
- break;
- case TLV_ERROR:
- trace_dw3000_nfcc_coex_err(dw, "nfcc sent an error");
- break;
- default:
- trace_dw3000_nfcc_coex_warn(
- dw, "ignoring unexpected TLV type");
- break;
}
}
@@ -341,7 +294,7 @@ int dw3000_nfcc_coex_message_check(
if (rx_msg_info->next_slot_found)
trace_dw3000_nfcc_coex_rx_msg_info(
- dw, rx_msg_info->next_timestamp_sys_time,
- rx_msg_info->next_duration_sys_time);
+ dw, rx_msg_info->next_timestamp_dtu,
+ rx_msg_info->next_duration_dtu);
return 0;
}
diff --git a/kernel/drivers/net/ieee802154/dw3000_nfcc_coex_msg.h b/kernel/drivers/net/ieee802154/dw3000_nfcc_coex_msg.h
index cb51efc..d2e0eac 100644
--- a/kernel/drivers/net/ieee802154/dw3000_nfcc_coex_msg.h
+++ b/kernel/drivers/net/ieee802154/dw3000_nfcc_coex_msg.h
@@ -26,29 +26,48 @@
#include <linux/module.h>
#include "dw3000_nfcc_coex.h"
+#define TLV_MAX_NB_SLOTS 4
+
/* Forward declaration. */
struct dw3000;
-/* TLVs types. */
-#define TLV_SESSION_TIME0 1
-#define TLV_SLOT_LIST 2
-#define TLV_UWBCNT_OFFS 3
-#define TLV_ERROR 4
+/**
+ * enum dw3000_nfcc_coex_tlv_type - TLVs types.
+ *
+ * @DW3000_NFCC_COEX_TLV_TYPE_UNSPEC: Invalid command.
+ * @DW3000_NFCC_COEX_TLV_TYPE_SESSION_TIME0:
+ * Indicate start of UWB session in RCTU time unit.
+ * @DW3000_NFCC_COEX_TLV_TYPE_SLOT_LIST:
+ * Indicate the requested next time slots.
+ * @DW3000_NFCC_COEX_TLV_TYPE_TLV_UWBCNT_OFFS:
+ * Indicate the UWB clock offset in V1 protocol.
+ * @DW3000_NFCC_COEX_TLV_TYPE_ERROR:
+ * Indicate error condition.
+ * @DW3000_NFCC_COEX_TLV_TYPE_SLOT_LIST_UUS:
+ * Indicate the UWB clock offset in V2 protocol.
+ */
+enum dw3000_nfcc_coex_tlv_type {
+ DW3000_NFCC_COEX_TLV_TYPE_UNSPEC,
-#define TLV_MAX_NB_SLOTS 4
+ DW3000_NFCC_COEX_TLV_TYPE_SESSION_TIME0,
+ DW3000_NFCC_COEX_TLV_TYPE_SLOT_LIST,
+ DW3000_NFCC_COEX_TLV_TYPE_TLV_UWBCNT_OFFS,
+ DW3000_NFCC_COEX_TLV_TYPE_ERROR,
+ DW3000_NFCC_COEX_TLV_TYPE_SLOT_LIST_UUS,
+};
/**
* struct dw3000_nfcc_coex_tlv_slot - TLV slot definition.
*/
struct dw3000_nfcc_coex_tlv_slot {
/**
- * @start_sys_time: Start date in sys time unit.
+ * @t_start_uus: Start date in 65536*RCTU (close to usec unit).
*/
- u32 start_sys_time;
+ u32 t_start_uus;
/**
- * @end_sys_time: End date in sys time unit.
+ * @t_end_uus: End date in 65536*RCTU (close to usec unit).
*/
- u32 end_sys_time;
+ u32 t_end_uus;
};
/**
@@ -67,13 +86,6 @@ struct dw3000_nfcc_coex_tlv_slot_list {
void dw3000_nfcc_coex_header_put(struct dw3000 *dw,
struct dw3000_nfcc_coex_buffer *buffer);
-void dw3000_nfcc_coex_single_tlv_slot_put(
- struct dw3000_nfcc_coex_buffer *buffer, u32 start, u32 end);
-void dw3000_nfcc_coex_tlv_u32_put(struct dw3000_nfcc_coex_buffer *buffer,
- u8 type, u32 value);
-void dw3000_nfcc_coex_tlv_slots_put(
- struct dw3000_nfcc_coex_buffer *buffer,
- const struct dw3000_nfcc_coex_tlv_slot_list *slot_list);
int dw3000_nfcc_coex_message_send(struct dw3000 *dw);
int dw3000_nfcc_coex_message_check(
struct dw3000 *dw, const struct dw3000_nfcc_coex_buffer *buffer,
diff --git a/kernel/drivers/net/ieee802154/dw3000_nfcc_coex_testmode.c b/kernel/drivers/net/ieee802154/dw3000_nfcc_coex_testmode.c
deleted file mode 100644
index e7a9d1f..0000000
--- a/kernel/drivers/net/ieee802154/dw3000_nfcc_coex_testmode.c
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * This file is part of the UWB stack for linux.
- *
- * Copyright (c) 2021 Qorvo US, Inc.
- *
- * This software is provided under the GNU General Public License, version 2
- * (GPLv2), as well as under a Qorvo commercial license.
- *
- * You may choose to use this software under the terms of the GPLv2 License,
- * version 2 ("GPLv2"), as published by the Free Software Foundation.
- * You should have received a copy of the GPLv2 along with this program. If
- * not, see <http://www.gnu.org/licenses/>.
- *
- * This program is distributed under the GPLv2 in the hope that it will be
- * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GPLv2 for more
- * details.
- *
- * If you cannot meet the requirements of the GPLv2, you may not use this
- * software for any purpose without first obtaining a commercial license from
- * Qorvo. Please contact Qorvo to inquire about licensing terms.
- */
-
-#include "dw3000_nfcc_coex_testmode.h"
-#include "dw3000_nfcc_coex_msg.h"
-#include "dw3000_nfcc_coex_core.h"
-#include "dw3000_nfcc_coex_buffer.h"
-#include "dw3000_nfcc_coex.h"
-#include "dw3000.h"
-#include "dw3000_trc.h"
-#include "dw3000_core.h"
-
-#define CCC_TEST_SLOT_DELTA_PC 15 /* Percent. */
-/* Request an end of access without error on current access. */
-#define DW3000_CCC_RETURN_STOP 1
-
-/**
- * dw3000_nfcc_coex_generate_test_slots() - Generates a series of valid, interleaved slots.
- * @in: Slots found in incomming message.
- * @out: Slots output to write.
- * @margin_pc: Margin in pourcent.
- * @slot_after: True when reuse last free slot duration is permit.
- *
- * Return: 0 on success, else an error.
- *
- * For instance, if given the input:
- * [t_start0, t_end0], [t_start1, t_end1], [t_start2, t_end2]
- * We generate the output:
- * [t_end0 + DELTA0, t_start1 - DELTA0], [t_end1 + DELTA1, t_start2 - DELTA1]
- * Where DELTAn = (( t_startn+1 - t_endn ) * margin_pc) / 100
- *
- * NB :
- * - assumes input slots are valid, i.e in->nb_slots <= TLV_MAX_NB_SLOTS
- * - If slot_after is passed true, append a last slot AFTER all NFCC slots
- */
-static int dw3000_nfcc_coex_generate_test_slots(
- const struct dw3000_nfcc_coex_tlv_slot_list *in,
- struct dw3000_nfcc_coex_tlv_slot_list *out, u32 margin_pc,
- bool slot_after)
-{
- int i;
- u32 free_slot_duration;
- u32 delta_i;
-
- if (in->nb_slots == 0)
- return -1;
-
- out->nb_slots = in->nb_slots - 1;
- for (i = 0; i < out->nb_slots; i++) {
- free_slot_duration = in->slots[i + 1].end_sys_time -
- in->slots[i].start_sys_time;
- delta_i = (free_slot_duration * margin_pc) / 100;
- /* gen slot : [t_endi + DELTAi, t_starti+1 - DELTAi] */
- out->slots[i].start_sys_time =
- in->slots[i].end_sys_time + delta_i;
- out->slots[i].end_sys_time =
- in->slots[i + 1].start_sys_time - delta_i;
- }
-
- if (slot_after) {
- if (out->nb_slots == 0) {
- /* we need a value for free_slot_duration and delta_i. */
- free_slot_duration = in->slots[0].end_sys_time -
- in->slots[0].start_sys_time;
- delta_i = (free_slot_duration * margin_pc) / 100;
- }
- /* Add a last slot reusing last free_slot_duration and delta_i. */
- out->nb_slots++;
- out->slots[i].start_sys_time =
- in->slots[i].end_sys_time + delta_i;
- out->slots[i].end_sys_time = in->slots[i].end_sys_time -
- delta_i + free_slot_duration;
- }
- return 0;
-}
-
-/**
- * dw3000_nfcc_coex_testmode_config_spi_avail_handler() - Config testmode callback.
- * @dw: Driver context.
- * @buffer: Memory read from scratch memory.
- *
- * Return: 0 on success, else an error.
- */
-static int dw3000_nfcc_coex_testmode_config_spi_avail_handler(
- struct dw3000 *dw, const struct dw3000_nfcc_coex_buffer *buffer)
-{
- const struct dw3000_nfcc_coex_testmode_config *test_conf =
- dw->nfcc_coex.testmode_config;
- const u32 dtu_per_ms = dw->llhw->dtu_freq_hz / 1000;
- struct dw3000_nfcc_coex_rx_msg_info rx_msg_info = {};
- struct dw3000_nfcc_coex_buffer out = {};
- struct dw3000_nfcc_coex_tlv_slot_list out_slot_list = {};
- u32 cur_time_dtu, next_slot_dtu;
- u32 diff_dtu, diff_ms;
- int rc;
-
- dw->nfcc_coex.testmode_round_count++;
-
- rc = dw3000_nfcc_coex_message_check(dw, buffer, &rx_msg_info);
- if (rc)
- return rc;
-
- if (!rx_msg_info.next_slot_found)
- return dw3000_nfcc_coex_disable(dw);
-
- dw3000_nfcc_coex_header_put(dw, &out);
- cur_time_dtu = dw3000_get_dtu_time(dw);
-
- /* Behavior depends on test mode. */
- switch (test_conf->mode) {
- case DW3000_CCC_TEST_DIRECT:
- break;
- case DW3000_CCC_TEST_WAIT:
- /* Margin is typically 100ms hence msleep is used. */
- msleep(test_conf->margin_ms);
- break;
- case DW3000_CCC_TEST_LATE:
- if (rx_msg_info.next_timestamp_sys_time == 0)
- break;
- next_slot_dtu = dw3000_sys_time_to_dtu(
- dw, rx_msg_info.next_timestamp_sys_time, cur_time_dtu);
- diff_dtu = next_slot_dtu - cur_time_dtu;
- diff_ms = diff_dtu / dtu_per_ms;
- if (test_conf->RRcount == 0 ||
- dw->nfcc_coex.testmode_round_count++ % test_conf->RRcount ==
- 0) {
- /* Margin is typically 100ms and diff_ms is a
- * multiple of 96ms, hence msleep is used. */
- msleep(diff_ms + test_conf->margin_ms);
- break;
- }
- if (diff_dtu > dw3000_nfcc_coex_margin_dtu) {
- /* Difference is a multiple of 96ms, hence msleep
- * is used. */
- msleep((diff_dtu - dw3000_nfcc_coex_margin_dtu) /
- dtu_per_ms);
- }
- break;
- case DW3000_CCC_TEST_CONFLICT:
- if (dw3000_nfcc_coex_generate_test_slots(
- rx_msg_info.slot_list, &out_slot_list,
- CCC_TEST_SLOT_DELTA_PC, true))
- break;
- if ((test_conf->RRcount == 0 ||
- (dw->nfcc_coex.testmode_round_count++ %
- test_conf->RRcount ==
- 0)) &&
- test_conf->conflict_slot_idx < out_slot_list.nb_slots) {
- /* We want a conflict this round
- * and we have enough slot, given conflict_slot_idx.
- * So, just copy the input slot values. */
- const int n = test_conf->conflict_slot_idx;
- const struct dw3000_nfcc_coex_tlv_slot *slot_b =
- &rx_msg_info.slot_list->slots[n];
- struct dw3000_nfcc_coex_tlv_slot *slot_a =
- &out_slot_list.slots[n];
-
- *slot_a = *slot_b;
- }
- dw3000_nfcc_coex_tlv_slots_put(&out, &out_slot_list);
- break;
- case DW3000_CCC_TEST_SLEEP_OFFSET:
- dw3000_nfcc_coex_tlv_u32_put(&out, TLV_UWBCNT_OFFS,
- test_conf->offset_ms);
- break;
- default:
- return DW3000_CCC_RETURN_STOP;
- }
-
- return dw3000_nfcc_coex_write_buffer(dw, &out, MSG_LEN(out));
-}
-
-/**
- * dw3000_nfcc_coex_testmode_write_msg() - Write custom message for NFCC.
- * @dw: Driver context.
- * @session_time0: Offset in ms to add to current time.
- * @start: Start date of NFCC session in ms.
- * @end: End date of NFCC session in ms.
- *
- * Return: 0 on success, else an error.
- */
-static int dw3000_nfcc_coex_testmode_write_msg(struct dw3000 *dw,
- u32 session_time0, u32 start,
- u32 end)
-{
- u32 absolute_session_time0_sys;
- u32 start_time_dtu;
- u64 session_time0_dtu;
- struct dw3000_nfcc_coex_buffer buffer;
-
- start_time_dtu = dw3000_get_dtu_time(dw);
- dw3000_nfcc_coex_header_put(dw, &buffer);
- /* session_time0 is the offset of the NFCC ranging start time in
- * microseconds. The absolute NFCC ranging start time is transmitted
- * to the NFCC in SYS_TIME. */
- session_time0_dtu =
- ((u64)session_time0 * (u64)(dw->llhw->dtu_freq_hz)) / 1000000;
- absolute_session_time0_sys = (start_time_dtu + session_time0_dtu)
- << DW3000_DTU_PER_SYS_POWER;
-
- dw3000_nfcc_coex_tlv_u32_put(&buffer, TLV_SESSION_TIME0,
- absolute_session_time0_sys);
-
- if (start && end) {
- start *= (u64)(dw->llhw->dtu_freq_hz) / 1000000;
- start += start_time_dtu;
- end *= (u64)(dw->llhw->dtu_freq_hz) / 1000000;
- end += start_time_dtu;
- dw3000_nfcc_coex_single_tlv_slot_put(&buffer, start, end);
- }
-
- return dw3000_nfcc_coex_write_buffer(dw, &buffer, MSG_LEN(buffer));
-}
-
-/**
- * dw3000_nfcc_coex_testmode_session_spi_avail_handler() - Start testmode callback.
- * @dw: Driver context.
- * @buffer: Memory read from scratch memory.
- *
- * Return: 0 on success, else an error.
- */
-static int dw3000_nfcc_coex_testmode_session_spi_avail_handler(
- struct dw3000 *dw, const struct dw3000_nfcc_coex_buffer *buffer)
-{
- struct dw3000_nfcc_coex_rx_msg_info rx_msg_info = {};
- struct dw3000_nfcc_coex_buffer out = {};
- u32 curtime_dtu = 0;
- u32 nextslot_dtu = 0;
- u32 diff_dtu;
- int rc = -1;
-
- rc = dw3000_nfcc_coex_message_check(dw, buffer, &rx_msg_info);
- if (rc)
- return rc;
-
- if (!rx_msg_info.next_slot_found)
- return dw3000_nfcc_coex_disable(dw);
-
- curtime_dtu = dw3000_get_dtu_time(dw);
- nextslot_dtu = dw3000_sys_time_to_dtu(
- dw, rx_msg_info.next_timestamp_sys_time, curtime_dtu);
- diff_dtu = nextslot_dtu - curtime_dtu;
- if (diff_dtu > dw3000_nfcc_coex_margin_dtu) {
- /* Wait for next slot, use a margin, as it looks like we do have a
- * lot of fluctuations on NFCC side, leading to TXLATE when trying small
- * delay.
- * The next message is send in dw3000_isr_handle_spi_ready() on the wake up.
- */
- rc = dw3000_nfcc_coex_sleep(
- dw, diff_dtu - dw3000_nfcc_coex_margin_dtu);
- } else {
- /* The delay is too short to sleep before respond to the NFCC. */
- dw3000_nfcc_coex_header_put(dw, &out);
- rc = dw3000_nfcc_coex_write_buffer(dw, &out, MSG_LEN(out));
- }
- return rc;
-}
-
-/**
- * dw3000_nfcc_coex_testmode_session() - Start one custom NFCC session.
- * @dw: Driver context.
- * @chan: Channel number.
- * @session_time0: Offset in ms to add to current time.
- * @start: Start date of NFCC session in ms.
- * @end: End date of NFCC session in ms.
- *
- * Return: 0 on success, else an error.
- */
-int dw3000_nfcc_coex_testmode_session(struct dw3000 *dw, u8 chan,
- u32 session_time0, u32 start, u32 end)
-{
- int r;
-
- r = dw3000_nfcc_coex_enable(
- dw, chan, dw3000_nfcc_coex_testmode_session_spi_avail_handler);
- if (r)
- return r;
-
- trace_dw3000_nfcc_coex_warn(dw, "testmode start");
- return dw3000_nfcc_coex_testmode_write_msg(dw, session_time0, start,
- end);
-}
-
-/**
- * dw3000_nfcc_coex_testmode_config() - Process testmode config.
- * @dw: Driver context.
- * @testmode_config: Pointer on persistente config to use.
- *
- * Return: 0 on success, else an error.
- */
-int dw3000_nfcc_coex_testmode_config(
- struct dw3000 *dw,
- const struct dw3000_nfcc_coex_testmode_config *testmode_config)
-{
- int r;
-
- if (!testmode_config) {
- trace_dw3000_nfcc_coex_err(
- dw, "can't start testmode with a NULL conf");
- return -EINVAL;
- }
-
- dw->nfcc_coex.testmode_config = testmode_config;
- dw->nfcc_coex.testmode_round_count = 0;
- r = dw3000_nfcc_coex_enable(
- dw, testmode_config->channel,
- dw3000_nfcc_coex_testmode_config_spi_avail_handler);
- if (r)
- return r;
-
- trace_dw3000_nfcc_coex_warn(dw, "testmode run config");
- return dw3000_nfcc_coex_testmode_write_msg(
- dw, testmode_config->session_time0, testmode_config->start,
- testmode_config->end);
-}
diff --git a/kernel/drivers/net/ieee802154/dw3000_nfcc_coex_testmode.h b/kernel/drivers/net/ieee802154/dw3000_nfcc_coex_testmode.h
deleted file mode 100644
index 10e5c90..0000000
--- a/kernel/drivers/net/ieee802154/dw3000_nfcc_coex_testmode.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * This file is part of the UWB stack for linux.
- *
- * Copyright (c) 2021 Qorvo US, Inc.
- *
- * This software is provided under the GNU General Public License, version 2
- * (GPLv2), as well as under a Qorvo commercial license.
- *
- * You may choose to use this software under the terms of the GPLv2 License,
- * version 2 ("GPLv2"), as published by the Free Software Foundation.
- * You should have received a copy of the GPLv2 along with this program. If
- * not, see <http://www.gnu.org/licenses/>.
- *
- * This program is distributed under the GPLv2 in the hope that it will be
- * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GPLv2 for more
- * details.
- *
- * If you cannot meet the requirements of the GPLv2, you may not use this
- * software for any purpose without first obtaining a commercial license from
- * Qorvo. Please contact Qorvo to inquire about licensing terms.
- */
-#ifndef __DW3000_NFCC_COEX_TESTMODE_H
-#define __DW3000_NFCC_COEX_TESTMODE_H
-
-#include <linux/module.h>
-
-/* Forward declaration. */
-struct dw3000;
-
-/**
- * struct dw3000_nfcc_coex_testmode_config - Test config used in testmode.
- */
-struct dw3000_nfcc_coex_testmode_config {
- /**
- * @mode: test mode identifier.
- */
- enum { DW3000_CCC_TEST_DIRECT,
- DW3000_CCC_TEST_WAIT,
- DW3000_CCC_TEST_LATE,
- DW3000_CCC_TEST_CONFLICT,
- DW3000_CCC_TEST_SLEEP_OFFSET,
- } mode;
- /**
- * @margin_ms: Delay in ms to apply after Ranging Round(RR).
- */
- u32 margin_ms;
- /**
- * @RRcount: Ranging Round count.
- */
- u32 RRcount;
- /**
- * @conflict_slot_idx: slot index with conflict on date.
- */
- u32 conflict_slot_idx;
- /**
- * @offset_ms: Duration in ms to add to NFCC base time;
- */
- u32 offset_ms;
- /**
- * @channel: Channel number.
- */
- u8 channel;
- /**
- * @session_time0: Offset in ms to add to SESSION_TIME0.
- */
- u32 session_time0;
- /**
- * @start: Start offset in ms for the first slot.
- */
- u32 start;
- /**
- * @end: End offset in ms for the first slot.
- */
- u32 end;
-};
-
-int dw3000_nfcc_coex_testmode_session(struct dw3000 *dw, u8 chan,
- u32 session_time0, u32 start, u32 end);
-int dw3000_nfcc_coex_testmode_config(
- struct dw3000 *dw,
- const struct dw3000_nfcc_coex_testmode_config *testmode_config);
-
-#endif /* __DW3000_NFCC_COEX_TESTMODE_H */
diff --git a/kernel/drivers/net/ieee802154/dw3000_stm.c b/kernel/drivers/net/ieee802154/dw3000_stm.c
index 0fb84b8..4b0f1cb 100644
--- a/kernel/drivers/net/ieee802154/dw3000_stm.c
+++ b/kernel/drivers/net/ieee802154/dw3000_stm.c
@@ -87,8 +87,8 @@ int dw3000_enqueue_generic(struct dw3000 *dw, struct dw3000_stm_command *cmd)
stm->pending_work |= work;
stm->generic_work = cmd;
wake_up_locked(&stm->work_wq);
- while (-ERESTARTSYS == wait_event_interruptible_locked_irq(stm->work_wq,
- !(stm->pending_work & work))) {}
+ wait_event_interruptible_locked_irq(stm->work_wq,
+ !(stm->pending_work & work));
spin_unlock_irqrestore(&stm->work_wq.lock, flags);
mutex_unlock(&stm->mtx);
return cmd->ret;
diff --git a/kernel/drivers/net/ieee802154/dw3000_testmode.c b/kernel/drivers/net/ieee802154/dw3000_testmode.c
index 3afb2a4..fea6360 100644
--- a/kernel/drivers/net/ieee802154/dw3000_testmode.c
+++ b/kernel/drivers/net/ieee802154/dw3000_testmode.c
@@ -29,7 +29,6 @@
#include "dw3000_trc.h"
#include "dw3000_testmode.h"
#include "dw3000_testmode_nl.h"
-#include "dw3000_nfcc_coex_testmode.h"
static const struct nla_policy dw3000_tm_policy[DW3000_TM_ATTR_MAX + 1] = {
[DW3000_TM_ATTR_CMD] = { .type = NLA_U32 },
@@ -40,14 +39,6 @@ static const struct nla_policy dw3000_tm_policy[DW3000_TM_ATTR_MAX + 1] = {
[DW3000_TM_ATTR_OTP_ADDR] = { .type = NLA_U16 },
[DW3000_TM_ATTR_OTP_VAL] = { .type = NLA_U32 },
[DW3000_TM_ATTR_OTP_DONE] = { .type = NLA_U8 },
- [DW3000_TM_ATTR_CCC_TIME0] = { .type = NLA_U32 },
- [DW3000_TM_ATTR_CCC_CHANNEL] = { .type = NLA_U8 },
- [DW3000_TM_ATTR_CCC_TSTART] = { .type = NLA_U32 },
- [DW3000_TM_ATTR_CCC_TEND] = { .type = NLA_U32 },
- [DW3000_TM_ATTR_CCC_MARGIN_MS] = { .type = NLA_U32 },
- [DW3000_TM_ATTR_CCC_RR_COUNT] = { .type = NLA_U32 },
- [DW3000_TM_ATTR_CCC_OFFSET_MS] = { .type = NLA_U32 },
- [DW3000_TM_ATTR_CCC_CONFLICT_SLOT_IDX] = { .type = NLA_U32 },
[DW3000_TM_ATTR_DEEP_SLEEP_DELAY_MS] = { .type = NLA_U32 },
[DW3000_TM_ATTR_CONTTX_FRAME_LENGHT] = { .type = NLA_U32 },
[DW3000_TM_ATTR_CONTTX_RATE] = { .type = NLA_U32 },
@@ -258,318 +249,6 @@ nla_put_failure:
return rc;
}
-/* helper function for common CCC command returning their rc code */
-static int tm_ccc_cmd_done(struct dw3000 *dw, struct mcps802154_llhw *llhw,
- u8 ccc_cmd_rc)
-{
- struct sk_buff *msg;
- int rc;
-
- msg = mcps802154_testmode_alloc_reply_skb(llhw, 2 * sizeof(u32));
- if (!msg) {
- dev_err(dw->dev, "failed to alloc skb reply\n");
- return -ENOMEM;
- }
-
- /* Append ccc cmd rc to the netlink message */
- rc = nla_put_u8(msg, DW3000_TM_ATTR_CCC_CMD_RC, ccc_cmd_rc);
- if (rc) {
- dev_err(dw->dev, "failed to put testmode ccc cmd rc: %d\n", rc);
- goto nla_put_failure;
- }
- return mcps802154_testmode_reply(llhw, msg);
-
-nla_put_failure:
- nlmsg_free(msg);
- return rc;
-}
-
-static int do_tm_cmd_ccc_start(struct dw3000 *dw, const void *in, void *out)
-{
- const struct do_tm_cmd_params *params = in;
- u8 channel;
- u32 session_time0;
- u32 start = 0;
- u32 end = 0;
- u8 ccc_cmd_rc;
-
- /* Verify the ccc channel attribute exists */
- if (!params->nl_attr[DW3000_TM_ATTR_CCC_CHANNEL])
- return -EINVAL;
- channel = nla_get_u8(params->nl_attr[DW3000_TM_ATTR_CCC_CHANNEL]);
-
- /* Verify the ccc time0 attribute exists */
- if (!params->nl_attr[DW3000_TM_ATTR_CCC_TIME0])
- return -EINVAL;
- session_time0 = nla_get_u32(params->nl_attr[DW3000_TM_ATTR_CCC_TIME0]);
-
- if (params->nl_attr[DW3000_TM_ATTR_CCC_TSTART] &&
- params->nl_attr[DW3000_TM_ATTR_CCC_TEND]) {
- start = nla_get_u32(params->nl_attr[DW3000_TM_ATTR_CCC_TSTART]);
- end = nla_get_u32(params->nl_attr[DW3000_TM_ATTR_CCC_TEND]);
- }
-
- if (dw3000_nfcc_coex_testmode_session(dw, channel, session_time0, start,
- end))
- ccc_cmd_rc = 0;
- else
- ccc_cmd_rc = 1;
-
- return tm_ccc_cmd_done(dw, params->llhw, ccc_cmd_rc);
-}
-
-static int do_tm_cmd_ccc_test_scratch(struct dw3000 *dw, const void *in,
- void *out)
-{
- const struct do_tm_cmd_params *params = in;
- u8 ccc_cmd_rc;
-
- /* TODO: write to the whole memory, read back, validate */
- ccc_cmd_rc = 1;
-
- return tm_ccc_cmd_done(dw, params->llhw, ccc_cmd_rc);
-}
-
-static int do_tm_cmd_ccc_test_spi1(struct dw3000 *dw, const void *in, void *out)
-{
- const struct do_tm_cmd_params *params = in;
- u8 ccc_cmd_rc;
-
- /**
- * TODO: test SPI1
- * - enable SPI1
- * - check SPI1 is enabled
- * - release SPI1
- * - check SPI1 is disabled
- */
- ccc_cmd_rc = 1;
-
- return tm_ccc_cmd_done(dw, params->llhw, ccc_cmd_rc);
-}
-
-static int do_tm_cmd_ccc_test_spi2(struct dw3000 *dw, const void *in, void *out)
-{
- const struct do_tm_cmd_params *params = in;
- u8 ccc_cmd_rc;
-
- /**
- * TODO: test SPI2
- * - enable SPI2
- * - wait for release (from other side code or watchdog?)
- */
- ccc_cmd_rc = 1;
-
- return tm_ccc_cmd_done(dw, params->llhw, ccc_cmd_rc);
-}
-
-static int do_tm_cmd_ccc_test_direct(struct dw3000 *dw, const void *in,
- void *out)
-{
- const struct do_tm_cmd_params *params = in;
- u8 ccc_cmd_rc;
- static struct dw3000_nfcc_coex_testmode_config conf = {
- .mode = DW3000_CCC_TEST_DIRECT,
- .start = 0,
- .end = 0,
- };
-
- /* Verify the ccc channel attribute exists */
- if (!params->nl_attr[DW3000_TM_ATTR_CCC_CHANNEL])
- return -EINVAL;
- conf.channel = nla_get_u8(params->nl_attr[DW3000_TM_ATTR_CCC_CHANNEL]);
-
- /* Verify the ccc time0 attribute exists */
- if (!params->nl_attr[DW3000_TM_ATTR_CCC_TIME0])
- return -EINVAL;
- conf.session_time0 =
- nla_get_u32(params->nl_attr[DW3000_TM_ATTR_CCC_TIME0]);
-
- if (dw3000_nfcc_coex_testmode_config(dw, &conf))
- ccc_cmd_rc = 0;
- else
- ccc_cmd_rc = 1;
-
- return tm_ccc_cmd_done(dw, params->llhw, ccc_cmd_rc);
-}
-
-static int do_tm_cmd_ccc_test_wait(struct dw3000 *dw, const void *in, void *out)
-{
- const struct do_tm_cmd_params *params = in;
- u8 ccc_cmd_rc;
- static struct dw3000_nfcc_coex_testmode_config conf = {
- .mode = DW3000_CCC_TEST_WAIT,
- .margin_ms = 0,
- .start = 0,
- .end = 0,
- };
-
- /* Verify the ccc channel attribute exists */
- if (!params->nl_attr[DW3000_TM_ATTR_CCC_CHANNEL])
- return -EINVAL;
- conf.channel = nla_get_u8(params->nl_attr[DW3000_TM_ATTR_CCC_CHANNEL]);
-
- /* Verify the ccc time0 attribute exists */
- if (!params->nl_attr[DW3000_TM_ATTR_CCC_TIME0])
- return -EINVAL;
- conf.session_time0 =
- nla_get_u32(params->nl_attr[DW3000_TM_ATTR_CCC_TIME0]);
-
- /* margin_ms is optional */
- if (params->nl_attr[DW3000_TM_ATTR_CCC_MARGIN_MS])
- conf.margin_ms = nla_get_u32(
- params->nl_attr[DW3000_TM_ATTR_CCC_MARGIN_MS]);
-
- if (dw3000_nfcc_coex_testmode_config(dw, &conf))
- ccc_cmd_rc = 0;
- else
- ccc_cmd_rc = 1;
-
- return tm_ccc_cmd_done(dw, params->llhw, ccc_cmd_rc);
-}
-
-static int do_tm_cmd_ccc_test_late(struct dw3000 *dw, const void *in, void *out)
-{
- const struct do_tm_cmd_params *params = in;
- u8 ccc_cmd_rc;
- static struct dw3000_nfcc_coex_testmode_config conf = {
- .mode = DW3000_CCC_TEST_LATE,
- .margin_ms = 0,
- .RRcount = 0,
- .start = 0,
- .end = 0,
- };
-
- /* Verify the ccc channel attribute exists */
- if (!params->nl_attr[DW3000_TM_ATTR_CCC_CHANNEL])
- return -EINVAL;
- conf.channel = nla_get_u8(params->nl_attr[DW3000_TM_ATTR_CCC_CHANNEL]);
-
- /* Verify the ccc time0 attribute exists */
- if (!params->nl_attr[DW3000_TM_ATTR_CCC_TIME0])
- return -EINVAL;
- conf.session_time0 =
- nla_get_u32(params->nl_attr[DW3000_TM_ATTR_CCC_TIME0]);
-
- /* margin_ms is mandatory */
- if (!params->nl_attr[DW3000_TM_ATTR_CCC_MARGIN_MS])
- return -EINVAL;
- conf.margin_ms =
- nla_get_u32(params->nl_attr[DW3000_TM_ATTR_CCC_MARGIN_MS]);
-
- /* RRcount is optional */
- if (params->nl_attr[DW3000_TM_ATTR_CCC_RR_COUNT])
- conf.RRcount = nla_get_u32(
- params->nl_attr[DW3000_TM_ATTR_CCC_RR_COUNT]);
-
- if (dw3000_nfcc_coex_testmode_config(dw, &conf))
- ccc_cmd_rc = 0;
- else
- ccc_cmd_rc = 1;
-
- return tm_ccc_cmd_done(dw, params->llhw, ccc_cmd_rc);
-}
-
-static int do_tm_cmd_ccc_test_conflict(struct dw3000 *dw, const void *in,
- void *out)
-{
- const struct do_tm_cmd_params *params = in;
- u8 ccc_cmd_rc;
- static struct dw3000_nfcc_coex_testmode_config conf = {
- .mode = DW3000_CCC_TEST_CONFLICT,
- .RRcount = 0,
- .start = 0,
- .end = 0,
- };
-
- /* Verify the ccc channel attribute exists */
- if (!params->nl_attr[DW3000_TM_ATTR_CCC_CHANNEL])
- return -EINVAL;
- conf.channel = nla_get_u8(params->nl_attr[DW3000_TM_ATTR_CCC_CHANNEL]);
-
- /* Verify the ccc time0 attribute exists */
- if (!params->nl_attr[DW3000_TM_ATTR_CCC_TIME0])
- return -EINVAL;
- conf.session_time0 =
- nla_get_u32(params->nl_attr[DW3000_TM_ATTR_CCC_TIME0]);
-
- /* conflict_slot_idx is mandatory */
- if (!params->nl_attr[DW3000_TM_ATTR_CCC_CONFLICT_SLOT_IDX])
- return -EINVAL;
- conf.conflict_slot_idx = nla_get_u32(
- params->nl_attr[DW3000_TM_ATTR_CCC_CONFLICT_SLOT_IDX]);
-
- /* RRcount is optional */
- if (params->nl_attr[DW3000_TM_ATTR_CCC_RR_COUNT])
- conf.RRcount = nla_get_u32(
- params->nl_attr[DW3000_TM_ATTR_CCC_RR_COUNT]);
-
- if (dw3000_nfcc_coex_testmode_config(dw, &conf))
- ccc_cmd_rc = 0;
- else
- ccc_cmd_rc = 1;
-
- return tm_ccc_cmd_done(dw, params->llhw, ccc_cmd_rc);
-}
-
-static int do_tm_cmd_ccc_test_offset(struct dw3000 *dw, const void *in,
- void *out)
-{
- const struct do_tm_cmd_params *params = in;
- u8 ccc_cmd_rc;
- static struct dw3000_nfcc_coex_testmode_config conf = {
- .mode = DW3000_CCC_TEST_SLEEP_OFFSET,
- .offset_ms = 0,
- .start = 0,
- .end = 0,
- };
-
- /* Verify the ccc channel attribute exists */
- if (!params->nl_attr[DW3000_TM_ATTR_CCC_CHANNEL])
- return -EINVAL;
- conf.channel = nla_get_u8(params->nl_attr[DW3000_TM_ATTR_CCC_CHANNEL]);
-
- /* Verify the ccc time0 attribute exists */
- if (!params->nl_attr[DW3000_TM_ATTR_CCC_TIME0])
- return -EINVAL;
- conf.session_time0 =
- nla_get_u32(params->nl_attr[DW3000_TM_ATTR_CCC_TIME0]);
-
- /* offset_ms is mandatory */
- if (!params->nl_attr[DW3000_TM_ATTR_CCC_OFFSET_MS])
- return -EINVAL;
- conf.offset_ms =
- nla_get_u32(params->nl_attr[DW3000_TM_ATTR_CCC_OFFSET_MS]);
- if (dw3000_nfcc_coex_testmode_config(dw, &conf))
- ccc_cmd_rc = 0;
- else
- ccc_cmd_rc = 1;
-
- return tm_ccc_cmd_done(dw, params->llhw, ccc_cmd_rc);
-}
-
-static int do_tm_cmd_ccc_read_tlvs(struct dw3000 *dw, const void *in, void *out)
-{
- const struct do_tm_cmd_params *params = in;
- u8 ccc_cmd_rc;
-
- /* TODO: read tlvs values */
- ccc_cmd_rc = 1;
-
- return tm_ccc_cmd_done(dw, params->llhw, ccc_cmd_rc);
-}
-
-static int do_tm_cmd_ccc_write_tlvs(struct dw3000 *dw, const void *in,
- void *out)
-{
- const struct do_tm_cmd_params *params = in;
- u8 ccc_cmd_rc;
-
- /* TODO: write tlvs values */
- ccc_cmd_rc = 1;
-
- return tm_ccc_cmd_done(dw, params->llhw, ccc_cmd_rc);
-}
-
static int do_tm_cmd_deep_sleep(struct dw3000 *dw, const void *in, void *out)
{
const struct do_tm_cmd_params *params = in;
@@ -647,17 +326,6 @@ int dw3000_tm_cmd(struct mcps802154_llhw *llhw, void *data, int len)
[DW3000_TM_CMD_STOP_TX_CWTONE] = do_tm_cmd_stop_tx_cwtone,
[DW3000_TM_CMD_START_CONTINUOUS_TX] = do_tm_cmd_start_cont_tx,
[DW3000_TM_CMD_STOP_CONTINUOUS_TX] = do_tm_cmd_stop_cont_tx,
- [DW3000_TM_CMD_CCC_START] = do_tm_cmd_ccc_start,
- [DW3000_TM_CMD_CCC_TEST_SCRATCH] = do_tm_cmd_ccc_test_scratch,
- [DW3000_TM_CMD_CCC_TEST_SPI1] = do_tm_cmd_ccc_test_spi1,
- [DW3000_TM_CMD_CCC_TEST_SPI2] = do_tm_cmd_ccc_test_spi2,
- [DW3000_TM_CMD_CCC_READ_TLVS] = do_tm_cmd_ccc_read_tlvs,
- [DW3000_TM_CMD_CCC_WRITE_TLVS] = do_tm_cmd_ccc_write_tlvs,
- [DW3000_TM_CMD_CCC_TEST_DIRECT] = do_tm_cmd_ccc_test_direct,
- [DW3000_TM_CMD_CCC_TEST_WAIT] = do_tm_cmd_ccc_test_wait,
- [DW3000_TM_CMD_CCC_TEST_LATE] = do_tm_cmd_ccc_test_late,
- [DW3000_TM_CMD_CCC_TEST_CONFLICT] = do_tm_cmd_ccc_test_conflict,
- [DW3000_TM_CMD_CCC_TEST_OFFSET] = do_tm_cmd_ccc_test_offset,
[DW3000_TM_CMD_DEEP_SLEEP] = do_tm_cmd_deep_sleep,
};
u32 tm_cmd;
diff --git a/kernel/drivers/net/ieee802154/dw3000_testmode_nl.h b/kernel/drivers/net/ieee802154/dw3000_testmode_nl.h
index 68d4c81..0fa1495 100644
--- a/kernel/drivers/net/ieee802154/dw3000_testmode_nl.h
+++ b/kernel/drivers/net/ieee802154/dw3000_testmode_nl.h
@@ -61,15 +61,6 @@ enum dw3000_tm_attr {
DW3000_TM_ATTR_OTP_ADDR,
DW3000_TM_ATTR_OTP_VAL,
DW3000_TM_ATTR_OTP_DONE,
- DW3000_TM_ATTR_CCC_TIME0,
- DW3000_TM_ATTR_CCC_CHANNEL,
- DW3000_TM_ATTR_CCC_TSTART,
- DW3000_TM_ATTR_CCC_TEND,
- DW3000_TM_ATTR_CCC_MARGIN_MS,
- DW3000_TM_ATTR_CCC_RR_COUNT,
- DW3000_TM_ATTR_CCC_OFFSET_MS,
- DW3000_TM_ATTR_CCC_CONFLICT_SLOT_IDX,
- DW3000_TM_ATTR_CCC_CMD_RC,
DW3000_TM_ATTR_DEEP_SLEEP_DELAY_MS,
DW3000_TM_ATTR_CONTTX_FRAME_LENGHT,
DW3000_TM_ATTR_CONTTX_RATE,
@@ -98,7 +89,7 @@ enum dw3000_tm_cmd {
DW3000_TM_CMD_START_CONTINUOUS_TX,
DW3000_TM_CMD_STOP_CONTINUOUS_TX,
- /* CCC NFCC/AP coexistence test commands */
+ /* TODO: CCC enum could be remove, as their are no more used. */
DW3000_TM_CMD_CCC_START,
DW3000_TM_CMD_CCC_TEST_SCRATCH,
DW3000_TM_CMD_CCC_TEST_SPI1,
diff --git a/kernel/drivers/net/ieee802154/dw3000_trc.h b/kernel/drivers/net/ieee802154/dw3000_trc.h
index ffd42f0..a69ab40 100644
--- a/kernel/drivers/net/ieee802154/dw3000_trc.h
+++ b/kernel/drivers/net/ieee802154/dw3000_trc.h
@@ -30,6 +30,7 @@
#include "dw3000.h"
#include "dw3000_nfcc_coex.h"
+#include "dw3000_nfcc_coex_msg.h"
#include "dw3000_testmode_nl.h"
#include "dw3000_core_reg.h"
#include "dw3000_core.h"
@@ -248,6 +249,33 @@ TRACE_DEFINE_ENUM(DW3000_PWR_TX);
#define TX_FRAME_INFO_FLAGS_PR_ARG \
__print_flags(__entry->flags, "|", TX_FRAME_INFO_FLAGS)
+#define dw3000_nfcc_coex_tlv_type_name(name) \
+ { \
+ DW3000_NFCC_COEX_TLV_TYPE_##name, #name \
+ }
+
+#define DW3000_NFCC_COEX_TLV_TYPE_ENTRY \
+ __field(enum dw3000_nfcc_coex_tlv_type, type)
+#define DW3000_NFCC_COEX_TLV_TYPE_ASSIGN __entry->type = type
+#define DW3000_NFCC_COEX_TLV_TYPE_PR_FMT "type: %s"
+/* clang-format off */
+#define DW3000_NFCC_COEX_TLV_TYPE_SYMBOLS \
+ dw3000_nfcc_coex_tlv_type_name(UNSPEC), \
+ dw3000_nfcc_coex_tlv_type_name(SESSION_TIME0), \
+ dw3000_nfcc_coex_tlv_type_name(SLOT_LIST), \
+ dw3000_nfcc_coex_tlv_type_name(TLV_UWBCNT_OFFS), \
+ dw3000_nfcc_coex_tlv_type_name(ERROR), \
+ dw3000_nfcc_coex_tlv_type_name(SLOT_LIST_UUS)
+/* clang-format on */
+TRACE_DEFINE_ENUM(DW3000_NFCC_COEX_TLV_TYPE_UNSPEC);
+TRACE_DEFINE_ENUM(DW3000_NFCC_COEX_TLV_TYPE_SESSION_TIME0);
+TRACE_DEFINE_ENUM(DW3000_NFCC_COEX_TLV_TYPE_SLOT_LIST);
+TRACE_DEFINE_ENUM(DW3000_NFCC_COEX_TLV_TYPE_TLV_UWBCNT_OFFS);
+TRACE_DEFINE_ENUM(DW3000_NFCC_COEX_TLV_TYPE_ERROR);
+TRACE_DEFINE_ENUM(DW3000_NFCC_COEX_TLV_TYPE_SLOT_LIST_UUS);
+#define DW3000_NFCC_COEX_TLV_TYPE_ARG \
+ __print_symbolic(__entry->type, DW3000_NFCC_COEX_TLV_TYPE_SYMBOLS)
+
/* We don't want clang-format to modify the following events definition!
Look at net/wireless/trace.h for the required format. */
/* clang-format off */
@@ -284,7 +312,7 @@ TRACE_EVENT(dw3000_return_int,
DW_ASSIGN;
__entry->ret = ret;
),
- TP_printk(DW_PR_FMT ", return %d", DW_PR_ARG, __entry->ret)
+ TP_printk(DW_PR_FMT ", return: %d", DW_PR_ARG, __entry->ret)
);
TRACE_EVENT(dw3000_return_int_u32,
@@ -300,7 +328,7 @@ TRACE_EVENT(dw3000_return_int_u32,
__entry->ret = ret;
__entry->val = val;
),
- TP_printk(DW_PR_FMT ", return %d, value %#x", DW_PR_ARG,
+ TP_printk(DW_PR_FMT ", return: %d, value: 0x%x", DW_PR_ARG,
__entry->ret, __entry->val)
);
@@ -317,7 +345,7 @@ TRACE_EVENT(dw3000_return_int_u64,
__entry->ret = ret;
__entry->val = val;
),
- TP_printk(DW_PR_FMT ", return %d, value %#llx", DW_PR_ARG,
+ TP_printk(DW_PR_FMT ", return: %d, value: 0x%llx", DW_PR_ARG,
__entry->ret, __entry->val)
);
@@ -352,6 +380,24 @@ TRACE_EVENT(dw3000_mcps_tx_frame,
DW_PR_ARG, TX_FRAME_INFO_FLAGS_PR_ARG,__entry->len)
);
+TRACE_EVENT(dw3000_mcps_tx_frame_too_late,
+ TP_PROTO(struct dw3000 *dw, u32 tx_date_dtu, u32 cur_time_dtu),
+ TP_ARGS(dw, tx_date_dtu, cur_time_dtu),
+ TP_STRUCT__entry(
+ DW_ENTRY
+ __field(u32, tx_date_dtu)
+ __field(u32, cur_time_dtu)
+ ),
+ TP_fast_assign(
+ DW_ASSIGN;
+ __entry->tx_date_dtu = tx_date_dtu;
+ __entry->cur_time_dtu = cur_time_dtu;
+ ),
+ TP_printk(DW_PR_FMT ", cannot program delayed, tx_date_dtu: 0x%x"
+ ", cur_time_dtu: 0x%x", DW_PR_ARG, __entry->tx_date_dtu,
+ __entry->cur_time_dtu)
+);
+
TRACE_EVENT(dw3000_mcps_rx_enable,
TP_PROTO(struct dw3000 *dw, u8 flags, int timeout),
TP_ARGS(dw, flags, timeout),
@@ -369,6 +415,23 @@ TRACE_EVENT(dw3000_mcps_rx_enable,
DW_PR_ARG, RX_INFO_FLAGS_PR_ARG, __entry->timeout)
);
+TRACE_EVENT(dw3000_mcps_rx_enable_too_late,
+ TP_PROTO(struct dw3000 *dw, u32 rx_date_dtu, u32 cur_time_dtu),
+ TP_ARGS(dw, rx_date_dtu, cur_time_dtu),
+ TP_STRUCT__entry(
+ DW_ENTRY
+ __field(u32, rx_date_dtu)
+ __field(u32, cur_time_dtu)
+ ),
+ TP_fast_assign(
+ DW_ASSIGN;
+ __entry->rx_date_dtu = rx_date_dtu;
+ __entry->cur_time_dtu = cur_time_dtu;
+ ),
+ TP_printk(DW_PR_FMT ", too late to program delayed, rx_date_dtu: 0x%x, current_dtu: 0x%x",
+ DW_PR_ARG, __entry->rx_date_dtu, __entry->cur_time_dtu)
+);
+
DEFINE_EVENT(dw_only_evt, dw3000_mcps_rx_disable,
TP_PROTO(struct dw3000 *dw),
TP_ARGS(dw)
@@ -573,6 +636,21 @@ TRACE_EVENT(dw3000_isr,
DW_PR_ARG, DW3000_SYS_STATUS_FLAGS_PR_ARG)
);
+TRACE_EVENT(dw3000_check_idlerc,
+ TP_PROTO(struct dw3000 *dw, u32 low_sys_status),
+ TP_ARGS(dw, low_sys_status),
+ TP_STRUCT__entry(
+ DW_ENTRY
+ __field(u32, low_sys_status)
+ ),
+ TP_fast_assign(
+ DW_ASSIGN;
+ __entry->low_sys_status = low_sys_status;
+ ),
+ TP_printk(DW_PR_FMT ", low_sys_status: 0x%08x",
+ DW_PR_ARG, __entry->low_sys_status)
+);
+
TRACE_EVENT(dw3000_set_operational_state,
TP_PROTO(struct dw3000 *dw, enum operational_state operational_state),
TP_ARGS(dw, operational_state),
@@ -862,8 +940,8 @@ TRACE_EVENT(dw3000_rx_rssi,
__entry->prf_64mhz = prf_64mhz;
__entry->dgc_dec = dgc_dec;
),
- TP_printk(DW_PR_FMT ", chip: %s sts: %u cir_pwr: %u pacc_cnt: %u"
- " prf_64mhz: %u dgc_dec: %u",
+ TP_printk(DW_PR_FMT ", chip: %s, sts: %u, cir_pwr: %u, pacc_cnt: %u"
+ ", prf_64mhz: %u, dgc_dec: %u",
DW_PR_ARG, __entry->chip_name, __entry->sts,
__entry->cir_pwr, __entry->pacc_cnt, __entry->prf_64mhz,
__entry->dgc_dec)
@@ -880,7 +958,7 @@ TRACE_EVENT(dw3000_nfcc_coex_isr,
DW_ASSIGN;
__entry->dss_stat = dss_stat;
),
- TP_printk(DW_PR_FMT ", dss_stat=%#x", DW_PR_ARG, __entry->dss_stat)
+ TP_printk(DW_PR_FMT ", dss_stat: 0x%x", DW_PR_ARG, __entry->dss_stat)
);
TRACE_EVENT(dw3000_nfcc_coex_sleep,
@@ -894,7 +972,24 @@ TRACE_EVENT(dw3000_nfcc_coex_sleep,
DW_ASSIGN;
__entry->sleep_dtu = sleep_dtu;
),
- TP_printk(DW_PR_FMT ", sleep_dtu=%u", DW_PR_ARG, __entry->sleep_dtu)
+ TP_printk(DW_PR_FMT ", sleep_dtu: 0x%08x", DW_PR_ARG, __entry->sleep_dtu)
+);
+
+TRACE_EVENT(dw3000_nfcc_coex_header_put,
+ TP_PROTO(struct dw3000 *dw, u8 ver_id, u8 seq_num),
+ TP_ARGS(dw, ver_id, seq_num),
+ TP_STRUCT__entry(
+ DW_ENTRY
+ __field(u8, ver_id)
+ __field(u8, seq_num)
+ ),
+ TP_fast_assign(
+ DW_ASSIGN;
+ __entry->ver_id = ver_id;
+ __entry->seq_num = seq_num;
+ ),
+ TP_printk(DW_PR_FMT ", ver_id: %u, seq_num: %u", DW_PR_ARG,
+ __entry->ver_id, __entry->seq_num)
);
TRACE_EVENT(dw3000_nfcc_coex_clock_sync_payload_put,
@@ -908,7 +1003,7 @@ TRACE_EVENT(dw3000_nfcc_coex_clock_sync_payload_put,
DW_ASSIGN;
__entry->session_time0_sys_time = session_time0_sys_time;
),
- TP_printk(DW_PR_FMT ", session_time0_sys_time=%#08x", DW_PR_ARG,
+ TP_printk(DW_PR_FMT ", session_time0_sys_time: 0x%08x", DW_PR_ARG,
__entry->session_time0_sys_time)
);
@@ -923,28 +1018,27 @@ TRACE_EVENT(dw3000_nfcc_coex_clock_offset_payload_put,
DW_ASSIGN;
__entry->clock_offset_sys_time = clock_offset_sys_time;
),
- TP_printk(DW_PR_FMT ", clock_offset_sys_time=%#08x", DW_PR_ARG,
+ TP_printk(DW_PR_FMT ", clock_offset_sys_time: 0x%08x", DW_PR_ARG,
__entry->clock_offset_sys_time)
);
TRACE_EVENT(dw3000_nfcc_coex_rx_msg_info,
- TP_PROTO(struct dw3000 *dw, u32 next_timestamp_sys_time,
- int next_duration_sys_time),
- TP_ARGS(dw, next_timestamp_sys_time, next_duration_sys_time),
+ TP_PROTO(struct dw3000 *dw, u32 next_timestamp_dtu,
+ int next_duration_dtu),
+ TP_ARGS(dw, next_timestamp_dtu, next_duration_dtu),
TP_STRUCT__entry(
DW_ENTRY
- __field(u32, next_timestamp_sys_time)
- __field(int, next_duration_sys_time)
+ __field(u32, next_timestamp_dtu)
+ __field(int, next_duration_dtu)
),
TP_fast_assign(
DW_ASSIGN;
- __entry->next_timestamp_sys_time = next_timestamp_sys_time;
- __entry->next_duration_sys_time = next_duration_sys_time;
+ __entry->next_timestamp_dtu = next_timestamp_dtu;
+ __entry->next_duration_dtu = next_duration_dtu;
),
- TP_printk(DW_PR_FMT ", next_timestamp_sys_time=%#08x"
- ", next_duration_sys_time=%#08x", DW_PR_ARG,
- __entry->next_timestamp_sys_time,
- __entry->next_duration_sys_time)
+ TP_printk(DW_PR_FMT ", next_timestamp_dtu: 0x%08x"
+ ", next_duration_dtu: 0x%08x", DW_PR_ARG,
+ __entry->next_timestamp_dtu, __entry->next_duration_dtu)
);
TRACE_EVENT(dw3000_nfcc_coex_header_check,
@@ -966,11 +1060,56 @@ TRACE_EVENT(dw3000_nfcc_coex_header_check,
__entry->seq_num = seq_num;
__entry->nb_tlv = nb_tlv;
),
- TP_printk(DW_PR_FMT ", signature=%s, ver_id=%u, seq_num=%u, nb_tlv=%u", DW_PR_ARG,
- __print_array(__entry->signature, DW3000_NFCC_COEX_SIGNATURE_LEN, sizeof(u8)),
+ TP_printk(DW_PR_FMT ", signature: %s, ver_id: %u, seq_num: %u"
+ ", nb_tlv: %u", DW_PR_ARG,
+ __print_array(__entry->signature,
+ DW3000_NFCC_COEX_SIGNATURE_LEN, sizeof(u8)),
__entry->ver_id, __entry->seq_num, __entry->nb_tlv)
);
+TRACE_EVENT(dw3000_nfcc_coex_tlv_check,
+ TP_PROTO(struct dw3000 *dw, enum dw3000_nfcc_coex_tlv_type type,
+ u8 len, const u8 *data),
+ TP_ARGS(dw, type, len, data),
+ TP_STRUCT__entry(
+ DW_ENTRY
+ DW3000_NFCC_COEX_TLV_TYPE_ENTRY
+ __dynamic_array(u8, data, len)
+ ),
+ TP_fast_assign(
+ DW_ASSIGN;
+ DW3000_NFCC_COEX_TLV_TYPE_ASSIGN;
+ memcpy(__get_dynamic_array(data), data,
+ __get_dynamic_array_len(data));
+ ),
+ TP_printk(DW_PR_FMT ", " DW3000_NFCC_COEX_TLV_TYPE_PR_FMT ", data: %s",
+ DW_PR_ARG, DW3000_NFCC_COEX_TLV_TYPE_ARG,
+ __print_hex(__get_dynamic_array(data), __get_dynamic_array_len(data)))
+);
+
+TRACE_EVENT(dw3000_nfcc_coex_handle_access,
+ TP_PROTO(struct dw3000 *dw, const struct dw3000_vendor_cmd_nfcc_coex_handle_access *info),
+ TP_ARGS(dw, info),
+ TP_STRUCT__entry(
+ DW_ENTRY
+ __field(bool, start)
+ __field(u32, timestamp_dtu)
+ __field(int, duration_dtu)
+ __field(int, chan)
+ ),
+ TP_fast_assign(
+ DW_ASSIGN;
+ __entry->start = info->start;
+ __entry->timestamp_dtu = info->timestamp_dtu;
+ __entry->duration_dtu = info->duration_dtu;
+ __entry->chan = info->chan;
+ ),
+ TP_printk(DW_PR_FMT ", start: %s, timestamp_dtu: 0x%08x"
+ ", duration_dtu: 0x%08x, chan: %d", DW_PR_ARG,
+ __entry->start ? "true" : "false", __entry->timestamp_dtu,
+ __entry->duration_dtu, __entry->chan)
+);
+
TRACE_EVENT(dw3000_nfcc_coex_err,
TP_PROTO(struct dw3000 *dw, const char *err),
TP_ARGS(dw, err),
@@ -982,7 +1121,7 @@ TRACE_EVENT(dw3000_nfcc_coex_err,
DW_ASSIGN;
__assign_str(err, err);
),
- TP_printk(DW_PR_FMT ", err=\"%s\"", DW_PR_ARG, __get_str(err))
+ TP_printk(DW_PR_FMT ", err: \"%s\"", DW_PR_ARG, __get_str(err))
);
TRACE_EVENT(dw3000_nfcc_coex_warn,
@@ -996,7 +1135,7 @@ TRACE_EVENT(dw3000_nfcc_coex_warn,
DW_ASSIGN;
__assign_str(warn, warn);
),
- TP_printk(DW_PR_FMT ", warn=\"%s\"", DW_PR_ARG, __get_str(warn))
+ TP_printk(DW_PR_FMT ", warn: \"%s\"", DW_PR_ARG, __get_str(warn))
);
DEFINE_EVENT(dw_only_evt, dw3000_nfcc_coex_watchdog,
@@ -1015,7 +1154,7 @@ TRACE_EVENT(dw3000_nfcc_coex_enable,
DW_ASSIGN;
__entry->channel = channel;
),
- TP_printk(DW_PR_FMT ", channel=%d", DW_PR_ARG, __entry->channel)
+ TP_printk(DW_PR_FMT ", channel: %d", DW_PR_ARG, __entry->channel)
);
DEFINE_EVENT(dw_only_evt, dw3000_nfcc_coex_disable,
@@ -1056,7 +1195,7 @@ TRACE_EVENT(dw3000_set_pdoa,
DW_ASSIGN;
__entry->mode = mode;
),
- TP_printk(DW_PR_FMT " Set PDoA mode to %d", DW_PR_ARG,
+ TP_printk(DW_PR_FMT ", mode: %d", DW_PR_ARG,
__entry->mode)
);
@@ -1071,7 +1210,7 @@ TRACE_EVENT(dw3000_read_pdoa,
DW_ASSIGN;
__entry->pdoa = pdoa;
),
- TP_printk(DW_PR_FMT " pdoa=%#08x", DW_PR_ARG,
+ TP_printk(DW_PR_FMT ", pdoa: 0x%08x", DW_PR_ARG,
__entry->pdoa)
);
@@ -1090,7 +1229,7 @@ TRACE_EVENT(dw3000_testmode_continuous_tx_start,
__entry->len = len;
__entry->rate = rate;
),
- TP_printk(DW_PR_FMT " chan=%d, len=%d, rate=%d", DW_PR_ARG,
+ TP_printk(DW_PR_FMT ", chan: %d, len: %d, rate: %d", DW_PR_ARG,
__entry->chan,
__entry->len,
__entry->rate)
@@ -1119,7 +1258,7 @@ TRACE_EVENT(dw3000_read_clockoffset,
DW_ASSIGN;
__entry->cfo = cfo;
),
- TP_printk(DW_PR_FMT " clockoffset=%d", DW_PR_ARG,
+ TP_printk(DW_PR_FMT ", clockoffset: %d", DW_PR_ARG,
__entry->cfo)
);
diff --git a/kernel/net/mcps802154/fira_trace.h b/kernel/net/mcps802154/fira_trace.h
index 4edab7e..0005946 100644
--- a/kernel/net/mcps802154/fira_trace.h
+++ b/kernel/net/mcps802154/fira_trace.h
@@ -123,6 +123,7 @@ TRACE_EVENT(region_fira_session_params,
__field(int, initiation_time_ms)
__field(int, slot_duration_dtu)
__field(int, block_duration_dtu)
+ __field(int, block_stride_len)
__field(int, round_duration_slots)
__field(bool, round_hopping)
__field(int, priority)
@@ -155,6 +156,7 @@ TRACE_EVENT(region_fira_session_params,
__entry->initiation_time_ms = params->initiation_time_ms;
__entry->slot_duration_dtu = params->slot_duration_dtu;
__entry->block_duration_dtu = params->block_duration_dtu;
+ __entry->block_stride_len = params->block_stride_len;
__entry->round_duration_slots = params->round_duration_slots;
__entry->round_hopping = params->round_hopping;
__entry->priority = params->priority;
@@ -180,7 +182,7 @@ TRACE_EVENT(region_fira_session_params,
),
TP_printk(FIRA_SESSION_PR_FMT " device_type=%s ranging_round_usage=%s multi_node_mode=%s "
"controller_short_addr=0x%x initiation_time_ms=%d slot_duration_dtu=%d "
- "block_duration_dtu=%d round_duration_slots=%d round_hopping=%d "
+ "block_duration_dtu=%d block_stride_len=%d round_duration_slots=%d round_hopping=%d "
"priority=%d channel_number=%d preamble_code_index=%d rframe_config=%s "
"preamble_duration=%s sfd_id=%d psdu_data_rate=%s mac_fcs_type=%s "
"sts_config=%s vupper64=%s aoa_result_req=%d report_tof=%d report_aoa_azimuth=%d "
@@ -195,6 +197,7 @@ TRACE_EVENT(region_fira_session_params,
__entry->initiation_time_ms,
__entry->slot_duration_dtu,
__entry->block_duration_dtu,
+ __entry->block_stride_len,
__entry->round_duration_slots,
__entry->round_hopping,
__entry->priority,
@@ -260,6 +263,42 @@ TRACE_EVENT(region_fira_tx_message_type,
)
);
+TRACE_EVENT(region_fira_block_index,
+ TP_PROTO(const struct fira_session *session,
+ int block_index),
+ TP_ARGS(session, block_index),
+ TP_STRUCT__entry(
+ FIRA_SESSION_ENTRY
+ __field(int, block_index)
+ ),
+ TP_fast_assign(
+ FIRA_SESSION_ASSIGN;
+ __entry->block_index = block_index;
+ ),
+ TP_printk(FIRA_SESSION_PR_FMT "block index = %d",
+ FIRA_SESSION_PR_ARG,
+ __entry->block_index
+ )
+ );
+
+TRACE_EVENT(region_fira_next_block,
+ TP_PROTO(const struct fira_session *session,
+ int block_index),
+ TP_ARGS(session, block_index),
+ TP_STRUCT__entry(
+ FIRA_SESSION_ENTRY
+ __field(int, block_index)
+ ),
+ TP_fast_assign(
+ FIRA_SESSION_ASSIGN;
+ __entry->block_index = block_index;
+ ),
+ TP_printk(FIRA_SESSION_PR_FMT "next block index = %d",
+ FIRA_SESSION_PR_ARG,
+ __entry->block_index
+ )
+ );
+
#endif /* !FIRA_TRACE_H || TRACE_HEADER_MULTI_READ */
#undef TRACE_INCLUDE_PATH
diff --git a/mac/fira_access.c b/mac/fira_access.c
index adcbcfb..7931d39 100644
--- a/mac/fira_access.c
+++ b/mac/fira_access.c
@@ -39,7 +39,6 @@
#define FIRA_STS_FOM_THRESHOLD 153
-static void fira_update_antennas_id(struct fira_session *session);
static struct mcps802154_access *
fira_access_controlee(struct fira_local *local, struct fira_session *session);
@@ -258,7 +257,7 @@ static void fira_rx_frame_control(struct fira_local *local,
struct mcps802154_ie_get_context ie_get = {};
u32 sts_index;
unsigned int n_slots;
- int last_slot_index;
+ int last_slot_index, block_stride_len;
int i;
bool stop_ranging;
@@ -274,11 +273,12 @@ static void fira_rx_frame_control(struct fira_local *local,
goto failed;
if (allow_resync_session) {
session = local->current_session = allow_resync_session;
+ fira_session_prepare(local, session);
fira_access_controlee(local, session);
}
if (!fira_frame_control_payload_check(local, skb, &ie_get, &n_slots,
- &stop_ranging))
+ &stop_ranging, &block_stride_len))
goto failed;
fira_session_resync(local, session, sts_index, info->timestamp_dtu);
@@ -310,6 +310,8 @@ static void fira_rx_frame_control(struct fira_local *local,
session->params.slot_duration_dtu * (last_slot_index + 1);
local->access.n_frames = n_slots;
+ session->next_block_stride_len = block_stride_len;
+
return;
failed:
fira_ranging_info_set_status(ranging_info,
@@ -542,44 +544,6 @@ struct mcps802154_access_ops fira_access_ops = {
.tx_return = fira_tx_return,
};
-static int fira_next_in_bitfield_u8(u8 bitfield, int prev)
-{
- u32 padded_bitfield = 1 << 16 | bitfield << 8 | bitfield;
- u32 rotated_bitfield = padded_bitfield >> (prev + 1);
-
- return (ffs(rotated_bitfield) + prev) % 8;
-}
-
-static void fira_update_antennas_id(struct fira_session *session)
-{
- const struct fira_session_params *p = &session->params;
-
- session->tx_ant = fira_next_in_bitfield_u8(p->tx_antenna_selection,
- session->tx_ant);
-
- switch (p->rx_antenna_switch) {
- default:
- case FIRA_RX_ANTENNA_SWITCH_BETWEEN_ROUND:
- /* Switch pairs between round. */
- session->rx_ant_pair[0] = session->rx_ant_pair[1] =
- fira_next_in_bitfield_u8(p->rx_antenna_selection,
- session->rx_ant_pair[0]);
- break;
- case FIRA_RX_ANTENNA_SWITCH_DURING_ROUND:
- session->rx_ant_pair[0] = p->rx_antenna_pair_azimuth;
- session->rx_ant_pair[1] = p->rx_antenna_pair_elevation;
- break;
- case FIRA_RX_ANTENNA_SWITCH_TWO_RANGING:
- /* Switch from one ranging to another. */
- if (session->rx_ant_pair[0] == p->rx_antenna_pair_azimuth)
- session->rx_ant_pair[0] = p->rx_antenna_pair_elevation;
- else
- session->rx_ant_pair[0] = p->rx_antenna_pair_azimuth;
- session->rx_ant_pair[1] = session->rx_ant_pair[0];
- break;
- }
-}
-
static __le16 fira_access_set_short_address(struct fira_local *local,
struct fira_session *session,
struct mcps802154_access *access)
@@ -649,8 +613,6 @@ fira_access_controller(struct fira_local *local, struct fira_session *session)
access->frames = local->frames;
access->channel = fira_access_channel(local, session);
- fira_update_antennas_id(session);
-
local->n_stopped_controlees_short_addr = 0;
for (i = 0; i < controlees_array->size; i++) {
const struct fira_controlee *c = &controlees_array->data[i];
@@ -773,7 +735,6 @@ fira_access_controlee(struct fira_local *local, struct fira_session *session)
access->frames = local->frames;
access->n_frames = 1;
access->channel = fira_access_channel(local, session);
- fira_update_antennas_id(session);
ri = local->ranging_info;
memset(ri, 0, sizeof(*ri));
@@ -841,6 +802,7 @@ struct mcps802154_access *fira_get_access(struct mcps802154_region *region,
struct mcps802154_access *fira_compute_access(struct fira_local *local,
struct fira_session *session)
{
+ fira_session_prepare(local, session);
if (session->params.device_type == FIRA_DEVICE_TYPE_CONTROLLER)
return fira_access_controller(local, session);
else
diff --git a/mac/fira_frame.c b/mac/fira_frame.c
index a526c3b..663bc7d 100644
--- a/mac/fira_frame.c
+++ b/mac/fira_frame.c
@@ -142,7 +142,7 @@ void fira_frame_control_payload_put(const struct fira_local *local,
*p++ = n_mngt;
*p++ = 0;
- *p++ = 0;
+ *p++ = session->next_block_stride_len;
for (i = 0; i < local->access.n_frames - 1; i++) {
const struct fira_slot *slot = &local->slots[i + 1];
@@ -384,11 +384,11 @@ bool fira_frame_header_check(const struct fira_local *local,
static bool fira_frame_control_read(struct fira_local *local, u8 *p,
unsigned int ie_len, unsigned int *n_slots,
- bool *stop)
+ bool *stop, int *block_stride_len)
{
const struct fira_session *session = local->current_session;
struct fira_slot *slot, last;
- int n_mngt, stride_len, i;
+ int n_mngt, i;
u16 msg_ids = 0;
bool stop_found = false;
@@ -397,10 +397,7 @@ static bool fira_frame_control_read(struct fira_local *local, u8 *p,
return false;
p++;
- stride_len = *p++;
- if (stride_len)
- /* Not supported for the moment. */
- return false;
+ *block_stride_len = *p++;
slot = local->slots;
last = *slot++;
@@ -474,7 +471,8 @@ static bool fira_frame_control_read(struct fira_local *local, u8 *p,
bool fira_frame_control_payload_check(struct fira_local *local,
struct sk_buff *skb,
struct mcps802154_ie_get_context *ie_get,
- unsigned int *n_slots, bool *stop_ranging)
+ unsigned int *n_slots, bool *stop_ranging,
+ int *block_stride_len)
{
bool fira_payload_seen = false;
int r;
@@ -505,7 +503,8 @@ bool fira_frame_control_payload_check(struct fira_local *local,
return false;
if (!fira_frame_control_read(local, p, ie_get->len,
- n_slots, stop_ranging))
+ n_slots, stop_ranging,
+ block_stride_len))
return false;
fira_payload_seen = true;
diff --git a/mac/fira_frame.h b/mac/fira_frame.h
index d038ca8..6ef5a88 100644
--- a/mac/fira_frame.h
+++ b/mac/fira_frame.h
@@ -106,14 +106,15 @@ bool fira_frame_header_check(const struct fira_local *local,
* @ie_get: Context used to read IE, must have been used to read header first.
* @n_slots: Pointer where to store number of used slots.
* @stop_ranging: True if the message indicates that the ranging must be stopped.
+ * @block_stride_len: Pointer where to store number of blocks to stride.
*
* Return: true if message is correct. Extra payload is accepted.
*/
bool fira_frame_control_payload_check(struct fira_local *local,
struct sk_buff *skb,
struct mcps802154_ie_get_context *ie_get,
- unsigned int *n_slots,
- bool *stop_ranging);
+ unsigned int *n_slots, bool *stop_ranging,
+ int *block_stride_len);
/**
* fira_frame_measurement_report_payload_check() - Check FiRa frame payload for
diff --git a/mac/fira_region.c b/mac/fira_region.c
index 2322d84..a9cc6a7 100644
--- a/mac/fira_region.c
+++ b/mac/fira_region.c
@@ -245,7 +245,7 @@ void fira_report(struct fira_local *local, struct fira_session *session,
{
struct sk_buff *msg;
struct nlattr *data, *measurements, *measurement;
- int block_duration_ms, i, r;
+ int ranging_interval_ms, i, r;
bool stop_completed;
msg = mcps802154_region_event_alloc_skb(local->llhw, &local->region,
@@ -262,12 +262,13 @@ void fira_report(struct fira_local *local, struct fira_session *session,
if (!data)
goto nla_put_failure;
- block_duration_ms = session->params.block_duration_dtu /
- (local->llhw->dtu_freq_hz / 1000);
+ ranging_interval_ms = session->params.block_duration_dtu *
+ (session->block_stride_len + 1) /
+ (local->llhw->dtu_freq_hz / 1000);
if (nla_put_u32(msg, FIRA_RANGING_DATA_ATTR_BLOCK_INDEX,
session->block_index) ||
nla_put_u32(msg, FIRA_RANGING_DATA_ATTR_RANGING_INTERVAL_MS,
- block_duration_ms))
+ ranging_interval_ms))
goto nla_put_failure;
stop_completed = session->stop_request &&
diff --git a/mac/fira_region.h b/mac/fira_region.h
index d2b8910..3003574 100644
--- a/mac/fira_region.h
+++ b/mac/fira_region.h
@@ -38,6 +38,7 @@
#define FIRA_IN_BAND_TERMINATION_ATTEMPT_COUNT_MAX 10
#define FIRA_IN_BAND_TERMINATION_ATTEMPT_COUNT_MIN 1
#define FIRA_BOOLEAN_MAX 1
+#define FIRA_BLOCK_STRIDE_LEN_MAX 255
#define FIRA_FRAMES_MAX (3 + 3 * FIRA_CONTROLEES_MAX)
#define FIRA_CONTROLEE_FRAMES_MAX (3 + 3 + 1)
/* IEEE 802.15.4z 2020 section 6.9.7.2 */
diff --git a/mac/fira_region_call.c b/mac/fira_region_call.c
index 5cdf5b8..251e770 100644
--- a/mac/fira_region_call.c
+++ b/mac/fira_region_call.c
@@ -66,16 +66,15 @@ static const struct nla_policy fira_session_param_nla_policy[FIRA_SESSION_PARAM_
[FIRA_SESSION_PARAM_ATTR_SLOT_DURATION_RSTU] = { .type = NLA_U32 },
[FIRA_SESSION_PARAM_ATTR_BLOCK_DURATION_MS] = { .type = NLA_U32 },
[FIRA_SESSION_PARAM_ATTR_ROUND_DURATION_SLOTS] = { .type = NLA_U32 },
- [FIRA_SESSION_PARAM_ATTR_BLOCK_STRIDING_VALUE] = { .type = NLA_U32 },
+ [FIRA_SESSION_PARAM_ATTR_BLOCK_STRIDE_LENGTH] = {
+ .type = NLA_U32, .validation_type = NLA_VALIDATE_MAX,
+ .max = FIRA_BLOCK_STRIDE_LEN_MAX },
+ [FIRA_SESSION_PARAM_ATTR_MAX_NUMBER_OF_MEASUREMENTS] = { .type = NLA_U32 },
[FIRA_SESSION_PARAM_ATTR_MAX_RR_RETRY] = { .type = NLA_U32 },
[FIRA_SESSION_PARAM_ATTR_ROUND_HOPPING] = {
.type = NLA_U8, .validation_type = NLA_VALIDATE_MAX,
.max = FIRA_BOOLEAN_MAX
},
- [FIRA_SESSION_PARAM_ATTR_BLOCK_STRIDING] = {
- .type = NLA_U8, .validation_type = NLA_VALIDATE_MAX,
- .max = FIRA_BOOLEAN_MAX
- },
[FIRA_SESSION_PARAM_ATTR_PRIORITY] = {
.type = NLA_U8, .validation_type = NLA_VALIDATE_MAX,
.max = FIRA_PRIORITY_MAX
@@ -273,6 +272,7 @@ static int fira_session_start(struct fira_local *local, u32 session_id,
if (!active) {
u32 now_dtu;
int initiation_time_dtu;
+ int block_stride_len;
int r;
r = fira_crypto_derive_per_session(local, session);
@@ -305,6 +305,12 @@ static int fira_session_start(struct fira_local *local, u32 session_id,
} else {
initiation_time_dtu = 0;
}
+
+ if (session->params.device_type == FIRA_DEVICE_TYPE_CONTROLLER)
+ block_stride_len = session->params.block_stride_len;
+ else
+ block_stride_len = 0;
+
session->block_start_dtu = now_dtu + initiation_time_dtu;
session->block_index = 0;
session->sts_index = session->crypto.sts_index_init;
@@ -312,11 +318,13 @@ static int fira_session_start(struct fira_local *local, u32 session_id,
session->params.round_hopping;
session->round_index = 0;
session->next_round_index = 0;
+ session->block_stride_len = block_stride_len;
+ session->next_block_stride_len = block_stride_len;
session->synchronised = false;
session->last_access_timestamp_dtu = -1;
session->last_access_duration_dtu = 0;
- session->last_block_index = -1;
- fira_session_round_hopping(session);
+ session->last_block_index = -(block_stride_len + 1);
+ fira_session_update_round_index(session);
session->tx_ant = -1;
session->rx_ant_pair[0] = -1;
session->rx_ant_pair[1] = -1;
@@ -426,14 +434,25 @@ static int fira_session_deinit(struct fira_local *local, u32 session_id,
return 0;
}
-static int is_allowed_param_active(int param)
+static int is_allowed_param_active(enum fira_device_type dev_type, int param)
{
- /* This array contains attributes which can be changed in an active
- session */
- static const int allowed_param_active[] = {
+ /* These arrays contain attributes which can be changed in an active
+ controller or controlee session */
+ static const int allowed_controller_param_active[] = {
FIRA_SESSION_PARAM_ATTR_DATA_PAYLOAD,
+ FIRA_SESSION_PARAM_ATTR_BLOCK_STRIDE_LENGTH,
};
- static const int num_allowed = ARRAY_SIZE(allowed_param_active);
+ static const int allowed_controlee_param_active[] = {
+ FIRA_SESSION_PARAM_ATTR_DATA_PAYLOAD,
+ };
+ const int *allowed_param_active =
+ dev_type == FIRA_DEVICE_TYPE_CONTROLLER ?
+ allowed_controller_param_active :
+ allowed_controlee_param_active;
+ const int num_allowed =
+ dev_type == FIRA_DEVICE_TYPE_CONTROLLER ?
+ ARRAY_SIZE(allowed_controller_param_active) :
+ ARRAY_SIZE(allowed_controlee_param_active);
int i;
for (i = 0; i < num_allowed; i++)
@@ -474,18 +493,19 @@ static int fira_session_set_parameters(struct fira_local *local, u32 session_id,
if (r)
return r;
+ p = &session->params;
+
if (active) {
int i;
for (i = FIRA_SESSION_PARAM_ATTR_UNSPEC + 1;
i <= FIRA_SESSION_PARAM_ATTR_MAX; i++) {
- if (attrs[i] && !is_allowed_param_active(i))
+ if (attrs[i] &&
+ !is_allowed_param_active(p->device_type, i))
return -EBUSY;
}
}
- p = &session->params;
-
#define P(attr, member, type, conv) \
do { \
int x; \
@@ -529,6 +549,7 @@ static int fira_session_set_parameters(struct fira_local *local, u32 session_id,
/* Behaviour parameters. */
P(MAX_RR_RETRY, max_rr_retry, u32, x);
P(ROUND_HOPPING, round_hopping, u8, !!x);
+ P(BLOCK_STRIDE_LENGTH, block_stride_len, u32, x);
P(PRIORITY, priority, u8, x);
P(RESULT_REPORT_PHASE, result_report_phase, u8, !!x);
P(MAX_NUMBER_OF_MEASUREMENTS, max_number_of_measurements, u16, x);
@@ -632,43 +653,6 @@ nla_put_failure:
}
/**
- * fira_session_get_count() - Get count of active and inactive sessions.
- * @local: FiRa context.
- *
- * Return: 0 or error.
- */
-static int fira_session_get_count(struct fira_local *local)
-{
- struct fira_session *session;
- struct sk_buff *msg;
- uint8_t count = 0;
-
- list_for_each_entry(session, &local->inactive_sessions, entry) {
- count++;
- }
-
- list_for_each_entry(session, &local->active_sessions, entry) {
- count++;
- }
-
- msg = mcps802154_region_call_alloc_reply_skb(
- local->llhw, &local->region, FIRA_CALL_SESSION_GET_COUNT,
- NLMSG_DEFAULT_SIZE);
- if (!msg)
- return -ENOMEM;
-
- if (nla_put_u8(msg, FIRA_CALL_ATTR_SESSION_COUNT, count))
- goto nla_put_failure;
-
- return mcps802154_region_call_reply(local->llhw, msg);
-
-nla_put_failure:
- kfree_skb(msg);
- return -ENOBUFS;
-
-}
-
-/**
* fira_session_get_parameters() - Get Fira session parameters.
* @local: FiRa context.
* @session_id: Fira session id.
@@ -899,8 +883,111 @@ static int fira_manage_controlees(struct fira_local *local, u32 call_id,
int fira_get_capabilities(struct fira_local *local,
const struct genl_info *info)
{
- /* TODO: inform netlink about capabilities. */
- return 0;
+ struct sk_buff *msg;
+ struct nlattr *capabilities;
+
+ if (!info)
+ return 0;
+
+ msg = mcps802154_region_call_alloc_reply_skb(local->llhw,
+ &local->region,
+ FIRA_CALL_GET_CAPABILITIES,
+ NLMSG_DEFAULT_SIZE);
+ if (!msg)
+ return -ENOMEM;
+
+ capabilities = nla_nest_start(msg, FIRA_CALL_ATTR_CAPABILITIES);
+ if (!capabilities) {
+ goto nla_put_failure;
+ }
+
+#define P(name, type, value) \
+ do { \
+ if (nla_put_##type(msg, FIRA_CAPABILITY_ATTR_##name, value)) { \
+ goto nla_put_failure; \
+ } \
+ } while (0)
+#define F(name) \
+ do { \
+ if (nla_put_flag(msg, FIRA_CAPABILITY_ATTR_##name)) { \
+ goto nla_put_failure; \
+ } \
+ } while (0)
+
+ /* Main session capabilities. */
+ P(FIRA_PHY_VERSION_RANGE, u32, 0x01010101);
+ P(FIRA_MAC_VERSION_RANGE, u32, 0x01010101);
+ P(DEVICE_CLASS, u8, 1);
+ F(DEVICE_TYPE_CONTROLEE_RESPONDER);
+ F(DEVICE_TYPE_CONTROLLER_INITIATOR);
+ F(MULTI_NODE_MODE_UNICAST);
+ F(MULTI_NODE_MODE_ONE_TO_MANY);
+ F(RANGING_ROUND_USAGE_DS_TWR);
+ P(NUMBER_OF_CONTROLEES_MAX, u32, FIRA_CONTROLEES_MAX);
+ /* Behaviour. */
+ F(ROUND_HOPPING);
+ F(BLOCK_STRIDING);
+ /* Radio. */
+ P(CHANNEL_NUMBER, u16,
+ local->llhw->hw->phy->supported
+ .channels[local->llhw->hw->phy->current_page]);
+ F(RFRAME_CONFIG_SP1);
+ F(RFRAME_CONFIG_SP3);
+ F(PRF_MODE_BPRF);
+ F(PREAMBLE_DURATION_64);
+ F(SFD_ID_2);
+ F(NUMBER_OF_STS_SEGMENTS_0);
+ F(NUMBER_OF_STS_SEGMENTS_1);
+ F(PSDU_DATA_RATE_6M81);
+ F(BPRF_PHR_DATA_RATE_850K);
+ F(TX_ADAPTIVE_PAYLOAD_POWER);
+ /* Antenna. */
+ P(RX_ANTENNA_PAIRS, u32, local->llhw->rx_antenna_pairs);
+ P(TX_ANTENNAS, u32, local->llhw->tx_antennas);
+ /* STS and crypto capabilities. */
+ F(STS_CONFIG_STATIC);
+ /* Report. */
+ F(AOA_AZIMUTH);
+ F(AOA_ELEVATION);
+ F(AOA_FOM);
+#undef F
+#undef P
+
+ nla_nest_end(msg, capabilities);
+ return mcps802154_region_call_reply(local->llhw, msg);
+nla_put_failure:
+ kfree_skb(msg);
+ return -ENOBUFS;
+}
+
+int fira_session_get_count(struct fira_local *local)
+{
+ struct fira_session *session;
+ struct sk_buff *msg;
+ u32 count = 0;
+
+ list_for_each_entry (session, &local->inactive_sessions, entry) {
+ count++;
+ }
+
+ list_for_each_entry (session, &local->active_sessions, entry) {
+ count++;
+ }
+
+ msg = mcps802154_region_call_alloc_reply_skb(
+ local->llhw, &local->region, FIRA_CALL_SESSION_GET_COUNT,
+ NLMSG_DEFAULT_SIZE);
+ if (!msg)
+ return -ENOMEM;
+
+ if (nla_put_u32(msg, FIRA_CALL_ATTR_SESSION_COUNT, count))
+ goto nla_put_failure;
+
+ return mcps802154_region_call_reply(local->llhw, msg);
+
+nla_put_failure:
+ kfree_skb(msg);
+ return -ENOBUFS;
}
int fira_session_control(struct fira_local *local, u32 call_id,
diff --git a/mac/fira_session.c b/mac/fira_session.c
index 6f673ad..90f6dc3 100644
--- a/mac/fira_session.c
+++ b/mac/fira_session.c
@@ -25,6 +25,7 @@
#include "fira_crypto.h"
#include "fira_round_hopping_sequence.h"
#include "fira_access.h"
+#include "fira_trace.h"
#include "mcps802154_i.h"
#include <linux/errno.h>
@@ -275,13 +276,68 @@ bool fira_session_is_ready(struct fira_local *local,
round_duration_dtu < params->block_duration_dtu;
}
-void fira_session_round_hopping(struct fira_session *session)
+static int fira_next_in_bitfield_u8(u8 bitfield, int prev)
+{
+ u32 padded_bitfield = 1 << 16 | bitfield << 8 | bitfield;
+ u32 rotated_bitfield = padded_bitfield >> (prev + 1);
+
+ return (ffs(rotated_bitfield) + prev) % 8;
+}
+
+static void fira_update_antennas_id(struct fira_session *session)
+{
+ const struct fira_session_params *p = &session->params;
+
+ session->tx_ant = fira_next_in_bitfield_u8(p->tx_antenna_selection,
+ session->tx_ant);
+
+ switch (p->rx_antenna_switch) {
+ default:
+ case FIRA_RX_ANTENNA_SWITCH_BETWEEN_ROUND:
+ /* Switch pairs between round. */
+ session->rx_ant_pair[0] = session->rx_ant_pair[1] =
+ fira_next_in_bitfield_u8(p->rx_antenna_selection,
+ session->rx_ant_pair[0]);
+ break;
+ case FIRA_RX_ANTENNA_SWITCH_DURING_ROUND:
+ session->rx_ant_pair[0] = p->rx_antenna_pair_azimuth;
+ session->rx_ant_pair[1] = p->rx_antenna_pair_elevation;
+ break;
+ case FIRA_RX_ANTENNA_SWITCH_TWO_RANGING:
+ /* Switch from one ranging to another. */
+ if (session->rx_ant_pair[0] == p->rx_antenna_pair_azimuth)
+ session->rx_ant_pair[0] = p->rx_antenna_pair_elevation;
+ else
+ session->rx_ant_pair[0] = p->rx_antenna_pair_azimuth;
+ session->rx_ant_pair[1] = session->rx_ant_pair[0];
+ break;
+ }
+}
+
+void fira_session_prepare(struct fira_local *local,
+ struct fira_session *session)
+{
+ fira_update_antennas_id(session);
+ if (session->params.device_type == FIRA_DEVICE_TYPE_CONTROLLER) {
+ session->next_block_stride_len =
+ session->params.block_stride_len;
+ if (session->params.round_hopping) {
+ u32 next_block_index = session->block_index +
+ session->next_block_stride_len +
+ 1;
+ trace_region_fira_next_block(session, next_block_index);
+ session->next_round_index =
+ fira_round_hopping_sequence_get(
+ session, next_block_index);
+ }
+ }
+}
+
+void fira_session_update_round_index(struct fira_session *session)
{
if (session->hopping_sequence_generation) {
session->round_index = fira_round_hopping_sequence_get(
session, session->block_index);
- session->next_round_index = fira_round_hopping_sequence_get(
- session, session->block_index + 1);
} else {
session->round_index = session->next_round_index;
session->hopping_sequence_generation =
@@ -293,35 +349,75 @@ static void fira_session_update(struct fira_local *local,
struct fira_session *session,
u32 next_timestamp_dtu)
{
+ u32 access_dtu;
s32 diff_dtu;
int block_duration_margin_dtu = 0;
if (session->params.device_type == FIRA_DEVICE_TYPE_CONTROLEE)
block_duration_margin_dtu =
fira_session_get_block_duration_margin(local, session);
- diff_dtu = session->block_start_dtu +
- fira_session_get_round_slot(session) *
- session->params.slot_duration_dtu -
- block_duration_margin_dtu - next_timestamp_dtu;
+
+ /* Do we have the time to participate in the current block? */
+ access_dtu = session->block_start_dtu +
+ fira_session_get_round_slot(session) *
+ session->params.slot_duration_dtu -
+ block_duration_margin_dtu;
+ diff_dtu = access_dtu - next_timestamp_dtu;
if (diff_dtu < 0) {
int block_duration_dtu = session->params.block_duration_dtu;
int block_duration_slots =
block_duration_dtu / session->params.slot_duration_dtu;
- int add_blocks;
+ int block_stride_len = session->block_stride_len;
+ int block_stride_duration_dtu =
+ block_duration_dtu * (block_stride_len + 1);
+ int add_blocks, add_strides;
+
+ /*
+ * No time in current block, which block should we try? The
+ * result of this can be 0, meaning that we are still in the
+ * same block, but the access was earlier in this block.
+ */
+ diff_dtu = session->block_start_dtu -
+ block_duration_margin_dtu - next_timestamp_dtu;
+ add_strides = -diff_dtu / block_stride_duration_dtu;
+ add_blocks = add_strides * (block_stride_len + 1);
- add_blocks = (-diff_dtu + block_duration_dtu - 1) /
- block_duration_dtu;
session->block_start_dtu += add_blocks * block_duration_dtu;
session->block_index += add_blocks;
session->sts_index += add_blocks * block_duration_slots;
- if (add_blocks != 1)
- session->hopping_sequence_generation =
- session->params.round_hopping;
- fira_session_round_hopping(session);
+ if (add_blocks != 0) {
+ /*
+ * More than one ranging round skipped, can not trust
+ * last hopping instructions.
+ */
+ if (add_blocks > block_stride_len + 1)
+ session->hopping_sequence_generation =
+ session->params.round_hopping;
+ fira_session_update_round_index(session);
+ }
+
+ /* Retry in the found block. */
+ access_dtu = session->block_start_dtu +
+ fira_session_get_round_slot(session) *
+ session->params.slot_duration_dtu -
+ block_duration_margin_dtu;
+ diff_dtu = access_dtu - next_timestamp_dtu;
+
+ if (diff_dtu < 0) {
+ /* Still no time, next one will be OK. */
+ add_blocks = block_stride_len + 1;
+ session->block_start_dtu +=
+ add_blocks * block_duration_dtu;
+ session->block_index += add_blocks;
+ session->sts_index += add_blocks * block_duration_slots;
+ fira_session_update_round_index(session);
+ }
+ trace_region_fira_block_index(session, session->block_index);
}
}
+
static inline bool
fira_session_has_higher_priority(const struct fira_session *session,
const struct fira_session *selected_session)
@@ -397,9 +493,11 @@ static struct fira_session *fira_session_find_next(struct fira_local *local,
access_duration_dtu = demand.duration_dtu;
unsync_access_duration_dtu = U32_MAX;
if (session->params.max_rr_retry) {
- int nb_blocks = session->params.max_rr_retry +
- session->last_block_index -
- session->block_index;
+ int nb_blocks =
+ session->params.max_rr_retry *
+ (session->block_stride_len + 1) +
+ session->last_block_index -
+ session->block_index;
unsync_access_duration_dtu =
min((u32)session->params.block_duration_dtu *
@@ -457,7 +555,8 @@ fira_session_check_max_number_of_measurements(struct fira_local *local,
static bool fira_session_check_max_rr_retry(struct fira_session *session)
{
if (session->params.max_rr_retry &&
- !((s32)(session->block_index - session->last_block_index -
+ !((s32)((session->block_index - session->last_block_index) /
+ (session->block_stride_len + 1) -
session->params.max_rr_retry) < 0)) {
session->stop_no_response = true;
return true;
@@ -638,5 +737,6 @@ void fira_session_access_done(struct fira_local *local,
if (session == local->current_session) {
fira_session_stop_expired_sessions(local);
+ session->block_stride_len = session->next_block_stride_len;
}
}
diff --git a/mac/fira_session.h b/mac/fira_session.h
index c1e334b..47abf84 100644
--- a/mac/fira_session.h
+++ b/mac/fira_session.h
@@ -59,6 +59,7 @@ struct fira_session_params {
int max_number_of_measurements;
int max_rr_retry;
bool round_hopping;
+ int block_stride_len;
int priority;
bool result_report_phase;
/* Radio. */
@@ -136,6 +137,15 @@ struct fira_session {
*/
int next_round_index;
/**
+ * @block_stride_len: Stride length for the reference block.
+ */
+ int block_stride_len;
+ /**
+ * @next_block_stride_len: Stride length for the block after the
+ * reference block.
+ */
+ int next_block_stride_len;
+ /**
* @tx_ant: Antenna index to use for transmission in the reference
* block.
*/
@@ -307,6 +317,14 @@ bool fira_session_is_ready(struct fira_local *local,
struct fira_session *session);
/**
+ * fira_session_prepare() - Prepare a FiRa session to run.
+ * @local: FiRa context.
+ * @session: Session.
+ */
+void fira_session_prepare(struct fira_local *local,
+ struct fira_session *session);
+
+/**
* fira_session_next() - Find the next session to use after the given timestamp.
* @local: FiRa context.
* @next_timestamp_dtu: Next access opportunity.
@@ -319,10 +337,10 @@ struct fira_session *fira_session_next(struct fira_local *local,
u32 max_access_duration_dtu);
/**
- * fira_session_round_hopping() - Update round index for round hopping.
+ * fira_session_update_round_index() - Update round index for round hopping.
* @session: Session to update.
*/
-void fira_session_round_hopping(struct fira_session *session);
+void fira_session_update_round_index(struct fira_session *session);
/**
* fira_session_resync() - Resync session parameters on control message.
@@ -381,6 +399,7 @@ fira_session_get_block_duration_margin(struct fira_local *local,
const struct fira_session *session)
{
return (long long int)session->params.block_duration_dtu *
+ (session->block_stride_len + 1) *
local->block_duration_rx_margin_ppm / 1000000;
}
diff --git a/mac/include/net/fira_region_nl.h b/mac/include/net/fira_region_nl.h
index 714f1b8..3e390d2 100644
--- a/mac/include/net/fira_region_nl.h
+++ b/mac/include/net/fira_region_nl.h
@@ -259,6 +259,7 @@ enum fira_call_attrs {
FIRA_CALL_ATTR_SESSION_PARAMS,
FIRA_CALL_ATTR_CONTROLEES,
FIRA_CALL_ATTR_RANGING_DATA,
+ FIRA_CALL_ATTR_CAPABILITIES,
FIRA_CALL_ATTR_SESSION_STATE,
FIRA_CALL_ATTR_SESSION_COUNT,
@@ -289,7 +290,7 @@ enum fira_call_attrs {
* Block size in unit of 1200 RSTU (same as ms), default 200.
* @FIRA_SESSION_PARAM_ATTR_ROUND_DURATION_SLOTS:
* Number of slots per ranging round, default 30 (UCI: SLOTS_PER_RR)
- * @FIRA_SESSION_PARAM_ATTR_BLOCK_STRIDING_VALUE:
+ * @FIRA_SESSION_PARAM_ATTR_BLOCK_STRIDE_LENGTH:
* Value of block striding, default 0, can be changed when the
* session is active [controller only]
* @FIRA_SESSION_PARAM_ATTR_MAX_RR_RETRY:
@@ -297,8 +298,6 @@ enum fira_call_attrs {
* or disabled (0, default) [controller only]
* @FIRA_SESSION_PARAM_ATTR_ROUND_HOPPING:
* Disabled (0, default) or enabled (1)
- * @FIRA_SESSION_PARAM_ATTR_BLOCK_STRIDING:
- * Disabled (0, default) or enabled upon controller decision (1)
* @FIRA_SESSION_PARAM_ATTR_PRIORITY:
* Priority value, higher has more priority (1-100, default 50)
* @FIRA_SESSION_PARAM_ATTR_RESULT_REPORT_PHASE:
@@ -402,11 +401,10 @@ enum fira_session_param_attrs {
FIRA_SESSION_PARAM_ATTR_SLOT_DURATION_RSTU,
FIRA_SESSION_PARAM_ATTR_BLOCK_DURATION_MS,
FIRA_SESSION_PARAM_ATTR_ROUND_DURATION_SLOTS,
- FIRA_SESSION_PARAM_ATTR_BLOCK_STRIDING_VALUE,
+ FIRA_SESSION_PARAM_ATTR_BLOCK_STRIDE_LENGTH,
/* Behaviour */
FIRA_SESSION_PARAM_ATTR_MAX_RR_RETRY,
FIRA_SESSION_PARAM_ATTR_ROUND_HOPPING,
- FIRA_SESSION_PARAM_ATTR_BLOCK_STRIDING,
FIRA_SESSION_PARAM_ATTR_PRIORITY,
FIRA_SESSION_PARAM_ATTR_RESULT_REPORT_PHASE,
FIRA_SESSION_PARAM_ATTR_MR_AT_INITIATOR,
diff --git a/mac/include/net/mcps802154.h b/mac/include/net/mcps802154.h
index 1de283d..bf3847d 100644
--- a/mac/include/net/mcps802154.h
+++ b/mac/include/net/mcps802154.h
@@ -121,6 +121,14 @@ struct mcps802154_llhw {
*/
int current_preamble_code;
/**
+ * @rx_antenna_pairs: Number of antenna pairs for RX.
+ */
+ u32 rx_antenna_pairs;
+ /**
+ * @tx_antennas: Number of antennas for TX.
+ */
+ u32 tx_antennas;
+ /**
* @flags: Low-level hardware flags, see &enum mcps802154_llhw_flags.
*/
u32 flags;