blob: c1e334b6aa976f6871e957584f764fae8553a24b [file] [log] [blame]
/*
* This file is part of the UWB stack for linux.
*
* Copyright (c) 2020-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 NET_MCPS802154_FIRA_SESSION_H
#define NET_MCPS802154_FIRA_SESSION_H
#include "fira_region.h"
#include "fira_crypto.h"
#include "fira_round_hopping_crypto_impl.h"
enum fira_session_state {
SESSION_STATE_INIT = 0x00,
SESSION_STATE_DEINIT = 0x01,
SESSION_STATE_ACTIVE = 0x02,
SESSION_STATE_IDLE = 0x03,
// RFU 0x04 - 0xff
// UCI_SESSION_STATE_ERROR = 0xff,
};
struct fira_controlees_array {
struct fira_controlee data[FIRA_CONTROLEES_MAX];
/* Number of data valid. */
size_t size;
};
struct fira_session_params {
/* Main parameters. */
enum fira_device_type device_type;
enum fira_ranging_round_usage ranging_round_usage;
enum fira_multi_node_mode multi_node_mode;
__le16 short_addr;
__le16 controller_short_addr;
/* Timings parameters. */
int initiation_time_ms;
int slot_duration_dtu;
int block_duration_dtu;
int round_duration_slots;
/* Behaviour parameters. */
int max_number_of_measurements;
int max_rr_retry;
bool round_hopping;
int priority;
bool result_report_phase;
/* Radio. */
int channel_number;
int preamble_code_index;
enum fira_rframe_config rframe_config;
enum fira_preambule_duration preamble_duration;
enum fira_sfd_id sfd_id;
enum fira_psdu_data_rate psdu_data_rate;
enum fira_mac_fcs_type mac_fcs_type;
/* STS and crypto. */
enum fira_sts_config sts_config;
u8 vupper64[FIRA_VUPPER64_SIZE];
size_t n_controlees_max;
bool aoa_result_req;
bool report_tof;
bool report_aoa_azimuth;
bool report_aoa_elevation;
bool report_aoa_fom;
u8 rx_antenna_selection;
u8 rx_antenna_pair_azimuth;
u8 rx_antenna_pair_elevation;
u8 tx_antenna_selection;
u8 rx_antenna_switch;
u32 data_vendor_oui;
u8 data_payload[FIRA_DATA_PAYLOAD_SIZE_MAX];
u32 data_payload_seq;
int data_payload_len;
};
/**
* struct fira_session - Session information.
*/
struct fira_session {
/**
* @id: Session identifier.
*/
u32 id;
/**
* @state: Session state.
*/
enum fira_session_state state;
/**
* @entry: Entry in list of sessions.
*/
struct list_head entry;
/**
* @params: Session parameters, mostly read only while the session is
* active.
*/
struct fira_session_params params;
/**
* @block_start_dtu: Timestamp of the current or previous block. All
* other fields are referring to this same block.
*/
u32 block_start_dtu;
/**
* @block_index: Block index of the reference block.
*/
u32 block_index;
/**
* @sts_index: STS index value at reference block start.
*/
u32 sts_index;
/**
* @hopping_sequence_generation: Whether to compute round index from ranging round sequence.
*/
bool hopping_sequence_generation;
/**
* @round_index: Round index of the reference block.
*/
int round_index;
/**
* @next_round_index: Round index of the block after the reference block.
*/
int next_round_index;
/**
* @tx_ant: Antenna index to use for transmission in the reference
* block.
*/
int tx_ant;
/**
* @rx_ant_pair: Antenna pair indexes to use for reception in the
* reference block.
*/
int rx_ant_pair[2];
/**
* @stop_request: Session has been requested to stop.
*/
bool stop_request;
/**
* @stop_inband: Session has been requested to stop by controller. This
* field is only used for controlee sessions.
*/
bool stop_inband;
/**
* @stop_no_response: Session has been requested to stop because ranging
* failed for max_rr_retry consecutives rounds.
*/
bool stop_no_response;
/**
* @max_number_of_measurements_reached: Session has been requested to stop
* because max_number_of_measurements was reached.
*/
bool max_number_of_measurements_reached;
/**
* @crypto: Crypto context.
*/
struct fira_crypto crypto;
/**
* @round_hopping_sequence: Round hopping sequence generation context.
*/
struct fira_round_hopping_sequence round_hopping_sequence;
/**
* @event_portid: Port identifier to use for notifications.
*/
u32 event_portid;
/**
* @synchronised: Whether a controlee session was synchronised. This
* field is not used for controller sessions.
*/
bool synchronised;
/**
* @last_access_timestamp_dtu: Timestamp of the last computed access.
*/
u32 last_access_timestamp_dtu;
/**
* @last_access_duration_dtu: Duration of the last computed access.
*/
u32 last_access_duration_dtu;
/**
* @data_payload_seq_sent: Sequence number of last sent data.
*/
u32 data_payload_seq_sent;
/**
* @last_block_index: Block index of the last successful ranging.
*/
u32 last_block_index;
/**
* @new_controlees: List of controlees to applies on next ca.
*/
struct fira_controlees_array new_controlees;
/**
* @current_controlees: List of controlees currently applied.
*/
struct fira_controlees_array current_controlees;
/**
* @controlee_management_flags: Flags used to indicates if the list of
* controlees must be updated and if any controlee must be stopped
* before allowing updates again. See
* &fira_session_controlee_management_flags.
*/
u32 controlee_management_flags;
/**
* @number_of_measurements: Number of measurements.
*/
u32 number_of_measurements;
};
/**
* fira_session_new() - Create a new session.
* @local: FiRa context.
* @session_id: Session identifier, must be unique.
*
* Return: The new session or NULL on error.
*/
struct fira_session *fira_session_new(struct fira_local *local, u32 session_id);
/**
* fira_session_free() - Remove a session.
* @local: FiRa context.
* @session: Session to remove, must be inactive.
*/
void fira_session_free(struct fira_local *local, struct fira_session *session);
/**
* fira_session_get() - Get a session by its identifier.
* @local: FiRa context.
* @session_id: Session identifier.
* @active: When session is found set to true if active, false if inactive.
*
* Return: The session or NULL if not found.
*/
struct fira_session *fira_session_get(struct fira_local *local, u32 session_id,
bool *active);
/**
* fira_session_copy_controlees() - copy controlees array between two array.
* @to: FiRa controlees array to write.
* @from: FiRa controlees array to read.
*/
void fira_session_copy_controlees(struct fira_controlees_array *to,
const struct fira_controlees_array *from);
/**
* fira_session_new_controlees() - Add new controlees.
* @local: FiRa context.
* @session: Session.
* @controlees_array: Destination array where store new controlees list.
* @controlees: Controlees information.
* @n_controlees: Number of controlees.
*
* Return: 0 or error.
*/
int fira_session_new_controlees(struct fira_local *local,
struct fira_session *session,
struct fira_controlees_array *controlees_array,
const struct fira_controlee *controlees,
size_t n_controlees);
/**
* fira_session_del_controlees() - Set flag to indicate that controlees are
* to be stopped then deleted.
* @local: FiRa context.
* @session: Session.
* @controlees_array: Destination array where store new controlees list.
* @controlees: Controlees information.
* @n_controlees: Number of controlees.
*
* Return: 0 or error.
*/
int fira_session_del_controlees(struct fira_local *local,
struct fira_session *session,
struct fira_controlees_array *controlees_array,
const struct fira_controlee *controlees,
size_t n_controlees);
/**
* fira_session_stop_controlees() - Stop controlees.
* @local: FiRa context.
* @session: Session.
* @controlees_array: Destination array where store new controlees list.
*/
void fira_session_stop_controlees(
struct fira_local *local, struct fira_session *session,
struct fira_controlees_array *controlees_array);
/**
* fira_session_is_ready() - Test whether a session is ready to be started.
* @local: FiRa context.
* @session: Session to test.
*
* Return: true if the session can be started.
*/
bool fira_session_is_ready(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.
* @max_access_duration_dtu: Maximum access duration.
*
* Return: The session or NULL if none.
*/
struct fira_session *fira_session_next(struct fira_local *local,
u32 next_timestamp_dtu,
u32 max_access_duration_dtu);
/**
* fira_session_round_hopping() - Update round index for round hopping.
* @session: Session to update.
*/
void fira_session_round_hopping(struct fira_session *session);
/**
* fira_session_resync() - Resync session parameters on control message.
* @local: FiRa context.
* @session: Session to synchronize.
* @sts_index: STS index of control message.
* @timestamp_dtu: Timestamp of control message.
*/
void fira_session_resync(struct fira_local *local, struct fira_session *session,
u32 sts_index, u32 timestamp_dtu);
/**
* fira_session_access_done() - Update session at end of access, or on event
* when no access is active.
* @local: FiRa context.
* @session: Session.
* @add_measurements: True to add measurements to report.
*/
void fira_session_access_done(struct fira_local *local,
struct fira_session *session,
bool add_measurements);
/**
* fira_session_get_round_slot() - Get current round's slot.
* @session: Session.
*
* Return: The first slot of the current round.
*/
static inline u32
fira_session_get_round_slot(const struct fira_session *session)
{
return session->round_index * session->params.round_duration_slots;
}
/**
* fira_session_get_round_sts_index() - Get current round's STS index.
* @session: Session.
*
* Return: The STS of the first slot of the current round.
*/
static inline u32
fira_session_get_round_sts_index(const struct fira_session *session)
{
return session->sts_index + fira_session_get_round_slot(session);
}
/**
* fira_session_get_block_duration_margin() - Get block duration margin.
* @local: FiRa context.
* @session: Session.
*
* Return: Block duration margin in dtu.
*/
static inline int
fira_session_get_block_duration_margin(struct fira_local *local,
const struct fira_session *session)
{
return (long long int)session->params.block_duration_dtu *
local->block_duration_rx_margin_ppm / 1000000;
}
#endif /* NET_MCPS802154_FIRA_SESSION_H */