phy-packet-definitions.h 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. //
  3. // phy-packet-definitions.h - The definitions of phy packet for IEEE 1394.
  4. //
  5. // Copyright (c) 2024 Takashi Sakamoto
  6. #ifndef _FIREWIRE_PHY_PACKET_DEFINITIONS_H
  7. #define _FIREWIRE_PHY_PACKET_DEFINITIONS_H
  8. #define PACKET_IDENTIFIER_MASK 0xc0000000
  9. #define PACKET_IDENTIFIER_SHIFT 30
  10. static inline unsigned int phy_packet_get_packet_identifier(u32 quadlet)
  11. {
  12. return (quadlet & PACKET_IDENTIFIER_MASK) >> PACKET_IDENTIFIER_SHIFT;
  13. }
  14. static inline void phy_packet_set_packet_identifier(u32 *quadlet, unsigned int packet_identifier)
  15. {
  16. *quadlet &= ~PACKET_IDENTIFIER_MASK;
  17. *quadlet |= (packet_identifier << PACKET_IDENTIFIER_SHIFT) & PACKET_IDENTIFIER_MASK;
  18. }
  19. #define PHY_PACKET_PACKET_IDENTIFIER_PHY_CONFIG 0
  20. #define PHY_CONFIG_ROOT_ID_MASK 0x3f000000
  21. #define PHY_CONFIG_ROOT_ID_SHIFT 24
  22. #define PHY_CONFIG_FORCE_ROOT_NODE_MASK 0x00800000
  23. #define PHY_CONFIG_FORCE_ROOT_NODE_SHIFT 23
  24. #define PHY_CONFIG_GAP_COUNT_OPTIMIZATION_MASK 0x00400000
  25. #define PHY_CONFIG_GAP_COUNT_OPTIMIZATION_SHIFT 22
  26. #define PHY_CONFIG_GAP_COUNT_MASK 0x003f0000
  27. #define PHY_CONFIG_GAP_COUNT_SHIFT 16
  28. static inline unsigned int phy_packet_phy_config_get_root_id(u32 quadlet)
  29. {
  30. return (quadlet & PHY_CONFIG_ROOT_ID_MASK) >> PHY_CONFIG_ROOT_ID_SHIFT;
  31. }
  32. static inline void phy_packet_phy_config_set_root_id(u32 *quadlet, unsigned int root_id)
  33. {
  34. *quadlet &= ~PHY_CONFIG_ROOT_ID_MASK;
  35. *quadlet |= (root_id << PHY_CONFIG_ROOT_ID_SHIFT) & PHY_CONFIG_ROOT_ID_MASK;
  36. }
  37. static inline bool phy_packet_phy_config_get_force_root_node(u32 quadlet)
  38. {
  39. return (quadlet & PHY_CONFIG_FORCE_ROOT_NODE_MASK) >> PHY_CONFIG_FORCE_ROOT_NODE_SHIFT;
  40. }
  41. static inline void phy_packet_phy_config_set_force_root_node(u32 *quadlet, bool has_force_root_node)
  42. {
  43. *quadlet &= ~PHY_CONFIG_FORCE_ROOT_NODE_MASK;
  44. *quadlet |= (has_force_root_node << PHY_CONFIG_FORCE_ROOT_NODE_SHIFT) & PHY_CONFIG_FORCE_ROOT_NODE_MASK;
  45. }
  46. static inline bool phy_packet_phy_config_get_gap_count_optimization(u32 quadlet)
  47. {
  48. return (quadlet & PHY_CONFIG_GAP_COUNT_OPTIMIZATION_MASK) >> PHY_CONFIG_GAP_COUNT_OPTIMIZATION_SHIFT;
  49. }
  50. static inline void phy_packet_phy_config_set_gap_count_optimization(u32 *quadlet, bool has_gap_count_optimization)
  51. {
  52. *quadlet &= ~PHY_CONFIG_GAP_COUNT_OPTIMIZATION_MASK;
  53. *quadlet |= (has_gap_count_optimization << PHY_CONFIG_GAP_COUNT_OPTIMIZATION_SHIFT) & PHY_CONFIG_GAP_COUNT_OPTIMIZATION_MASK;
  54. }
  55. static inline unsigned int phy_packet_phy_config_get_gap_count(u32 quadlet)
  56. {
  57. return (quadlet & PHY_CONFIG_GAP_COUNT_MASK) >> PHY_CONFIG_GAP_COUNT_SHIFT;
  58. }
  59. static inline void phy_packet_phy_config_set_gap_count(u32 *quadlet, unsigned int gap_count)
  60. {
  61. *quadlet &= ~PHY_CONFIG_GAP_COUNT_MASK;
  62. *quadlet |= (gap_count << PHY_CONFIG_GAP_COUNT_SHIFT) & PHY_CONFIG_GAP_COUNT_MASK;
  63. }
  64. #define PHY_PACKET_PACKET_IDENTIFIER_SELF_ID 2
  65. #define SELF_ID_PHY_ID_MASK 0x3f000000
  66. #define SELF_ID_PHY_ID_SHIFT 24
  67. #define SELF_ID_EXTENDED_MASK 0x00800000
  68. #define SELF_ID_EXTENDED_SHIFT 23
  69. #define SELF_ID_MORE_PACKETS_MASK 0x00000001
  70. #define SELF_ID_MORE_PACKETS_SHIFT 0
  71. #define SELF_ID_ZERO_LINK_ACTIVE_MASK 0x00400000
  72. #define SELF_ID_ZERO_LINK_ACTIVE_SHIFT 22
  73. #define SELF_ID_ZERO_GAP_COUNT_MASK 0x003f0000
  74. #define SELF_ID_ZERO_GAP_COUNT_SHIFT 16
  75. #define SELF_ID_ZERO_SCODE_MASK 0x0000c000
  76. #define SELF_ID_ZERO_SCODE_SHIFT 14
  77. #define SELF_ID_ZERO_CONTENDER_MASK 0x00000800
  78. #define SELF_ID_ZERO_CONTENDER_SHIFT 11
  79. #define SELF_ID_ZERO_POWER_CLASS_MASK 0x00000700
  80. #define SELF_ID_ZERO_POWER_CLASS_SHIFT 8
  81. #define SELF_ID_ZERO_INITIATED_RESET_MASK 0x00000002
  82. #define SELF_ID_ZERO_INITIATED_RESET_SHIFT 1
  83. #define SELF_ID_EXTENDED_SEQUENCE_MASK 0x00700000
  84. #define SELF_ID_EXTENDED_SEQUENCE_SHIFT 20
  85. #define SELF_ID_PORT_STATUS_MASK 0x3
  86. #define SELF_ID_SEQUENCE_MAXIMUM_QUADLET_COUNT 4
  87. static inline unsigned int phy_packet_self_id_get_phy_id(u32 quadlet)
  88. {
  89. return (quadlet & SELF_ID_PHY_ID_MASK) >> SELF_ID_PHY_ID_SHIFT;
  90. }
  91. static inline void phy_packet_self_id_set_phy_id(u32 *quadlet, unsigned int phy_id)
  92. {
  93. *quadlet &= ~SELF_ID_PHY_ID_MASK;
  94. *quadlet |= (phy_id << SELF_ID_PHY_ID_SHIFT) & SELF_ID_PHY_ID_MASK;
  95. }
  96. static inline bool phy_packet_self_id_get_extended(u32 quadlet)
  97. {
  98. return (quadlet & SELF_ID_EXTENDED_MASK) >> SELF_ID_EXTENDED_SHIFT;
  99. }
  100. static inline void phy_packet_self_id_set_extended(u32 *quadlet, bool extended)
  101. {
  102. *quadlet &= ~SELF_ID_EXTENDED_MASK;
  103. *quadlet |= (extended << SELF_ID_EXTENDED_SHIFT) & SELF_ID_EXTENDED_MASK;
  104. }
  105. static inline bool phy_packet_self_id_zero_get_link_active(u32 quadlet)
  106. {
  107. return (quadlet & SELF_ID_ZERO_LINK_ACTIVE_MASK) >> SELF_ID_ZERO_LINK_ACTIVE_SHIFT;
  108. }
  109. static inline void phy_packet_self_id_zero_set_link_active(u32 *quadlet, bool is_active)
  110. {
  111. *quadlet &= ~SELF_ID_ZERO_LINK_ACTIVE_MASK;
  112. *quadlet |= (is_active << SELF_ID_ZERO_LINK_ACTIVE_SHIFT) & SELF_ID_ZERO_LINK_ACTIVE_MASK;
  113. }
  114. static inline unsigned int phy_packet_self_id_zero_get_gap_count(u32 quadlet)
  115. {
  116. return (quadlet & SELF_ID_ZERO_GAP_COUNT_MASK) >> SELF_ID_ZERO_GAP_COUNT_SHIFT;
  117. }
  118. static inline void phy_packet_self_id_zero_set_gap_count(u32 *quadlet, unsigned int gap_count)
  119. {
  120. *quadlet &= ~SELF_ID_ZERO_GAP_COUNT_MASK;
  121. *quadlet |= (gap_count << SELF_ID_ZERO_GAP_COUNT_SHIFT) & SELF_ID_ZERO_GAP_COUNT_MASK;
  122. }
  123. static inline unsigned int phy_packet_self_id_zero_get_scode(u32 quadlet)
  124. {
  125. return (quadlet & SELF_ID_ZERO_SCODE_MASK) >> SELF_ID_ZERO_SCODE_SHIFT;
  126. }
  127. static inline void phy_packet_self_id_zero_set_scode(u32 *quadlet, unsigned int speed)
  128. {
  129. *quadlet &= ~SELF_ID_ZERO_SCODE_MASK;
  130. *quadlet |= (speed << SELF_ID_ZERO_SCODE_SHIFT) & SELF_ID_ZERO_SCODE_MASK;
  131. }
  132. static inline bool phy_packet_self_id_zero_get_contender(u32 quadlet)
  133. {
  134. return (quadlet & SELF_ID_ZERO_CONTENDER_MASK) >> SELF_ID_ZERO_CONTENDER_SHIFT;
  135. }
  136. static inline void phy_packet_self_id_zero_set_contender(u32 *quadlet, bool is_contender)
  137. {
  138. *quadlet &= ~SELF_ID_ZERO_CONTENDER_MASK;
  139. *quadlet |= (is_contender << SELF_ID_ZERO_CONTENDER_SHIFT) & SELF_ID_ZERO_CONTENDER_MASK;
  140. }
  141. static inline unsigned int phy_packet_self_id_zero_get_power_class(u32 quadlet)
  142. {
  143. return (quadlet & SELF_ID_ZERO_POWER_CLASS_MASK) >> SELF_ID_ZERO_POWER_CLASS_SHIFT;
  144. }
  145. static inline void phy_packet_self_id_zero_set_power_class(u32 *quadlet, unsigned int power_class)
  146. {
  147. *quadlet &= ~SELF_ID_ZERO_POWER_CLASS_MASK;
  148. *quadlet |= (power_class << SELF_ID_ZERO_POWER_CLASS_SHIFT) & SELF_ID_ZERO_POWER_CLASS_MASK;
  149. }
  150. static inline bool phy_packet_self_id_zero_get_initiated_reset(u32 quadlet)
  151. {
  152. return (quadlet & SELF_ID_ZERO_INITIATED_RESET_MASK) >> SELF_ID_ZERO_INITIATED_RESET_SHIFT;
  153. }
  154. static inline void phy_packet_self_id_zero_set_initiated_reset(u32 *quadlet, bool is_initiated_reset)
  155. {
  156. *quadlet &= ~SELF_ID_ZERO_INITIATED_RESET_MASK;
  157. *quadlet |= (is_initiated_reset << SELF_ID_ZERO_INITIATED_RESET_SHIFT) & SELF_ID_ZERO_INITIATED_RESET_MASK;
  158. }
  159. static inline bool phy_packet_self_id_get_more_packets(u32 quadlet)
  160. {
  161. return (quadlet & SELF_ID_MORE_PACKETS_MASK) >> SELF_ID_MORE_PACKETS_SHIFT;
  162. }
  163. static inline void phy_packet_self_id_set_more_packets(u32 *quadlet, bool is_more_packets)
  164. {
  165. *quadlet &= ~SELF_ID_MORE_PACKETS_MASK;
  166. *quadlet |= (is_more_packets << SELF_ID_MORE_PACKETS_SHIFT) & SELF_ID_MORE_PACKETS_MASK;
  167. }
  168. static inline unsigned int phy_packet_self_id_extended_get_sequence(u32 quadlet)
  169. {
  170. return (quadlet & SELF_ID_EXTENDED_SEQUENCE_MASK) >> SELF_ID_EXTENDED_SEQUENCE_SHIFT;
  171. }
  172. static inline void phy_packet_self_id_extended_set_sequence(u32 *quadlet, unsigned int sequence)
  173. {
  174. *quadlet &= ~SELF_ID_EXTENDED_SEQUENCE_MASK;
  175. *quadlet |= (sequence << SELF_ID_EXTENDED_SHIFT) & SELF_ID_EXTENDED_SEQUENCE_MASK;
  176. }
  177. struct self_id_sequence_enumerator {
  178. const u32 *cursor;
  179. unsigned int quadlet_count;
  180. };
  181. static inline const u32 *self_id_sequence_enumerator_next(
  182. struct self_id_sequence_enumerator *enumerator, unsigned int *quadlet_count)
  183. {
  184. const u32 *self_id_sequence, *cursor;
  185. u32 quadlet;
  186. unsigned int count;
  187. unsigned int sequence;
  188. if (enumerator->cursor == NULL || enumerator->quadlet_count == 0)
  189. return ERR_PTR(-ENODATA);
  190. cursor = enumerator->cursor;
  191. count = 1;
  192. quadlet = *cursor;
  193. sequence = 0;
  194. while (phy_packet_self_id_get_more_packets(quadlet)) {
  195. if (count >= enumerator->quadlet_count ||
  196. count >= SELF_ID_SEQUENCE_MAXIMUM_QUADLET_COUNT)
  197. return ERR_PTR(-EPROTO);
  198. ++cursor;
  199. ++count;
  200. quadlet = *cursor;
  201. if (!phy_packet_self_id_get_extended(quadlet) ||
  202. sequence != phy_packet_self_id_extended_get_sequence(quadlet))
  203. return ERR_PTR(-EPROTO);
  204. ++sequence;
  205. }
  206. *quadlet_count = count;
  207. self_id_sequence = enumerator->cursor;
  208. enumerator->cursor += count;
  209. enumerator->quadlet_count -= count;
  210. return self_id_sequence;
  211. }
  212. enum phy_packet_self_id_port_status {
  213. PHY_PACKET_SELF_ID_PORT_STATUS_NONE = 0,
  214. PHY_PACKET_SELF_ID_PORT_STATUS_NCONN = 1,
  215. PHY_PACKET_SELF_ID_PORT_STATUS_PARENT = 2,
  216. PHY_PACKET_SELF_ID_PORT_STATUS_CHILD = 3,
  217. };
  218. static inline unsigned int self_id_sequence_get_port_capacity(unsigned int quadlet_count)
  219. {
  220. return quadlet_count * 8 - 5;
  221. }
  222. static inline enum phy_packet_self_id_port_status self_id_sequence_get_port_status(
  223. const u32 *self_id_sequence, unsigned int quadlet_count, unsigned int port_index)
  224. {
  225. unsigned int index, shift;
  226. index = (port_index + 5) / 8;
  227. shift = 16 - ((port_index + 5) % 8) * 2;
  228. if (index < quadlet_count && index < SELF_ID_SEQUENCE_MAXIMUM_QUADLET_COUNT)
  229. return (self_id_sequence[index] >> shift) & SELF_ID_PORT_STATUS_MASK;
  230. return PHY_PACKET_SELF_ID_PORT_STATUS_NONE;
  231. }
  232. static inline void self_id_sequence_set_port_status(u32 *self_id_sequence, unsigned int quadlet_count,
  233. unsigned int port_index,
  234. enum phy_packet_self_id_port_status status)
  235. {
  236. unsigned int index, shift;
  237. index = (port_index + 5) / 8;
  238. shift = 16 - ((port_index + 5) % 8) * 2;
  239. if (index < quadlet_count) {
  240. self_id_sequence[index] &= ~(SELF_ID_PORT_STATUS_MASK << shift);
  241. self_id_sequence[index] |= status << shift;
  242. }
  243. }
  244. #endif // _FIREWIRE_PHY_PACKET_DEFINITIONS_H