~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to drivers/staging/octeon/cvmx-mdio.h

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***********************license start***************
 
2
 * Author: Cavium Networks
 
3
 *
 
4
 * Contact: support@caviumnetworks.com
 
5
 * This file is part of the OCTEON SDK
 
6
 *
 
7
 * Copyright (c) 2003-2008 Cavium Networks
 
8
 *
 
9
 * This file is free software; you can redistribute it and/or modify
 
10
 * it under the terms of the GNU General Public License, Version 2, as
 
11
 * published by the Free Software Foundation.
 
12
 *
 
13
 * This file is distributed in the hope that it will be useful, but
 
14
 * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
 
15
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
 
16
 * NONINFRINGEMENT.  See the GNU General Public License for more
 
17
 * details.
 
18
 *
 
19
 * You should have received a copy of the GNU General Public License
 
20
 * along with this file; if not, write to the Free Software
 
21
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
22
 * or visit http://www.gnu.org/licenses/.
 
23
 *
 
24
 * This file may also be available under a different license from Cavium.
 
25
 * Contact Cavium Networks for more information
 
26
 ***********************license end**************************************/
 
27
 
 
28
/*
 
29
 *
 
30
 * Interface to the SMI/MDIO hardware, including support for both IEEE 802.3
 
31
 * clause 22 and clause 45 operations.
 
32
 *
 
33
 */
 
34
 
 
35
#ifndef __CVMX_MIO_H__
 
36
#define __CVMX_MIO_H__
 
37
 
 
38
#include "cvmx-smix-defs.h"
 
39
 
 
40
/**
 
41
 * PHY register 0 from the 802.3 spec
 
42
 */
 
43
#define CVMX_MDIO_PHY_REG_CONTROL 0
 
44
typedef union {
 
45
        uint16_t u16;
 
46
        struct {
 
47
                uint16_t reset:1;
 
48
                uint16_t loopback:1;
 
49
                uint16_t speed_lsb:1;
 
50
                uint16_t autoneg_enable:1;
 
51
                uint16_t power_down:1;
 
52
                uint16_t isolate:1;
 
53
                uint16_t restart_autoneg:1;
 
54
                uint16_t duplex:1;
 
55
                uint16_t collision_test:1;
 
56
                uint16_t speed_msb:1;
 
57
                uint16_t unidirectional_enable:1;
 
58
                uint16_t reserved_0_4:5;
 
59
        } s;
 
60
} cvmx_mdio_phy_reg_control_t;
 
61
 
 
62
/**
 
63
 * PHY register 1 from the 802.3 spec
 
64
 */
 
65
#define CVMX_MDIO_PHY_REG_STATUS 1
 
66
typedef union {
 
67
        uint16_t u16;
 
68
        struct {
 
69
                uint16_t capable_100base_t4:1;
 
70
                uint16_t capable_100base_x_full:1;
 
71
                uint16_t capable_100base_x_half:1;
 
72
                uint16_t capable_10_full:1;
 
73
                uint16_t capable_10_half:1;
 
74
                uint16_t capable_100base_t2_full:1;
 
75
                uint16_t capable_100base_t2_half:1;
 
76
                uint16_t capable_extended_status:1;
 
77
                uint16_t capable_unidirectional:1;
 
78
                uint16_t capable_mf_preamble_suppression:1;
 
79
                uint16_t autoneg_complete:1;
 
80
                uint16_t remote_fault:1;
 
81
                uint16_t capable_autoneg:1;
 
82
                uint16_t link_status:1;
 
83
                uint16_t jabber_detect:1;
 
84
                uint16_t capable_extended_registers:1;
 
85
 
 
86
        } s;
 
87
} cvmx_mdio_phy_reg_status_t;
 
88
 
 
89
/**
 
90
 * PHY register 2 from the 802.3 spec
 
91
 */
 
92
#define CVMX_MDIO_PHY_REG_ID1 2
 
93
typedef union {
 
94
        uint16_t u16;
 
95
        struct {
 
96
                uint16_t oui_bits_3_18;
 
97
        } s;
 
98
} cvmx_mdio_phy_reg_id1_t;
 
99
 
 
100
/**
 
101
 * PHY register 3 from the 802.3 spec
 
102
 */
 
103
#define CVMX_MDIO_PHY_REG_ID2 3
 
