summaryrefslogtreecommitdiffstats
path: root/drivers/net/bcm570x_autoneg.h
blob: 7830944b8a4a7f8c740e2ddea7bda1a4e9416542 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
/******************************************************************************/
/*                                                                            */
/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2001 Broadcom         */
/* Corporation.                                                               */
/* All rights reserved.                                                       */
/*                                                                            */
/* This program is free software; you can redistribute it and/or modify       */
/* it under the terms of the GNU General Public License as published by       */
/* the Free Software Foundation, located in the file LICENSE.                 */
/*                                                                            */
/* History:                                                                   */
/******************************************************************************/


#ifndef AUTONEG_H
#define AUTONEG_H


/******************************************************************************/
/* Constants. */
/******************************************************************************/

#define AN_LINK_TIMER_INTERVAL_US           9000       /* 10ms */

/* TRUE, FALSE */
#define AN_TRUE                             1
#define AN_FALSE                            0


/******************************************************************************/
/* Main data structure for keeping track of 802.3z auto-negotation state */
/* variables as shown in Figure 37-6 of the IEEE 802.3z specification. */
/******************************************************************************/

typedef struct
{
    /* Current auto-negotiation state. */
    unsigned long State;
    #define AN_STATE_UNKNOWN                        0
    #define AN_STATE_AN_ENABLE                      1
    #define AN_STATE_AN_RESTART_INIT                2
    #define AN_STATE_AN_RESTART                     3
    #define AN_STATE_DISABLE_LINK_OK                4
    #define AN_STATE_ABILITY_DETECT_INIT            5
    #define AN_STATE_ABILITY_DETECT                 6
    #define AN_STATE_ACK_DETECT_INIT                7
    #define AN_STATE_ACK_DETECT                     8
    #define AN_STATE_COMPLETE_ACK_INIT              9
    #define AN_STATE_COMPLETE_ACK                   10
    #define AN_STATE_IDLE_DETECT_INIT               11
    #define AN_STATE_IDLE_DETECT                    12
    #define AN_STATE_LINK_OK                        13
    #define AN_STATE_NEXT_PAGE_WAIT_INIT            14
    #define AN_STATE_NEXT_PAGE_WAIT                 16

    /* Link timer. */
    unsigned long LinkTime_us;

    /* Current time. */
    unsigned long CurrentTime_us;

    /* Need these values for consistency check. */
    unsigned short AbilityMatchCfg;

    /* Ability, idle, and ack match functions. */
    unsigned long AbilityMatchCnt;
    char AbilityMatch;
    char IdleMatch;
    char AckMatch;

    /* Tx config data */
    union
    {
	/* The TxConfig register is arranged as follows:                      */
	/*                                                                    */
	/* MSB                                                           LSB  */
	/* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  */
	/* | D7| D6| D5| D4| D3| D2| D1| D0|D15|D14|D13|D12|D11|D10| D9| D8|  */
	/* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  */
	struct
	{
#ifdef BIG_ENDIAN_HOST
	    unsigned int D7:1;        /* PS1 */
	    unsigned int D6:1;        /* HD */
	    unsigned int D5:1;        /* FD */
	    unsigned int D4:1;
	    unsigned int D3:1;
	    unsigned int D2:1;
	    unsigned int D1:1;
	    unsigned int D0:1;
	    unsigned int D15:1;       /* NP */
	    unsigned int D14:1;       /* ACK */
	    unsigned int D13:1;       /* RF2 */
	    unsigned int D12:1;       /* RF1 */
	    unsigned int D11:1;
	    unsigned int D10:1;
	    unsigned int D9:1;
	    unsigned int D8:1;        /* PS2 */
#else /* BIG_ENDIAN_HOST */
	    unsigned int D8:1;        /* PS2 */
	    unsigned int D9:1;
	    unsigned int D10:1;
	    unsigned int D11:1;
	    unsigned int D12:1;       /* RF1 */
	    unsigned int D13:1;       /* RF2 */
	    unsigned int D14:1;       /* ACK */
	    unsigned int D15:1;       /* NP */
	    unsigned int D0:1;
	    unsigned int D1:1;
	    unsigned int D2:1;
	    unsigned int D3:1;
	    unsigned int D4:1;
	    unsigned int D5:1;        /* FD */
	    unsigned int D6:1;        /* HD */
	    unsigned int D7:1;        /* PS1 */
#endif
	} bits;

	unsigned short AsUSHORT;

	#define D8_PS2                      bits.D8
	#define D12_RF1                     bits.D12
	#define D13_RF2                     bits.D13
	#define D14_ACK                     bits.D14
	#define D15_NP                      bits.D15
	#define D5_FD                       bits.D5
	#define D6_HD                       bits.D6
	#define D7_PS1                      bits.D7
    } TxConfig;

    /* Rx config data */
    union
    {
	/* The RxConfig register is arranged as follows:                      */
	/*                                                                    */
	/* MSB                                                           LSB  */
	/* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  */
	/* | D7| D6| D5| D4| D3| D2| D1| D0|D15|D14|D13|D12|D11|D10| D9| D8|  */
	/* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  */
	struct
	{
#ifdef BIG_ENDIAN_HOST
	    unsigned int D7:1;        /* PS1 */
	    unsigned int D6:1;        /* HD */
	    unsigned int D5:1;        /* FD */
	    unsigned int D4:1;
	    unsigned int D3:1;
	    unsigned int D2:1;
	    unsigned int D1:1;
	    unsigned int D0:1;
	    unsigned int D15:1;       /* NP */
	    unsigned int D14:1;       /* ACK */
	    unsigned int D13:1;       /* RF2 */
	    unsigned int D12:1;       /* RF1 */
	    unsigned int D11:1;
	    unsigned int D10:1;
	    unsigned int D9:1;
	    unsigned int D8:1;        /* PS2 */
#else /* BIG_ENDIAN_HOST */
	    unsigned int D8:1;        /* PS2 */
	    unsigned int D9:1;
	    unsigned int D10:1;
	    unsigned int D11:1;
	    unsigned int D12:1;       /* RF1 */
	    unsigned int D13:1;       /* RF2 */
	    unsigned int D14:1;       /* ACK */
	    unsigned int D15:1;       /* NP */
	    unsigned int D0:1;
	    unsigned int D1:1;
	    unsigned int D2:1;
	    unsigned int D3:1;
	    unsigned int D4:1;
	    unsigned int D5:1;        /* FD */
	    unsigned int D6:1;        /* HD */
	    unsigned int D7:1;        /* PS1 */
#endif
	} bits;

	unsigned short AsUSHORT;
    } RxConfig;

    #define AN_CONFIG_NP                            0x0080
    #define AN_CONFIG_ACK                           0x0040
    #define AN_CONFIG_RF2                           0x0020
    #define AN_CONFIG_RF1                           0x0010
    #define AN_CONFIG_PS2                           0x0001
    #define AN_CONFIG_PS1                           0x8000
    #define AN_CONFIG_HD                            0x4000
    #define AN_CONFIG_FD                            0x2000


    /* Management registers. */

    /* Control register. */
    union
    {
	struct
	{
	    unsigned int an_enable:1;
	    unsigned int loopback:1;
	    unsigned int reset:1;
	    unsigned int restart_an:1;
	} bits;

	unsigned short AsUSHORT;

	#define mr_an_enable                Mr0.bits.an_enable
	#define mr_loopback                 Mr0.bits.loopback
	#define mr_main_reset               Mr0.bits.reset
	#define mr_restart_an               Mr0.bits.restart_an
    } Mr0;

    /* Status register. */
    union
    {
	struct
	{
	    unsigned int an_complete:1;
	    unsigned int link_ok:1;
	} bits;

	unsigned short AsUSHORT;

	#define mr_an_complete              Mr1.bits.an_complete
	#define mr_link_ok                  Mr1.bits.link_ok
    } Mr1;

    /* Advertisement register. */
    union
    {
	struct
	{
	    unsigned int reserved_4:5;
	    unsigned int full_duplex:1;
	    unsigned int half_duplex:1;
	    unsigned int sym_pause:1;
	    unsigned int asym_pause:1;
	    unsigned int reserved_11:3;
	    unsigned int remote_fault1:1;
	    unsigned int remote_fault2:1;
	    unsigned int reserved_14:1;
	    unsigned int next_page:1;
	} bits;

	unsigned short AsUSHORT;

	#define mr_adv_full_duplex          Mr4.bits.full_duplex
	#define mr_adv_half_duplex          Mr4.bits.half_duplex
	#define mr_adv_sym_pause            Mr4.bits.sym_pause
	#define mr_adv_asym_pause           Mr4.bits.asym_pause
	#define mr_adv_remote_fault1        Mr4.bits.remote_fault1
	#define mr_adv_remote_fault2        Mr4.bits.remote_fault2
	#define mr_adv_next_page            Mr4.bits.next_page
    } Mr4;

    /* Link partner advertisement register. */
    union
    {
	struct
	{
	    unsigned int reserved_4:5;
	    unsigned int lp_full_duplex:1;
	    unsigned int lp_half_duplex:1;
	    unsigned int lp_sym_pause:1;
	    unsigned int lp_asym_pause:1;
	    unsigned int reserved_11:3;
	    unsigned int lp_remote_fault1:1;
	    unsigned int lp_remote_fault2:1;
	    unsigned int lp_ack:1;
	    unsigned int lp_next_page:1;
	} bits;

	unsigned short AsUSHORT;

	#define mr_lp_adv_full_duplex       Mr5.bits.lp_full_duplex
	#define mr_lp_adv_half_duplex       Mr5.bits.lp_half_duplex
	#define mr_lp_adv_sym_pause         Mr5.bits.lp_sym_pause
	#define mr_lp_adv_asym_pause        Mr5.bits.lp_asym_pause
	#define mr_lp_adv_remote_fault1     Mr5.bits.lp_remote_fault1
	#define mr_lp_adv_remote_fault2     Mr5.bits.lp_remote_fault2
	#define mr_lp_adv_next_page         Mr5.bits.lp_next_page
    } Mr5;

    /* Auto-negotiation expansion register. */
    union
    {
	struct
	{
	    unsigned int reserved_0:1;
	    unsigned int page_received:1;
	    unsigned int next_pageable:1;
	    unsigned int reserved_15:13;
	} bits;

	unsigned short AsUSHORT;
    } Mr6;

    /* Auto-negotiation next page transmit register. */
    union
    {
	struct
	{
	    unsigned int code_field:11;
	    unsigned int toggle:1;
	    unsigned int ack2:1;
	    unsigned int message_page:1;
	    unsigned int reserved_14:1;
	    unsigned int next_page:1;
	} bits;

	unsigned short AsUSHORT;

	#define mr_np_tx                    Mr7.AsUSHORT
    } Mr7;

    /* Auto-negotiation link partner ability register. */
    union
    {
	struct
	{
	    unsigned int code_field:11;
	    unsigned int toggle:1;
	    unsigned int ack2:1;
	    unsigned int message_page:1;
	    unsigned int ack:1;
	    unsigned int next_page:1;
	} bits;

	unsigned short AsUSHORT;

	#define mr_lp_np_rx                 Mr8.AsUSHORT
    } Mr8;

    /* Extended status register. */
    union
    {
	struct
	{
	    unsigned int reserved_11:12;
	    unsigned int base1000_t_hd:1;
	    unsigned int base1000_t_fd:1;
	    unsigned int base1000_x_hd:1;
	    unsigned int base1000_x_fd:1;
	} bits;

	unsigned short AsUSHORT;
    } Mr15;

    /* Miscellaneous state variables. */
    union
    {
	struct
	{
	    unsigned int toggle_tx:1;
	    unsigned int toggle_rx:1;
	    unsigned int np_rx:1;
	    unsigned int page_rx:1;
	    unsigned int np_loaded:1;
	} bits;

	unsigned short AsUSHORT;

	#define mr_toggle_tx                MrMisc.bits.toggle_tx
	#define mr_toggle_rx                MrMisc.bits.toggle_rx
	#define mr_np_rx                    MrMisc.bits.np_rx
	#define mr_page_rx                  MrMisc.bits.page_rx
	#define mr_np_loaded                MrMisc.bits.np_loaded
    } MrMisc;


    /* Implement specifics */

    /* Pointer to the operating system specific data structure. */
    void *pContext;
} AN_STATE_INFO, *PAN_STATE_INFO;


/******************************************************************************/
/* Return code of Autoneg8023z. */
/******************************************************************************/

typedef enum
{
    AUTONEG_STATUS_OK               = 0,
    AUTONEG_STATUS_DONE             = 1,
    AUTONEG_STATUS_TIMER_ENABLED    = 2,
    AUTONEG_STATUS_FAILED           = 0xfffffff
} AUTONEG_STATUS, *PAUTONEG_STATUS;


/******************************************************************************/
/* Function prototypes. */
/******************************************************************************/

AUTONEG_STATUS Autoneg8023z(PAN_STATE_INFO pAnInfo);
void AutonegInit(PAN_STATE_INFO pAnInfo);


/******************************************************************************/
/* The following functions are defined in the os-dependent module. */
/******************************************************************************/

void MM_AnTxConfig(PAN_STATE_INFO pAnInfo);
void MM_AnTxIdle(PAN_STATE_INFO pAnInfo);
char MM_AnRxConfig(PAN_STATE_INFO pAnInfo, unsigned short *pRxConfig);


#endif /* AUTONEG_H */