1/*
2 * Copyright (c) 2012, 2015, The Linux Foundation. All rights reserved.
3 * Permission to use, copy, modify, and/or distribute this software for
4 * any purpose with or without fee is hereby granted, provided that the
5 * above copyright notice and this permission notice appear in all copies.
6 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
7 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
8 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
9 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
10 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
11 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
12 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
13 */
14
15
16/**
17 * @defgroup garuda_port_ctrl GARUDA_PORT_CONTROL
18 * @{
19 */
20#include "sw.h"
21#include "hsl.h"
22#include "hsl_dev.h"
23#include "hsl_port_prop.h"
24#include "garuda_port_ctrl.h"
25#include "garuda_reg.h"
26#include "hsl_phy.h"
27
28static sw_error_t
29_garuda_port_duplex_set(a_uint32_t dev_id, fal_port_t port_id,
30                        fal_port_duplex_t duplex)
31{
32    sw_error_t rv;
33    a_uint32_t phy_id = 0;
34    a_uint32_t reg_save = 0;
35    a_uint32_t reg_val = 0;
36    hsl_phy_ops_t *phy_drv;
37
38    HSL_DEV_ID_CHECK(dev_id);
39
40    if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY))
41    {
42        return SW_BAD_PARAM;
43    }
44
45    SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id));
46    if (NULL == phy_drv->phy_duplex_set)
47    	  return SW_NOT_SUPPORTED;
48
49    if (FAL_DUPLEX_BUTT <= duplex)
50    {
51        return SW_BAD_PARAM;
52    }
53
54    rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id);
55    SW_RTN_ON_ERROR(rv);
56
57    //save reg value
58    HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id,
59                      (a_uint8_t *) (&reg_val), sizeof (a_uint32_t));
60    reg_save = reg_val;
61
62    SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 0, reg_val);
63    SW_SET_REG_BY_FIELD(PORT_STATUS, RXMAC_EN, 0, reg_val);
64    SW_SET_REG_BY_FIELD(PORT_STATUS, TXMAC_EN, 0, reg_val);
65
66    //set mac be config by sw   and turn off RX TX MAC_EN
67    HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id,
68                      (a_uint8_t *) (&reg_val), sizeof (a_uint32_t));
69
70    rv = phy_drv->phy_duplex_set(dev_id, phy_id, duplex);
71
72    //retore reg value
73    HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id,
74                      (a_uint8_t *) (&reg_save), sizeof (a_uint32_t));
75
76    return rv;
77}
78
79
80static sw_error_t
81_garuda_port_duplex_get(a_uint32_t dev_id, fal_port_t port_id,
82                        fal_port_duplex_t * pduplex)
83{
84    sw_error_t rv;
85    a_uint32_t phy_id;
86    hsl_phy_ops_t *phy_drv;
87
88    HSL_DEV_ID_CHECK(dev_id);
89
90    if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY))
91    {
92        return SW_BAD_PARAM;
93    }
94
95    SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id));
96    if (NULL == phy_drv->phy_duplex_get)
97         return SW_NOT_SUPPORTED;
98
99    rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id);
100    SW_RTN_ON_ERROR(rv);
101
102    rv = phy_drv->phy_duplex_get(dev_id, phy_id, pduplex);
103    return rv;
104}
105
106static sw_error_t
107_garuda_port_speed_set(a_uint32_t dev_id, fal_port_t port_id,
108                       fal_port_speed_t speed)
109{
110    sw_error_t rv;
111    a_uint32_t phy_id = 0;
112    hsl_phy_ops_t *phy_drv;
113
114    HSL_DEV_ID_CHECK(dev_id);
115
116    if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY))
117    {
118        return SW_BAD_PARAM;
119    }
120
121    SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id));
122    if (NULL == phy_drv->phy_speed_set)
123         return SW_NOT_SUPPORTED;
124
125    rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id);
126    SW_RTN_ON_ERROR(rv);
127
128    if (FAL_SPEED_1000 < speed)
129    {
130        return SW_BAD_PARAM;
131    }
132
133    rv = phy_drv->phy_speed_set(dev_id, phy_id, speed);
134
135    return rv;
136}
137
138
139static sw_error_t
140_garuda_port_speed_get(a_uint32_t dev_id, fal_port_t port_id,
141                       fal_port_speed_t * pspeed)
142{
143    sw_error_t rv;
144    a_uint32_t phy_id;
145    hsl_phy_ops_t *phy_drv;
146
147    HSL_DEV_ID_CHECK(dev_id);
148
149    if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY))
150    {
151        return SW_BAD_PARAM;
152    }
153
154    SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id));
155    if (NULL == phy_drv->phy_speed_get)
156        return SW_NOT_SUPPORTED;
157
158    rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id);
159    SW_RTN_ON_ERROR(rv);
160
161    rv = phy_drv->phy_speed_get(dev_id, phy_id, pspeed);
162
163    return rv;
164}
165
166static sw_error_t
167_garuda_port_autoneg_status_get(a_uint32_t dev_id, fal_port_t port_id,
168                                a_bool_t * status)
169{
170    a_uint32_t phy_id;
171    sw_error_t rv;
172    hsl_phy_ops_t *phy_drv;
173
174    HSL_DEV_ID_CHECK(dev_id);
175
176    if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY))
177    {
178        return SW_BAD_PARAM;
179    }
180
181    SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id));
182    if (NULL == phy_drv->phy_autoneg_status_get)
183        return SW_NOT_SUPPORTED;
184
185    rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id);
186    SW_RTN_ON_ERROR(rv);
187
188    *status = phy_drv->phy_autoneg_status_get (dev_id, phy_id);
189
190    return SW_OK;
191}
192
193static sw_error_t
194_garuda_port_autoneg_enable(a_uint32_t dev_id, fal_port_t port_id)
195{
196    sw_error_t rv;
197    a_uint32_t phy_id;
198    hsl_phy_ops_t *phy_drv;
199
200    HSL_DEV_ID_CHECK(dev_id);
201
202    if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY))
203    {
204        return SW_BAD_PARAM;
205    }
206
207    SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id));
208    if (NULL == phy_drv->phy_autoneg_enable_set)
209 	  return SW_NOT_SUPPORTED;
210
211    rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id);
212    SW_RTN_ON_ERROR(rv);
213
214    rv = phy_drv->phy_autoneg_enable_set(dev_id, phy_id);
215    return rv;
216}
217
218static sw_error_t
219_garuda_port_autoneg_restart(a_uint32_t dev_id, fal_port_t port_id)
220{
221    sw_error_t rv;
222    a_uint32_t phy_id;
223    hsl_phy_ops_t *phy_drv;
224
225    HSL_DEV_ID_CHECK(dev_id);
226
227    if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY))
228    {
229        return SW_BAD_PARAM;
230    }
231
232    SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id));
233    if (NULL == phy_drv->phy_restart_autoneg)
234	 return SW_NOT_SUPPORTED;
235
236    rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id);
237    SW_RTN_ON_ERROR(rv);
238
239    rv = phy_drv->phy_restart_autoneg(dev_id, phy_id);
240    return rv;
241}
242
243
244static sw_error_t
245_garuda_port_autoneg_adv_set(a_uint32_t dev_id, fal_port_t port_id,
246                             a_uint32_t autoadv)
247{
248    sw_error_t rv;
249    a_uint32_t phy_id;
250    hsl_phy_ops_t *phy_drv;
251
252    HSL_DEV_ID_CHECK(dev_id);
253
254    if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY))
255    {
256        return SW_BAD_PARAM;
257    }
258
259    SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id));
260    if (NULL == phy_drv->phy_autoneg_adv_set)
261    	 return SW_NOT_SUPPORTED;
262
263    rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id);
264    SW_RTN_ON_ERROR(rv);
265
266    rv = phy_drv->phy_autoneg_adv_set(dev_id, phy_id, autoadv);
267    SW_RTN_ON_ERROR(rv);
268
269    return SW_OK;
270}
271
272
273static sw_error_t
274_garuda_port_autoneg_adv_get(a_uint32_t dev_id, fal_port_t port_id,
275                             a_uint32_t * autoadv)
276{
277    sw_error_t rv;
278    a_uint32_t phy_id;
279    hsl_phy_ops_t *phy_drv;
280
281    HSL_DEV_ID_CHECK(dev_id);
282
283    if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY))
284    {
285        return SW_BAD_PARAM;
286    }
287
288    SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id));
289    if (NULL == phy_drv->phy_autoneg_adv_get)
290        return SW_NOT_SUPPORTED;
291
292    rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id);
293    SW_RTN_ON_ERROR(rv);
294
295    *autoadv = 0;
296    rv = phy_drv->phy_autoneg_adv_get(dev_id, phy_id, autoadv);
297    SW_RTN_ON_ERROR(rv);
298
299    return SW_OK;
300}
301
302static sw_error_t
303_garuda_port_hdr_status_set(a_uint32_t dev_id, fal_port_t port_id,
304                            a_bool_t enable)
305{
306    sw_error_t rv;
307    a_uint32_t val;
308
309    HSL_DEV_ID_CHECK(dev_id);
310
311    if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU))
312    {
313        return SW_BAD_PARAM;
314    }
315
316    if (A_TRUE == enable)
317    {
318        val = 1;
319    }
320    else if (A_FALSE == enable)
321    {
322        val = 0;
323    }
324    else
325    {
326        return SW_BAD_PARAM;
327    }
328
329    HSL_REG_FIELD_SET(rv, dev_id, PORT_CTL, port_id, HEAD_EN,
330                      (a_uint8_t *) (&val), sizeof (a_uint32_t));
331
332    return rv;
333}
334
335static sw_error_t
336_garuda_port_hdr_status_get(a_uint32_t dev_id, fal_port_t port_id,
337                            a_bool_t * enable)
338{
339    sw_error_t rv;
340    a_uint32_t val;
341
342    HSL_DEV_ID_CHECK(dev_id);
343
344    if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU))
345    {
346        return SW_BAD_PARAM;
347    }
348
349    HSL_REG_FIELD_GET(rv, dev_id, PORT_CTL, port_id, HEAD_EN,
350                      (a_uint8_t *) (&val), sizeof (a_uint32_t));
351    SW_RTN_ON_ERROR(rv);
352
353    if (1 == val)
354    {
355        *enable = A_TRUE;
356    }
357    else
358    {
359        *enable = A_FALSE;
360    }
361
362    return rv;
363}
364
365static sw_error_t
366_garuda_port_flowctrl_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable)
367{
368    sw_error_t rv;
369    a_uint32_t val, force, reg;
370
371    if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU))
372    {
373        return SW_BAD_PARAM;
374    }
375
376    if (A_TRUE == enable)
377    {
378        val = 1;
379    }
380    else if (A_FALSE == enable)
381    {
382        val = 0;
383    }
384    else
385    {
386        return SW_BAD_PARAM;
387    }
388
389    HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id,
390                      (a_uint8_t *) (&reg), sizeof (a_uint32_t));
391    SW_RTN_ON_ERROR(rv);
392
393    SW_GET_FIELD_BY_REG(PORT_STATUS, FLOW_LINK_EN, force, reg);
394    if (force)
395    {
396        /* flow control isn't in force mode so can't set */
397        return SW_DISABLE;
398    }
399
400    SW_SET_REG_BY_FIELD(PORT_STATUS, RX_FLOW_EN, val, reg);
401    SW_SET_REG_BY_FIELD(PORT_STATUS, TX_FLOW_EN, val, reg);
402    SW_SET_REG_BY_FIELD(PORT_STATUS, TX_HALF_FLOW_EN, val, reg);
403
404    HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id,
405                      (a_uint8_t *) (&reg), sizeof (a_uint32_t));
406    return rv;
407}
408
409
410static sw_error_t
411_garuda_port_flowctrl_get(a_uint32_t dev_id, fal_port_t port_id,
412                          a_bool_t * enable)
413{
414    sw_error_t rv;
415    a_uint32_t tx, rx, reg;
416
417    if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU))
418    {
419        return SW_BAD_PARAM;
420    }
421
422    HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id,
423                      (a_uint8_t *) (&reg), sizeof (a_uint32_t));
424    SW_RTN_ON_ERROR(rv);
425
426    SW_GET_FIELD_BY_REG(PORT_STATUS, RX_FLOW_EN, rx, reg);
427    SW_GET_FIELD_BY_REG(PORT_STATUS, TX_FLOW_EN, tx, reg);
428
429    if (1 == rx)
430    {
431        *enable = A_TRUE;
432    }
433    else
434    {
435        *enable = A_FALSE;
436    }
437
438    return SW_OK;
439}
440
441static sw_error_t
442_garuda_port_flowctrl_forcemode_set(a_uint32_t dev_id, fal_port_t port_id,
443                                    a_bool_t enable)
444{
445    sw_error_t rv;
446    a_uint32_t force, reg;
447
448    if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU))
449    {
450        return SW_BAD_PARAM;
451    }
452
453    HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id,
454                      (a_uint8_t *) (&reg), sizeof (a_uint32_t));
455    SW_RTN_ON_ERROR(rv);
456
457    SW_GET_FIELD_BY_REG(PORT_STATUS, FLOW_LINK_EN, force, reg);
458    if (force != (a_uint32_t) enable)
459    {
460        return SW_OK;
461    }
462
463    if (A_TRUE == enable)
464    {
465        SW_SET_REG_BY_FIELD(PORT_STATUS, FLOW_LINK_EN, 0, reg);
466        SW_SET_REG_BY_FIELD(PORT_STATUS, TX_FLOW_EN, 0, reg);
467        SW_SET_REG_BY_FIELD(PORT_STATUS, RX_FLOW_EN, 0, reg);
468    }
469    else if (A_FALSE == enable)
470    {
471        SW_SET_REG_BY_FIELD(PORT_STATUS, FLOW_LINK_EN, 1, reg);
472    }
473    else
474    {
475        return SW_BAD_PARAM;
476    }
477    SW_SET_REG_BY_FIELD(PORT_STATUS, TX_HALF_FLOW_EN, 0, reg);
478
479    HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id,
480                      (a_uint8_t *) (&reg), sizeof (a_uint32_t));
481    return rv;
482}
483
484static sw_error_t
485_garuda_port_flowctrl_forcemode_get(a_uint32_t dev_id, fal_port_t port_id,
486                                    a_bool_t * enable)
487{
488    sw_error_t rv;
489    a_uint32_t force, reg;
490
491    if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU))
492    {
493        return SW_BAD_PARAM;
494    }
495
496    HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id,
497                      (a_uint8_t *) (&reg), sizeof (a_uint32_t));
498    SW_RTN_ON_ERROR(rv);
499
500    SW_GET_FIELD_BY_REG(PORT_STATUS, FLOW_LINK_EN, force, reg);
501    if (0 == force)
502    {
503        *enable = A_TRUE;
504    }
505    else
506    {
507        *enable = A_FALSE;
508    }
509
510    return SW_OK;
511}
512
513static sw_error_t
514_garuda_port_powersave_set(a_uint32_t dev_id, fal_port_t port_id,
515                           a_bool_t enable)
516{
517    sw_error_t rv;
518    a_uint32_t phy_id = 0;
519    hsl_phy_ops_t *phy_drv;
520
521    HSL_DEV_ID_CHECK(dev_id);
522
523    if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY))
524    {
525        return SW_BAD_PARAM;
526    }
527
528   SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id));
529   if (NULL == phy_drv->phy_powersave_set)
530	 return SW_NOT_SUPPORTED;
531
532    rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id);
533    SW_RTN_ON_ERROR(rv);
534
535    rv = phy_drv->phy_powersave_set(dev_id, phy_id, enable);
536
537    return rv;
538}
539
540static sw_error_t
541_garuda_port_powersave_get(a_uint32_t dev_id, fal_port_t port_id,
542                           a_bool_t *enable)
543{
544    sw_error_t rv;
545    a_uint32_t phy_id = 0;
546    hsl_phy_ops_t *phy_drv;
547
548    HSL_DEV_ID_CHECK(dev_id);
549
550    if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY))
551    {
552        return SW_BAD_PARAM;
553    }
554
555    SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id));
556    if (NULL == phy_drv->phy_powersave_get)
557         return SW_NOT_SUPPORTED;
558
559    rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id);
560    SW_RTN_ON_ERROR(rv);
561
562    rv = phy_drv->phy_powersave_get(dev_id, phy_id, enable);
563
564    return rv;
565}
566
567static sw_error_t
568_garuda_port_hibernate_set(a_uint32_t dev_id, fal_port_t port_id,
569                           a_bool_t enable)
570{
571    sw_error_t rv;
572    a_uint32_t phy_id = 0;
573    hsl_phy_ops_t *phy_drv;
574
575    HSL_DEV_ID_CHECK(dev_id);
576
577    if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY))
578    {
579        return SW_BAD_PARAM;
580    }
581
582    SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id));
583    if (NULL == phy_drv->phy_hibernation_set)
584        return SW_NOT_SUPPORTED;
585
586    rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id);
587    SW_RTN_ON_ERROR(rv);
588
589    rv = phy_drv->phy_hibernation_set(dev_id, phy_id, enable);
590
591    return rv;
592}
593
594static sw_error_t
595_garuda_port_hibernate_get(a_uint32_t dev_id, fal_port_t port_id,
596                           a_bool_t *enable)
597{
598    sw_error_t rv;
599    a_uint32_t phy_id = 0;
600    hsl_phy_ops_t *phy_drv;
601
602    HSL_DEV_ID_CHECK(dev_id);
603
604    if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY))
605    {
606        return SW_BAD_PARAM;
607    }
608
609    SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id));
610    if (NULL == phy_drv->phy_hibernation_get)
611        return SW_NOT_SUPPORTED;
612
613    rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id);
614    SW_RTN_ON_ERROR(rv);
615
616    rv = phy_drv->phy_hibernation_get(dev_id, phy_id, enable);
617
618    return rv;
619}
620
621static sw_error_t
622_garuda_port_cdt(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t mdi_pair,
623                 fal_cable_status_t *cable_status, a_uint32_t *cable_len)
624{
625    sw_error_t rv;
626    a_uint32_t phy_id = 0;
627    hsl_phy_ops_t *phy_drv;
628
629    HSL_DEV_ID_CHECK(dev_id);
630
631    if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY))
632    {
633        return SW_BAD_PARAM;
634    }
635
636    SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id));
637    if (NULL == phy_drv->phy_cdt)
638        return SW_NOT_SUPPORTED;
639
640    rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id);
641    SW_RTN_ON_ERROR(rv);
642
643    rv = phy_drv->phy_cdt(dev_id, phy_id, mdi_pair, cable_status, cable_len);
644
645    return rv;
646}
647
648/**
649 * @brief Set duplex mode on a particular port.
650 * @param[in] dev_id device id
651 * @param[in] port_id port id
652 * @param[in] duplex duplex mode
653 * @return SW_OK or error code
654 */
655HSL_LOCAL sw_error_t
656garuda_port_duplex_set(a_uint32_t dev_id, fal_port_t port_id,
657                       fal_port_duplex_t duplex)
658{
659    sw_error_t rv;
660
661    HSL_API_LOCK;
662    rv = _garuda_port_duplex_set(dev_id, port_id, duplex);
663    HSL_API_UNLOCK;
664    return rv;
665}
666
667/**
668 * @brief Get duplex mode on a particular port.
669 * @param[in] dev_id device id
670 * @param[in] port_id port id
671 * @param[out] duplex duplex mode
672 * @return SW_OK or error code
673 */
674HSL_LOCAL sw_error_t
675garuda_port_duplex_get(a_uint32_t dev_id, fal_port_t port_id,
676                       fal_port_duplex_t * pduplex)
677{
678    sw_error_t rv;
679
680    HSL_API_LOCK;
681    rv = _garuda_port_duplex_get(dev_id, port_id, pduplex);
682    HSL_API_UNLOCK;
683    return rv;
684}
685
686/**
687 * @brief Set speed on a particular port.
688 * @param[in] dev_id device id
689 * @param[in] port_id port id
690 * @param[in] speed port speed
691 * @return SW_OK or error code
692 */
693HSL_LOCAL sw_error_t
694garuda_port_speed_set(a_uint32_t dev_id, fal_port_t port_id,
695                      fal_port_speed_t speed)
696{
697    sw_error_t rv;
698
699    HSL_API_LOCK;
700    rv = _garuda_port_speed_set(dev_id, port_id, speed);
701    HSL_API_UNLOCK;
702    return rv;
703}
704
705/**
706 * @brief Get speed on a particular port.
707 * @param[in] dev_id device id
708 * @param[in] port_id port id
709 * @param[out] speed port speed
710 * @return SW_OK or error code
711 */
712HSL_LOCAL sw_error_t
713garuda_port_speed_get(a_uint32_t dev_id, fal_port_t port_id,
714                      fal_port_speed_t * pspeed)
715{
716    sw_error_t rv;
717
718    HSL_API_LOCK;
719    rv = _garuda_port_speed_get(dev_id, port_id, pspeed);
720    HSL_API_UNLOCK;
721    return rv;
722}
723
724/**
725 * @brief Get auto negotiation status on a particular port.
726 * @param[in] dev_id device id
727 * @param[in] port_id port id
728 * @param[out] status A_TRUE or A_FALSE
729 * @return SW_OK or error code
730 */
731HSL_LOCAL sw_error_t
732garuda_port_autoneg_status_get(a_uint32_t dev_id, fal_port_t port_id,
733                               a_bool_t * status)
734{
735    sw_error_t rv;
736
737    HSL_API_LOCK;
738    rv = _garuda_port_autoneg_status_get(dev_id, port_id, status);
739    HSL_API_UNLOCK;
740    return rv;
741}
742
743/**
744 * @brief Enable auto negotiation status on a particular port.
745 * @param[in] dev_id device id
746 * @param[in] port_id port id
747 * @return SW_OK or error code
748 */
749HSL_LOCAL sw_error_t
750garuda_port_autoneg_enable(a_uint32_t dev_id, fal_port_t port_id)
751{
752    sw_error_t rv;
753
754    HSL_API_LOCK;
755    rv = _garuda_port_autoneg_enable(dev_id, port_id);
756    HSL_API_UNLOCK;
757    return rv;
758}
759
760/**
761 * @brief Restart auto negotiation procedule on a particular port.
762 * @param[in] dev_id device id
763 * @param[in] port_id port id
764 * @return SW_OK or error code
765 */
766HSL_LOCAL sw_error_t
767garuda_port_autoneg_restart(a_uint32_t dev_id, fal_port_t port_id)
768{
769    sw_error_t rv;
770
771    HSL_API_LOCK;
772    rv = _garuda_port_autoneg_restart(dev_id, port_id);
773    HSL_API_UNLOCK;
774    return rv;
775}
776
777/**
778 * @brief Set auto negotiation advtisement ability on a particular port.
779 *   @details  Comments:
780 *   auto negotiation advtisement ability is defined by macro such as
781 *   FAL_PHY_ADV_10T_HD, FAL_PHY_ADV_PAUSE...
782 * @param[in] dev_id device id
783 * @param[in] port_id port id
784 * @param[in] autoadv auto negotiation advtisement ability bit map
785 * @return SW_OK or error code
786 */
787HSL_LOCAL sw_error_t
788garuda_port_autoneg_adv_set(a_uint32_t dev_id, fal_port_t port_id,
789                            a_uint32_t autoadv)
790{
791    sw_error_t rv;
792
793    HSL_API_LOCK;
794    rv = _garuda_port_autoneg_adv_set(dev_id, port_id, autoadv);
795    HSL_API_UNLOCK;
796    return rv;
797}
798
799/**
800 * @brief Get auto negotiation advtisement ability on a particular port.
801 * @param[in] dev_id device id
802 * @param[in] port_id port id
803 * @param[out] autoadv auto negotiation advtisement ability bit map
804 * @return SW_OK or error code
805 */
806HSL_LOCAL sw_error_t
807garuda_port_autoneg_adv_get(a_uint32_t dev_id, fal_port_t port_id,
808                            a_uint32_t * autoadv)
809{
810    sw_error_t rv;
811
812    HSL_API_LOCK;
813    rv = _garuda_port_autoneg_adv_get(dev_id, port_id, autoadv);
814    HSL_API_UNLOCK;
815    return rv;
816}
817
818/**
819 * @brief Set status of Atheros header packets parsed on a particular port.
820 * @param[in] dev_id device id
821 * @param[in] port_id port id
822 * @param[in] enable A_TRUE or A_FALSE
823 * @return SW_OK or error code
824 */
825HSL_LOCAL sw_error_t
826garuda_port_hdr_status_set(a_uint32_t dev_id, fal_port_t port_id,
827                           a_bool_t enable)
828{
829    sw_error_t rv;
830
831    HSL_API_LOCK;
832    rv = _garuda_port_hdr_status_set(dev_id, port_id, enable);
833    HSL_API_UNLOCK;
834    return rv;
835}
836
837/**
838 * @brief Get status of Atheros header packets parsed on a particular port.
839 * @param[in] dev_id device id
840 * @param[in] port_id port id
841 * @param[out] enable A_TRUE or A_FALSE
842 * @return SW_OK or error code
843 */
844HSL_LOCAL sw_error_t
845garuda_port_hdr_status_get(a_uint32_t dev_id, fal_port_t port_id,
846                           a_bool_t * enable)
847{
848    sw_error_t rv;
849
850    HSL_API_LOCK;
851    rv = _garuda_port_hdr_status_get(dev_id, port_id, enable);
852    HSL_API_UNLOCK;
853    return rv;
854}
855
856/**
857 * @brief Set flow control status on a particular port.
858 * @param[in] dev_id device id
859 * @param[in] port_id port id
860 * @param[in] enable A_TRUE or A_FALSE
861 * @return SW_OK or error code
862 */
863HSL_LOCAL sw_error_t
864garuda_port_flowctrl_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable)
865{
866    sw_error_t rv;
867
868    HSL_API_LOCK;
869    rv = _garuda_port_flowctrl_set(dev_id, port_id, enable);
870    HSL_API_UNLOCK;
871    return rv;
872}
873
874/**
875 * @brief Get flow control status on a particular port.
876 * @param[in] dev_id device id
877 * @param[in] port_id port id
878 * @param[out] enable A_TRUE or A_FALSE
879 * @return SW_OK or error code
880 */
881HSL_LOCAL sw_error_t
882garuda_port_flowctrl_get(a_uint32_t dev_id, fal_port_t port_id,
883                         a_bool_t * enable)
884{
885    sw_error_t rv;
886
887    HSL_API_LOCK;
888    rv = _garuda_port_flowctrl_get(dev_id, port_id, enable);
889    HSL_API_UNLOCK;
890    return rv;
891}
892
893/**
894 * @brief Set flow control force mode on a particular port.
895 * @param[in] dev_id device id
896 * @param[in] port_id port id
897 * @param[out] enable A_TRUE or A_FALSE
898 * @return SW_OK or error code
899 */
900HSL_LOCAL sw_error_t
901garuda_port_flowctrl_forcemode_set(a_uint32_t dev_id, fal_port_t port_id,
902                                   a_bool_t enable)
903{
904    sw_error_t rv;
905
906    HSL_API_LOCK;
907    rv = _garuda_port_flowctrl_forcemode_set(dev_id, port_id, enable);
908    HSL_API_UNLOCK;
909    return rv;
910}
911
912/**
913 * @brief Get flow control force mode on a particular port.
914 * @param[in] dev_id device id
915 * @param[in] port_id port id
916 * @param[out] enable A_TRUE or A_FALSE
917 * @return SW_OK or error code
918 */
919HSL_LOCAL sw_error_t
920garuda_port_flowctrl_forcemode_get(a_uint32_t dev_id, fal_port_t port_id,
921                                   a_bool_t * enable)
922{
923    sw_error_t rv;
924
925    HSL_API_LOCK;
926    rv = _garuda_port_flowctrl_forcemode_get(dev_id, port_id, enable);
927    HSL_API_UNLOCK;
928    return rv;
929}
930
931/**
932 * @brief Set powersaving status on a particular port.
933 * @param[in] dev_id device id
934 * @param[in] port_id port id
935 * @param[out] enable A_TRUE or A_FALSE
936 * @return SW_OK or error code
937 */
938HSL_LOCAL sw_error_t
939garuda_port_powersave_set(a_uint32_t dev_id, fal_port_t port_id,
940                          a_bool_t enable)
941{
942    sw_error_t rv;
943
944    HSL_API_LOCK;
945    rv = _garuda_port_powersave_set(dev_id, port_id, enable);
946    HSL_API_UNLOCK;
947    return rv;
948}
949
950/**
951 * @brief Get powersaving status on a particular port.
952 * @param[in] dev_id device id
953 * @param[in] port_id port id
954 * @param[out] enable A_TRUE or A_FALSE
955 * @return SW_OK or error code
956 */
957HSL_LOCAL sw_error_t
958garuda_port_powersave_get(a_uint32_t dev_id, fal_port_t port_id,
959                          a_bool_t *enable)
960{
961    sw_error_t rv;
962
963    HSL_API_LOCK;
964    rv = _garuda_port_powersave_get(dev_id, port_id, enable);
965    HSL_API_UNLOCK;
966    return rv;
967}
968
969/**
970 * @brief Set hibernate status on a particular port.
971 * @param[in] dev_id device id
972 * @param[in] port_id port id
973 * @param[out] enable A_TRUE or A_FALSE
974 * @return SW_OK or error code
975 */
976HSL_LOCAL sw_error_t
977garuda_port_hibernate_set(a_uint32_t dev_id, fal_port_t port_id,
978                          a_bool_t enable)
979{
980    sw_error_t rv;
981
982    HSL_API_LOCK;
983    rv = _garuda_port_hibernate_set(dev_id, port_id, enable);
984    HSL_API_UNLOCK;
985    return rv;
986}
987
988/**
989 * @brief Get hibernate status on a particular port.
990 * @param[in] dev_id device id
991 * @param[in] port_id port id
992 * @param[out] enable A_TRUE or A_FALSE
993 * @return SW_OK or error code
994 */
995HSL_LOCAL sw_error_t
996garuda_port_hibernate_get(a_uint32_t dev_id, fal_port_t port_id,
997                          a_bool_t *enable)
998{
999    sw_error_t rv;
1000
1001    HSL_API_LOCK;
1002    rv = _garuda_port_hibernate_get(dev_id, port_id, enable);
1003    HSL_API_UNLOCK;
1004    return rv;
1005}
1006
1007/**
1008 * @brief Run cable diagnostic test on a particular port.
1009 * @param[in] dev_id device id
1010 * @param[in] port_id port id
1011 * @param[in] mdi_pair mdi pair id
1012 * @param[out] cable_status cable status
1013 * @param[out] cable_len cable len
1014 * @return SW_OK or error code
1015 */
1016HSL_LOCAL sw_error_t
1017garuda_port_cdt(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t mdi_pair,
1018                fal_cable_status_t *cable_status, a_uint32_t *cable_len)
1019{
1020    sw_error_t rv;
1021
1022    HSL_API_LOCK;
1023    rv = _garuda_port_cdt(dev_id, port_id, mdi_pair, cable_status, cable_len);
1024    HSL_API_UNLOCK;
1025    return rv;
1026}
1027
1028sw_error_t
1029garuda_port_ctrl_init(a_uint32_t dev_id)
1030{
1031    HSL_DEV_ID_CHECK(dev_id);
1032
1033#ifndef HSL_STANDALONG
1034    {
1035        hsl_api_t *p_api;
1036
1037        SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id));
1038
1039        p_api->port_duplex_get = garuda_port_duplex_get;
1040        p_api->port_duplex_set = garuda_port_duplex_set;
1041        p_api->port_speed_get = garuda_port_speed_get;
1042        p_api->port_speed_set = garuda_port_speed_set;
1043        p_api->port_autoneg_status_get = garuda_port_autoneg_status_get;
1044        p_api->port_autoneg_enable = garuda_port_autoneg_enable;
1045        p_api->port_autoneg_restart = garuda_port_autoneg_restart;
1046        p_api->port_autoneg_adv_get = garuda_port_autoneg_adv_get;
1047        p_api->port_autoneg_adv_set = garuda_port_autoneg_adv_set;
1048        p_api->port_hdr_status_set = garuda_port_hdr_status_set;
1049        p_api->port_hdr_status_get = garuda_port_hdr_status_get;
1050        p_api->port_flowctrl_set = garuda_port_flowctrl_set;
1051        p_api->port_flowctrl_get = garuda_port_flowctrl_get;
1052        p_api->port_flowctrl_forcemode_set = garuda_port_flowctrl_forcemode_set;
1053        p_api->port_flowctrl_forcemode_get = garuda_port_flowctrl_forcemode_get;
1054        p_api->port_powersave_set = garuda_port_powersave_set;
1055        p_api->port_powersave_get = garuda_port_powersave_get;
1056        p_api->port_hibernate_set = garuda_port_hibernate_set;
1057        p_api->port_hibernate_get = garuda_port_hibernate_get;
1058        p_api->port_cdt           = garuda_port_cdt;
1059
1060    }
1061#endif
1062
1063    return SW_OK;
1064}
1065
1066/**
1067 * @}
1068 */
1069
1070