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 */
phy_test_rx_polarity_is_missing(struct kunit * test)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 */
phy_test_rx_polarity_more_values_than_names(struct kunit * test)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 */
phy_test_rx_polarity_single_value_no_names(struct kunit * test)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 */
phy_test_rx_polarity_more_names_than_values(struct kunit * test)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 */
phy_test_rx_polarity_find_by_name(struct kunit * test)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 */
phy_test_rx_polarity_name_not_found_no_default(struct kunit * test)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 */
phy_test_rx_polarity_name_not_found_with_default(struct kunit * test)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 */
phy_test_rx_polarity_unsupported_value(struct kunit * test)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 */
phy_test_tx_polarity_is_missing(struct kunit * test)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 */
phy_test_tx_polarity_more_values_than_names(struct kunit * test)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 */
phy_test_tx_polarity_single_value_no_names(struct kunit * test)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 */
phy_test_tx_polarity_more_names_than_values(struct kunit * test)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 */
phy_test_tx_polarity_find_by_name(struct kunit * test)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 */
phy_test_tx_polarity_name_not_found_no_default(struct kunit * test)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 */
phy_test_tx_polarity_name_not_found_with_default(struct kunit * test)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) */
phy_test_tx_polarity_unsupported_value(struct kunit * test)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