source: rtems/c/src/lib/libbsp/arm/csb336/network/lan91c11x.c @ 9b4422a2

4.115
Last change on this file since 9b4422a2 was 9b4422a2, checked in by Joel Sherrill <joel.sherrill@…>, on 05/03/12 at 15:09:24

Remove All CVS Id Strings Possible Using a Script

Script does what is expected and tries to do it as
smartly as possible.

+ remove occurrences of two blank comment lines

next to each other after Id string line removed.

+ remove entire comment blocks which only exited to

contain CVS Ids

+ If the processing left a blank line at the top of

a file, it was removed.

  • Property mode set to 100644
File size: 6.2 KB
Line 
1/*
2 *  Helper functions for SMSC LAN91C11x
3 *
4 *  Copyright (c) 2004 by Cogent Computer Systems
5 *  Written by Jay Monkman <jtm@lopingdog.com>
6 *
7 *  The license and distribution terms for this file may be
8 *  found in the file LICENSE in this distribution or at
9 *  http://www.rtems.com/license/LICENSE.
10 */
11#include <rtems.h>
12#include "lan91c11x.h"
13
14uint16_t lan91c11x_read_reg(int reg)
15{
16    volatile uint16_t *ptr = (uint16_t *)LAN91C11X_BASE_ADDR;
17    uint16_t old_bank;
18    uint16_t val;
19    rtems_interrupt_level level;
20
21    rtems_interrupt_disable(level);
22
23    /* save the bank register */
24    old_bank = ptr[7] & 0x7;
25
26    /* set the bank register */
27    ptr[7] = (reg >> 4) & 0x7;
28
29    val = ptr[((reg & 0xf) >> 1)];
30
31    /* restore the bank register */
32    ptr[7] = old_bank;
33
34    rtems_interrupt_enable(level);
35    return val;
36}
37
38void lan91c11x_write_reg(int reg, uint16_t value)
39{
40    volatile uint16_t *ptr = (uint16_t *)LAN91C11X_BASE_ADDR;
41    uint16_t old_bank;
42    rtems_interrupt_level level;
43
44    rtems_interrupt_disable(level);
45
46    /* save the bank register */
47    old_bank = ptr[7] & 0x7;
48
49    /* set the bank register */
50    ptr[7] = (reg >> 4) & 0x7;
51
52    ptr[((reg & 0xf) >> 1)] = value;
53
54    /* restore the bank register */
55    ptr[7] = old_bank;
56
57    rtems_interrupt_enable(level);
58}
59
60uint16_t lan91c11x_read_reg_fast(int reg)
61{
62    volatile uint16_t *ptr = (uint16_t *)LAN91C11X_BASE_ADDR;
63    uint16_t val;
64
65    val = ptr[((reg & 0xf) >> 1)];
66
67    return val;
68}
69
70void lan91c11x_write_reg_fast(int reg, uint16_t value)
71{
72    volatile uint16_t *ptr = (uint16_t *)LAN91C11X_BASE_ADDR;
73
74    ptr[((reg & 0xf) >> 1)] = value;
75}
76
77
78uint16_t lan91c11x_read_phy_reg(int reg)
79{
80    int i;
81    uint16_t mask;
82    uint16_t bits[64];
83    int clk_idx = 0;
84    int input_idx = 0;
85    uint16_t phydata;
86
87    /* 32 consecutive ones on MDO to establish sync */
88    for (i = 0; i < 32; ++i) {
89        bits[clk_idx++] = LAN91C11X_MGMT_MDOE | LAN91C11X_MGMT_MDO;
90    }
91
92    /* Start code <01> */
93    bits[clk_idx++] = LAN91C11X_MGMT_MDOE;
94    bits[clk_idx++] = LAN91C11X_MGMT_MDOE | LAN91C11X_MGMT_MDO;
95
96    /* Read command <10> */
97    bits[clk_idx++] = LAN91C11X_MGMT_MDOE | LAN91C11X_MGMT_MDO;
98    bits[clk_idx++] = LAN91C11X_MGMT_MDOE;
99
100    /* Output the PHY address, msb first - Internal PHY is address 0 */
101    for (i = 0; i < 5; ++i) {
102        bits[clk_idx++] = LAN91C11X_MGMT_MDOE;
103    }
104
105    /* Output the phy register number, msb first */
106    mask = 0x10;
107    for (i = 0; i < 5; ++i) {
108        if (reg & mask) {
109            bits[clk_idx++] = LAN91C11X_MGMT_MDOE | LAN91C11X_MGMT_MDO;
110        } else {
111            bits[clk_idx++] = LAN91C11X_MGMT_MDOE;
112        }
113
114
115        /* Shift to next lowest bit */
116        mask >>= 1;
117    }
118
119    /* 1 bit time for turnaround */
120    bits[clk_idx++] = 0;
121
122    /* Input starts at this bit time */
123    input_idx = clk_idx;
124
125    /* Will input 16 bits */
126    for (i = 0; i < 16; ++i) {
127        bits[clk_idx++] = 0;
128    }
129
130    /* Final clock bit */
131    bits[clk_idx++] = 0;
132
133    /* Turn off all MII Interface bits */
134    lan91c11x_write_reg(LAN91C11X_MGMT,
135                        lan91c11x_read_reg(LAN91C11X_MGMT) & 0xfff0);
136
137    /* Clock all 64 cycles */
138    for (i = 0; i < sizeof bits; ++i) {
139        /* Clock Low - output data */
140        lan91c11x_write_reg(LAN91C11X_MGMT, bits[i]);
141        rtems_task_wake_after(1);
142
143        /* Clock Hi - input data */
144        lan91c11x_write_reg(LAN91C11X_MGMT, bits[i] | LAN91C11X_MGMT_MCLK);
145        rtems_task_wake_after(1);
146        bits[i] |= lan91c11x_read_reg(LAN91C11X_MGMT) & LAN91C11X_MGMT_MDI;
147    }
148
149    /* Return to idle state */
150    /* Set clock to low, data to low, and output tristated */
151    lan91c11x_write_reg(LAN91C11X_MGMT, lan91c11x_read_reg(LAN91C11X_MGMT) & 0xfff0);
152    rtems_task_wake_after(1);
153
154    /* Recover input data */
155    phydata = 0;
156    for (i = 0; i < 16; ++i) {
157        phydata <<= 1;
158
159        if (bits[input_idx++] & LAN91C11X_MGMT_MDI) {
160            phydata |= 0x0001;
161        }
162    }
163
164    return phydata;
165}
166
167
168
169void lan91c11x_write_phy_reg(int reg, uint16_t phydata)
170{
171    int i;
172    ushort mask;
173    ushort bits[64];
174    int clk_idx = 0;
175
176    /* 32 consecutive ones on MDO to establish sync */
177    for (i = 0; i < 32; ++i) {
178        bits[clk_idx++] = LAN91C11X_MGMT_MDOE | LAN91C11X_MGMT_MDO;
179    }
180
181    /* Start code <01> */
182    bits[clk_idx++] = LAN91C11X_MGMT_MDOE;
183    bits[clk_idx++] = LAN91C11X_MGMT_MDOE | LAN91C11X_MGMT_MDO;
184
185    /* Write command <01> */
186    bits[clk_idx++] = LAN91C11X_MGMT_MDOE;
187    bits[clk_idx++] = LAN91C11X_MGMT_MDOE | LAN91C11X_MGMT_MDO;
188
189    /* Output the PHY address, msb first - Internal PHY is address 0 */
190    for (i = 0; i < 5; ++i) {
191        bits[clk_idx++] = LAN91C11X_MGMT_MDOE;
192    }
193
194    /* Output the phy register number, msb first */
195    mask = 0x10;
196    for (i = 0; i < 5; ++i) {
197        if (reg & mask) {
198            bits[clk_idx++] = LAN91C11X_MGMT_MDOE | LAN91C11X_MGMT_MDO;
199        } else {
200            bits[clk_idx++] = LAN91C11X_MGMT_MDOE;
201        }
202
203        /* Shift to next lowest bit */
204        mask >>= 1;
205    }
206
207    /* 2 extra bit times for turnaround */
208    bits[clk_idx++] = 0;
209    bits[clk_idx++] = 0;
210
211    /* Write out 16 bits of data, msb first */
212    mask = 0x8000;
213    for (i = 0; i < 16; ++i) {
214        if (phydata & mask) {
215            bits[clk_idx++] = LAN91C11X_MGMT_MDOE | LAN91C11X_MGMT_MDO;
216        } else {
217            bits[clk_idx++] = LAN91C11X_MGMT_MDOE;
218        }
219
220        /* Shift to next lowest bit */
221        mask >>= 1;
222    }
223
224    /* Turn off all MII Interface bits */
225    lan91c11x_write_reg(LAN91C11X_MGMT,
226                        lan91c11x_read_reg(LAN91C11X_MGMT) & 0xfff0);
227
228    /* Clock all 64 cycles */
229    for (i = 0; i < sizeof bits; ++i) {
230        /* Clock Low - output data */
231        lan91c11x_write_reg(LAN91C11X_MGMT, bits[i]);
232        rtems_task_wake_after(1);
233
234        /* Clock Hi - input data */
235        lan91c11x_write_reg(LAN91C11X_MGMT, bits[i] | LAN91C11X_MGMT_MCLK);
236        rtems_task_wake_after(1);
237        bits[i] |= lan91c11x_read_reg(LAN91C11X_MGMT) & LAN91C11X_MGMT_MDI;
238    }
239
240    /* Return to idle state */
241    /* Set clock to low, data to low, and output tristated */
242    lan91c11x_write_reg(LAN91C11X_MGMT,
243                        lan91c11x_read_reg(LAN91C11X_MGMT) & 0xfff0);
244    rtems_task_wake_after(1);
245
246}
247
248
249
Note: See TracBrowser for help on using the repository browser.