xref: /linux/drivers/phy/phy-common-props-test.c (revision d8f87aa5fa0a4276491fa8ef436cd22605a3f9ba)
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