104
typedef union {
 
105
        uint16_t u16;
 
106
        struct {
 
107
                uint16_t oui_bits_19_24:6;
 
108
                uint16_t model:6;
 
109
                uint16_t revision:4;
 
110
        } s;
 
111
} cvmx_mdio_phy_reg_id2_t;
 
112
 
 
113
/**
 
114
 * PHY register 4 from the 802.3 spec
 
115
 */
 
116
#define CVMX_MDIO_PHY_REG_AUTONEG_ADVER 4
 
117
typedef union {
 
118
        uint16_t u16;
 
119
        struct {
 
120
                uint16_t next_page:1;
 
121
                uint16_t reserved_14:1;
 
122
                uint16_t remote_fault:1;
 
123
                uint16_t reserved_12:1;
 
124
                uint16_t asymmetric_pause:1;
 
125
                uint16_t pause:1;
 
126
                uint16_t advert_100base_t4:1;
 
127
                uint16_t advert_100base_tx_full:1;
 
128
                uint16_t advert_100base_tx_half:1;
 
129
                uint16_t advert_10base_tx_full:1;
 
130
                uint16_t advert_10base_tx_half:1;
 
131
                uint16_t selector:5;
 
132
        } s;
 
133
} cvmx_mdio_phy_reg_autoneg_adver_t;
 
134
 
 
135
/**
 
136
 * PHY register 5 from the 802.3 spec
 
137
 */
 
138
#define CVMX_MDIO_PHY_REG_LINK_PARTNER_ABILITY 5
 
139
typedef union {
 
140
        uint16_t u16;
 
141
        struct {
 
142
                uint16_t next_page:1;
 
143
                uint16_t ack:1;
 
144
                uint16_t remote_fault:1;
 
145
                uint16_t reserved_12:1;
 
146
                uint16_t asymmetric_pause:1;
 
147
                uint16_t pause:1;
 
148
                uint16_t advert_100base_t4:1;
 
149
                uint16_t advert_100base_tx_full:1;
 
150
                uint16_t advert_100base_tx_half:1;
 
151
                uint16_t advert_10base_tx_full:1;
 
152
                uint16_t advert_10base_tx_half:1;
 
153
                uint16_t selector:5;
 
154
        } s;
 
155
} cvmx_mdio_phy_reg_link_partner_ability_t;
 
156
 
 
157
/**
 
158
 * PHY register 6 from the 802.3 spec
 
159
 */
 
160
#define CVMX_MDIO_PHY_REG_AUTONEG_EXPANSION 6
 
161
typedef union {
 
162
        uint16_t u16;
 
163
        struct {
 
164
                uint16_t reserved_5_15:11;
 
165
                uint16_t parallel_detection_fault:1;
 
166
                uint16_t link_partner_next_page_capable:1;
 
167
                uint16_t local_next_page_capable:1;
 
168
                uint16_t page_received:1;
 
169
                uint16_t link_partner_autoneg_capable:1;
 
170
 
 
171
        } s;
 
172
} cvmx_mdio_phy_reg_autoneg_expansion_t;
 
173
 
 
174
/**
 
175
 * PHY register 9 from the 802.3 spec
 
176
 */
 
177
#define CVMX_MDIO_PHY_REG_CONTROL_1000 9
 
178
typedef union {
 
179
        uint16_t u16;
 
180
        struct {
 
181
                uint16_t test_mode:3;
 
182
                uint16_t manual_master_slave:1;
 
183
                uint16_t master:1;
 
184
                uint16_t port_type:1;
 
185
                uint16_t advert_1000base_t_full:1;
 
186
                uint16_t advert_1000base_t_half:1;
 
187
                uint16_t reserved_0_7:8;
 
188
        } s;
 
189
} cvmx_mdio_phy_reg_control_1000_t;
 
190
 
 
191
/**
 
192
 * PHY register 10 from the 802.3 spec
 
193
 */
 
194
#define CVMX_MDIO_PHY_REG_STATUS_1000 10
 
195
typedef union {
 
196
        uint16_t u16;
 
197
        struct {
 
198
                uint16_t master_slave_fault:1;
 
199
                uint16_t is_master:1;
 
200
                uint16_t local_receiver_ok:1;
 
201
                uint16_t remote_receiver_ok:1;
 
202
                uint16_t remote_capable_1000base_t_full:1;
 
203
                uint16_t remote_capable_1000base_t_half:1;
 
204
                uint16_t reserved_8_9:2;
 
205
                uint16_t idle_error_count:8;
 
206
        } s;
 
207
} cvmx_mdio_phy_reg_status_1000_t;
 
