]> CyberLeo.Net >> Repos - FreeBSD/releng/8.2.git/blob - sys/contrib/octeon-sdk/cvmx-mdio.h
Copy stable/8 to releng/8.2 in preparation for FreeBSD-8.2 release.
[FreeBSD/releng/8.2.git] / sys / contrib / octeon-sdk / cvmx-mdio.h
1 /***********************license start***************
2  *  Copyright (c) 2003-2008 Cavium Networks (support@cavium.com). All rights
3  *  reserved.
4  *
5  *
6  *  Redistribution and use in source and binary forms, with or without
7  *  modification, are permitted provided that the following conditions are
8  *  met:
9  *
10  *      * Redistributions of source code must retain the above copyright
11  *        notice, this list of conditions and the following disclaimer.
12  *
13  *      * Redistributions in binary form must reproduce the above
14  *        copyright notice, this list of conditions and the following
15  *        disclaimer in the documentation and/or other materials provided
16  *        with the distribution.
17  *
18  *      * Neither the name of Cavium Networks nor the names of
19  *        its contributors may be used to endorse or promote products
20  *        derived from this software without specific prior written
21  *        permission.
22  *
23  *  TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
24  *  AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS
25  *  OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH
26  *  RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY
27  *  REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT
28  *  DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES
29  *  OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR
30  *  PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET
31  *  POSSESSION OR CORRESPONDENCE TO DESCRIPTION.  THE ENTIRE RISK ARISING OUT
32  *  OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
33  *
34  *
35  *  For any questions regarding licensing please contact marketing@caviumnetworks.com
36  *
37  ***********************license end**************************************/
38
39
40
41
42
43
44 /**
45  * @file
46  *
47  * Interface to the SMI/MDIO hardware, including support for both IEEE 802.3
48  * clause 22 and clause 45 operations.
49  *
50  * <hr>$Revision: 41586 $<hr>
51  */
52
53 #ifndef __CVMX_MIO_H__
54 #define __CVMX_MIO_H__
55
56 #ifdef  __cplusplus
57 extern "C" {
58 #endif
59
60 /**
61  * PHY register 0 from the 802.3 spec
62  */
63 #define CVMX_MDIO_PHY_REG_CONTROL 0
64 typedef union
65 {
66     uint16_t u16;
67     struct
68     {
69         uint16_t reset : 1;
70         uint16_t loopback : 1;
71         uint16_t speed_lsb : 1;
72         uint16_t autoneg_enable : 1;
73         uint16_t power_down : 1;
74         uint16_t isolate : 1;
75         uint16_t restart_autoneg : 1;
76         uint16_t duplex : 1;
77         uint16_t collision_test : 1;
78         uint16_t speed_msb : 1;
79         uint16_t unidirectional_enable : 1;
80         uint16_t reserved_0_4 : 5;
81     } s;
82 } cvmx_mdio_phy_reg_control_t;
83
84 /**
85  * PHY register 1 from the 802.3 spec
86  */
87 #define CVMX_MDIO_PHY_REG_STATUS 1
88 typedef union
89 {
90     uint16_t u16;
91     struct
92     {
93         uint16_t capable_100base_t4 : 1;
94         uint16_t capable_100base_x_full : 1;
95         uint16_t capable_100base_x_half : 1;
96         uint16_t capable_10_full : 1;
97         uint16_t capable_10_half : 1;
98         uint16_t capable_100base_t2_full : 1;
99         uint16_t capable_100base_t2_half : 1;
100         uint16_t capable_extended_status : 1;
101         uint16_t capable_unidirectional : 1;
102         uint16_t capable_mf_preamble_suppression : 1;
103         uint16_t autoneg_complete : 1;
104         uint16_t remote_fault : 1;
105         uint16_t capable_autoneg : 1;
106         uint16_t link_status : 1;
107         uint16_t jabber_detect : 1;
108         uint16_t capable_extended_registers : 1;
109
110     } s;
111 } cvmx_mdio_phy_reg_status_t;
112
113 /**
114  * PHY register 2 from the 802.3 spec
115  */
116 #define CVMX_MDIO_PHY_REG_ID1 2
117 typedef union
118 {
119     uint16_t u16;
120     struct
121     {
122         uint16_t oui_bits_3_18;
123     } s;
124 } cvmx_mdio_phy_reg_id1_t;
125
126 /**
127  * PHY register 3 from the 802.3 spec
128  */
129 #define CVMX_MDIO_PHY_REG_ID2 3
130 typedef union
131 {
132     uint16_t u16;
133     struct
134     {
135         uint16_t oui_bits_19_24 : 6;
136         uint16_t model : 6;
137         uint16_t revision : 4;
138     } s;
139 } cvmx_mdio_phy_reg_id2_t;
140
141 /**
142  * PHY register 4 from the 802.3 spec
143  */
144 #define CVMX_MDIO_PHY_REG_AUTONEG_ADVER 4
145 typedef union
146 {
147     uint16_t u16;
148     struct
149     {
150         uint16_t next_page : 1;
151         uint16_t reserved_14 : 1;
152         uint16_t remote_fault : 1;
153         uint16_t reserved_12 : 1;
154         uint16_t asymmetric_pause : 1;
155         uint16_t pause : 1;
156         uint16_t advert_100base_t4 : 1;
157         uint16_t advert_100base_tx_full : 1;
158         uint16_t advert_100base_tx_half : 1;
159         uint16_t advert_10base_tx_full : 1;
160         uint16_t advert_10base_tx_half : 1;
161         uint16_t selector : 5;
162     } s;
163 } cvmx_mdio_phy_reg_autoneg_adver_t;
164
165 /**
166  * PHY register 5 from the 802.3 spec
167  */
168 #define CVMX_MDIO_PHY_REG_LINK_PARTNER_ABILITY 5
169 typedef union
170 {
171     uint16_t u16;
172     struct
173     {
174         uint16_t next_page : 1;
175         uint16_t ack : 1;
176         uint16_t remote_fault : 1;
177         uint16_t reserved_12 : 1;
178         uint16_t asymmetric_pause : 1;
179         uint16_t pause : 1;
180         uint16_t advert_100base_t4 : 1;
181         uint16_t advert_100base_tx_full : 1;
182         uint16_t advert_100base_tx_half : 1;
183         uint16_t advert_10base_tx_full : 1;
184         uint16_t advert_10base_tx_half : 1;
185         uint16_t selector : 5;
186     } s;
187 } cvmx_mdio_phy_reg_link_partner_ability_t;
188
189 /**
190  * PHY register 6 from the 802.3 spec
191  */
192 #define CVMX_MDIO_PHY_REG_AUTONEG_EXPANSION 6
193 typedef union
194 {
195     uint16_t u16;
196     struct
197     {
198         uint16_t reserved_5_15 : 11;
199         uint16_t parallel_detection_fault : 1;
200         uint16_t link_partner_next_page_capable : 1;
201         uint16_t local_next_page_capable : 1;
202         uint16_t page_received : 1;
203         uint16_t link_partner_autoneg_capable : 1;
204
205     } s;
206 } cvmx_mdio_phy_reg_autoneg_expansion_t;
207
208 /**
209  * PHY register 9 from the 802.3 spec
210  */
211 #define CVMX_MDIO_PHY_REG_CONTROL_1000 9
212 typedef union
213 {
214     uint16_t u16;
215     struct
216     {
217         uint16_t test_mode : 3;
218         uint16_t manual_master_slave : 1;
219         uint16_t master : 1;
220         uint16_t port_type : 1;
221         uint16_t advert_1000base_t_full : 1;
222         uint16_t advert_1000base_t_half : 1;
223         uint16_t reserved_0_7 : 8;
224     } s;
225 } cvmx_mdio_phy_reg_control_1000_t;
226
227 /**
228  * PHY register 10 from the 802.3 spec
229  */
230 #define CVMX_MDIO_PHY_REG_STATUS_1000 10
231 typedef union
232 {
233     uint16_t u16;
234     struct
235     {
236         uint16_t master_slave_fault : 1;
237         uint16_t is_master : 1;
238         uint16_t local_receiver_ok : 1;
239         uint16_t remote_receiver_ok : 1;
240         uint16_t remote_capable_1000base_t_full : 1;
241         uint16_t remote_capable_1000base_t_half : 1;
242         uint16_t reserved_8_9 : 2;
243         uint16_t idle_error_count : 8;
244     } s;
245 } cvmx_mdio_phy_reg_status_1000_t;
246
247 /**
248  * PHY register 15 from the 802.3 spec
249  */
250 #define CVMX_MDIO_PHY_REG_EXTENDED_STATUS 15
251 typedef union
252 {
253     uint16_t u16;
254     struct
255     {
256         uint16_t capable_1000base_x_full : 1;
257         uint16_t capable_1000base_x_half : 1;
258         uint16_t capable_1000base_t_full : 1;
259         uint16_t capable_1000base_t_half : 1;
260         uint16_t reserved_0_11 : 12;
261     } s;
262 } cvmx_mdio_phy_reg_extended_status_t;
263
264
265 /**
266  * PHY register 13 from the 802.3 spec
267  */
268 #define CVMX_MDIO_PHY_REG_MMD_CONTROL 13
269 typedef union
270 {
271     uint16_t u16;
272     struct
273     {
274         uint16_t function : 2;
275         uint16_t reserved_5_13 : 9;
276         uint16_t devad : 5;
277     } s;
278 } cvmx_mdio_phy_reg_mmd_control_t;
279
280 /**
281  * PHY register 14 from the 802.3 spec
282  */
283 #define CVMX_MDIO_PHY_REG_MMD_ADDRESS_DATA 14
284 typedef union
285 {
286     uint16_t u16;
287     struct
288     {
289         uint16_t address_data : 16;
290     } s;
291 } cvmx_mdio_phy_reg_mmd_address_data_t;
292
293 /* Operating request encodings. */
294 #define MDIO_CLAUSE_22_WRITE    0
295 #define MDIO_CLAUSE_22_READ     1
296
297 #define MDIO_CLAUSE_45_ADDRESS  0
298 #define MDIO_CLAUSE_45_WRITE    1
299 #define MDIO_CLAUSE_45_READ_INC 2
300 #define MDIO_CLAUSE_45_READ     3
301
302 /* MMD identifiers, mostly for accessing devices withing XENPAK modules. */
303 #define CVMX_MMD_DEVICE_PMA_PMD      1
304 #define CVMX_MMD_DEVICE_WIS          2
305 #define CVMX_MMD_DEVICE_PCS          3
306 #define CVMX_MMD_DEVICE_PHY_XS       4
307 #define CVMX_MMD_DEVICE_DTS_XS       5
308 #define CVMX_MMD_DEVICE_TC           6
309 #define CVMX_MMD_DEVICE_CL22_EXT     29
310 #define CVMX_MMD_DEVICE_VENDOR_1     30
311 #define CVMX_MMD_DEVICE_VENDOR_2     31
312
313 /* Helper function to put MDIO interface into clause 45 mode */
314 static inline void __cvmx_mdio_set_clause45_mode(int bus_id)
315 {
316     cvmx_smix_clk_t smi_clk;
317     /* Put bus into clause 45 mode */
318     smi_clk.u64 = cvmx_read_csr(CVMX_SMIX_CLK(bus_id));
319     smi_clk.s.mode = 1;
320     smi_clk.s.preamble = 1;
321     cvmx_write_csr(CVMX_SMIX_CLK(bus_id), smi_clk.u64);
322 }
323 /* Helper function to put MDIO interface into clause 22 mode */
324 static inline void __cvmx_mdio_set_clause22_mode(int bus_id)
325 {
326     cvmx_smix_clk_t smi_clk;
327     /* Put bus into clause 22 mode */
328     smi_clk.u64 = cvmx_read_csr(CVMX_SMIX_CLK(bus_id));
329     smi_clk.s.mode = 0;
330     cvmx_write_csr(CVMX_SMIX_CLK(bus_id), smi_clk.u64);
331 }
332
333 /**
334  * Perform an MII read. This function is used to read PHY
335  * registers controlling auto negotiation.
336  *
337  * @param bus_id   MDIO bus number. Zero on most chips, but some chips (ex CN56XX)
338  *                 support multiple busses.
339  * @param phy_id   The MII phy id
340  * @param location Register location to read
341  *
342  * @return Result from the read or -1 on failure
343  */
344 static inline int cvmx_mdio_read(int bus_id, int phy_id, int location)
345 {
346     cvmx_smix_cmd_t smi_cmd;
347     cvmx_smix_rd_dat_t smi_rd;
348     int timeout = 1000;
349
350     if (octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45))
351         __cvmx_mdio_set_clause22_mode(bus_id);
352
353     smi_cmd.u64 = 0;
354     smi_cmd.s.phy_op = MDIO_CLAUSE_22_READ;
355     smi_cmd.s.phy_adr = phy_id;
356     smi_cmd.s.reg_adr = location;
357     cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64);
358
359     do
360     {
361         cvmx_wait(1000);
362         smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(bus_id));
363     } while (smi_rd.s.pending && timeout--);
364
365     if (smi_rd.s.val)
366         return smi_rd.s.dat;
367     else
368         return -1;
369 }
370
371
372 /**
373  * Perform an MII write. This function is used to write PHY
374  * registers controlling auto negotiation.
375  *
376  * @param bus_id   MDIO bus number. Zero on most chips, but some chips (ex CN56XX)
377  *                 support multiple busses.
378  * @param phy_id   The MII phy id
379  * @param location Register location to write
380  * @param val      Value to write
381  *
382  * @return -1 on error
383  *         0 on success
384  */
385 static inline int cvmx_mdio_write(int bus_id, int phy_id, int location, int val)
386 {
387     cvmx_smix_cmd_t smi_cmd;
388     cvmx_smix_wr_dat_t smi_wr;
389     int timeout = 1000;
390
391     if (octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45))
392         __cvmx_mdio_set_clause22_mode(bus_id);
393
394     smi_wr.u64 = 0;
395     smi_wr.s.dat = val;
396     cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64);
397
398     smi_cmd.u64 = 0;
399     smi_cmd.s.phy_op = MDIO_CLAUSE_22_WRITE;
400     smi_cmd.s.phy_adr = phy_id;
401     smi_cmd.s.reg_adr = location;
402     cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64);
403
404     do
405     {
406         cvmx_wait(1000);
407         smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id));
408     } while (smi_wr.s.pending && --timeout);
409     if (timeout <= 0)
410         return -1;
411
412     return 0;
413 }
414
415 /**
416  * Perform an IEEE 802.3 clause 45 MII read. This function is used to read PHY
417  * registers controlling auto negotiation.
418  *
419  * @param bus_id   MDIO bus number. Zero on most chips, but some chips (ex CN56XX)
420  *                 support multiple busses.
421  * @param phy_id   The MII phy id
422  * @param device   MDIO Managable Device (MMD) id
423  * @param location Register location to read
424  *
425  * @return Result from the read or -1 on failure
426  */
427
428 static inline int cvmx_mdio_45_read(int bus_id, int phy_id, int device, int location)
429 {
430     cvmx_smix_cmd_t smi_cmd;
431     cvmx_smix_rd_dat_t smi_rd;
432     cvmx_smix_wr_dat_t smi_wr;
433     int timeout = 1000;
434
435     if (!octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45))
436         return -1;
437
438     __cvmx_mdio_set_clause45_mode(bus_id);
439
440     smi_wr.u64 = 0;
441     smi_wr.s.dat = location;
442     cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64);
443
444     smi_cmd.u64 = 0;
445     smi_cmd.s.phy_op = MDIO_CLAUSE_45_ADDRESS;
446     smi_cmd.s.phy_adr = phy_id;
447     smi_cmd.s.reg_adr = device;
448     cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64);
449
450     do
451     {
452         cvmx_wait(1000);
453         smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id));
454     } while (smi_wr.s.pending && --timeout);
455     if (timeout <= 0)
456     {
457         cvmx_dprintf ("cvmx_mdio_45_read: bus_id %d phy_id %2d device %2d register %2d   TIME OUT(address)\n", bus_id, phy_id, device, location);
458         return -1;
459     }
460
461     smi_cmd.u64 = 0;
462     smi_cmd.s.phy_op = MDIO_CLAUSE_45_READ;
463     smi_cmd.s.phy_adr = phy_id;
464     smi_cmd.s.reg_adr = device;
465     cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64);
466
467     do
468     {
469         cvmx_wait(1000);
470         smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(bus_id));
471     } while (smi_rd.s.pending && timeout--);
472
473     if(timeout <= 0)
474     {
475         cvmx_dprintf ("cvmx_mdio_45_read: bus_id %d phy_id %2d device %2d register %2d   TIME OUT(data)\n", bus_id, phy_id, device, location);
476         return -1;
477     }
478
479     if (smi_rd.s.val)
480         return smi_rd.s.dat;
481     else
482     {
483         cvmx_dprintf ("cvmx_mdio_45_read: bus_id %d phy_id %2d device %2d register %2d   INVALID READ\n", bus_id, phy_id, device, location);
484         return -1;
485     }
486 }
487
488 /**
489  * Perform an IEEE 802.3 clause 45 MII write. This function is used to write PHY
490  * registers controlling auto negotiation.
491  *
492  * @param bus_id   MDIO bus number. Zero on most chips, but some chips (ex CN56XX)
493  *                 support multiple busses.
494  * @param phy_id   The MII phy id
495  * @param device   MDIO Managable Device (MMD) id
496  * @param location Register location to write
497  * @param val      Value to write
498  *
499  * @return -1 on error
500  *         0 on success
501  */
502 static inline int cvmx_mdio_45_write(int bus_id, int phy_id, int device, int location,
503                                      int val)
504 {
505     cvmx_smix_cmd_t smi_cmd;
506     cvmx_smix_wr_dat_t smi_wr;
507     int timeout = 1000;
508
509     if (!octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45))
510         return -1;
511
512     __cvmx_mdio_set_clause45_mode(bus_id);
513
514     smi_wr.u64 = 0;
515     smi_wr.s.dat = location;
516     cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64);
517
518     smi_cmd.u64 = 0;
519     smi_cmd.s.phy_op = MDIO_CLAUSE_45_ADDRESS;
520     smi_cmd.s.phy_adr = phy_id;
521     smi_cmd.s.reg_adr = device;
522     cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64);
523
524     do
525     {
526         cvmx_wait(1000);
527         smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id));
528     } while (smi_wr.s.pending && --timeout);
529     if (timeout <= 0)
530         return -1;
531
532     smi_wr.u64 = 0;
533     smi_wr.s.dat = val;
534     cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64);
535
536     smi_cmd.u64 = 0;
537     smi_cmd.s.phy_op = MDIO_CLAUSE_45_WRITE;
538     smi_cmd.s.phy_adr = phy_id;
539     smi_cmd.s.reg_adr = device;
540     cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64);
541
542     do
543     {
544         cvmx_wait(1000);
545         smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id));
546     } while (smi_wr.s.pending && --timeout);
547     if (timeout <= 0)
548         return -1;
549
550     return 0;
551 }
552
553
554 #ifdef  __cplusplus
555 }
556 #endif
557
558 #endif
559