1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * phy-common-props-test.c -- Unit tests for PHY common properties API 4 * 5 * Copyright 2025-2026 NXP 6 */ 7 #include <kunit/test.h> 8 #include <linux/property.h> 9 #include <linux/phy/phy-common-props.h> 10 #include <dt-bindings/phy/phy.h> 11 12 /* Test: rx-polarity property is missing */ 13 static void phy_test_rx_polarity_is_missing(struct kunit *test) 14 { 15 static const struct property_entry entries[] = { 16 {} 17 }; 18 struct fwnode_handle *node; 19 unsigned int val; 20 int ret; 21 22 node = fwnode_create_software_node(entries, NULL); 23 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, node); 24 25 ret = phy_get_manual_rx_polarity(node, "sgmii", &val); 26 KUNIT_EXPECT_EQ(test, ret, 0); 27 KUNIT_EXPECT_EQ(test, val, PHY_POL_NORMAL); 28 29 fwnode_remove_software_node(node); 30 } 31 32 /* Test: rx-polarity has more values than rx-polarity-names */ 33 static void phy_test_rx_polarity_more_values_than_names(struct kunit *test) 34 { 35 static const u32 rx_pol[] = { PHY_POL_NORMAL, PHY_POL_INVERT, PHY_POL_NORMAL }; 36 static const char * const rx_pol_names[] = { "sgmii", "2500base-x" }; 37 static const struct property_entry entries[] = { 38 PROPERTY_ENTRY_U32_ARRAY("rx-polarity", rx_pol), 39 PROPERTY_ENTRY_STRING_ARRAY("rx-polarity-names", rx_pol_names), 40 {} 41 }; 42 struct fwnode_handle *node; 43 unsigned int val; 44 int ret; 45 46 node = fwnode_create_software_node(entries, NULL); 47 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, node); 48 49 ret = phy_get_manual_rx_polarity(node, "sgmii", &val); 50 KUNIT_EXPECT_EQ(test, ret, -EINVAL); 51 52 fwnode_remove_software_node(node); 53 } 54 55 /* Test: rx-polarity has 1 value and rx-polarity-names does not exist */ 56 static void phy_test_rx_polarity_single_value_no_names(struct kunit *test) 57 { 58 static const u32 rx_pol[] = { PHY_POL_INVERT }; 59 static const struct property_entry entries[] = { 60 PROPERTY_ENTRY_U32_ARRAY("rx-polarity", rx_pol), 61 {} 62 }; 63 struct fwnode_handle *node; 64 unsigned int val; 65 int ret; 66 67 node = fwnode_create_software_node(entries, NULL); 68 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, node); 69 70 ret = phy_get_manual_rx_polarity(node, "sgmii", &val); 71 KUNIT_EXPECT_EQ(test, ret, 0); 72 KUNIT_EXPECT_EQ(test, val, PHY_POL_INVERT); 73 74 fwnode_remove_software_node(node); 75 } 76 77 /* Test: rx-polarity-names has more values than rx-polarity */ 78 static void phy_test_rx_polarity_more_names_than_values(struct kunit *test) 79 { 80 static const u32 rx_pol[] = { PHY_POL_NORMAL, PHY_POL_INVERT }; 81 static const char * const rx_pol_names[] = { "sgmii", "2500base-x", "1000base-x" }; 82 static const struct property_entry entries[] = { 83 PROPERTY_ENTRY_U32_ARRAY("rx-polarity", rx_pol), 84 PROPERTY_ENTRY_STRING_ARRAY("rx-polarity-names", rx_pol_names), 85 {} 86 }; 87 struct fwnode_handle *node; 88 unsigned int val; 89 int ret; 90 91 node = fwnode_create_software_node(entries, NULL); 92 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, node); 93 94 ret = phy_get_manual_rx_polarity(node, "sgmii", &val); 95 KUNIT_EXPECT_EQ(test, ret, -EINVAL); 96 97 fwnode_remove_software_node(node); 98 } 99 100 /* Test: rx-polarity and rx-polarity-names have same length, find the name */ 101 static void phy_test_rx_polarity_find_by_name(struct kunit *test) 102 { 103 static const u32 rx_pol[] = { PHY_POL_NORMAL, PHY_POL_INVERT, PHY_POL_AUTO }; 104 static const char * const rx_pol_names[] = { "sgmii", "2500base-x", "usb-ss" }; 105 static const struct property_entry entries[] = { 106 PROPERTY_ENTRY_U32_ARRAY("rx-polarity", rx_pol), 107 PROPERTY_ENTRY_STRING_ARRAY("rx-polarity-names", rx_pol_names), 108 {} 109 }; 110 struct fwnode_handle *node; 111 unsigned int val; 112 int ret; 113 114 node = fwnode_create_software_node(entries, NULL); 115 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, node); 116 117 ret = phy_get_manual_rx_polarity(node, "sgmii", &val); 118 KUNIT_EXPECT_EQ(test, ret, 0); 119 KUNIT_EXPECT_EQ(test, val, PHY_POL_NORMAL); 120 121 ret = phy_get_manual_rx_polarity(node, "2500base-x", &val); 122 KUNIT_EXPECT_EQ(test, ret, 0); 123 KUNIT_EXPECT_EQ(test, val, PHY_POL_INVERT); 124 125 ret = phy_get_rx_polarity(node, "usb-ss", BIT(PHY_POL_AUTO), 126 PHY_POL_AUTO, &val); 127 KUNIT_EXPECT_EQ(test, ret, 0); 128 KUNIT_EXPECT_EQ(test, val, PHY_POL_AUTO); 129 130 fwnode_remove_software_node(node); 131 } 132 133 /* Test: same length, name not found, no "default" - error */ 134 static void phy_test_rx_polarity_name_not_found_no_default(struct kunit *test) 135 { 136 static const u32 rx_pol[] = { PHY_POL_NORMAL, PHY_POL_INVERT }; 137 static const char * const rx_pol_names[] = { "2500base-x", "1000base-x" }; 138 static const struct property_entry entries[] = { 139 PROPERTY_ENTRY_U32_ARRAY("rx-polarity", rx_pol), 140 PROPERTY_ENTRY_STRING_ARRAY("rx-polarity-names", rx_pol_names), 141 {} 142 }; 143 struct fwnode_handle *node; 144 unsigned int val; 145 int ret; 146 147 node = fwnode_create_software_node(entries, NULL); 148 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, node); 149 150 ret = phy_get_manual_rx_polarity(node, "sgmii", &val); 151 KUNIT_EXPECT_EQ(test, ret, -EINVAL); 152 153 fwnode_remove_software_node(node); 154 } 155 156 /* Test: same length, name not found, but "default" exists */ 157 static void phy_test_rx_polarity_name_not_found_with_default(struct kunit *test) 158 { 159 static const u32 rx_pol[] = { PHY_POL_NORMAL, PHY_POL_INVERT }; 160 static const char * const rx_pol_names[] = { "2500base-x", "default" }; 161 static const struct property_entry entries[] = { 162 PROPERTY_ENTRY_U32_ARRAY("rx-polarity", rx_pol), 163 PROPERTY_ENTRY_STRING_ARRAY("rx-polarity-names", rx_pol_names), 164 {} 165 }; 166 struct fwnode_handle *node; 167 unsigned int val; 168 int ret; 169 170 node = fwnode_create_software_node(entries, NULL); 171 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, node); 172 173 ret = phy_get_manual_rx_polarity(node, "sgmii", &val); 174 KUNIT_EXPECT_EQ(test, ret, 0); 175 KUNIT_EXPECT_EQ(test, val, PHY_POL_INVERT); 176 177 fwnode_remove_software_node(node); 178 } 179 180 /* Test: polarity found but value is unsupported */ 181 static void phy_test_rx_polarity_unsupported_value(struct kunit *test) 182 { 183 static const u32 rx_pol[] = { PHY_POL_AUTO }; 184 static const char * const rx_pol_names[] = { "sgmii" }; 185 static const struct property_entry entries[] = { 186 PROPERTY_ENTRY_U32_ARRAY("rx-polarity", rx_pol), 187 PROPERTY_ENTRY_STRING_ARRAY("rx-polarity-names", rx_pol_names), 188 {} 189 }; 190 struct fwnode_handle *node; 191 unsigned int val; 192 int ret; 193 194 node = fwnode_create_software_node(entries, NULL); 195 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, node); 196 197 ret = phy_get_manual_rx_polarity(node, "sgmii", &val); 198 KUNIT_EXPECT_EQ(test, ret, -EOPNOTSUPP); 199 200 fwnode_remove_software_node(node); 201 } 202 203 /* Test: tx-polarity property is missing */ 204 static void phy_test_tx_polarity_is_missing(struct kunit *test) 205 { 206 static const struct property_entry entries[] = { 207 {} 208 }; 209 struct fwnode_handle *node; 210 unsigned int val; 211 int ret; 212 213 node = fwnode_create_software_node(entries, NULL); 214 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, node); 215 216 ret = phy_get_manual_tx_polarity(node, "sgmii", &val); 217 KUNIT_EXPECT_EQ(test, ret, 0); 218 KUNIT_EXPECT_EQ(test, val, PHY_POL_NORMAL); 219 220 fwnode_remove_software_node(node); 221 } 222 223 /* Test: tx-polarity has more values than tx-polarity-names */ 224 static void phy_test_tx_polarity_more_values_than_names(struct kunit *test) 225 { 226 static const u32 tx_pol[] = { PHY_POL_NORMAL, PHY_POL_INVERT, PHY_POL_NORMAL }; 227 static const char * const tx_pol_names[] = { "sgmii", "2500base-x" }; 228 static const struct property_entry entries[] = { 229 PROPERTY_ENTRY_U32_ARRAY("tx-polarity", tx_pol), 230 PROPERTY_ENTRY_STRING_ARRAY("tx-polarity-names", tx_pol_names), 231 {} 232 }; 233 struct fwnode_handle *node; 234 unsigned int val; 235 int ret; 236 237 node = fwnode_create_software_node(entries, NULL); 238 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, node); 239 240 ret = phy_get_manual_tx_polarity(node, "sgmii", &val); 241 KUNIT_EXPECT_EQ(test, ret, -EINVAL); 242 243 fwnode_remove_software_node(node); 244 } 245 246 /* Test: tx-polarity has 1 value and tx-polarity-names does not exist */ 247 static void phy_test_tx_polarity_single_value_no_names(struct kunit *test) 248 { 249 static const u32 tx_pol[] = { PHY_POL_INVERT }; 250 static const struct property_entry entries[] = { 251 PROPERTY_ENTRY_U32_ARRAY("tx-polarity", tx_pol), 252 {} 253 }; 254 struct fwnode_handle *node; 255 unsigned int val; 256 int ret; 257 258 node = fwnode_create_software_node(entries, NULL); 259 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, node); 260 261 ret = phy_get_manual_tx_polarity(node, "sgmii", &val); 262 KUNIT_EXPECT_EQ(test, ret, 0); 263 KUNIT_EXPECT_EQ(test, val, PHY_POL_INVERT); 264 265 fwnode_remove_software_node(node); 266 } 267 268 /* Test: tx-polarity-names has more values than tx-polarity */ 269 static void phy_test_tx_polarity_more_names_than_values(struct kunit *test) 270 { 271 static const u32 tx_pol[] = { PHY_POL_NORMAL, PHY_POL_INVERT }; 272 static const char * const tx_pol_names[] = { "sgmii", "2500base-x", "1000base-x" }; 273 static const struct property_entry entries[] = { 274 PROPERTY_ENTRY_U32_ARRAY("tx-polarity", tx_pol), 275 PROPERTY_ENTRY_STRING_ARRAY("tx-polarity-names", tx_pol_names), 276 {} 277 }; 278 struct fwnode_handle *node; 279 unsigned int val; 280 int ret; 281 282 node = fwnode_create_software_node(entries, NULL); 283 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, node); 284 285 ret = phy_get_manual_tx_polarity(node, "sgmii", &val); 286 KUNIT_EXPECT_EQ(test, ret, -EINVAL); 287 288 fwnode_remove_software_node(node); 289 } 290 291 /* Test: tx-polarity and tx-polarity-names have same length, find the name */ 292 static void phy_test_tx_polarity_find_by_name(struct kunit *test) 293 { 294 static const u32 tx_pol[] = { PHY_POL_NORMAL, PHY_POL_INVERT, PHY_POL_NORMAL }; 295 static const char * const tx_pol_names[] = { "sgmii", "2500base-x", "1000base-x" }; 296 static const struct property_entry entries[] = { 297 PROPERTY_ENTRY_U32_ARRAY("tx-polarity", tx_pol), 298 PROPERTY_ENTRY_STRING_ARRAY("tx-polarity-names", tx_pol_names), 299 {} 300 }; 301 struct fwnode_handle *node; 302 unsigned int val; 303 int ret; 304 305 node = fwnode_create_software_node(entries, NULL); 306 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, node); 307 308 ret = phy_get_manual_tx_polarity(node, "sgmii", &val); 309 KUNIT_EXPECT_EQ(test, ret, 0); 310 KUNIT_EXPECT_EQ(test, val, PHY_POL_NORMAL); 311 312 ret = phy_get_manual_tx_polarity(node, "2500base-x", &val); 313 KUNIT_EXPECT_EQ(test, ret, 0); 314 KUNIT_EXPECT_EQ(test, val, PHY_POL_INVERT); 315 316 ret = phy_get_manual_tx_polarity(node, "1000base-x", &val); 317 KUNIT_EXPECT_EQ(test, ret, 0); 318 KUNIT_EXPECT_EQ(test, val, PHY_POL_NORMAL); 319 320 fwnode_remove_software_node(node); 321 } 322 323 /* Test: same length, name not found, no "default" - error */ 324 static void phy_test_tx_polarity_name_not_found_no_default(struct kunit *test) 325 { 326 static const u32 tx_pol[] = { PHY_POL_NORMAL, PHY_POL_INVERT }; 327 static const char * const tx_pol_names[] = { "2500base-x", "1000base-x" }; 328 static const struct property_entry entries[] = { 329 PROPERTY_ENTRY_U32_ARRAY("tx-polarity", tx_pol), 330 PROPERTY_ENTRY_STRING_ARRAY("tx-polarity-names", tx_pol_names), 331 {} 332 }; 333 struct fwnode_handle *node; 334 unsigned int val; 335 int ret; 336 337 node = fwnode_create_software_node(entries, NULL); 338 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, node); 339 340 ret = phy_get_manual_tx_polarity(node, "sgmii", &val); 341 KUNIT_EXPECT_EQ(test, ret, -EINVAL); 342 343 fwnode_remove_software_node(node); 344 } 345 346 /* Test: same length, name not found, but "default" exists */ 347 static void phy_test_tx_polarity_name_not_found_with_default(struct kunit *test) 348 { 349 static const u32 tx_pol[] = { PHY_POL_NORMAL, PHY_POL_INVERT }; 350 static const char * const tx_pol_names[] = { "2500base-x", "default" }; 351 static const struct property_entry entries[] = { 352 PROPERTY_ENTRY_U32_ARRAY("tx-polarity", tx_pol), 353 PROPERTY_ENTRY_STRING_ARRAY("tx-polarity-names", tx_pol_names), 354 {} 355 }; 356 struct fwnode_handle *node; 357 unsigned int val; 358 int ret; 359 360 node = fwnode_create_software_node(entries, NULL); 361 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, node); 362 363 ret = phy_get_manual_tx_polarity(node, "sgmii", &val); 364 KUNIT_EXPECT_EQ(test, ret, 0); 365 KUNIT_EXPECT_EQ(test, val, PHY_POL_INVERT); 366 367 fwnode_remove_software_node(node); 368 } 369 370 /* Test: polarity found but value is unsupported (AUTO for TX) */ 371 static void phy_test_tx_polarity_unsupported_value(struct kunit *test) 372 { 373 static const u32 tx_pol[] = { PHY_POL_AUTO }; 374 static const char * const tx_pol_names[] = { "sgmii" }; 375 static const struct property_entry entries[] = { 376 PROPERTY_ENTRY_U32_ARRAY("tx-polarity", tx_pol), 377 PROPERTY_ENTRY_STRING_ARRAY("tx-polarity-names", tx_pol_names), 378 {} 379 }; 380 struct fwnode_handle *node; 381 unsigned int val; 382 int ret; 383 384 node = fwnode_create_software_node(entries, NULL); 385 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, node); 386 387 ret = phy_get_manual_tx_polarity(node, "sgmii", &val); 388 KUNIT_EXPECT_EQ(test, ret, -EOPNOTSUPP); 389 390 fwnode_remove_software_node(node); 391 } 392 393 static struct kunit_case phy_common_props_test_cases[] = { 394 KUNIT_CASE(phy_test_rx_polarity_is_missing), 395 KUNIT_CASE(phy_test_rx_polarity_more_values_than_names), 396 KUNIT_CASE(phy_test_rx_polarity_single_value_no_names), 397 KUNIT_CASE(phy_test_rx_polarity_more_names_than_values), 398 KUNIT_CASE(phy_test_rx_polarity_find_by_name), 399 KUNIT_CASE(phy_test_rx_polarity_name_not_found_no_default), 400 KUNIT_CASE(phy_test_rx_polarity_name_not_found_with_default), 401 KUNIT_CASE(phy_test_rx_polarity_unsupported_value), 402 KUNIT_CASE(phy_test_tx_polarity_is_missing), 403 KUNIT_CASE(phy_test_tx_polarity_more_values_than_names), 404 KUNIT_CASE(phy_test_tx_polarity_single_value_no_names), 405 KUNIT_CASE(phy_test_tx_polarity_more_names_than_values), 406 KUNIT_CASE(phy_test_tx_polarity_find_by_name), 407 KUNIT_CASE(phy_test_tx_polarity_name_not_found_no_default), 408 KUNIT_CASE(phy_test_tx_polarity_name_not_found_with_default), 409 KUNIT_CASE(phy_test_tx_polarity_unsupported_value), 410 {} 411 }; 412 413 static struct kunit_suite phy_common_props_test_suite = { 414 .name = "phy-common-props", 415 .test_cases = phy_common_props_test_cases, 416 }; 417 418 kunit_test_suite(phy_common_props_test_suite); 419 420 MODULE_DESCRIPTION("Test module for PHY common properties API"); 421 MODULE_AUTHOR("Vladimir Oltean <vladimir.oltean@nxp.com>"); 422 MODULE_LICENSE("GPL"); 423