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