OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [ecos-2.0/] [packages/] [devs/] [eth/] [powerpc/] [quicc2/] [v2_0/] [src/] [EnetPHY.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1254 phoenix
//####ECOSGPLCOPYRIGHTBEGIN####
2
// -------------------------------------------
3
// This file is part of eCos, the Embedded Configurable Operating System.
4
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
5
// Copyright (C) 2002 Gary Thomas
6
//
7
// eCos is free software; you can redistribute it and/or modify it under
8
// the terms of the GNU General Public License as published by the Free
9
// Software Foundation; either version 2 or (at your option) any later version.
10
//
11
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
12
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
// for more details.
15
//
16
// You should have received a copy of the GNU General Public License along
17
// with eCos; if not, write to the Free Software Foundation, Inc.,
18
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
19
//
20
// As a special exception, if other files instantiate templates or use macros
21
// or inline functions from this file, or you compile this file and link it
22
// with other works to produce a work based on this file, this file does not
23
// by itself cause the resulting work to be covered by the GNU General Public
24
// License. However the source code for this file must still be made available
25
// in accordance with section (3) of the GNU General Public License.
26
//
27
// This exception does not invalidate any other reasons why a work based on
28
// this file might be covered by the GNU General Public License.
29
//
30
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
31
// at http://sources.redhat.com/ecos/ecos-license/
32
// -------------------------------------------
33
//####ECOSGPLCOPYRIGHTEND####
34
/*-------------------------------------------------------------------
35
*
36
* FILE: enetPHY.c
37
*
38
* DESCRIPTION:   GPIO Management Pins driver for the LXT970a
39
*
40
*
41
* Modified for the mpc8260 VADS board
42
*--------------------------------------------------------------------*/
43
#include "types.h"
44
#include "EnetPHY.h"
45
 
46
/* Internal functions */
47
void    MdioSend(UINT32, UINT16);
48
UINT16  MdioReceive(UINT16);
49
UINT16  MdioFrame(MDIORW, UINT16, UINT16, UINT32);
50
 
51
VUINT32 * pPortDir;
52
VUINT32 * pPortData;
53
 
54
/*-------------------------------------------------------------------
55
*
56
* FUNCTION NAME:
57
*
58
* DESCRIPTION:
59
*
60
* EXTERNAL EFFECT: Turns on the LXT970 transciever
61
*
62
* PARAMETERS:
63
*
64
* RETURNS: None
65
*
66
* ASSUMPTIONS:
67
*
68
*-------------------------------------------------------------------*/
69
void
70
EnableResetPHY(volatile t_BCSR *pBCSR)
71
{
72
  // active low FETHIEN on BSCR1, assert reset low
73
  pBCSR->bcsr1 &= ~(FETHIEN_ | FETHRST_);
74
  // de-assert reset
75
  pBCSR->bcsr1 |= FETHRST_;
76
 
77
}
78
 
79
 
80
/*-------------------------------------------------------------------
81
*
82
* FUNCTION NAME:
83
*
84
* DESCRIPTION: Writes parameters to the control registers of LXT970
85
*
86
* EXTERNAL EFFECT:
87
*
88
* PARAMETERS:
89
*
90
* RETURNS: None
91
*
92
* ASSUMPTIONS:
93
*
94
*-------------------------------------------------------------------*/
95
UINT16
96
InitEthernetPHY(VUINT32* pdir, VUINT32* pdat, UINT16 link)
97
{
98
 
99
  VUINT16 FrameValue;
100
 
101
  /* 8101 Ethernet Management Pin Assignments */
102
  pPortDir = pdir;
103
  pPortData = pdat;
104
 
105
  (*pPortDir) |= MDC_PIN_MASK;   /* MD_Clock will always be output only */
106
 
107
  /* Test MDC & MDIO Pin Connection to PHY */
108
  MdioFrame(WRITE, 0, MIRROR_REG, MD_TEST_FRAME); //send test frame
109
  MdioFrame(WRITE, 0, MIRROR_REG, MD_TEST_FRAME); //send test frame
110
  FrameValue = MdioFrame(READ, 0, MIRROR_REG, 0); //read test frame
111
 
112
  if (FrameValue != MD_TEST_FRAME)
113
    return LINKERROR;   //test data integrity
114
 
115
  /* General Configuration */
116
  MdioFrame(WRITE, 0, CONFIG_REG, 0x0000);
117
 
118
  if(link == HUNDRED_HD)
119
      MdioFrame(WRITE, 0, AUTONEG_AD_REG, 0x0081); //100 Mbps Half, 802.3
120
  else
121
      MdioFrame(WRITE, 0, AUTONEG_AD_REG, 0x0021); //10  Mbps Half, 802.3
122
 
123
  // 100 Mbps full duplex not supported
124
  // MdioFrame(WRITE, 0, AUTONEG_AD_REG, 0x0101); //100 Mbps Full, 802.3
125
 
126
  MdioFrame(WRITE, 0, CONTROL_REG, 0x1300);
127
 
128
  return 0;
129
}
130
 
131
/*-------------------------------------------------------------------
132
*
133
* FUNCTION NAME:
134
*
135
* DESCRIPTION:
136
*
137
* EXTERNAL EFFECT:
138
*
139
* PARAMETERS:
140
*
141
* RETURNS: None
142
*
143
* ASSUMPTIONS:
144
*
145
*-------------------------------------------------------------------*/
146
UINT16
147
EthernetPHYInterruptHandler()
148
{
149
  // Reading registers 1 and 18 in sequence 
150
  // clears the transceiver interrupt
151
 
152
  MdioFrame(READ, 0, STATUS_REG, 0);
153
  MdioFrame(READ, 0, INT_STAT_REG, 0);
154
 
155
  return LinkTestPHY();
156
} /* end EthernetPHYInterruptHandler */
157
 
158
/*-------------------------------------------------------------------
159
*
160
* FUNCTION NAME:
161
*
162
* DESCRIPTION:
163
*
164
* EXTERNAL EFFECT:
165
*
166
* PARAMETERS:
167
*
168
* RETURNS: None
169
*
170
* ASSUMPTIONS:
171
*
172
*-------------------------------------------------------------------*/
173
UINT16
174
LinkTestPHY()
175
{
176
  UINT32 j, cnt;
177
  UINT16 FrameValue;
178
 
179
  //for (j = 0; j < 10; j++) {
180
  for (j = 0; j < 5; j++) {
181
 
182
    for (cnt = 0; cnt < 1000000; cnt ++) {
183
 
184
      asm("nop");
185
      asm("nop");
186
      asm("nop");
187
    }
188
 
189
    FrameValue = MdioFrame(READ,0,CHIP_STAT_REG,0);
190
 
191
    if ( (FrameValue & 0x0200) != 0 )
192
      break;
193
  }
194
 
195
  FrameValue &= 0x3800;
196
 
197
  switch (FrameValue) {
198
 
199
    case 0x3800: return HUNDRED_FD;
200
    case 0x2800: return HUNDRED_HD;
201
    case 0x3000: return TEN_FD;
202
    case 0x2000: return TEN_HD;
203
    default:     return NOTLINKED;
204
  }
205
 
206
}
207
 
208
/*-------------------------------------------------------------------
209
*
210
* FUNCTION NAME:
211
*
212
* DESCRIPTION:
213
*
214
* EXTERNAL EFFECT:
215
*
216
* PARAMETERS:
217
*
218
* RETURNS: None
219
*
220
* ASSUMPTIONS:
221
*
222
*-------------------------------------------------------------------*/
223
void EnablePHYinterrupt(UINT8 enable)
224
{
225
  MdioFrame(WRITE, 0, INT_EN_REG, enable?0x2:0x0);
226
}
227
 
228
/*----------------------------------------------------------------------
229
*
230
* FUNCTION NAME:
231
*
232
* DESCRIPTION: generic READ/WRITE function of LXT970
233
*              through the MDC/MDIO interface.
234
*
235
* EXTERNAL EFFECT:
236
*
237
* PARAMETERS:
238
*
239
* RETURNS: None
240
*
241
* ASSUMPTIONS:
242
*
243
*---------------------------------------------------------------------*/
244
UINT16
245
MdioFrame(MDIORW R_W, UINT16 PhyAddr, UINT16 RegAddr, UINT32 PutData) {
246
 
247
  UINT16 GetData;
248
 
249
  *pPortDir |= MDIO_PIN_MASK;   //set to output mode
250
 
251
  MdioSend(0xFFFFFFFF,32);      //PreAmble
252
  MdioSend(0x1,2);              //Start Frame Delimiter
253
  if (R_W==READ)
254
    MdioSend(0x2,2);            //Read OpCode
255
  else
256
    MdioSend(0x1,2);            //Write OpCode
257
 
258
  MdioSend(PhyAddr,5);         //Send PHY transciever Address
259
  MdioSend(RegAddr,5);         //Send Register Address
260
 
261
  if (R_W==READ) {
262
    *pPortDir &= ~MDIO_PIN_MASK;  //set to input mode
263
    GetData = MdioReceive(17);    //Drive TurnAround and Data
264
    MdioReceive(2);
265
  }
266
  else {
267
    MdioSend(0x2,2);              //Drive TurnAround
268
    MdioSend(PutData, 16);        //Send Data
269
    GetData = 0;
270
    *pPortDir &= ~MDIO_PIN_MASK;  //set to input mode
271
  }
272
 
273
  return GetData;
274
 
275
}
276
/*----------------------------------------------------------------------
277
*
278
* FUNCTION NAME:
279
*
280
* DESCRIPTION:  Shift out  bits of data
281
*
282
* EXTERNAL EFFECT:
283
*
284
* PARAMETERS:
285
*
286
* RETURNS: None
287
*
288
* ASSUMPTIONS:
289
*
290
*----------------------------------------------------------------------*/
291
void
292
MdioSend(UINT32 txF, UINT16 size) {
293
 
294
  UINT32 dmask;
295
  INT_NATIVE i, j;
296
 
297
  dmask = 1 << (size-1);            // msbit out first
298
 
299
  for (i = 0; i < size; i++) {      // for "size" bits
300
 
301
    if ( txF & dmask )              //output data bit high
302
      *pPortData |=  MDIO_PIN_MASK;
303
    else                            //output data bit low > 400ns
304
      *pPortData &= ~MDIO_PIN_MASK;
305
                                        // >10ns       
306
    *pPortData |= MDC_PIN_MASK;         // clock rise
307
 
308
    txF = (UINT32)(txF << 1);           // >160ns
309
 
310
    for (j=0; j<MDC_HOLD_TIME; j++);
311
 
312
    *pPortData &= ~MDC_PIN_MASK;        // clock fall 
313
 
314
    for (j=0; j<MDC_HOLD_TIME; j++);
315
 
316
  }
317
 
318
  return;
319
}
320
 
321
 
322
/*---------------------------------------------------------------------
323
*
324
* FUNCTION NAME:
325
*
326
* DESCRIPTION:  Shifts in bits of data
327
*
328
* EXTERNAL EFFECT:
329
*
330
* PARAMETERS:
331
*
332
* RETURNS:
333
*
334
* ASSUMPTIONS:
335
*
336
*---------------------------------------------------------------------*/
337
UINT16
338
MdioReceive(UINT16 size) {
339
 
340
  UINT16 i,j, rxF = 0;
341
 
342
  for (i = 0; i < size; i++) {    // 16 bits
343
 
344
    *pPortData |= MDC_PIN_MASK;            // clock rise
345
 
346
    if ( *pPortData & MDIO_PIN_MASK )             // if read in a high bit
347
      rxF = ( (UINT16)(rxF << 1) | 1 );           // shift in a one
348
    else                                          // if read in a low bit
349
      rxF = ( (UINT16)(rxF << 1) & ~(UINT16)1 );  // shift in a zero
350
 
351
 
352
    for (j=0; j<MDC_HOLD_TIME; j++);
353
 
354
    *pPortData &= ~MDC_PIN_MASK;          // clock fall         
355
 
356
    for (j=0; j<MDC_HOLD_TIME; j++);
357
 
358
  }
359
 
360
  return rxF;
361
}
362
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.