blob: d2b89104a0e763554d7fdb79397c9e87c7b102d6 [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_FIRA_REGION_H
#define NET_FIRA_REGION_H
#include <linux/kernel.h>
#include <net/mcps802154_schedule.h>
#include "fira_region_params.h"
#define FIRA_SLOT_DURATION_RSTU_DEFAULT 2400
#define FIRA_BLOCK_DURATION_MS_DEFAULT 200
#define FIRA_ROUND_DURATION_SLOTS_DEFAULT 30
#define FIRA_MAX_RR_RETRY_DEFAULT 0
#define FIRA_PRIORITY_MAX 100
#define FIRA_PRIORITY_DEFAULT 50
#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_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 */
#define UWB_BLOCK_DURATION_MARGIN_PPM 100
/* FiRa Tx should arrive between 0 and 10 us, always add 2 us. */
#define FIRA_TX_MARGIN_US 2
/**
* enum fira_message_id - Message identifiers, used in internal state and in
* messages.
* @FIRA_MESSAGE_ID_RANGING_INITIATION: Initial ranging message.
* @FIRA_MESSAGE_ID_RANGING_RESPONSE: Response ranging message.
* @FIRA_MESSAGE_ID_RANGING_FINAL: Final ranging message, only for DS-TWR.
* @FIRA_MESSAGE_ID_CONTROL: Control message, sent by the controller.
* @FIRA_MESSAGE_ID_MEASUREMENT_REPORT: Deferred report of ranging measures.
* @FIRA_MESSAGE_ID_RESULT_REPORT: Report computed ranging result.
* @FIRA_MESSAGE_ID_CONTROL_UPDATE: Message to change hopping.
* @FIRA_MESSAGE_ID_RFRAME_MAX: Maximum identifier of message transmitted using
* an RFRAME.
* @FIRA_MESSAGE_ID_MAX: Maximum message identifier.
*/
enum fira_message_id {
FIRA_MESSAGE_ID_RANGING_INITIATION = 0,
FIRA_MESSAGE_ID_RANGING_RESPONSE = 1,
FIRA_MESSAGE_ID_RANGING_FINAL = 2,
FIRA_MESSAGE_ID_CONTROL = 3,
FIRA_MESSAGE_ID_MEASUREMENT_REPORT = 4,
FIRA_MESSAGE_ID_RESULT_REPORT = 5,
FIRA_MESSAGE_ID_CONTROL_UPDATE = 6,
FIRA_MESSAGE_ID_RFRAME_MAX = FIRA_MESSAGE_ID_RANGING_FINAL,
FIRA_MESSAGE_ID_MAX = FIRA_MESSAGE_ID_CONTROL_UPDATE,
};
/**
* struct fira_slot - Information on an active slot.
*/
struct fira_slot {
/**
* @index: Index of this slot, add it to the block STS index to get the
* slot STS index. Note: there can be holes for a controlee as only
* relevant slots are recorded.
*/
int index;
/**
* @tx_controlee_index: Index of the controlee transmitting in this
* slot, or -1 for the controller.
*/
int tx_controlee_index;
/**
* @ranging_index: Index of the ranging in the ranging information
* table, -1 if none.
*/
int ranging_index;
/**
* @message_id: Identifier of the message exchanged in this slot.
*/
enum fira_message_id message_id;
/**
* @tx_ant: Tx antenna selection.
*/
int tx_ant;
/**
* @rx_ant_pair: Rx antenna selection.
*/
int rx_ant_pair;
};
/**
* struct fira_aoa_info - Ranging AoA information.
*/
struct fira_local_aoa_info {
/**
* @pdoa_2pi: Phase Difference of Arrival.
*/
s16 pdoa_2pi;
/**
* @aoa_2pi: Angle of Arrival.
*/
s16 aoa_2pi;
/**
* @aoa_fom: Figure of merit of the AoA.
*/
u8 aoa_fom;
/**
* @rx_ant_pair: Antenna pair index.
*/
u8 rx_ant_pair;
/**
* @present: true if AoA information is present.
*/
bool present;
};
/**
* struct fira_ranging_info - Ranging information.
*/
struct fira_ranging_info {
/**
* @timestamps_rctu: Timestamps of the ranging messages.
*/
u64 timestamps_rctu[FIRA_MESSAGE_ID_RFRAME_MAX + 1];
/**
* @tof_rctu: Computed Time of Flight.
*/
int tof_rctu;
/**
* @local_aoa: Local ranging AoA information.
*/
struct fira_local_aoa_info local_aoa;
/**
* @local_aoa_azimuth: Azimuth ranging AoA information.
*/
struct fira_local_aoa_info local_aoa_azimuth;
/**
* @local_aoa_elevation: Elevation ranging AoA information.
*/
struct fira_local_aoa_info local_aoa_elevation;
/**
* @remote_aoa_azimuth_2pi: Remote azimuth AoA.
*/
s16 remote_aoa_azimuth_2pi;
/**
* @remote_aoa_elevation_pi: Remote elevation AoA.
*/
s16 remote_aoa_elevation_pi;
/**
* @remote_aoa_azimuth_fom: Remote azimuth FoM.
*/
u8 remote_aoa_azimuth_fom;
/**
* @remote_aoa_elevation_fom: Remote elevation FoM.
*/
u8 remote_aoa_elevation_fom;
/**
* @short_addr: Peer short address.
*/
__le16 short_addr;
/**
* @status: Success or failure reason.
*/
enum fira_ranging_status status;
/**
* @slot_index: In case of failure, the slot index where it has occured.
*/
u8 slot_index;
/**
* @tof_present: true if time of flight information is present.
*/
bool tof_present;
/**
* @remote_aoa_azimuth_present: true if azimuth AoA information is present.
*/
bool remote_aoa_azimuth_present;
/**
* @remote_aoa_elevation_present: true if elevation AoA information is present.
*/
bool remote_aoa_elevation_present;
/**
* @remote_aoa_fom_present: true if FoM AoA is present.
*/
bool remote_aoa_fom_present;
/**
* @data_payload: Custom data payload.
*/
u8 data_payload[FIRA_DATA_PAYLOAD_SIZE_MAX];
/**
* @data_payload_len: Custom data payload length.
*/
int data_payload_len;
};
/**
* struct fira_local - Local context.
*/
struct fira_local {
/**
* @region: Region instance returned to MCPS.
*/
struct mcps802154_region region;
/**
* @llhw: Low-level device pointer.
*/
struct mcps802154_llhw *llhw;
/**
* @access: Access returned to MCPS.
*/
struct mcps802154_access access;
/**
* @frames: Access frames referenced from access.
*/
struct mcps802154_access_frame frames[FIRA_FRAMES_MAX];
/**
* @sts_params: STS parameters for access frames.
*/
struct mcps802154_sts_params sts_params[FIRA_FRAMES_MAX];
/**
* @channel: Channel parameters for access.
*/
struct mcps802154_channel channel;
/**
* @current_session: Pointer to the current session.
*/
struct fira_session *current_session;
/**
* @slots: Descriptions of each active slots for the current session.
* When controller, this is filled when the access is requested. When
* controlee, the first slot is filled when the access is requested and
* the other slots are filled when the control message is received.
*/
struct fira_slot slots[FIRA_FRAMES_MAX];
/**
* @ranging_info: Information on ranging for the current session. Index
* in the table is determined by the order of the ranging messages.
* First ranging exchange is put at index 0. When a message is shared
* between several exchanges, its information is stored at index 0.
* Reset when access is requested.
*/
struct fira_ranging_info ranging_info[FIRA_CONTROLEES_MAX];
/**
* @n_ranging_info: Number of element in the ranging information table.
*/
int n_ranging_info;
/**
* @n_ranging_valid: Number of valid ranging in the current ranging
* information table.
*/
int n_ranging_valid;
/**
* @src_short_addr: Source address for the current session (actually
* never put as a source address in a frame, but used for control
* message).
*/
__le16 src_short_addr;
/**
* @dst_short_addr: Destination address for the current session. When
* controller, this is broadcast or the address of the only controlee.
* When controlee, this is the address of the controller.
*/
__le16 dst_short_addr;
/**
* @inactive_sessions: List of inactive sessions.
*/
struct list_head inactive_sessions;
/**
* @active_sessions: List of active sessions.
*/
struct list_head active_sessions;
/**
* @stopped_controlees_short_addr: Short addresses of the stopped
* controlees for which an element must be added to the Device
* Management List of the RCM message.
*/
__le16 stopped_controlees_short_addr[FIRA_CONTROLEES_MAX];
/**
* @n_stopped_controlees_short_addr: Number of elements in the stopped
* controlees short addr table.
*/
int n_stopped_controlees_short_addr;
/**
* @block_duration_rx_margin_ppm: Block duration rx margin for
* controlees.
*/
int block_duration_rx_margin_ppm;
};
static inline struct fira_local *
region_to_local(struct mcps802154_region *region)
{
return container_of(region, struct fira_local, region);
}
static inline struct fira_local *
access_to_local(struct mcps802154_access *access)
{
return container_of(access, struct fira_local, access);
}
/**
* fira_report() - Report state change or ranging result for a session.
* @local: FiRa context.
* @session: Session to report. Report ranging result if current session.
* @add_measurements: True to add measurements to report.
*/
void fira_report(struct fira_local *local, struct fira_session *session,
bool add_measurements);
/**
* fira_session_notify_state_change() - Notify session state change to upper layers.
* @local: FiRa context.
* @session_id: Fira session id.
* @state: Fira session state.
*/
void fira_session_notify_state_change(struct fira_local *local, u32 session_id, uint8_t state);
#endif /* NET_FIRA_REGION_H */