| /* |
| * 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_H |
| #define NET_MCPS802154_H |
| |
| #include <net/mac802154.h> |
| #include <crypto/aes.h> |
| |
| /* Antenna index to use for transmission by default. */ |
| #define TX_ANT_ID_DEFAULT 0 |
| /* Antenna pair index to use for reception by default. */ |
| #define RX_ANT_PAIR_ID_DEFAULT 0 |
| |
| /** Maximum number of STS segments. */ |
| #define MCPS802154_STS_N_SEGS_MAX 4 |
| |
| /** |
| * struct mcps802154_channel - Channel parameters. |
| */ |
| struct mcps802154_channel { |
| /** |
| * @page: Channel page used in conjunction with channel to uniquely |
| * identify the channel. |
| */ |
| int page; |
| /** |
| * @channel: RF channel to use for all transmissions and receptions. |
| */ |
| int channel; |
| /** |
| * @preamble_code: Preamble code index for HRP UWB. Must be zero for |
| * other PHYs. |
| */ |
| int preamble_code; |
| }; |
| |
| /** |
| * enum mcps802154_llhw_flags - Low-level hardware without MCPS flags. |
| * @MCPS802154_LLHW_RDEV: |
| * Support for ranging (RDEV). TODO: move to &ieee802154_hw. |
| * @MCPS802154_LLHW_ERDEV: |
| * Support for enhanced ranging (ERDEV). TODO: move to &ieee802154_hw. |
| */ |
| enum mcps802154_llhw_flags { |
| MCPS802154_LLHW_RDEV = BIT(0), |
| MCPS802154_LLHW_ERDEV = BIT(1), |
| }; |
| |
| /** |
| * struct mcps802154_llhw - Low-level hardware without MCPS. |
| * |
| * This must be allocated with mcps802154_alloc_llhw(). The low-level driver |
| * should then initialize it. |
| */ |
| struct mcps802154_llhw { |
| /** |
| * @dtu_freq_hz: Inverse of device time unit duration, in Hz. |
| */ |
| int dtu_freq_hz; |
| /** |
| * @symbol_dtu: Symbol duration in device time unit, can change if radio |
| * parameters are changed. Can be set to 1 if device time unit is the |
| * symbol. |
| */ |
| int symbol_dtu; |
| /** |
| * @cca_dtu: CCA duration in device time unit, can change if radio |
| * parameters or CCA modes are changed. |
| */ |
| int cca_dtu; |
| /** |
| * @shr_dtu: Synchronisation header duration in device time unit, can |
| * change if radio parameters are changed. If ranging is supported, this |
| * is the difference between the RMARKER and the first frame symbol. |
| */ |
| int shr_dtu; |
| /** |
| * @dtu_rctu: Duration of one device time unit in ranging counter time |
| * unit (RDEV only). |
| */ |
| int dtu_rctu; |
| /** |
| * @rstu_dtu: Duration of ranging slot time unit in device time unit |
| * (ERDEV only). |
| */ |
| int rstu_dtu; |
| /** |
| * @anticip_dtu: Reasonable delay between reading the current timestamp |
| * and doing an operation in device time unit. |
| */ |
| int anticip_dtu; |
| /** |
| * @idle_dtu: Duration long enough to prefer entering the idle mode |
| * rather than trying to find a valid access. |
| */ |
| int idle_dtu; |
| /** |
| * @current_preamble_code: Current value of preamble code index for HRP |
| * UWB. Must be zero for other PHYs. |
| */ |
| int current_preamble_code; |
| /** |
| * @flags: Low-level hardware flags, see &enum mcps802154_llhw_flags. |
| */ |
| u32 flags; |
| /** |
| * @hw: Pointer to IEEE802154 hardware exposed by MCPS. The low-level |
| * driver needs to update this and hw->phy according to supported |
| * hardware features and radio parameters. More specifically: |
| * |
| * * &ieee802154_hw.extra_tx_headroom |
| * * in &ieee802154_hw.flags: |
| * |
| * * IEEE802154_HW_TX_OMIT_CKSUM |
| * * IEEE802154_HW_RX_OMIT_CKSUM |
| * * IEEE802154_HW_RX_DROP_BAD_CKSUM |
| * |
| * * &wpan_phy.flags |
| * * &wpan_phy_supported |
| * * &wpan_phy.symbol_duration |
| */ |
| struct ieee802154_hw *hw; |
| /** |
| * @priv: Driver private data. |
| */ |
| void *priv; |
| }; |
| |
| /** |
| * enum mcps802154_tx_frame_info_flags - Flags for transmitting a frame. |
| * @MCPS802154_TX_FRAME_TIMESTAMP_DTU: |
| * Start transmission at given timestamp in device time unit. |
| * @MCPS802154_TX_FRAME_CCA: |
| * Use CCA before transmission using the programmed mode. |
| * @MCPS802154_TX_FRAME_RANGING: |
| * Enable precise timestamping for the transmitted frame and its response |
| * (RDEV only). |
| * @MCPS802154_TX_FRAME_KEEP_RANGING_CLOCK: |
| * Request that the ranging clock be kept valid after the transmission of |
| * this frame (RDEV only). |
| * @MCPS802154_TX_FRAME_RANGING_PDOA: |
| * Enable phase difference of arrival measurement for the response frame |
| * (RDEV only). |
| * @MCPS802154_TX_FRAME_SP1: |
| * Enable STS for the transmitted frame and its response, mode 1 (STS after |
| * SFD and before PHR, ERDEV only). |
| * @MCPS802154_TX_FRAME_SP2: |
| * Enable STS for the transmitted frame and its response, mode 2 (STS after |
| * the payload, ERDEV only). |
| * @MCPS802154_TX_FRAME_SP3: |
| * Enable STS for the transmitted frame and its response, mode 3 (STS after |
| * SFD, no PHR, no payload, ERDEV only). |
| * @MCPS802154_TX_FRAME_STS_MODE_MASK: |
| * Mask covering all the STS mode configuration values. |
| * |
| * If no timestamp flag is given, transmit as soon as possible. |
| */ |
| enum mcps802154_tx_frame_info_flags { |
| MCPS802154_TX_FRAME_TIMESTAMP_DTU = BIT(0), |
| MCPS802154_TX_FRAME_CCA = BIT(1), |
| MCPS802154_TX_FRAME_RANGING = BIT(2), |
| MCPS802154_TX_FRAME_KEEP_RANGING_CLOCK = BIT(3), |
| MCPS802154_TX_FRAME_RANGING_PDOA = BIT(4), |
| MCPS802154_TX_FRAME_SP1 = BIT(5), |
| MCPS802154_TX_FRAME_SP2 = BIT(6), |
| MCPS802154_TX_FRAME_SP3 = BIT(5) | BIT(6), |
| MCPS802154_TX_FRAME_STS_MODE_MASK = BIT(5) | BIT(6), |
| }; |
| |
| /** |
| * struct mcps802154_tx_frame_info - Information for transmitting a frame. |
| */ |
| struct mcps802154_tx_frame_info { |
| /** |
| * @timestamp_dtu: If timestamped, date of transmission start. |
| */ |
| u32 timestamp_dtu; |
| /** |
| * @rx_enable_after_tx_dtu: If positive, enable receiver this number of |
| * device time unit after the end of the transmitted frame. |
| */ |
| int rx_enable_after_tx_dtu; |
| /** |
| * @rx_enable_after_tx_timeout_dtu: When receiver is enabled after the |
| * end of the transmitted frame: if negative, no timeout, if zero, use |
| * a default timeout value, else this is the timeout value in device |
| * time unit. |
| */ |
| int rx_enable_after_tx_timeout_dtu; |
| /** |
| * @flags: See &enum mcps802154_tx_frame_info_flags. |
| */ |
| u8 flags; |
| /** |
| * @ant_id: antenna index to use for transmit. |
| */ |
| int ant_id; |
| }; |
| |
| /** |
| * enum mcps802154_rx_info_flags - Flags for enabling the receiver. |
| * @MCPS802154_RX_INFO_TIMESTAMP_DTU: |
| * Enable receiver at given timestamp in device time unit. |
| * @MCPS802154_RX_INFO_AACK: |
| * Enable automatic acknowledgment. |
| * @MCPS802154_RX_INFO_RANGING: |
| * Enable precise timestamping for the received frame (RDEV only). |
| * @MCPS802154_RX_INFO_KEEP_RANGING_CLOCK: |
| * Request that the ranging clock be kept valid after the reception of the |
| * frame (RDEV only). |
| * @MCPS802154_RX_INFO_RANGING_PDOA: |
| * Enable phase difference of arrival measurement (RDEV only). |
| * @MCPS802154_RX_INFO_SP1: |
| * Enable STS for the received frame, mode 1 (STS after SFD and before PHR, |
| * ERDEV only). |
| * @MCPS802154_RX_INFO_SP2: |
| * Enable STS for the received frame, mode 2 (STS after the payload, ERDEV |
| * only). |
| * @MCPS802154_RX_INFO_SP3: |
| * Enable STS for the received frame, mode 3 (STS after SFD, no PHR, no |
| * payload, ERDEV only). |
| * @MCPS802154_RX_INFO_STS_MODE_MASK: |
| * Mask covering all the STS mode configuration values. |
| * |
| * If no timestamp flag is given, enable receiver as soon as possible. |
| */ |
| enum mcps802154_rx_info_flags { |
| MCPS802154_RX_INFO_TIMESTAMP_DTU = BIT(0), |
| MCPS802154_RX_INFO_AACK = BIT(1), |
| MCPS802154_RX_INFO_RANGING = BIT(2), |
| MCPS802154_RX_INFO_KEEP_RANGING_CLOCK = BIT(3), |
| MCPS802154_RX_INFO_RANGING_PDOA = BIT(4), |
| MCPS802154_RX_INFO_SP1 = BIT(5), |
| MCPS802154_RX_INFO_SP2 = BIT(6), |
| MCPS802154_RX_INFO_SP3 = BIT(5) | BIT(6), |
| MCPS802154_RX_INFO_STS_MODE_MASK = BIT(5) | BIT(6), |
| }; |
| |
| /** |
| * struct mcps802154_rx_info - Information for enabling the receiver. |
| */ |
| struct mcps802154_rx_info { |
| /** |
| * @timestamp_dtu: If timestamped, date to enable the receiver. |
| */ |
| u32 timestamp_dtu; |
| /** |
| * @timeout_dtu: If negative, no timeout, if zero, use a default timeout |
| * value, else this is the timeout value in device time unit. |
| */ |
| int timeout_dtu; |
| /** |
| * @flags: See &enum mcps802154_rx_info_flags. |
| */ |
| u8 flags; |
| /** |
| * @ant_pair_id: Antenna pair index to use for reception. |
| */ |
| u8 ant_pair_id; |
| }; |
| |
| /** |
| * enum mcps802154_rx_frame_info_flags - Flags for a received frame. |
| * @MCPS802154_RX_FRAME_INFO_TIMESTAMP_DTU: |
| * Set by MCPS to request timestamp in device time unit. |
| * @MCPS802154_RX_FRAME_INFO_TIMESTAMP_RCTU: |
| * Set by MCPS to request RMARKER timestamp in ranging counter time unit |
| * (RDEV only). |
| * @MCPS802154_RX_FRAME_INFO_LQI: |
| * Set by MCPS to request link quality indicator (LQI). |
| * @MCPS802154_RX_FRAME_INFO_RSSI: |
| * Set by MCPS to request RSSI. |
| * @MCPS802154_RX_FRAME_INFO_RANGING_FOM: |
| * Set by MCPS to request ranging figure of merit (FoM, RDEV only). |
| * @MCPS802154_RX_FRAME_INFO_RANGING_OFFSET: |
| * Set by MCPS to request clock characterization data (RDEV only). |
| * @MCPS802154_RX_FRAME_INFO_RANGING_PDOA: |
| * Set by MCPS to request phase difference of arrival (RDEV only). |
| * @MCPS802154_RX_FRAME_INFO_RANGING_PDOA_FOM: |
| * Set by MCPS to request phase difference of arrival figure of merit (FoM, |
| * RDEV only). |
| * @MCPS802154_RX_FRAME_INFO_RANGING_STS_TIMESTAMP_RCTU: |
| * Set by MCPS to request SRMARKERx timestamps for each STS segments in |
| * ranging counter time unit (ERDEV only). |
| * @MCPS802154_RX_FRAME_INFO_RANGING_STS_FOM: |
| * Set by MCPS to request STS segments figure of merit measuring the |
| * correlation strength between the received STS segment and the expected |
| * one (FoM, ERDEV only). |
| * @MCPS802154_RX_FRAME_INFO_AACK: |
| * Set by low-level driver if an automatic acknowledgment was sent or is |
| * being sent. |
| * |
| * The low-level driver must clear the corresponding flag if the information is |
| * not available. |
| */ |
| enum mcps802154_rx_frame_info_flags { |
| MCPS802154_RX_FRAME_INFO_TIMESTAMP_DTU = BIT(0), |
| MCPS802154_RX_FRAME_INFO_TIMESTAMP_RCTU = BIT(1), |
| MCPS802154_RX_FRAME_INFO_LQI = BIT(2), |
| MCPS802154_RX_FRAME_INFO_RSSI = BIT(3), |
| MCPS802154_RX_FRAME_INFO_RANGING_FOM = BIT(4), |
| MCPS802154_RX_FRAME_INFO_RANGING_OFFSET = BIT(5), |
| MCPS802154_RX_FRAME_INFO_RANGING_PDOA = BIT(6), |
| MCPS802154_RX_FRAME_INFO_RANGING_PDOA_FOM = BIT(7), |
| MCPS802154_RX_FRAME_INFO_RANGING_STS_TIMESTAMP_RCTU = BIT(8), |
| MCPS802154_RX_FRAME_INFO_RANGING_STS_FOM = BIT(9), |
| MCPS802154_RX_FRAME_INFO_AACK = BIT(10), |
| }; |
| |
| /** |
| * struct mcps802154_rx_frame_info - Information on a received frame. |
| */ |
| struct mcps802154_rx_frame_info { |
| /** |
| * @timestamp_dtu: Timestamp of start of frame in device time unit. |
| */ |
| u32 timestamp_dtu; |
| /** |
| * @timestamp_rctu: Timestamp of RMARKER in ranging count time unit |
| * (RDEV only). |
| */ |
| u64 timestamp_rctu; |
| /** |
| * @frame_duration_dtu: Duration of the whole frame in device time unit |
| * or 0 if unknown. |
| */ |
| int frame_duration_dtu; |
| /** |
| * @rssi: Received signal strength indication (RSSI). |
| */ |
| int rssi; |
| /** |
| * @ranging_tracking_interval_rctu: Interval on which tracking offset |
| * was measured (RDEV only). |
| */ |
| int ranging_tracking_interval_rctu; |
| /** |
| * @ranging_offset_rctu: Difference between the transmitter and the |
| * receiver clock measure over the tracking interval, if positive, the |
| * transmitter operates at a higher frequency (RDEV only). |
| */ |
| int ranging_offset_rctu; |
| /** |
| * @ranging_pdoa_rad_q11: Phase difference of arrival, unit is radian |
| * multiplied by 2048 (RDEV only). |
| */ |
| int ranging_pdoa_rad_q11; |
| /** |
| * @ranging_pdoa_spacing_mm_q11: Spacing between antennas, unit is mm |
| * multiplied by 2048 (RDEV only). |
| */ |
| int ranging_pdoa_spacing_mm_q11; |
| /** |
| * @ranging_aoa_rad_q11: AoA interpolated by the driver from its |
| * calibration LUT. unit is rad multiplied by 2048 (RDEV only). |
| */ |
| int ranging_aoa_rad_q11; |
| /** |
| * @ranging_sts_timestamp_diffs_rctu: For each SRMARKERx, difference |
| * between the measured timestamp and the expected timestamp relative to |
| * RMARKER in ranging count time unit (ERDEV only). When STS mode is |
| * 1 or 3, SRMARKER0 is the same as RMARKER and difference is always 0. |
| */ |
| s16 ranging_sts_timestamp_diffs_rctu[MCPS802154_STS_N_SEGS_MAX + 1]; |
| /** |
| * @lqi: Link quality indicator (LQI). |
| */ |
| u8 lqi; |
| /** |
| * @ranging_fom: Ranging figure of merit (FoM, RDEV only). Should be |
| * formatted according to 802.15.4. |
| */ |
| u8 ranging_fom; |
| /** |
| * @ranging_pdoa_fom: Phase difference of arrival figure of merit (FoM, |
| * RDEV only). Range is 0 to 255, with 0 being an invalid measure and |
| * 255 being a 100% confidence. |
| */ |
| u8 ranging_pdoa_fom; |
| /** |
| * @ranging_sts_fom: Table of figures of merit measuring the correlation |
| * strength between the received STS segment and the expected one (FoM, |
| * ERDEV only). Range is 0 to 255, with 0 being an invalid measure and |
| * 255 being a 100% confidence. |
| */ |
| u8 ranging_sts_fom[MCPS802154_STS_N_SEGS_MAX]; |
| /** |
| * @flags: See &enum mcps802154_rx_frame_info_flags. |
| */ |
| u16 flags; |
| }; |
| |
| /** |
| * struct mcps802154_sts_params - STS parameters for HRP UWB. |
| */ |
| struct mcps802154_sts_params { |
| /** |
| * @v: Value V used in DRBG for generating the STS. The 32 LSB are the |
| * VCounter which is incremented every 128 generated pulse. |
| */ |
| u8 v[AES_BLOCK_SIZE]; |
| /** |
| * @key: STS AES key used in DRBG for generating the STS. |
| */ |
| u8 key[AES_KEYSIZE_128]; |
| /** |
| * @n_segs: Number of STS segments. |
| */ |
| int n_segs; |
| /** |
| * @seg_len: Length of STS segments. |
| */ |
| int seg_len; |
| /** |
| * @sp2_tx_gap_4chips: For SP2 frame format, additional gap in unit of |
| * 4 chips between the end of the payload and the start of the STS, used |
| * for TX. |
| */ |
| int sp2_tx_gap_4chips; |
| /** |
| * @sp2_rx_gap_4chips: For SP2 frame format, additional gap in unit of |
| * 4 chips between the end of the payload and the start of the STS, used |
| * for RX. A0 and A1 bits in PHR are used to index the array. |
| */ |
| int sp2_rx_gap_4chips[MCPS802154_STS_N_SEGS_MAX]; |
| }; |
| |
| /** |
| * struct mcps802154_ops - Callback from MCPS to the driver. |
| */ |
| struct mcps802154_ops { |
| /** |
| * @start: Initialize device. Reception should not be activated. |
| * |
| * Return: 0 or error. |
| */ |
| int (*start)(struct mcps802154_llhw *llhw); |
| /** |
| * @stop: Stop device. Should stop any transmission or reception and put |
| * the device in a low power mode. |
| */ |
| void (*stop)(struct mcps802154_llhw *llhw); |
| /** |
| * @tx_frame: Transmit a frame. skb contains the buffer starting from |
| * the IEEE 802.15.4 header. The low-level driver should send the frame |
| * as specified in info. Receiver should be disabled automatically |
| * unless a frame is being received. |
| * |
| * The &frame_idx parameter gives the index of the frame in a "block". |
| * Frames from the same block (aka frame_idx > 0) should maintain the |
| * same synchronization. |
| * |
| * The &next_delay_dtu parameter gives the expected delay between the |
| * start of the transmitted frame and the next action. |
| * |
| * Return: 0, -ETIME if frame can not be sent at specified timestamp, |
| * -EBUSY if a reception is happening right now, or any other error. |
| */ |
| int (*tx_frame)(struct mcps802154_llhw *llhw, struct sk_buff *skb, |
| const struct mcps802154_tx_frame_info *info, |
| int frame_idx, int next_delay_dtu); |
| /** |
| * @rx_enable: Enable receiver. |
| * |
| * The &frame_idx parameter gives the index of the frame in a "block". |
| * Frames from the same block (aka frame_idx > 0) should maintain the |
| * same synchronization. |
| * |
| * The &next_delay_dtu parameter gives the expected delay between the |
| * start of the received frame or timeout event and the next action. |
| * |
| * Return: 0, -ETIME if receiver can not be enabled at specified |
| * timestamp, or any other error. |
| */ |
| int (*rx_enable)(struct mcps802154_llhw *llhw, |
| const struct mcps802154_rx_info *info, int frame_idx, |
| int next_delay_dtu); |
| /** |
| * @rx_disable: Disable receiver, or a programmed receiver enabling, |
| * unless a frame reception is happening right now. |
| * |
| * Return: 0, -EBUSY if a reception is happening right now, or any other |
| * error. |
| */ |
| int (*rx_disable)(struct mcps802154_llhw *llhw); |
| /** |
| * @rx_get_frame: Get previously received frame. MCPS calls this handler |
| * after a frame reception has been signaled by the low-level driver. |
| * |
| * The received buffer is owned by MCPS after this call. Only the |
| * requested information need to be filled in the information structure. |
| * |
| * Return: 0, -EBUSY if no longer available, or any other error. |
| */ |
| int (*rx_get_frame)(struct mcps802154_llhw *llhw, struct sk_buff **skb, |
| struct mcps802154_rx_frame_info *info); |
| /** |
| * @rx_get_error_frame: Get information on rejected frame. MCPS can call |
| * this handler after a frame rejection has been signaled by the |
| * low-level driver. |
| * |
| * In case of error, info flags must be cleared by this callback. |
| * |
| * Return: 0, -EBUSY if no longer available, or any other error. |
| */ |
| int (*rx_get_error_frame)(struct mcps802154_llhw *llhw, |
| struct mcps802154_rx_frame_info *info); |
| /** |
| * @idle: Put the device into idle mode without time limit or until the |
| * given timestamp. The driver should call &mcps802154_timer_expired() |
| * before the given timestamp so that an action can be programmed at the |
| * given timestamp. |
| * |
| * The &mcps802154_timer_expired() function must not be called |
| * immediately from this callback, but should be scheduled to be called |
| * later. |
| * |
| * If the driver is late, the regular handling of late actions will take |
| * care of the situation. |
| * |
| * Return: 0 or error. |
| */ |
| int (*idle)(struct mcps802154_llhw *llhw, bool timestamp, |
| u32 timestamp_dtu); |
| /** |
| * @reset: Reset device after an unrecoverable error. |
| * |
| * Return: 0 or error. |
| */ |
| int (*reset)(struct mcps802154_llhw *llhw); |
| /** |
| * @get_current_timestamp_dtu: Get current timestamp in device time |
| * unit. |
| * |
| * If the device is currently in a low power state, the eventual wake up |
| * delay should be added to the returned timestamp. |
| * |
| * If the current timestamp can not be determined precisely, it should |
| * return a pessimistic value, i.e. rounded up. |
| * |
| * Return: 0 or error. |
| */ |
| int (*get_current_timestamp_dtu)(struct mcps802154_llhw *llhw, |
| u32 *timestamp_dtu); |
| /** |
| * @tx_timestamp_dtu_to_rmarker_rctu: Compute the RMARKER timestamp in |
| * ranging counter time unit for a frame transmitted at given timestamp |
| * in device time unit (RDEV only). |
| * |
| * Return: The RMARKER timestamp. |
| */ |
| u64 (*tx_timestamp_dtu_to_rmarker_rctu)(struct mcps802154_llhw *llhw, |
| u32 tx_timestamp_dtu, |
| int ant_id); |
| /** |
| * @difference_timestamp_rctu: Compute the difference between two |
| * timestamp values. |
| * |
| * Return: The difference between A and B. |
| */ |
| s64 (*difference_timestamp_rctu)(struct mcps802154_llhw *llhw, |
| u64 timestamp_a_rctu, |
| u64 timestamp_b_rctu); |
| /** |
| * @compute_frame_duration_dtu: Compute the duration of a frame with |
| * given payload length (header and checksum included) using the current |
| * radio parameters. |
| * |
| * Return: The duration in device time unit. |
| */ |
| int (*compute_frame_duration_dtu)(struct mcps802154_llhw *llhw, |
| int payload_bytes); |
| /** |
| * @set_channel: Set channel parameters. |
| * |
| * Return: 0 or error. |
| */ |
| int (*set_channel)(struct mcps802154_llhw *llhw, u8 page, u8 channel, |
| u8 preamble_code); |
| /** |
| * @set_hrp_uwb_params: Set radio parameters for HRP UWB. |
| * |
| * The parameters in &mcps802154_llhw can change according to radio |
| * parameters. |
| * |
| * Return: 0 or error. |
| */ |
| int (*set_hrp_uwb_params)(struct mcps802154_llhw *llhw, int prf, |
| int psr, int sfd_selector, int phr_rate, |
| int data_rate); |
| /** |
| * @set_sts_params: Set STS parameters (ERDEV only). |
| * |
| * Return: 0 or error. |
| */ |
| int (*set_sts_params)(struct mcps802154_llhw *llhw, |
| const struct mcps802154_sts_params *params); |
| /** |
| * @set_hw_addr_filt: Set hardware filter parameters. |
| * |
| * Return: 0 or error. |
| */ |
| int (*set_hw_addr_filt)(struct mcps802154_llhw *llhw, |
| struct ieee802154_hw_addr_filt *filt, |
| unsigned long changed); |
| /** |
| * @set_txpower: Set transmission power. |
| * |
| * Return: 0 or error. |
| */ |
| int (*set_txpower)(struct mcps802154_llhw *llhw, s32 mbm); |
| /** |
| * @set_cca_mode: Set CCA mode. |
| * |
| * The CCA duration in &mcps802154_llhw can change according to CCA |
| * mode. |
| * |
| * Return: 0 or error. |
| */ |
| int (*set_cca_mode)(struct mcps802154_llhw *llhw, |
| const struct wpan_phy_cca *cca); |
| /** |
| * @set_cca_ed_level: Set CCA energy detection threshold. |
| * |
| * Return: 0 or error. |
| */ |
| int (*set_cca_ed_level)(struct mcps802154_llhw *llhw, s32 mbm); |
| /** |
| * @set_promiscuous_mode: Set promiscuous mode. |
| * |
| * Return: 0 or error. |
| */ |
| int (*set_promiscuous_mode)(struct mcps802154_llhw *llhw, bool on); |
| /** |
| * @set_scanning_mode: Set SW scanning mode. |
| * |
| * Return: 0 or error. |
| */ |
| int (*set_scanning_mode)(struct mcps802154_llhw *llhw, bool on); |
| /** |
| * @set_calibration: Set calibration value. |
| * |
| * Set the calibration parameter specified by the key string with the |
| * value specified in the provided buffer. The provided length must |
| * match the length returned by the @get_calibration() callback. |
| * |
| * Return: 0 or error. |
| */ |
| int (*set_calibration)(struct mcps802154_llhw *llhw, const char *key, |
| void *value, size_t length); |
| /** |
| * @get_calibration: Get calibration value. |
| * |
| * Get the calibration parameter specified by the key string into the |
| * provided buffer. |
| * |
| * Return: size of parameter written in buffer or error. |
| */ |
| int (*get_calibration)(struct mcps802154_llhw *llhw, const char *key, |
| void *value, size_t length); |
| /** |
| * @list_calibration: Returns list of accepted calibration key strings |
| * |
| * Return: NULL terminated strings pointer array. |
| */ |
| const char *const *(*list_calibration)(struct mcps802154_llhw *llhw); |
| /** |
| * @vendor_cmd: Run a vendor specific command. |
| * |
| * Do not (ab)use this feature to implement features that could be |
| * openly shared across drivers. |
| * |
| * Return: 0 or error. |
| */ |
| int (*vendor_cmd)(struct mcps802154_llhw *llhw, u32 vendor_id, |
| u32 subcmd, void *data, size_t data_len); |
| #ifdef CONFIG_MCPS802154_TESTMODE |
| /** |
| * @testmode_cmd: Run a testmode command. |
| * |
| * Return: 0 or error. |
| */ |
| int (*testmode_cmd)(struct mcps802154_llhw *llhw, void *data, int len); |
| #endif |
| }; |
| |
| #ifdef CONFIG_MCPS802154_TESTMODE |
| #define MCPS802154_TESTMODE_CMD(cmd) .testmode_cmd = (cmd), |
| #else |
| #define MCPS802154_TESTMODE_CMD(cmd) |
| #endif |
| |
| /** |
| * enum mcps802154_rx_error_type - Type of reception errors. |
| * @MCPS802154_RX_ERROR_NONE: |
| * RX successful. |
| * @MCPS802154_RX_ERROR_TIMEOUT: |
| * RX timeout. |
| * @MCPS802154_RX_ERROR_BAD_CKSUM: |
| * Checksum is not correct. |
| * @MCPS802154_RX_ERROR_UNCORRECTABLE: |
| * During reception, the error correction code detected an uncorrectable |
| * error. |
| * @MCPS802154_RX_ERROR_FILTERED: |
| * A received frame was rejected due to frame filter. |
| * @MCPS802154_RX_ERROR_SFD_TIMEOUT: |
| * A preamble has been detected but no SFD. |
| * @MCPS802154_RX_ERROR_OTHER: |
| * Other error, frame reception is aborted. |
| */ |
| enum mcps802154_rx_error_type { |
| MCPS802154_RX_ERROR_NONE = 0, |
| MCPS802154_RX_ERROR_TIMEOUT = 1, |
| MCPS802154_RX_ERROR_BAD_CKSUM = 2, |
| MCPS802154_RX_ERROR_UNCORRECTABLE = 3, |
| MCPS802154_RX_ERROR_FILTERED = 4, |
| MCPS802154_RX_ERROR_SFD_TIMEOUT = 5, |
| MCPS802154_RX_ERROR_OTHER = 6, |
| }; |
| |
| /** |
| * mcps802154_alloc_llhw() - Allocate a new low-level hardware device. |
| * @priv_data_len: Length of private data. |
| * @ops: Callbacks for this device. |
| * |
| * Return: A pointer to the new low-level hardware device, or %NULL on error. |
| */ |
| struct mcps802154_llhw *mcps802154_alloc_llhw(size_t priv_data_len, |
| const struct mcps802154_ops *ops); |
| |
| /** |
| * mcps802154_free_llhw() - Free low-level hardware descriptor. |
| * @llhw: Low-level device pointer. |
| * |
| * You must call mcps802154_unregister_hw() before calling this function. |
| */ |
| void mcps802154_free_llhw(struct mcps802154_llhw *llhw); |
| |
| /** |
| * mcps802154_register_llhw() - Register low-level hardware device. |
| * @llhw: Low-level device pointer. |
| * |
| * Return: 0 or error. |
| */ |
| int mcps802154_register_llhw(struct mcps802154_llhw *llhw); |
| |
| /** |
| * mcps802154_unregister_llhw() - Unregister low-level hardware device. |
| * @llhw: Low-level device pointer. |
| */ |
| void mcps802154_unregister_llhw(struct mcps802154_llhw *llhw); |
| |
| /** |
| * mcps802154_rx_frame() - Signal a frame reception. |
| * @llhw: Low-level device this frame came in on. |
| * |
| * The MCPS will call the &mcps802154_ops.rx_get_frame() handler to retrieve |
| * frame. |
| */ |
| void mcps802154_rx_frame(struct mcps802154_llhw *llhw); |
| |
| /** |
| * mcps802154_rx_timeout() - Signal a reception timeout. |
| * @llhw: Low-level device pointer. |
| */ |
| void mcps802154_rx_timeout(struct mcps802154_llhw *llhw); |
| |
| /** |
| * mcps802154_rx_error() - Signal a reception error. |
| * @llhw: Low-level device pointer. |
| * @error: Type of detected error. |
| * |
| * In case of filtered frame, the MCPS can call the |
| * &mcps802154_ops.rx_get_error_frame() handler to retrieve frame information. |
| */ |
| void mcps802154_rx_error(struct mcps802154_llhw *llhw, |
| enum mcps802154_rx_error_type error); |
| |
| /** |
| * mcps802154_tx_done() - Signal the end of an MCPS transmission. |
| * @llhw: Low-level device pointer. |
| */ |
| void mcps802154_tx_done(struct mcps802154_llhw *llhw); |
| |
| /** |
| * mcps802154_broken() - Signal an unrecoverable error, device needs to be |
| * reset. |
| * @llhw: Low-level device pointer. |
| */ |
| void mcps802154_broken(struct mcps802154_llhw *llhw); |
| |
| /** |
| * mcps802154_timer_expired() - Signal that a programmed timer expired. |
| * @llhw: Low-level device pointer. |
| * |
| * To be called before the timestamp given to &mcps802154_ops.idle() callback. |
| */ |
| void mcps802154_timer_expired(struct mcps802154_llhw *llhw); |
| |
| #ifdef CONFIG_MCPS802154_TESTMODE |
| /** |
| * mcps802154_testmode_alloc_reply_skb() - Allocate testmode reply. |
| * @llhw: Low-level device pointer. |
| * @approxlen: an upper bound of the length of the data that will |
| * be put into the skb. |
| * |
| * This function allocates and pre-fills an skb for a reply to |
| * the testmode command. Since it is intended for a reply, calling |
| * it outside of the @testmode_cmd operation is invalid. |
| * |
| * The returned skb is pre-filled with the netlink message's header |
| * and attribute's data and set up in a way that any data that is |
| * put into the skb (with skb_put(), nla_put() or similar) will end up |
| * being within the %MCPS802154_ATTR_TESTDATA attribute, so all |
| * that needs to be done with the skb is adding data for |
| * the corresponding userspace tool which can then read that data |
| * out of the testdata attribute. You must not modify the skb |
| * in any other way. |
| * |
| * When done, call mcps802154_testmode_reply() with the skb and return |
| * its error code as the result of the @testmode_cmd operation. |
| * |
| * Return: An allocated and pre-filled skb. %NULL if any errors happen. |
| */ |
| struct sk_buff * |
| mcps802154_testmode_alloc_reply_skb(struct mcps802154_llhw *llhw, |
| int approxlen); |
| |
| /** |
| * mcps802154_testmode_reply() - Send the reply skb. |
| * @llhw: Low-level device pointer. |
| * @skb: The skb, must have been allocated with |
| * mcps802154_testmode_alloc_reply_skb(). |
| * |
| * Since calling this function will usually be the last thing |
| * before returning from the @testmode_cmd you should return |
| * the error code. Note that this function consumes the skb |
| * regardless of the return value. |
| * |
| * Return: 0 or error. |
| */ |
| int mcps802154_testmode_reply(struct mcps802154_llhw *llhw, |
| struct sk_buff *skb); |
| #endif |
| |
| #endif /* NET_MCPS802154_H */ |