208
 
 
209
/**
 
210
 * PHY register 15 from the 802.3 spec
 
211
 */
 
212
#define CVMX_MDIO_PHY_REG_EXTENDED_STATUS 15
 
213
typedef union {
 
214
        uint16_t u16;
 
215
        struct {
 
216
                uint16_t capable_1000base_x_full:1;
 
217
                uint16_t capable_1000base_x_half:1;
 
218
                uint16_t capable_1000base_t_full:1;
 
219
                uint16_t capable_1000base_t_half:1;
 
220
                uint16_t reserved_0_11:12;
 
221
        } s;
 
222
} cvmx_mdio_phy_reg_extended_status_t;
 
223
 
 
224
/**
 
225
 * PHY register 13 from the 802.3 spec
 
226
 */
 
227
#define CVMX_MDIO_PHY_REG_MMD_CONTROL 13
 
228
typedef union {
 
229
        uint16_t u16;
 
230
        struct {
 
231
                uint16_t function:2;
 
232
                uint16_t reserved_5_13:9;
 
233
                uint16_t devad:5;
 
234
        } s;
 
235
} cvmx_mdio_phy_reg_mmd_control_t;
 
236
 
 
237
/**
 
238
 * PHY register 14 from the 802.3 spec
 
239
 */
 
240
#define CVMX_MDIO_PHY_REG_MMD_ADDRESS_DATA 14
 
241
typedef union {
 
242
        uint16_t u16;
 
243
        struct {
 
244
                uint16_t address_data:16;
 
245
        } s;
 
246
} cvmx_mdio_phy_reg_mmd_address_data_t;
 
247
 
 
248
/* Operating request encodings. */
 
249
#define MDIO_CLAUSE_22_WRITE    0
 
250
#define MDIO_CLAUSE_22_READ     1
 
251
 
 
252
#define MDIO_CLAUSE_45_ADDRESS  0
 
253
#define MDIO_CLAUSE_45_WRITE    1
 
254
#define MDIO_CLAUSE_45_READ_INC 2
 
255
#define MDIO_CLAUSE_45_READ     3
 
256
 
 
257
/* MMD identifiers, mostly for accessing devices within XENPAK modules. */
 
258
#define CVMX_MMD_DEVICE_PMA_PMD      1
 
259
#define CVMX_MMD_DEVICE_WIS          2
 
260
#define CVMX_MMD_DEVICE_PCS          3
 
261
#define CVMX_MMD_DEVICE_PHY_XS       4
 
262
#define CVMX_MMD_DEVICE_DTS_XS       5
 
263
#define CVMX_MMD_DEVICE_TC           6
 
264
#define CVMX_MMD_DEVICE_CL22_EXT     29
 
265
#define CVMX_MMD_DEVICE_VENDOR_1     30
 
266
#define CVMX_MMD_DEVICE_VENDOR_2     31
 
267
 
 
268
/* Helper function to put MDIO interface into clause 45 mode */
 
269
static inline void __cvmx_mdio_set_clause45_mode(int bus_id)
 
270
{
 
271
        union cvmx_smix_clk smi_clk;
 
272
        /* Put bus into clause 45 mode */
 
273
        smi_clk.u64 = cvmx_read_csr(CVMX_SMIX_CLK(bus_id));
 
274
        smi_clk.s.mode = 1;
 
275
        smi_clk.s.preamble = 1;
 
276
        cvmx_write_csr(CVMX_SMIX_CLK(bus_id), smi_clk.u64);
 
277
}
 
278
 
 
279
/* Helper function to put MDIO interface into clause 22 mode */
 
280
static inline void __cvmx_mdio_set_clause22_mode(int bus_id)
 
281
{
 
282
        union cvmx_smix_clk smi_clk;
 
283
        /* Put bus into clause 22 mode */
 
284
        smi_clk.u64 = cvmx_read_csr(CVMX_SMIX_CLK(bus_id));
 
285
        smi_clk.s.mode = 0;
 
286
        cvmx_write_csr(CVMX_SMIX_CLK(bus_id), smi_clk.u64);
 
287
}
 
