Path: blob/master/drivers/firewire/phy-packet-definitions.h
26378 views
// SPDX-License-Identifier: GPL-2.0-or-later1//2// phy-packet-definitions.h - The definitions of phy packet for IEEE 1394.3//4// Copyright (c) 2024 Takashi Sakamoto56#ifndef _FIREWIRE_PHY_PACKET_DEFINITIONS_H7#define _FIREWIRE_PHY_PACKET_DEFINITIONS_H89#define PACKET_IDENTIFIER_MASK 0xc000000010#define PACKET_IDENTIFIER_SHIFT 301112static inline unsigned int phy_packet_get_packet_identifier(u32 quadlet)13{14return (quadlet & PACKET_IDENTIFIER_MASK) >> PACKET_IDENTIFIER_SHIFT;15}1617static inline void phy_packet_set_packet_identifier(u32 *quadlet, unsigned int packet_identifier)18{19*quadlet &= ~PACKET_IDENTIFIER_MASK;20*quadlet |= (packet_identifier << PACKET_IDENTIFIER_SHIFT) & PACKET_IDENTIFIER_MASK;21}2223#define PHY_PACKET_PACKET_IDENTIFIER_PHY_CONFIG 02425#define PHY_CONFIG_ROOT_ID_MASK 0x3f00000026#define PHY_CONFIG_ROOT_ID_SHIFT 2427#define PHY_CONFIG_FORCE_ROOT_NODE_MASK 0x0080000028#define PHY_CONFIG_FORCE_ROOT_NODE_SHIFT 2329#define PHY_CONFIG_GAP_COUNT_OPTIMIZATION_MASK 0x0040000030#define PHY_CONFIG_GAP_COUNT_OPTIMIZATION_SHIFT 2231#define PHY_CONFIG_GAP_COUNT_MASK 0x003f000032#define PHY_CONFIG_GAP_COUNT_SHIFT 163334static inline unsigned int phy_packet_phy_config_get_root_id(u32 quadlet)35{36return (quadlet & PHY_CONFIG_ROOT_ID_MASK) >> PHY_CONFIG_ROOT_ID_SHIFT;37}3839static inline void phy_packet_phy_config_set_root_id(u32 *quadlet, unsigned int root_id)40{41*quadlet &= ~PHY_CONFIG_ROOT_ID_MASK;42*quadlet |= (root_id << PHY_CONFIG_ROOT_ID_SHIFT) & PHY_CONFIG_ROOT_ID_MASK;43}4445static inline bool phy_packet_phy_config_get_force_root_node(u32 quadlet)46{47return (quadlet & PHY_CONFIG_FORCE_ROOT_NODE_MASK) >> PHY_CONFIG_FORCE_ROOT_NODE_SHIFT;48}4950static inline void phy_packet_phy_config_set_force_root_node(u32 *quadlet, bool has_force_root_node)51{52*quadlet &= ~PHY_CONFIG_FORCE_ROOT_NODE_MASK;53*quadlet |= (has_force_root_node << PHY_CONFIG_FORCE_ROOT_NODE_SHIFT) & PHY_CONFIG_FORCE_ROOT_NODE_MASK;54}5556static inline bool phy_packet_phy_config_get_gap_count_optimization(u32 quadlet)57{58return (quadlet & PHY_CONFIG_GAP_COUNT_OPTIMIZATION_MASK) >> PHY_CONFIG_GAP_COUNT_OPTIMIZATION_SHIFT;59}6061static inline void phy_packet_phy_config_set_gap_count_optimization(u32 *quadlet, bool has_gap_count_optimization)62{63*quadlet &= ~PHY_CONFIG_GAP_COUNT_OPTIMIZATION_MASK;64*quadlet |= (has_gap_count_optimization << PHY_CONFIG_GAP_COUNT_OPTIMIZATION_SHIFT) & PHY_CONFIG_GAP_COUNT_OPTIMIZATION_MASK;65}6667static inline unsigned int phy_packet_phy_config_get_gap_count(u32 quadlet)68{69return (quadlet & PHY_CONFIG_GAP_COUNT_MASK) >> PHY_CONFIG_GAP_COUNT_SHIFT;70}7172static inline void phy_packet_phy_config_set_gap_count(u32 *quadlet, unsigned int gap_count)73{74*quadlet &= ~PHY_CONFIG_GAP_COUNT_MASK;75*quadlet |= (gap_count << PHY_CONFIG_GAP_COUNT_SHIFT) & PHY_CONFIG_GAP_COUNT_MASK;76}7778#define PHY_PACKET_PACKET_IDENTIFIER_SELF_ID 27980#define SELF_ID_PHY_ID_MASK 0x3f00000081#define SELF_ID_PHY_ID_SHIFT 2482#define SELF_ID_EXTENDED_MASK 0x0080000083#define SELF_ID_EXTENDED_SHIFT 2384#define SELF_ID_MORE_PACKETS_MASK 0x0000000185#define SELF_ID_MORE_PACKETS_SHIFT 08687#define SELF_ID_ZERO_LINK_ACTIVE_MASK 0x0040000088#define SELF_ID_ZERO_LINK_ACTIVE_SHIFT 2289#define SELF_ID_ZERO_GAP_COUNT_MASK 0x003f000090#define SELF_ID_ZERO_GAP_COUNT_SHIFT 1691#define SELF_ID_ZERO_SCODE_MASK 0x0000c00092#define SELF_ID_ZERO_SCODE_SHIFT 1493#define SELF_ID_ZERO_CONTENDER_MASK 0x0000080094#define SELF_ID_ZERO_CONTENDER_SHIFT 1195#define SELF_ID_ZERO_POWER_CLASS_MASK 0x0000070096#define SELF_ID_ZERO_POWER_CLASS_SHIFT 897#define SELF_ID_ZERO_INITIATED_RESET_MASK 0x0000000298#define SELF_ID_ZERO_INITIATED_RESET_SHIFT 199100#define SELF_ID_EXTENDED_SEQUENCE_MASK 0x00700000101#define SELF_ID_EXTENDED_SEQUENCE_SHIFT 20102103#define SELF_ID_PORT_STATUS_MASK 0x3104105#define SELF_ID_SEQUENCE_MAXIMUM_QUADLET_COUNT 4106107static inline unsigned int phy_packet_self_id_get_phy_id(u32 quadlet)108{109return (quadlet & SELF_ID_PHY_ID_MASK) >> SELF_ID_PHY_ID_SHIFT;110}111112static inline void phy_packet_self_id_set_phy_id(u32 *quadlet, unsigned int phy_id)113{114*quadlet &= ~SELF_ID_PHY_ID_MASK;115*quadlet |= (phy_id << SELF_ID_PHY_ID_SHIFT) & SELF_ID_PHY_ID_MASK;116}117118static inline bool phy_packet_self_id_get_extended(u32 quadlet)119{120return (quadlet & SELF_ID_EXTENDED_MASK) >> SELF_ID_EXTENDED_SHIFT;121}122123static inline void phy_packet_self_id_set_extended(u32 *quadlet, bool extended)124{125*quadlet &= ~SELF_ID_EXTENDED_MASK;126*quadlet |= (extended << SELF_ID_EXTENDED_SHIFT) & SELF_ID_EXTENDED_MASK;127}128129static inline bool phy_packet_self_id_zero_get_link_active(u32 quadlet)130{131return (quadlet & SELF_ID_ZERO_LINK_ACTIVE_MASK) >> SELF_ID_ZERO_LINK_ACTIVE_SHIFT;132}133134static inline void phy_packet_self_id_zero_set_link_active(u32 *quadlet, bool is_active)135{136*quadlet &= ~SELF_ID_ZERO_LINK_ACTIVE_MASK;137*quadlet |= (is_active << SELF_ID_ZERO_LINK_ACTIVE_SHIFT) & SELF_ID_ZERO_LINK_ACTIVE_MASK;138}139140static inline unsigned int phy_packet_self_id_zero_get_gap_count(u32 quadlet)141{142return (quadlet & SELF_ID_ZERO_GAP_COUNT_MASK) >> SELF_ID_ZERO_GAP_COUNT_SHIFT;143}144145static inline void phy_packet_self_id_zero_set_gap_count(u32 *quadlet, unsigned int gap_count)146{147*quadlet &= ~SELF_ID_ZERO_GAP_COUNT_MASK;148*quadlet |= (gap_count << SELF_ID_ZERO_GAP_COUNT_SHIFT) & SELF_ID_ZERO_GAP_COUNT_MASK;149}150151static inline unsigned int phy_packet_self_id_zero_get_scode(u32 quadlet)152{153return (quadlet & SELF_ID_ZERO_SCODE_MASK) >> SELF_ID_ZERO_SCODE_SHIFT;154}155156static inline void phy_packet_self_id_zero_set_scode(u32 *quadlet, unsigned int speed)157{158*quadlet &= ~SELF_ID_ZERO_SCODE_MASK;159*quadlet |= (speed << SELF_ID_ZERO_SCODE_SHIFT) & SELF_ID_ZERO_SCODE_MASK;160}161162static inline bool phy_packet_self_id_zero_get_contender(u32 quadlet)163{164return (quadlet & SELF_ID_ZERO_CONTENDER_MASK) >> SELF_ID_ZERO_CONTENDER_SHIFT;165}166167static inline void phy_packet_self_id_zero_set_contender(u32 *quadlet, bool is_contender)168{169*quadlet &= ~SELF_ID_ZERO_CONTENDER_MASK;170*quadlet |= (is_contender << SELF_ID_ZERO_CONTENDER_SHIFT) & SELF_ID_ZERO_CONTENDER_MASK;171}172173static inline unsigned int phy_packet_self_id_zero_get_power_class(u32 quadlet)174{175return (quadlet & SELF_ID_ZERO_POWER_CLASS_MASK) >> SELF_ID_ZERO_POWER_CLASS_SHIFT;176}177178static inline void phy_packet_self_id_zero_set_power_class(u32 *quadlet, unsigned int power_class)179{180*quadlet &= ~SELF_ID_ZERO_POWER_CLASS_MASK;181*quadlet |= (power_class << SELF_ID_ZERO_POWER_CLASS_SHIFT) & SELF_ID_ZERO_POWER_CLASS_MASK;182}183184static inline bool phy_packet_self_id_zero_get_initiated_reset(u32 quadlet)185{186return (quadlet & SELF_ID_ZERO_INITIATED_RESET_MASK) >> SELF_ID_ZERO_INITIATED_RESET_SHIFT;187}188189static inline void phy_packet_self_id_zero_set_initiated_reset(u32 *quadlet, bool is_initiated_reset)190{191*quadlet &= ~SELF_ID_ZERO_INITIATED_RESET_MASK;192*quadlet |= (is_initiated_reset << SELF_ID_ZERO_INITIATED_RESET_SHIFT) & SELF_ID_ZERO_INITIATED_RESET_MASK;193}194195static inline bool phy_packet_self_id_get_more_packets(u32 quadlet)196{197return (quadlet & SELF_ID_MORE_PACKETS_MASK) >> SELF_ID_MORE_PACKETS_SHIFT;198}199200static inline void phy_packet_self_id_set_more_packets(u32 *quadlet, bool is_more_packets)201{202*quadlet &= ~SELF_ID_MORE_PACKETS_MASK;203*quadlet |= (is_more_packets << SELF_ID_MORE_PACKETS_SHIFT) & SELF_ID_MORE_PACKETS_MASK;204}205206static inline unsigned int phy_packet_self_id_extended_get_sequence(u32 quadlet)207{208return (quadlet & SELF_ID_EXTENDED_SEQUENCE_MASK) >> SELF_ID_EXTENDED_SEQUENCE_SHIFT;209}210211static inline void phy_packet_self_id_extended_set_sequence(u32 *quadlet, unsigned int sequence)212{213*quadlet &= ~SELF_ID_EXTENDED_SEQUENCE_MASK;214*quadlet |= (sequence << SELF_ID_EXTENDED_SHIFT) & SELF_ID_EXTENDED_SEQUENCE_MASK;215}216217struct self_id_sequence_enumerator {218const u32 *cursor;219unsigned int quadlet_count;220};221222static inline const u32 *self_id_sequence_enumerator_next(223struct self_id_sequence_enumerator *enumerator, unsigned int *quadlet_count)224{225const u32 *self_id_sequence, *cursor;226u32 quadlet;227unsigned int count;228unsigned int sequence;229230if (enumerator->cursor == NULL || enumerator->quadlet_count == 0)231return ERR_PTR(-ENODATA);232cursor = enumerator->cursor;233count = 1;234235quadlet = *cursor;236sequence = 0;237while (phy_packet_self_id_get_more_packets(quadlet)) {238if (count >= enumerator->quadlet_count ||239count >= SELF_ID_SEQUENCE_MAXIMUM_QUADLET_COUNT)240return ERR_PTR(-EPROTO);241++cursor;242++count;243quadlet = *cursor;244245if (!phy_packet_self_id_get_extended(quadlet) ||246sequence != phy_packet_self_id_extended_get_sequence(quadlet))247return ERR_PTR(-EPROTO);248++sequence;249}250251*quadlet_count = count;252self_id_sequence = enumerator->cursor;253254enumerator->cursor += count;255enumerator->quadlet_count -= count;256257return self_id_sequence;258}259260enum phy_packet_self_id_port_status {261PHY_PACKET_SELF_ID_PORT_STATUS_NONE = 0,262PHY_PACKET_SELF_ID_PORT_STATUS_NCONN = 1,263PHY_PACKET_SELF_ID_PORT_STATUS_PARENT = 2,264PHY_PACKET_SELF_ID_PORT_STATUS_CHILD = 3,265};266267static inline unsigned int self_id_sequence_get_port_capacity(unsigned int quadlet_count)268{269return quadlet_count * 8 - 5;270}271272static inline enum phy_packet_self_id_port_status self_id_sequence_get_port_status(273const u32 *self_id_sequence, unsigned int quadlet_count, unsigned int port_index)274{275unsigned int index, shift;276277index = (port_index + 5) / 8;278shift = 16 - ((port_index + 5) % 8) * 2;279280if (index < quadlet_count && index < SELF_ID_SEQUENCE_MAXIMUM_QUADLET_COUNT)281return (self_id_sequence[index] >> shift) & SELF_ID_PORT_STATUS_MASK;282283return PHY_PACKET_SELF_ID_PORT_STATUS_NONE;284}285286static inline void self_id_sequence_set_port_status(u32 *self_id_sequence, unsigned int quadlet_count,287unsigned int port_index,288enum phy_packet_self_id_port_status status)289{290unsigned int index, shift;291292index = (port_index + 5) / 8;293shift = 16 - ((port_index + 5) % 8) * 2;294295if (index < quadlet_count) {296self_id_sequence[index] &= ~(SELF_ID_PORT_STATUS_MASK << shift);297self_id_sequence[index] |= status << shift;298}299}300301#endif // _FIREWIRE_PHY_PACKET_DEFINITIONS_H302303304