288
 
 
289
/**
 
290
 * Perform an MII read. This function is used to read PHY
 
291
 * registers controlling auto negotiation.
 
292
 *
 
293
 * @bus_id:   MDIO bus number. Zero on most chips, but some chips (ex CN56XX)
 
294
 *                 support multiple busses.
 
295
 * @phy_id:   The MII phy id
 
296
 * @location: Register location to read
 
297
 *
 
298
 * Returns Result from the read or -1 on failure
 
299
 */
 
300
static inline int cvmx_mdio_read(int bus_id, int phy_id, int location)
 
301
{
 
302
        union cvmx_smix_cmd smi_cmd;
 
303
        union cvmx_smix_rd_dat smi_rd;
 
304
        int timeout = 1000;
 
305
 
 
306
        if (octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45))
 
307
                __cvmx_mdio_set_clause22_mode(bus_id);
 
308
 
 
309
        smi_cmd.u64 = 0;
 
310
        smi_cmd.s.phy_op = MDIO_CLAUSE_22_READ;
 
311
        smi_cmd.s.phy_adr = phy_id;
 
312
        smi_cmd.s.reg_adr = location;
 
313
        cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64);
 
314
 
 
315
        do {
 
316
                cvmx_wait(1000);
 
317
                smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(bus_id));
 
318
        } while (smi_rd.s.pending && timeout--);
 
319
 
 
320
        if (smi_rd.s.val)
 
321
                return smi_rd.s.dat;
 
322
        else
 
323
                return -1;
 
324
}
 
325
 
 
326
/**
 
327
 * Perform an MII write. This function is used to write PHY
 
328
 * registers controlling auto negotiation.
 
329
 *
 
330
 * @bus_id:   MDIO bus number. Zero on most chips, but some chips (ex CN56XX)
 
331
 *                 support multiple busses.
 
332
 * @phy_id:   The MII phy id
 
333
 * @location: Register location to write
 
334
 * @val:      Value to write
 
335
 *
 
336
 * Returns -1 on error
 
337
 *         0 on success
 
338
 */
 
339
static inline int cvmx_mdio_write(int bus_id, int phy_id, int location, int val)
 
340
{
 
341
        union cvmx_smix_cmd smi_cmd;
 
342
        union cvmx_smix_wr_dat smi_wr;
 
343
        int timeout = 1000;
 
344
 
 
345
        if (octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45))
 
346
                __cvmx_mdio_set_clause22_mode(bus_id);
 
347
 
 
348
        smi_wr.u64 = 0;
 
349
        smi_wr.s.dat = val;
 
350
        cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64);
 
351
 
 
352
        smi_cmd.u64 = 0;
 
353
        smi_cmd.s.phy_op = MDIO_CLAUSE_22_WRITE;
 
354
        smi_cmd.s.phy_adr = phy_id;
 
355
        smi_cmd.s.reg_adr = location;
 
356
        cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64);
 
357
 
 
358
        do {
 
359
                cvmx_wait(1000);
 
360
                smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id));
 
361
        } while (smi_wr.s.pending && --timeout);
 
362
        if (timeout <= 0)
 
363
                return -1;
 
364
 
 
365
        return 0;
 
366
}
 
367
 
 
368
/**
 
369
 * Perform an IEEE 802.3 clause 45 MII read. This function is used to
 
370
 * read PHY registers controlling auto negotiation.
 
371
 *
 
372
 * @bus_id:   MDIO bus number. Zero on most chips, but some chips (ex CN56XX)
 
373
 *                 support multiple busses.
 
374
 * @phy_id:   The MII phy id
 
375
 * @device:   MDIO Managable Device (MMD) id
 
376
 * @location: Register location to read
 
377
 *
 
378
 * Returns Result from the read or -1 on failure
 
379
 */
 
380
 
 
381
static inline int cvmx_mdio_45_read(int bus_id, int phy_id, int device,
 
382
                                    int location)
 
383
{
 
384
        union cvmx_smix_cmd smi_cmd;
 
385
        union cvmx_smix_rd_dat smi_rd;
 
386
        union cvmx_smix_wr_dat smi_wr;
 
387
        int timeout = 1000;
 
388
 
 
389
        if (!octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45))
 
390
                return -1;
 
391
 
 
392
        __cvmx_mdio_set_clause45_mode(bus_id);
 
393
 
 
394
        smi_wr.u64 = 0;
 
395
        smi_wr.s.dat = location;
 
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_45_ADDRESS;
 
400
        smi_cmd.s.phy_adr = phy_id;
 
401
        smi_cmd.s.reg_adr = device;
 
402
        cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64);
 
403
 
 
404
        do {
 
405
                cvmx_wait(1000);
 
406
                smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id));
 
407
        } while (smi_wr.s.pending && --timeout);
 
408
        if (timeout <= 0) {
 
409
                cvmx_dprintf("cvmx_mdio_45_read: bus_id %d phy_id %2d "
 
410
                             "device %2d register %2d   TIME OUT(address)\n",
 
411
                     bus_id, phy_id, device, location);
 
412
                return -1;
 
413
        }
 
414
 
 
415
        smi_cmd.u64 = 0;
 
416
        smi_cmd.s.phy_op = MDIO_CLAUSE_45_READ;
 
417
        smi_cmd.s.phy_adr = phy_id;
 
418
        smi_cmd.s.reg_adr = device;
 
419
        cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64);
 
420
 
 
421
        do {
 
422
                cvmx_wait(1000);
 
423
                smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(bus_id));
 
424
        } while (smi_rd.s.pending && --timeout);
 
425
 
 
426
        if (timeout <= 0) {
 
427
                cvmx_dprintf("cvmx_mdio_45_read: bus_id %d phy_id %2d "
 
428
                             "device %2d register %2d   TIME OUT(data)\n",
 
429
                     bus_id, phy_id, device, location);
 
430
                return -1;
 
431
        }
 
432
 
 
433
        if (smi_rd.s.val)
 
434
                return smi_rd.s.dat;
 
435
        else {
 
436
                cvmx_dprintf("cvmx_mdio_45_read: bus_id %d phy_id %2d "
 
437
                             "device %2d register %2d   INVALID READ\n",
 
438
                     bus_id, phy_id, device, location);
 
439
                return -1;
 
440
        }
 
441
}
 
442
 
 
443
/**
 
444
 * Perform an IEEE 802.3 clause 45 MII write. This function is used to
 
445
 * write PHY registers controlling auto negotiation.
 
446
 *
 
447
 * @bus_id:   MDIO bus number. Zero on most chips, but some chips (ex CN56XX)
 
448
 *                 support multiple busses.
 
449
 * @phy_id:   The MII phy id
 
450
 * @device:   MDIO Managable Device (MMD) id
 
451
 * @location: Register location to write
 
452
 * @val:      Value to write
 
453
 *
 
454
 * Returns -1 on error
 
455
 *         0 on success
 
456
 */
 
457
static inline int cvmx_mdio_45_write(int bus_id, int phy_id, int device,
 
458
                                     int location, int val)
 
459
{
 
460
        union cvmx_smix_cmd smi_cmd;
 
461
        union cvmx_smix_wr_dat smi_wr;
 
462
        int timeout = 1000;
 
463
 
 
464
        if (!octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45))
 
465
                return -1;
 
466
 
 
467
        __cvmx_mdio_set_clause45_mode(bus_id);
 
468
 
 
469
        smi_wr.u64 = 0;
 
470
        smi_wr.s.dat = location;
 
471
        cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64);
 
472
 
 
473
        smi_cmd.u64 = 0;
 
474
        smi_cmd.s.phy_op = MDIO_CLAUSE_45_ADDRESS;
 
475
        smi_cmd.s.phy_adr = phy_id;
 
476
        smi_cmd.s.reg_adr = device;
 
477
        cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64);
 
478
 
 
479
        do {
 
480
                cvmx_wait(1000);
 
481
                smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id));
 
482
        } while (smi_wr.s.pending && --timeout);
 
483
        if (timeout <= 0)
 
484
                return -1;
 
485
 
 
486
        smi_wr.u64 = 0;
 
487
        smi_wr.s.dat = val;
 
488
        cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64);
 
489
 
 
490
        smi_cmd.u64 = 0;
 
491
        smi_cmd.s.phy_op = MDIO_CLAUSE_45_WRITE;
 
492
        smi_cmd.s.phy_adr = phy_id;
 
493
        smi_cmd.s.reg_adr = device;
 
494
        cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64);
 
495
 
 
496
        do {
 
497
                cvmx_wait(1000);
 
498
                smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id));
 
499
        } while (smi_wr.s.pending && --timeout);
 
500
        if (timeout <= 0)
 
501
                return -1;
 
502
 
 
503
        return 0;
 
504
}
 
505
 
 
506
#endif