aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/skfp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/skfp')
-rw-r--r--drivers/net/skfp/Makefile20
-rw-r--r--drivers/net/skfp/can.c83
-rw-r--r--drivers/net/skfp/cfm.c627
-rw-r--r--drivers/net/skfp/drvfbi.c1529
-rw-r--r--drivers/net/skfp/ecm.c536
-rw-r--r--drivers/net/skfp/ess.c720
-rw-r--r--drivers/net/skfp/fplustm.c1561
-rw-r--r--drivers/net/skfp/h/cmtdef.h763
-rw-r--r--drivers/net/skfp/h/fddi.h69
-rw-r--r--drivers/net/skfp/h/fddimib.h349
-rw-r--r--drivers/net/skfp/h/fplustm.h274
-rw-r--r--drivers/net/skfp/h/hwmtm.h424
-rw-r--r--drivers/net/skfp/h/lnkstat.h84
-rw-r--r--drivers/net/skfp/h/mbuf.h54
-rw-r--r--drivers/net/skfp/h/osdef1st.h123
-rw-r--r--drivers/net/skfp/h/sba.h142
-rw-r--r--drivers/net/skfp/h/sba_def.h76
-rw-r--r--drivers/net/skfp/h/skfbi.h1919
-rw-r--r--drivers/net/skfp/h/skfbiinc.h123
-rw-r--r--drivers/net/skfp/h/smc.h471
-rw-r--r--drivers/net/skfp/h/smt.h882
-rw-r--r--drivers/net/skfp/h/smt_p.h326
-rw-r--r--drivers/net/skfp/h/smtstate.h106
-rw-r--r--drivers/net/skfp/h/supern_2.h1059
-rw-r--r--drivers/net/skfp/h/targethw.h169
-rw-r--r--drivers/net/skfp/h/targetos.h165
-rw-r--r--drivers/net/skfp/h/types.h39
-rw-r--r--drivers/net/skfp/hwmtm.c2219
-rw-r--r--drivers/net/skfp/hwt.c305
-rw-r--r--drivers/net/skfp/lnkstat.c204
-rw-r--r--drivers/net/skfp/pcmplc.c2024
-rw-r--r--drivers/net/skfp/pmf.c1671
-rw-r--r--drivers/net/skfp/queue.c173
-rw-r--r--drivers/net/skfp/rmt.c654
-rw-r--r--drivers/net/skfp/skfddi.c2293
-rw-r--r--drivers/net/skfp/smt.c2097
-rw-r--r--drivers/net/skfp/smtdef.c360
-rw-r--r--drivers/net/skfp/smtinit.c125
-rw-r--r--drivers/net/skfp/smtparse.c467
-rw-r--r--drivers/net/skfp/smttimer.c156
-rw-r--r--drivers/net/skfp/srf.c429
41 files changed, 25870 insertions, 0 deletions
diff --git a/drivers/net/skfp/Makefile b/drivers/net/skfp/Makefile
new file mode 100644
index 000000000000..6cfccfb7889f
--- /dev/null
+++ b/drivers/net/skfp/Makefile
@@ -0,0 +1,20 @@
1#
2# Makefile for the SysKonnect FDDI PCI adapter driver
3#
4
5obj-$(CONFIG_SKFP) += skfp.o
6
7skfp-objs := skfddi.o hwmtm.o fplustm.o smt.o cfm.o \
8 ecm.o pcmplc.o pmf.o queue.o rmt.o \
9 smtdef.o smtinit.o smttimer.o srf.o lnkstat.o \
10 smtparse.o hwt.o drvfbi.o ess.o
11
12# NOTE:
13# Compiling this driver produces some warnings (and some more are
14# switched off below), but I did not fix this, because the Hardware
15# Module source (see skfddi.c for details) is used for different
16# drivers, and fixing it for Linux might bring problems on other
17# projects. To keep the source common for all those drivers (and
18# thus simplify fixes to it), please do not clean it up!
19
20EXTRA_CFLAGS += -Idrivers/net/skfp -DPCI -DMEM_MAPPED_IO -Wno-strict-prototypes
diff --git a/drivers/net/skfp/can.c b/drivers/net/skfp/can.c
new file mode 100644
index 000000000000..8a49abce7961
--- /dev/null
+++ b/drivers/net/skfp/can.c
@@ -0,0 +1,83 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * See the file "skfddi.c" for further information.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * The information in this file is provided "AS IS" without warranty.
14 *
15 ******************************************************************************/
16
17#ifndef lint
18static const char xID_sccs[] = "@(#)can.c 1.5 97/04/07 (C) SK " ;
19#endif
20
21/*
22 * canonical bit order
23 */
24const u_char canonical[256] = {
25 0x00,0x80,0x40,0xc0,0x20,0xa0,0x60,0xe0,
26 0x10,0x90,0x50,0xd0,0x30,0xb0,0x70,0xf0,
27 0x08,0x88,0x48,0xc8,0x28,0xa8,0x68,0xe8,
28 0x18,0x98,0x58,0xd8,0x38,0xb8,0x78,0xf8,
29 0x04,0x84,0x44,0xc4,0x24,0xa4,0x64,0xe4,
30 0x14,0x94,0x54,0xd4,0x34,0xb4,0x74,0xf4,
31 0x0c,0x8c,0x4c,0xcc,0x2c,0xac,0x6c,0xec,
32 0x1c,0x9c,0x5c,0xdc,0x3c,0xbc,0x7c,0xfc,
33 0x02,0x82,0x42,0xc2,0x22,0xa2,0x62,0xe2,
34 0x12,0x92,0x52,0xd2,0x32,0xb2,0x72,0xf2,
35 0x0a,0x8a,0x4a,0xca,0x2a,0xaa,0x6a,0xea,
36 0x1a,0x9a,0x5a,0xda,0x3a,0xba,0x7a,0xfa,
37 0x06,0x86,0x46,0xc6,0x26,0xa6,0x66,0xe6,
38 0x16,0x96,0x56,0xd6,0x36,0xb6,0x76,0xf6,
39 0x0e,0x8e,0x4e,0xce,0x2e,0xae,0x6e,0xee,
40 0x1e,0x9e,0x5e,0xde,0x3e,0xbe,0x7e,0xfe,
41 0x01,0x81,0x41,0xc1,0x21,0xa1,0x61,0xe1,
42 0x11,0x91,0x51,0xd1,0x31,0xb1,0x71,0xf1,
43 0x09,0x89,0x49,0xc9,0x29,0xa9,0x69,0xe9,
44 0x19,0x99,0x59,0xd9,0x39,0xb9,0x79,0xf9,
45 0x05,0x85,0x45,0xc5,0x25,0xa5,0x65,0xe5,
46 0x15,0x95,0x55,0xd5,0x35,0xb5,0x75,0xf5,
47 0x0d,0x8d,0x4d,0xcd,0x2d,0xad,0x6d,0xed,
48 0x1d,0x9d,0x5d,0xdd,0x3d,0xbd,0x7d,0xfd,
49 0x03,0x83,0x43,0xc3,0x23,0xa3,0x63,0xe3,
50 0x13,0x93,0x53,0xd3,0x33,0xb3,0x73,0xf3,
51 0x0b,0x8b,0x4b,0xcb,0x2b,0xab,0x6b,0xeb,
52 0x1b,0x9b,0x5b,0xdb,0x3b,0xbb,0x7b,0xfb,
53 0x07,0x87,0x47,0xc7,0x27,0xa7,0x67,0xe7,
54 0x17,0x97,0x57,0xd7,0x37,0xb7,0x77,0xf7,
55 0x0f,0x8f,0x4f,0xcf,0x2f,0xaf,0x6f,0xef,
56 0x1f,0x9f,0x5f,0xdf,0x3f,0xbf,0x7f,0xff
57} ;
58
59#ifdef MAKE_TABLE
60int byte_reverse(x)
61int x ;
62{
63 int y = 0 ;
64
65 if (x & 0x01)
66 y |= 0x80 ;
67 if (x & 0x02)
68 y |= 0x40 ;
69 if (x & 0x04)
70 y |= 0x20 ;
71 if (x & 0x08)
72 y |= 0x10 ;
73 if (x & 0x10)
74 y |= 0x08 ;
75 if (x & 0x20)
76 y |= 0x04 ;
77 if (x & 0x40)
78 y |= 0x02 ;
79 if (x & 0x80)
80 y |= 0x01 ;
81 return(y) ;
82}
83#endif
diff --git a/drivers/net/skfp/cfm.c b/drivers/net/skfp/cfm.c
new file mode 100644
index 000000000000..4c8aaa762333
--- /dev/null
+++ b/drivers/net/skfp/cfm.c
@@ -0,0 +1,627 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * See the file "skfddi.c" for further information.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * The information in this file is provided "AS IS" without warranty.
14 *
15 ******************************************************************************/
16
17/*
18 SMT CFM
19 Configuration Management
20 DAS with single MAC
21*/
22
23/*
24 * Hardware independent state machine implemantation
25 * The following external SMT functions are referenced :
26 *
27 * queue_event()
28 *
29 * The following external HW dependent functions are referenced :
30 * config_mux()
31 *
32 * The following HW dependent events are required :
33 * NONE
34 */
35
36#include "h/types.h"
37#include "h/fddi.h"
38#include "h/smc.h"
39
40#define KERNEL
41#include "h/smtstate.h"
42
43#ifndef lint
44static const char ID_sccs[] = "@(#)cfm.c 2.18 98/10/06 (C) SK " ;
45#endif
46
47/*
48 * FSM Macros
49 */
50#define AFLAG 0x10
51#define GO_STATE(x) (smc->mib.fddiSMTCF_State = (x)|AFLAG)
52#define ACTIONS_DONE() (smc->mib.fddiSMTCF_State &= ~AFLAG)
53#define ACTIONS(x) (x|AFLAG)
54
55#ifdef DEBUG
56/*
57 * symbolic state names
58 */
59static const char * const cfm_states[] = {
60 "SC0_ISOLATED","CF1","CF2","CF3","CF4",
61 "SC1_WRAP_A","SC2_WRAP_B","SC5_TRHU_B","SC7_WRAP_S",
62 "SC9_C_WRAP_A","SC10_C_WRAP_B","SC11_C_WRAP_S","SC4_THRU_A"
63} ;
64
65/*
66 * symbolic event names
67 */
68static const char * const cfm_events[] = {
69 "NONE","CF_LOOP_A","CF_LOOP_B","CF_JOIN_A","CF_JOIN_B"
70} ;
71#endif
72
73/*
74 * map from state to downstream port type
75 */
76static const u_char cf_to_ptype[] = {
77 TNONE,TNONE,TNONE,TNONE,TNONE,
78 TNONE,TB,TB,TS,
79 TA,TB,TS,TB
80} ;
81
82/*
83 * CEM port states
84 */
85#define CEM_PST_DOWN 0
86#define CEM_PST_UP 1
87#define CEM_PST_HOLD 2
88/* define portstate array only for A and B port */
89/* Do this within the smc structure (use in multiple cards) */
90
91/*
92 * all Globals are defined in smc.h
93 * struct s_cfm
94 */
95
96/*
97 * function declarations
98 */
99static void cfm_fsm(struct s_smc *smc, int cmd);
100
101/*
102 init CFM state machine
103 clear all CFM vars and flags
104*/
105void cfm_init(struct s_smc *smc)
106{
107 smc->mib.fddiSMTCF_State = ACTIONS(SC0_ISOLATED) ;
108 smc->r.rm_join = 0 ;
109 smc->r.rm_loop = 0 ;
110 smc->y[PA].scrub = 0 ;
111 smc->y[PB].scrub = 0 ;
112 smc->y[PA].cem_pst = CEM_PST_DOWN ;
113 smc->y[PB].cem_pst = CEM_PST_DOWN ;
114}
115
116/* Some terms conditions used by the selection criteria */
117#define THRU_ENABLED(smc) (smc->y[PA].pc_mode != PM_TREE && \
118 smc->y[PB].pc_mode != PM_TREE)
119/* Selection criteria for the ports */
120static void selection_criteria (struct s_smc *smc, struct s_phy *phy)
121{
122
123 switch (phy->mib->fddiPORTMy_Type) {
124 case TA:
125 if ( !THRU_ENABLED(smc) && smc->y[PB].cf_join ) {
126 phy->wc_flag = TRUE ;
127 } else {
128 phy->wc_flag = FALSE ;
129 }
130
131 break;
132 case TB:
133 /* take precedence over PA */
134 phy->wc_flag = FALSE ;
135 break;
136 case TS:
137 phy->wc_flag = FALSE ;
138 break;
139 case TM:
140 phy->wc_flag = FALSE ;
141 break;
142 }
143
144}
145
146void all_selection_criteria(struct s_smc *smc)
147{
148 struct s_phy *phy ;
149 int p ;
150
151 for ( p = 0,phy = smc->y ; p < NUMPHYS; p++, phy++ ) {
152 /* Do the selection criteria */
153 selection_criteria (smc,phy);
154 }
155}
156
157static void cem_priv_state(struct s_smc *smc, int event)
158/* State machine for private PORT states: used to optimize dual homing */
159{
160 int np; /* Number of the port */
161 int i;
162
163 /* Do this only in a DAS */
164 if (smc->s.sas != SMT_DAS )
165 return ;
166
167 np = event - CF_JOIN;
168
169 if (np != PA && np != PB) {
170 return ;
171 }
172 /* Change the port state according to the event (portnumber) */
173 if (smc->y[np].cf_join) {
174 smc->y[np].cem_pst = CEM_PST_UP ;
175 } else if (!smc->y[np].wc_flag) {
176 /* set the port to done only if it is not withheld */
177 smc->y[np].cem_pst = CEM_PST_DOWN ;
178 }
179
180 /* Don't set an hold port to down */
181
182 /* Check all ports of restart conditions */
183 for (i = 0 ; i < 2 ; i ++ ) {
184 /* Check all port for PORT is on hold and no withhold is done */
185 if ( smc->y[i].cem_pst == CEM_PST_HOLD && !smc->y[i].wc_flag ) {
186 smc->y[i].cem_pst = CEM_PST_DOWN;
187 queue_event(smc,(int)(EVENT_PCM+i),PC_START) ;
188 }
189 if ( smc->y[i].cem_pst == CEM_PST_UP && smc->y[i].wc_flag ) {
190 smc->y[i].cem_pst = CEM_PST_HOLD;
191 queue_event(smc,(int)(EVENT_PCM+i),PC_START) ;
192 }
193 if ( smc->y[i].cem_pst == CEM_PST_DOWN && smc->y[i].wc_flag ) {
194 /*
195 * The port must be restarted when the wc_flag
196 * will be reset. So set the port on hold.
197 */
198 smc->y[i].cem_pst = CEM_PST_HOLD;
199 }
200 }
201 return ;
202}
203
204/*
205 CFM state machine
206 called by dispatcher
207
208 do
209 display state change
210 process event
211 until SM is stable
212*/
213void cfm(struct s_smc *smc, int event)
214{
215 int state ; /* remember last state */
216 int cond ;
217 int oldstate ;
218
219 /* We will do the following: */
220 /* - compute the variable WC_Flag for every port (This is where */
221 /* we can extend the requested path checking !!) */
222 /* - do the old (SMT 6.2 like) state machine */
223 /* - do the resulting station states */
224
225 all_selection_criteria (smc);
226
227 /* We will check now whether a state transition is allowed or not */
228 /* - change the portstates */
229 cem_priv_state (smc, event);
230
231 oldstate = smc->mib.fddiSMTCF_State ;
232 do {
233 DB_CFM("CFM : state %s%s",
234 (smc->mib.fddiSMTCF_State & AFLAG) ? "ACTIONS " : "",
235 cfm_states[smc->mib.fddiSMTCF_State & ~AFLAG]) ;
236 DB_CFM(" event %s\n",cfm_events[event],0) ;
237 state = smc->mib.fddiSMTCF_State ;
238 cfm_fsm(smc,event) ;
239 event = 0 ;
240 } while (state != smc->mib.fddiSMTCF_State) ;
241
242#ifndef SLIM_SMT
243 /*
244 * check peer wrap condition
245 */
246 cond = FALSE ;
247 if ( (smc->mib.fddiSMTCF_State == SC9_C_WRAP_A &&
248 smc->y[PA].pc_mode == PM_PEER) ||
249 (smc->mib.fddiSMTCF_State == SC10_C_WRAP_B &&
250 smc->y[PB].pc_mode == PM_PEER) ||
251 (smc->mib.fddiSMTCF_State == SC11_C_WRAP_S &&
252 smc->y[PS].pc_mode == PM_PEER &&
253 smc->y[PS].mib->fddiPORTNeighborType != TS ) ) {
254 cond = TRUE ;
255 }
256 if (cond != smc->mib.fddiSMTPeerWrapFlag)
257 smt_srf_event(smc,SMT_COND_SMT_PEER_WRAP,0,cond) ;
258
259#if 0
260 /*
261 * Don't send ever MAC_PATH_CHANGE events. Our MAC is hard-wired
262 * to the primary path.
263 */
264 /*
265 * path change
266 */
267 if (smc->mib.fddiSMTCF_State != oldstate) {
268 smt_srf_event(smc,SMT_EVENT_MAC_PATH_CHANGE,INDEX_MAC,0) ;
269 }
270#endif
271#endif /* no SLIM_SMT */
272
273 /*
274 * set MAC port type
275 */
276 smc->mib.m[MAC0].fddiMACDownstreamPORTType =
277 cf_to_ptype[smc->mib.fddiSMTCF_State] ;
278 cfm_state_change(smc,(int)smc->mib.fddiSMTCF_State) ;
279}
280
281/*
282 process CFM event
283*/
284/*ARGSUSED1*/
285static void cfm_fsm(struct s_smc *smc, int cmd)
286{
287 switch(smc->mib.fddiSMTCF_State) {
288 case ACTIONS(SC0_ISOLATED) :
289 smc->mib.p[PA].fddiPORTCurrentPath = MIB_PATH_ISOLATED ;
290 smc->mib.p[PB].fddiPORTCurrentPath = MIB_PATH_ISOLATED ;
291 smc->mib.p[PA].fddiPORTMACPlacement = 0 ;
292 smc->mib.p[PB].fddiPORTMACPlacement = 0 ;
293 smc->mib.fddiSMTStationStatus = MIB_SMT_STASTA_SEPA ;
294 config_mux(smc,MUX_ISOLATE) ; /* configure PHY Mux */
295 smc->r.rm_loop = FALSE ;
296 smc->r.rm_join = FALSE ;
297 queue_event(smc,EVENT_RMT,RM_JOIN) ;/* signal RMT */
298 /* Don't do the WC-Flag changing here */
299 ACTIONS_DONE() ;
300 DB_CFMN(1,"CFM : %s\n",cfm_states[smc->mib.fddiSMTCF_State],0) ;
301 break;
302 case SC0_ISOLATED :
303 /*SC07*/
304 /*SAS port can be PA or PB ! */
305 if (smc->s.sas && (smc->y[PA].cf_join || smc->y[PA].cf_loop ||
306 smc->y[PB].cf_join || smc->y[PB].cf_loop)) {
307 GO_STATE(SC11_C_WRAP_S) ;
308 break ;
309 }
310 /*SC01*/
311 if ((smc->y[PA].cem_pst == CEM_PST_UP && smc->y[PA].cf_join &&
312 !smc->y[PA].wc_flag) || smc->y[PA].cf_loop) {
313 GO_STATE(SC9_C_WRAP_A) ;
314 break ;
315 }
316 /*SC02*/
317 if ((smc->y[PB].cem_pst == CEM_PST_UP && smc->y[PB].cf_join &&
318 !smc->y[PB].wc_flag) || smc->y[PB].cf_loop) {
319 GO_STATE(SC10_C_WRAP_B) ;
320 break ;
321 }
322 break ;
323 case ACTIONS(SC9_C_WRAP_A) :
324 smc->mib.p[PA].fddiPORTCurrentPath = MIB_PATH_CONCATENATED ;
325 smc->mib.p[PB].fddiPORTCurrentPath = MIB_PATH_ISOLATED ;
326 smc->mib.p[PA].fddiPORTMACPlacement = INDEX_MAC ;
327 smc->mib.p[PB].fddiPORTMACPlacement = 0 ;
328 smc->mib.fddiSMTStationStatus = MIB_SMT_STASTA_CON ;
329 config_mux(smc,MUX_WRAPA) ; /* configure PHY mux */
330 if (smc->y[PA].cf_loop) {
331 smc->r.rm_join = FALSE ;
332 smc->r.rm_loop = TRUE ;
333 queue_event(smc,EVENT_RMT,RM_LOOP) ;/* signal RMT */
334 }
335 if (smc->y[PA].cf_join) {
336 smc->r.rm_loop = FALSE ;
337 smc->r.rm_join = TRUE ;
338 queue_event(smc,EVENT_RMT,RM_JOIN) ;/* signal RMT */
339 }
340 ACTIONS_DONE() ;
341 DB_CFMN(1,"CFM : %s\n",cfm_states[smc->mib.fddiSMTCF_State],0) ;
342 break ;
343 case SC9_C_WRAP_A :
344 /*SC10*/
345 if ( (smc->y[PA].wc_flag || !smc->y[PA].cf_join) &&
346 !smc->y[PA].cf_loop ) {
347 GO_STATE(SC0_ISOLATED) ;
348 break ;
349 }
350 /*SC12*/
351 else if ( (smc->y[PB].cf_loop && smc->y[PA].cf_join &&
352 smc->y[PA].cem_pst == CEM_PST_UP) ||
353 ((smc->y[PB].cf_loop ||
354 (smc->y[PB].cf_join &&
355 smc->y[PB].cem_pst == CEM_PST_UP)) &&
356 (smc->y[PA].pc_mode == PM_TREE ||
357 smc->y[PB].pc_mode == PM_TREE))) {
358 smc->y[PA].scrub = TRUE ;
359 GO_STATE(SC10_C_WRAP_B) ;
360 break ;
361 }
362 /*SC14*/
363 else if (!smc->s.attach_s &&
364 smc->y[PA].cf_join &&
365 smc->y[PA].cem_pst == CEM_PST_UP &&
366 smc->y[PA].pc_mode == PM_PEER && smc->y[PB].cf_join &&
367 smc->y[PB].cem_pst == CEM_PST_UP &&
368 smc->y[PB].pc_mode == PM_PEER) {
369 smc->y[PA].scrub = TRUE ;
370 smc->y[PB].scrub = TRUE ;
371 GO_STATE(SC4_THRU_A) ;
372 break ;
373 }
374 /*SC15*/
375 else if ( smc->s.attach_s &&
376 smc->y[PA].cf_join &&
377 smc->y[PA].cem_pst == CEM_PST_UP &&
378 smc->y[PA].pc_mode == PM_PEER &&
379 smc->y[PB].cf_join &&
380 smc->y[PB].cem_pst == CEM_PST_UP &&
381 smc->y[PB].pc_mode == PM_PEER) {
382 smc->y[PA].scrub = TRUE ;
383 smc->y[PB].scrub = TRUE ;
384 GO_STATE(SC5_THRU_B) ;
385 break ;
386 }
387 break ;
388 case ACTIONS(SC10_C_WRAP_B) :
389 smc->mib.p[PA].fddiPORTCurrentPath = MIB_PATH_ISOLATED ;
390 smc->mib.p[PB].fddiPORTCurrentPath = MIB_PATH_CONCATENATED ;
391 smc->mib.p[PA].fddiPORTMACPlacement = 0 ;
392 smc->mib.p[PB].fddiPORTMACPlacement = INDEX_MAC ;
393 smc->mib.fddiSMTStationStatus = MIB_SMT_STASTA_CON ;
394 config_mux(smc,MUX_WRAPB) ; /* configure PHY mux */
395 if (smc->y[PB].cf_loop) {
396 smc->r.rm_join = FALSE ;
397 smc->r.rm_loop = TRUE ;
398 queue_event(smc,EVENT_RMT,RM_LOOP) ;/* signal RMT */
399 }
400 if (smc->y[PB].cf_join) {
401 smc->r.rm_loop = FALSE ;
402 smc->r.rm_join = TRUE ;
403 queue_event(smc,EVENT_RMT,RM_JOIN) ;/* signal RMT */
404 }
405 ACTIONS_DONE() ;
406 DB_CFMN(1,"CFM : %s\n",cfm_states[smc->mib.fddiSMTCF_State],0) ;
407 break ;
408 case SC10_C_WRAP_B :
409 /*SC20*/
410 if ( !smc->y[PB].cf_join && !smc->y[PB].cf_loop ) {
411 GO_STATE(SC0_ISOLATED) ;
412 break ;
413 }
414 /*SC21*/
415 else if ( smc->y[PA].cf_loop && smc->y[PA].pc_mode == PM_PEER &&
416 smc->y[PB].cf_join && smc->y[PB].pc_mode == PM_PEER) {
417 smc->y[PB].scrub = TRUE ;
418 GO_STATE(SC9_C_WRAP_A) ;
419 break ;
420 }
421 /*SC24*/
422 else if (!smc->s.attach_s &&
423 smc->y[PA].cf_join && smc->y[PA].pc_mode == PM_PEER &&
424 smc->y[PB].cf_join && smc->y[PB].pc_mode == PM_PEER) {
425 smc->y[PA].scrub = TRUE ;
426 smc->y[PB].scrub = TRUE ;
427 GO_STATE(SC4_THRU_A) ;
428 break ;
429 }
430 /*SC25*/
431 else if ( smc->s.attach_s &&
432 smc->y[PA].cf_join && smc->y[PA].pc_mode == PM_PEER &&
433 smc->y[PB].cf_join && smc->y[PB].pc_mode == PM_PEER) {
434 smc->y[PA].scrub = TRUE ;
435 smc->y[PB].scrub = TRUE ;
436 GO_STATE(SC5_THRU_B) ;
437 break ;
438 }
439 break ;
440 case ACTIONS(SC4_THRU_A) :
441 smc->mib.p[PA].fddiPORTCurrentPath = MIB_PATH_THRU ;
442 smc->mib.p[PB].fddiPORTCurrentPath = MIB_PATH_THRU ;
443 smc->mib.p[PA].fddiPORTMACPlacement = 0 ;
444 smc->mib.p[PB].fddiPORTMACPlacement = INDEX_MAC ;
445 smc->mib.fddiSMTStationStatus = MIB_SMT_STASTA_THRU ;
446 config_mux(smc,MUX_THRUA) ; /* configure PHY mux */
447 smc->r.rm_loop = FALSE ;
448 smc->r.rm_join = TRUE ;
449 queue_event(smc,EVENT_RMT,RM_JOIN) ;/* signal RMT */
450 ACTIONS_DONE() ;
451 DB_CFMN(1,"CFM : %s\n",cfm_states[smc->mib.fddiSMTCF_State],0) ;
452 break ;
453 case SC4_THRU_A :
454 /*SC41*/
455 if (smc->y[PB].wc_flag || !smc->y[PB].cf_join) {
456 smc->y[PA].scrub = TRUE ;
457 GO_STATE(SC9_C_WRAP_A) ;
458 break ;
459 }
460 /*SC42*/
461 else if (!smc->y[PA].cf_join || smc->y[PA].wc_flag) {
462 smc->y[PB].scrub = TRUE ;
463 GO_STATE(SC10_C_WRAP_B) ;
464 break ;
465 }
466 /*SC45*/
467 else if (smc->s.attach_s) {
468 smc->y[PB].scrub = TRUE ;
469 GO_STATE(SC5_THRU_B) ;
470 break ;
471 }
472 break ;
473 case ACTIONS(SC5_THRU_B) :
474 smc->mib.p[PA].fddiPORTCurrentPath = MIB_PATH_THRU ;
475 smc->mib.p[PB].fddiPORTCurrentPath = MIB_PATH_THRU ;
476 smc->mib.p[PA].fddiPORTMACPlacement = INDEX_MAC ;
477 smc->mib.p[PB].fddiPORTMACPlacement = 0 ;
478 smc->mib.fddiSMTStationStatus = MIB_SMT_STASTA_THRU ;
479 config_mux(smc,MUX_THRUB) ; /* configure PHY mux */
480 smc->r.rm_loop = FALSE ;
481 smc->r.rm_join = TRUE ;
482 queue_event(smc,EVENT_RMT,RM_JOIN) ;/* signal RMT */
483 ACTIONS_DONE() ;
484 DB_CFMN(1,"CFM : %s\n",cfm_states[smc->mib.fddiSMTCF_State],0) ;
485 break ;
486 case SC5_THRU_B :
487 /*SC51*/
488 if (!smc->y[PB].cf_join || smc->y[PB].wc_flag) {
489 smc->y[PA].scrub = TRUE ;
490 GO_STATE(SC9_C_WRAP_A) ;
491 break ;
492 }
493 /*SC52*/
494 else if (!smc->y[PA].cf_join || smc->y[PA].wc_flag) {
495 smc->y[PB].scrub = TRUE ;
496 GO_STATE(SC10_C_WRAP_B) ;
497 break ;
498 }
499 /*SC54*/
500 else if (!smc->s.attach_s) {
501 smc->y[PA].scrub = TRUE ;
502 GO_STATE(SC4_THRU_A) ;
503 break ;
504 }
505 break ;
506 case ACTIONS(SC11_C_WRAP_S) :
507 smc->mib.p[PS].fddiPORTCurrentPath = MIB_PATH_CONCATENATED ;
508 smc->mib.p[PS].fddiPORTMACPlacement = INDEX_MAC ;
509 smc->mib.fddiSMTStationStatus = MIB_SMT_STASTA_CON ;
510 config_mux(smc,MUX_WRAPS) ; /* configure PHY mux */
511 if (smc->y[PA].cf_loop || smc->y[PB].cf_loop) {
512 smc->r.rm_join = FALSE ;
513 smc->r.rm_loop = TRUE ;
514 queue_event(smc,EVENT_RMT,RM_LOOP) ;/* signal RMT */
515 }
516 if (smc->y[PA].cf_join || smc->y[PB].cf_join) {
517 smc->r.rm_loop = FALSE ;
518 smc->r.rm_join = TRUE ;
519 queue_event(smc,EVENT_RMT,RM_JOIN) ;/* signal RMT */
520 }
521 ACTIONS_DONE() ;
522 DB_CFMN(1,"CFM : %s\n",cfm_states[smc->mib.fddiSMTCF_State],0) ;
523 break ;
524 case SC11_C_WRAP_S :
525 /*SC70*/
526 if ( !smc->y[PA].cf_join && !smc->y[PA].cf_loop &&
527 !smc->y[PB].cf_join && !smc->y[PB].cf_loop) {
528 GO_STATE(SC0_ISOLATED) ;
529 break ;
530 }
531 break ;
532 default:
533 SMT_PANIC(smc,SMT_E0106, SMT_E0106_MSG) ;
534 break;
535 }
536}
537
538/*
539 * get MAC's input Port
540 * return :
541 * PA or PB
542 */
543int cfm_get_mac_input(struct s_smc *smc)
544{
545 return((smc->mib.fddiSMTCF_State == SC10_C_WRAP_B ||
546 smc->mib.fddiSMTCF_State == SC5_THRU_B) ? PB : PA) ;
547}
548
549/*
550 * get MAC's output Port
551 * return :
552 * PA or PB
553 */
554int cfm_get_mac_output(struct s_smc *smc)
555{
556 return((smc->mib.fddiSMTCF_State == SC10_C_WRAP_B ||
557 smc->mib.fddiSMTCF_State == SC4_THRU_A) ? PB : PA) ;
558}
559
560static char path_iso[] = {
561 0,0, 0,RES_PORT, 0,PA + INDEX_PORT, 0,PATH_ISO,
562 0,0, 0,RES_MAC, 0,INDEX_MAC, 0,PATH_ISO,
563 0,0, 0,RES_PORT, 0,PB + INDEX_PORT, 0,PATH_ISO
564} ;
565
566static char path_wrap_a[] = {
567 0,0, 0,RES_PORT, 0,PA + INDEX_PORT, 0,PATH_PRIM,
568 0,0, 0,RES_MAC, 0,INDEX_MAC, 0,PATH_PRIM,
569 0,0, 0,RES_PORT, 0,PB + INDEX_PORT, 0,PATH_ISO
570} ;
571
572static char path_wrap_b[] = {
573 0,0, 0,RES_PORT, 0,PB + INDEX_PORT, 0,PATH_PRIM,
574 0,0, 0,RES_MAC, 0,INDEX_MAC, 0,PATH_PRIM,
575 0,0, 0,RES_PORT, 0,PA + INDEX_PORT, 0,PATH_ISO
576} ;
577
578static char path_thru[] = {
579 0,0, 0,RES_PORT, 0,PA + INDEX_PORT, 0,PATH_PRIM,
580 0,0, 0,RES_MAC, 0,INDEX_MAC, 0,PATH_PRIM,
581 0,0, 0,RES_PORT, 0,PB + INDEX_PORT, 0,PATH_PRIM
582} ;
583
584static char path_wrap_s[] = {
585 0,0, 0,RES_PORT, 0,PS + INDEX_PORT, 0,PATH_PRIM,
586 0,0, 0,RES_MAC, 0,INDEX_MAC, 0,PATH_PRIM,
587} ;
588
589static char path_iso_s[] = {
590 0,0, 0,RES_PORT, 0,PS + INDEX_PORT, 0,PATH_ISO,
591 0,0, 0,RES_MAC, 0,INDEX_MAC, 0,PATH_ISO,
592} ;
593
594int cem_build_path(struct s_smc *smc, char *to, int path_index)
595{
596 char *path ;
597 int len ;
598
599 switch (smc->mib.fddiSMTCF_State) {
600 default :
601 case SC0_ISOLATED :
602 path = smc->s.sas ? path_iso_s : path_iso ;
603 len = smc->s.sas ? sizeof(path_iso_s) : sizeof(path_iso) ;
604 break ;
605 case SC9_C_WRAP_A :
606 path = path_wrap_a ;
607 len = sizeof(path_wrap_a) ;
608 break ;
609 case SC10_C_WRAP_B :
610 path = path_wrap_b ;
611 len = sizeof(path_wrap_b) ;
612 break ;
613 case SC4_THRU_A :
614 path = path_thru ;
615 len = sizeof(path_thru) ;
616 break ;
617 case SC11_C_WRAP_S :
618 path = path_wrap_s ;
619 len = sizeof(path_wrap_s) ;
620 break ;
621 }
622 memcpy(to,path,len) ;
623
624 LINT_USE(path_index);
625
626 return(len) ;
627}
diff --git a/drivers/net/skfp/drvfbi.c b/drivers/net/skfp/drvfbi.c
new file mode 100644
index 000000000000..052e841ba187
--- /dev/null
+++ b/drivers/net/skfp/drvfbi.c
@@ -0,0 +1,1529 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * See the file "skfddi.c" for further information.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * The information in this file is provided "AS IS" without warranty.
14 *
15 ******************************************************************************/
16
17/*
18 * FBI board dependent Driver for SMT and LLC
19 */
20
21#include "h/types.h"
22#include "h/fddi.h"
23#include "h/smc.h"
24#include "h/supern_2.h"
25#include "h/skfbiinc.h"
26
27#ifndef lint
28static const char ID_sccs[] = "@(#)drvfbi.c 1.63 99/02/11 (C) SK " ;
29#endif
30
31/*
32 * PCM active state
33 */
34#define PC8_ACTIVE 8
35
36#define LED_Y_ON 0x11 /* Used for ring up/down indication */
37#define LED_Y_OFF 0x10
38
39
40#define MS2BCLK(x) ((x)*12500L)
41
42/*
43 * valid configuration values are:
44 */
45#ifdef ISA
46const int opt_ints[] = {8, 3, 4, 5, 9, 10, 11, 12, 15} ;
47const int opt_iops[] = {8,
48 0x100, 0x120, 0x180, 0x1a0, 0x220, 0x240, 0x320, 0x340};
49const int opt_dmas[] = {4, 3, 5, 6, 7} ;
50const int opt_eproms[] = {15, 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce,
51 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc} ;
52#endif
53#ifdef EISA
54const int opt_ints[] = {5, 9, 10, 11} ;
55const int opt_dmas[] = {0, 5, 6, 7} ;
56const int opt_eproms[] = {0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce,
57 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc} ;
58#endif
59
60#ifdef MCA
61int opt_ints[] = {3, 11, 10, 9} ; /* FM1 */
62int opt_eproms[] = {0, 0xc4, 0xc8, 0xcc, 0xd0, 0xd4, 0xd8, 0xdc} ;
63#endif /* MCA */
64
65/*
66 * xPOS_ID:xxxx
67 * | \ /
68 * | \/
69 * | --------------------- the patched POS_ID of the Adapter
70 * | xxxx = (Vendor ID low byte,
71 * | Vendor ID high byte,
72 * | Device ID low byte,
73 * | Device ID high byte)
74 * +------------------------------ the patched oem_id must be
75 * 'S' for SK or 'I' for IBM
76 * this is a short id for the driver.
77 */
78#ifndef MULT_OEM
79#ifndef OEM_CONCEPT
80#ifndef MCA
81const u_char oem_id[] = "xPOS_ID:xxxx" ;
82#else
83const u_char oem_id[] = "xPOSID1:xxxx" ; /* FM1 card id. */
84#endif
85#else /* OEM_CONCEPT */
86#ifndef MCA
87const u_char oem_id[] = OEM_ID ;
88#else
89const u_char oem_id[] = OEM_ID1 ; /* FM1 card id. */
90#endif /* MCA */
91#endif /* OEM_CONCEPT */
92#define ID_BYTE0 8
93#define OEMID(smc,i) oem_id[ID_BYTE0 + i]
94#else /* MULT_OEM */
95const struct s_oem_ids oem_ids[] = {
96#include "oemids.h"
97{0}
98};
99#define OEMID(smc,i) smc->hw.oem_id->oi_id[i]
100#endif /* MULT_OEM */
101
102/* Prototypes of external functions */
103#ifdef AIX
104extern int AIX_vpdReadByte() ;
105#endif
106
107
108/* Prototypes of local functions. */
109void smt_stop_watchdog(struct s_smc *smc);
110
111#ifdef MCA
112static int read_card_id() ;
113static void DisableSlotAccess() ;
114static void EnableSlotAccess() ;
115#ifdef AIX
116extern int attach_POS_addr() ;
117extern int detach_POS_addr() ;
118extern u_char read_POS() ;
119extern void write_POS() ;
120extern int AIX_vpdReadByte() ;
121#else
122#define read_POS(smc,a1,a2) ((u_char) inp(a1))
123#define write_POS(smc,a1,a2,a3) outp((a1),(a3))
124#endif
125#endif /* MCA */
126
127
128/*
129 * FDDI card reset
130 */
131static void card_start(struct s_smc *smc)
132{
133 int i ;
134#ifdef PCI
135 u_char rev_id ;
136 u_short word;
137#endif
138
139 smt_stop_watchdog(smc) ;
140
141#ifdef ISA
142 outpw(CSR_A,0) ; /* reset for all chips */
143 for (i = 10 ; i ; i--) /* delay for PLC's */
144 (void)inpw(ISR_A) ;
145 OUT_82c54_TIMER(3,COUNT(2) | RW_OP(3) | TMODE(2)) ;
146 /* counter 2, mode 2 */
147 OUT_82c54_TIMER(2,97) ; /* LSB */
148 OUT_82c54_TIMER(2,0) ; /* MSB ( 15.6 us ) */
149 outpw(CSR_A,CS_CRESET) ;
150#endif
151#ifdef EISA
152 outpw(CSR_A,0) ; /* reset for all chips */
153 for (i = 10 ; i ; i--) /* delay for PLC's */
154 (void)inpw(ISR_A) ;
155 outpw(CSR_A,CS_CRESET) ;
156 smc->hw.led = (2<<6) ;
157 outpw(CSR_A,CS_CRESET | smc->hw.led) ;
158#endif
159#ifdef MCA
160 outp(ADDR(CARD_DIS),0) ; /* reset for all chips */
161 for (i = 10 ; i ; i--) /* delay for PLC's */
162 (void)inpw(ISR_A) ;
163 outp(ADDR(CARD_EN),0) ;
164 /* first I/O after reset must not be a access to FORMAC or PLC */
165
166 /*
167 * bus timeout (MCA)
168 */
169 OUT_82c54_TIMER(3,COUNT(2) | RW_OP(3) | TMODE(3)) ;
170 /* counter 2, mode 3 */
171 OUT_82c54_TIMER(2,(2*24)) ; /* 3.9 us * 2 square wave */
172 OUT_82c54_TIMER(2,0) ; /* MSB */
173
174 /* POS 102 indicated an activ Check Line or Buss Error monitoring */
175 if (inpw(CSA_A) & (POS_EN_CHKINT | POS_EN_BUS_ERR)) {
176 outp(ADDR(IRQ_CHCK_EN),0) ;
177 }
178
179 if (!((i = inpw(CSR_A)) & CS_SAS)) {
180 if (!(i & CS_BYSTAT)) {
181 outp(ADDR(BYPASS(STAT_INS)),0) ;/* insert station */
182 }
183 }
184 outpw(LEDR_A,LED_1) ; /* yellow */
185#endif /* MCA */
186#ifdef PCI
187 /*
188 * make sure no transfer activity is pending
189 */
190 outpw(FM_A(FM_MDREG1),FM_MINIT) ;
191 outp(ADDR(B0_CTRL), CTRL_HPI_SET) ;
192 hwt_wait_time(smc,hwt_quick_read(smc),MS2BCLK(10)) ;
193 /*
194 * now reset everything
195 */
196 outp(ADDR(B0_CTRL),CTRL_RST_SET) ; /* reset for all chips */
197 i = (int) inp(ADDR(B0_CTRL)) ; /* do dummy read */
198 SK_UNUSED(i) ; /* Make LINT happy. */
199 outp(ADDR(B0_CTRL), CTRL_RST_CLR) ;
200
201 /*
202 * Reset all bits in the PCI STATUS register
203 */
204 outp(ADDR(B0_TST_CTRL), TST_CFG_WRITE_ON) ; /* enable for writes */
205 word = inpw(PCI_C(PCI_STATUS)) ;
206 outpw(PCI_C(PCI_STATUS), word | PCI_ERRBITS) ;
207 outp(ADDR(B0_TST_CTRL), TST_CFG_WRITE_OFF) ; /* disable writes */
208
209 /*
210 * Release the reset of all the State machines
211 * Release Master_Reset
212 * Release HPI_SM_Reset
213 */
214 outp(ADDR(B0_CTRL), CTRL_MRST_CLR|CTRL_HPI_CLR) ;
215
216 /*
217 * determine the adapter type
218 * Note: Do it here, because some drivers may call card_start() once
219 * at very first before any other initialization functions is
220 * executed.
221 */
222 rev_id = inp(PCI_C(PCI_REV_ID)) ;
223 if ((rev_id & 0xf0) == SK_ML_ID_1 || (rev_id & 0xf0) == SK_ML_ID_2) {
224 smc->hw.hw_is_64bit = TRUE ;
225 } else {
226 smc->hw.hw_is_64bit = FALSE ;
227 }
228
229 /*
230 * Watermark initialization
231 */
232 if (!smc->hw.hw_is_64bit) {
233 outpd(ADDR(B4_R1_F), RX_WATERMARK) ;
234 outpd(ADDR(B5_XA_F), TX_WATERMARK) ;
235 outpd(ADDR(B5_XS_F), TX_WATERMARK) ;
236 }
237
238 outp(ADDR(B0_CTRL),CTRL_RST_CLR) ; /* clear the reset chips */
239 outp(ADDR(B0_LED),LED_GA_OFF|LED_MY_ON|LED_GB_OFF) ; /* ye LED on */
240
241 /* init the timer value for the watch dog 2,5 minutes */
242 outpd(ADDR(B2_WDOG_INI),0x6FC23AC0) ;
243
244 /* initialize the ISR mask */
245 smc->hw.is_imask = ISR_MASK ;
246 smc->hw.hw_state = STOPPED ;
247#endif
248 GET_PAGE(0) ; /* necessary for BOOT */
249}
250
251void card_stop(struct s_smc *smc)
252{
253 smt_stop_watchdog(smc) ;
254 smc->hw.mac_ring_is_up = 0 ; /* ring down */
255#ifdef ISA
256 outpw(CSR_A,0) ; /* reset for all chips */
257#endif
258#ifdef EISA
259 outpw(CSR_A,0) ; /* reset for all chips */
260#endif
261#ifdef MCA
262 outp(ADDR(CARD_DIS),0) ; /* reset for all chips */
263#endif
264#ifdef PCI
265 /*
266 * make sure no transfer activity is pending
267 */
268 outpw(FM_A(FM_MDREG1),FM_MINIT) ;
269 outp(ADDR(B0_CTRL), CTRL_HPI_SET) ;
270 hwt_wait_time(smc,hwt_quick_read(smc),MS2BCLK(10)) ;
271 /*
272 * now reset everything
273 */
274 outp(ADDR(B0_CTRL),CTRL_RST_SET) ; /* reset for all chips */
275 outp(ADDR(B0_CTRL),CTRL_RST_CLR) ; /* reset for all chips */
276 outp(ADDR(B0_LED),LED_GA_OFF|LED_MY_OFF|LED_GB_OFF) ; /* all LEDs off */
277 smc->hw.hw_state = STOPPED ;
278#endif
279}
280/*--------------------------- ISR handling ----------------------------------*/
281
282void mac1_irq(struct s_smc *smc, u_short stu, u_short stl)
283{
284 int restart_tx = 0 ;
285again:
286#ifndef PCI
287#ifndef ISA
288/*
289 * FORMAC+ bug modified the queue pointer if many read/write accesses happens!?
290 */
291 if (stl & (FM_SPCEPDS | /* parit/coding err. syn.q.*/
292 FM_SPCEPDA0 | /* parit/coding err. a.q.0 */
293 FM_SPCEPDA1 | /* parit/coding err. a.q.1 */
294 FM_SPCEPDA2)) { /* parit/coding err. a.q.2 */
295 SMT_PANIC(smc,SMT_E0132, SMT_E0132_MSG) ;
296 }
297 if (stl & (FM_STBURS | /* tx buffer underrun syn.q.*/
298 FM_STBURA0 | /* tx buffer underrun a.q.0 */
299 FM_STBURA1 | /* tx buffer underrun a.q.1 */
300 FM_STBURA2)) { /* tx buffer underrun a.q.2 */
301 SMT_PANIC(smc,SMT_E0133, SMT_E0133_MSG) ;
302 }
303#endif
304 if ( (stu & (FM_SXMTABT | /* transmit abort */
305#ifdef SYNC
306 FM_STXABRS | /* syn. tx abort */
307#endif /* SYNC */
308 FM_STXABRA0)) || /* asyn. tx abort */
309 (stl & (FM_SQLCKS | /* lock for syn. q. */
310 FM_SQLCKA0)) ) { /* lock for asyn. q. */
311 formac_tx_restart(smc) ; /* init tx */
312 restart_tx = 1 ;
313 stu = inpw(FM_A(FM_ST1U)) ;
314 stl = inpw(FM_A(FM_ST1L)) ;
315 stu &= ~ (FM_STECFRMA0 | FM_STEFRMA0 | FM_STEFRMS) ;
316 if (stu || stl)
317 goto again ;
318 }
319
320#ifndef SYNC
321 if (stu & (FM_STECFRMA0 | /* end of chain asyn tx */
322 FM_STEFRMA0)) { /* end of frame asyn tx */
323 /* free tx_queue */
324 smc->hw.n_a_send = 0 ;
325 if (++smc->hw.fp.tx_free < smc->hw.fp.tx_max) {
326 start_next_send(smc);
327 }
328 restart_tx = 1 ;
329 }
330#else /* SYNC */
331 if (stu & (FM_STEFRMA0 | /* end of asyn tx */
332 FM_STEFRMS)) { /* end of sync tx */
333 restart_tx = 1 ;
334 }
335#endif /* SYNC */
336 if (restart_tx)
337 llc_restart_tx(smc) ;
338}
339#else /* PCI */
340
341 /*
342 * parity error: note encoding error is not possible in tag mode
343 */
344 if (stl & (FM_SPCEPDS | /* parity err. syn.q.*/
345 FM_SPCEPDA0 | /* parity err. a.q.0 */
346 FM_SPCEPDA1)) { /* parity err. a.q.1 */
347 SMT_PANIC(smc,SMT_E0134, SMT_E0134_MSG) ;
348 }
349 /*
350 * buffer underrun: can only occur if a tx threshold is specified
351 */
352 if (stl & (FM_STBURS | /* tx buffer underrun syn.q.*/
353 FM_STBURA0 | /* tx buffer underrun a.q.0 */
354 FM_STBURA1)) { /* tx buffer underrun a.q.2 */
355 SMT_PANIC(smc,SMT_E0133, SMT_E0133_MSG) ;
356 }
357
358 if ( (stu & (FM_SXMTABT | /* transmit abort */
359 FM_STXABRS | /* syn. tx abort */
360 FM_STXABRA0)) || /* asyn. tx abort */
361 (stl & (FM_SQLCKS | /* lock for syn. q. */
362 FM_SQLCKA0)) ) { /* lock for asyn. q. */
363 formac_tx_restart(smc) ; /* init tx */
364 restart_tx = 1 ;
365 stu = inpw(FM_A(FM_ST1U)) ;
366 stl = inpw(FM_A(FM_ST1L)) ;
367 stu &= ~ (FM_STECFRMA0 | FM_STEFRMA0 | FM_STEFRMS) ;
368 if (stu || stl)
369 goto again ;
370 }
371
372 if (stu & (FM_STEFRMA0 | /* end of asyn tx */
373 FM_STEFRMS)) { /* end of sync tx */
374 restart_tx = 1 ;
375 }
376
377 if (restart_tx)
378 llc_restart_tx(smc) ;
379}
380#endif /* PCI */
381/*
382 * interrupt source= plc1
383 * this function is called in nwfbisr.asm
384 */
385void plc1_irq(struct s_smc *smc)
386{
387 u_short st = inpw(PLC(PB,PL_INTR_EVENT)) ;
388
389#if (defined(ISA) || defined(EISA))
390 /* reset PLC Int. bits */
391 outpw(PLC1_I,inpw(PLC1_I)) ;
392#endif
393 plc_irq(smc,PB,st) ;
394}
395
396/*
397 * interrupt source= plc2
398 * this function is called in nwfbisr.asm
399 */
400void plc2_irq(struct s_smc *smc)
401{
402 u_short st = inpw(PLC(PA,PL_INTR_EVENT)) ;
403
404#if (defined(ISA) || defined(EISA))
405 /* reset PLC Int. bits */
406 outpw(PLC2_I,inpw(PLC2_I)) ;
407#endif
408 plc_irq(smc,PA,st) ;
409}
410
411
412/*
413 * interrupt source= timer
414 */
415void timer_irq(struct s_smc *smc)
416{
417 hwt_restart(smc);
418 smc->hw.t_stop = smc->hw.t_start;
419 smt_timer_done(smc) ;
420}
421
422/*
423 * return S-port (PA or PB)
424 */
425int pcm_get_s_port(struct s_smc *smc)
426{
427 SK_UNUSED(smc) ;
428 return(PS) ;
429}
430
431/*
432 * Station Label = "FDDI-XYZ" where
433 *
434 * X = connector type
435 * Y = PMD type
436 * Z = port type
437 */
438#define STATION_LABEL_CONNECTOR_OFFSET 5
439#define STATION_LABEL_PMD_OFFSET 6
440#define STATION_LABEL_PORT_OFFSET 7
441
442void read_address(struct s_smc *smc, u_char *mac_addr)
443{
444 char ConnectorType ;
445 char PmdType ;
446 int i ;
447
448 extern const u_char canonical[256] ;
449
450#if (defined(ISA) || defined(MCA))
451 for (i = 0; i < 4 ;i++) { /* read mac address from board */
452 smc->hw.fddi_phys_addr.a[i] =
453 canonical[(inpw(PR_A(i+SA_MAC))&0xff)] ;
454 }
455 for (i = 4; i < 6; i++) {
456 smc->hw.fddi_phys_addr.a[i] =
457 canonical[(inpw(PR_A(i+SA_MAC+PRA_OFF))&0xff)] ;
458 }
459#endif
460#ifdef EISA
461 /*
462 * Note: We get trouble on an Alpha machine if we make a inpw()
463 * instead of inp()
464 */
465 for (i = 0; i < 4 ;i++) { /* read mac address from board */
466 smc->hw.fddi_phys_addr.a[i] =
467 canonical[inp(PR_A(i+SA_MAC))] ;
468 }
469 for (i = 4; i < 6; i++) {
470 smc->hw.fddi_phys_addr.a[i] =
471 canonical[inp(PR_A(i+SA_MAC+PRA_OFF))] ;
472 }
473#endif
474#ifdef PCI
475 for (i = 0; i < 6; i++) { /* read mac address from board */
476 smc->hw.fddi_phys_addr.a[i] =
477 canonical[inp(ADDR(B2_MAC_0+i))] ;
478 }
479#endif
480#ifndef PCI
481 ConnectorType = inpw(PR_A(SA_PMD_TYPE)) & 0xff ;
482 PmdType = inpw(PR_A(SA_PMD_TYPE+1)) & 0xff ;
483#else
484 ConnectorType = inp(ADDR(B2_CONN_TYP)) ;
485 PmdType = inp(ADDR(B2_PMD_TYP)) ;
486#endif
487
488 smc->y[PA].pmd_type[PMD_SK_CONN] =
489 smc->y[PB].pmd_type[PMD_SK_CONN] = ConnectorType ;
490 smc->y[PA].pmd_type[PMD_SK_PMD ] =
491 smc->y[PB].pmd_type[PMD_SK_PMD ] = PmdType ;
492
493 if (mac_addr) {
494 for (i = 0; i < 6 ;i++) {
495 smc->hw.fddi_canon_addr.a[i] = mac_addr[i] ;
496 smc->hw.fddi_home_addr.a[i] = canonical[mac_addr[i]] ;
497 }
498 return ;
499 }
500 smc->hw.fddi_home_addr = smc->hw.fddi_phys_addr ;
501
502 for (i = 0; i < 6 ;i++) {
503 smc->hw.fddi_canon_addr.a[i] =
504 canonical[smc->hw.fddi_phys_addr.a[i]] ;
505 }
506}
507
508/*
509 * FDDI card soft reset
510 */
511void init_board(struct s_smc *smc, u_char *mac_addr)
512{
513 card_start(smc) ;
514 read_address(smc,mac_addr) ;
515
516#ifndef PCI
517 if (inpw(CSR_A) & CS_SAS)
518#else
519 if (!(inp(ADDR(B0_DAS)) & DAS_AVAIL))
520#endif
521 smc->s.sas = SMT_SAS ; /* Single att. station */
522 else
523 smc->s.sas = SMT_DAS ; /* Dual att. station */
524
525#ifndef PCI
526 if (inpw(CSR_A) & CS_BYSTAT)
527#else
528 if (!(inp(ADDR(B0_DAS)) & DAS_BYP_ST))
529#endif
530 smc->mib.fddiSMTBypassPresent = 0 ;
531 /* without opt. bypass */
532 else
533 smc->mib.fddiSMTBypassPresent = 1 ;
534 /* with opt. bypass */
535}
536
537/*
538 * insert or deinsert optical bypass (called by ECM)
539 */
540void sm_pm_bypass_req(struct s_smc *smc, int mode)
541{
542#if (defined(ISA) || defined(EISA))
543 int csra_v ;
544#endif
545
546 DB_ECMN(1,"ECM : sm_pm_bypass_req(%s)\n",(mode == BP_INSERT) ?
547 "BP_INSERT" : "BP_DEINSERT",0) ;
548
549 if (smc->s.sas != SMT_DAS)
550 return ;
551
552#if (defined(ISA) || defined(EISA))
553
554 csra_v = inpw(CSR_A) & ~CS_BYPASS ;
555#ifdef EISA
556 csra_v |= smc->hw.led ;
557#endif
558
559 switch(mode) {
560 case BP_INSERT :
561 outpw(CSR_A,csra_v | CS_BYPASS) ;
562 break ;
563 case BP_DEINSERT :
564 outpw(CSR_A,csra_v) ;
565 break ;
566 }
567#endif /* ISA / EISA */
568#ifdef MCA
569 switch(mode) {
570 case BP_INSERT :
571 outp(ADDR(BYPASS(STAT_INS)),0) ;/* insert station */
572 break ;
573 case BP_DEINSERT :
574 outp(ADDR(BYPASS(STAT_BYP)),0) ; /* bypass station */
575 break ;
576 }
577#endif
578#ifdef PCI
579 switch(mode) {
580 case BP_INSERT :
581 outp(ADDR(B0_DAS),DAS_BYP_INS) ; /* insert station */
582 break ;
583 case BP_DEINSERT :
584 outp(ADDR(B0_DAS),DAS_BYP_RMV) ; /* bypass station */
585 break ;
586 }
587#endif
588}
589
590/*
591 * check if bypass connected
592 */
593int sm_pm_bypass_present(struct s_smc *smc)
594{
595#ifndef PCI
596 return( (inpw(CSR_A) & CS_BYSTAT) ? FALSE : TRUE ) ;
597#else
598 return( (inp(ADDR(B0_DAS)) & DAS_BYP_ST) ? TRUE: FALSE) ;
599#endif
600}
601
602void plc_clear_irq(struct s_smc *smc, int p)
603{
604 SK_UNUSED(p) ;
605
606#if (defined(ISA) || defined(EISA))
607 switch (p) {
608 case PA :
609 /* reset PLC Int. bits */
610 outpw(PLC2_I,inpw(PLC2_I)) ;
611 break ;
612 case PB :
613 /* reset PLC Int. bits */
614 outpw(PLC1_I,inpw(PLC1_I)) ;
615 break ;
616 }
617#else
618 SK_UNUSED(smc) ;
619#endif
620}
621
622
623/*
624 * led_indication called by rmt_indication() and
625 * pcm_state_change()
626 *
627 * Input:
628 * smc: SMT context
629 * led_event:
630 * 0 Only switch green LEDs according to their respective PCM state
631 * LED_Y_OFF just switch yellow LED off
632 * LED_Y_ON just switch yello LED on
633 */
634void led_indication(struct s_smc *smc, int led_event)
635{
636 /* use smc->hw.mac_ring_is_up == TRUE
637 * as indication for Ring Operational
638 */
639 u_short led_state ;
640 struct s_phy *phy ;
641 struct fddi_mib_p *mib_a ;
642 struct fddi_mib_p *mib_b ;
643
644 phy = &smc->y[PA] ;
645 mib_a = phy->mib ;
646 phy = &smc->y[PB] ;
647 mib_b = phy->mib ;
648
649#ifdef EISA
650 /* Ring up = yellow led OFF*/
651 if (led_event == LED_Y_ON) {
652 smc->hw.led |= CS_LED_1 ;
653 }
654 else if (led_event == LED_Y_OFF) {
655 smc->hw.led &= ~CS_LED_1 ;
656 }
657 else {
658 /* Link at Port A or B = green led ON */
659 if (mib_a->fddiPORTPCMState == PC8_ACTIVE ||
660 mib_b->fddiPORTPCMState == PC8_ACTIVE) {
661 smc->hw.led |= CS_LED_0 ;
662 }
663 else {
664 smc->hw.led &= ~CS_LED_0 ;
665 }
666 }
667#endif
668#ifdef MCA
669 led_state = inpw(LEDR_A) ;
670
671 /* Ring up = yellow led OFF*/
672 if (led_event == LED_Y_ON) {
673 led_state |= LED_1 ;
674 }
675 else if (led_event == LED_Y_OFF) {
676 led_state &= ~LED_1 ;
677 }
678 else {
679 led_state &= ~(LED_2|LED_0) ;
680
681 /* Link at Port A = green led A ON */
682 if (mib_a->fddiPORTPCMState == PC8_ACTIVE) {
683 led_state |= LED_2 ;
684 }
685
686 /* Link at Port B/S = green led B ON */
687 if (mib_b->fddiPORTPCMState == PC8_ACTIVE) {
688 led_state |= LED_0 ;
689 }
690 }
691
692 outpw(LEDR_A, led_state) ;
693#endif /* MCA */
694#ifdef PCI
695 led_state = 0 ;
696
697 /* Ring up = yellow led OFF*/
698 if (led_event == LED_Y_ON) {
699 led_state |= LED_MY_ON ;
700 }
701 else if (led_event == LED_Y_OFF) {
702 led_state |= LED_MY_OFF ;
703 }
704 else { /* PCM state changed */
705 /* Link at Port A/S = green led A ON */
706 if (mib_a->fddiPORTPCMState == PC8_ACTIVE) {
707 led_state |= LED_GA_ON ;
708 }
709 else {
710 led_state |= LED_GA_OFF ;
711 }
712
713 /* Link at Port B = green led B ON */
714 if (mib_b->fddiPORTPCMState == PC8_ACTIVE) {
715 led_state |= LED_GB_ON ;
716 }
717 else {
718 led_state |= LED_GB_OFF ;
719 }
720 }
721
722 outp(ADDR(B0_LED), led_state) ;
723#endif /* PCI */
724
725}
726
727
728void pcm_state_change(struct s_smc *smc, int plc, int p_state)
729{
730 /*
731 * the current implementation of pcm_state_change() in the driver
732 * parts must be renamed to drv_pcm_state_change() which will be called
733 * now after led_indication.
734 */
735 DRV_PCM_STATE_CHANGE(smc,plc,p_state) ;
736
737 led_indication(smc,0) ;
738}
739
740
741void rmt_indication(struct s_smc *smc, int i)
742{
743 /* Call a driver special function if defined */
744 DRV_RMT_INDICATION(smc,i) ;
745
746 led_indication(smc, i ? LED_Y_OFF : LED_Y_ON) ;
747}
748
749
750/*
751 * llc_recover_tx called by init_tx (fplus.c)
752 */
753void llc_recover_tx(struct s_smc *smc)
754{
755#ifdef LOAD_GEN
756 extern int load_gen_flag ;
757
758 load_gen_flag = 0 ;
759#endif
760#ifndef SYNC
761 smc->hw.n_a_send= 0 ;
762#else
763 SK_UNUSED(smc) ;
764#endif
765}
766
767/*--------------------------- DMA init ----------------------------*/
768#ifdef ISA
769
770/*
771 * init DMA
772 */
773void init_dma(struct s_smc *smc, int dma)
774{
775 SK_UNUSED(smc) ;
776
777 /*
778 * set cascade mode,
779 * clear mask bit (enable DMA cannal)
780 */
781 if (dma > 3) {
782 outp(0xd6,(dma & 0x03) | 0xc0) ;
783 outp(0xd4, dma & 0x03) ;
784 }
785 else {
786 outp(0x0b,(dma & 0x03) | 0xc0) ;
787 outp(0x0a,dma & 0x03) ;
788 }
789}
790
791/*
792 * disable DMA
793 */
794void dis_dma(struct s_smc *smc, int dma)
795{
796 SK_UNUSED(smc) ;
797
798 /*
799 * set mask bit (disable DMA cannal)
800 */
801 if (dma > 3) {
802 outp(0xd4,(dma & 0x03) | 0x04) ;
803 }
804 else {
805 outp(0x0a,(dma & 0x03) | 0x04) ;
806 }
807}
808
809#endif /* ISA */
810
811#ifdef EISA
812
813/*arrays with io addresses of dma controller length and address registers*/
814static const int cntr[8] = { 0x001,0x003,0x005,0x007,0,0x0c6,0x0ca,0x0ce } ;
815static const int base[8] = { 0x000,0x002,0x004,0x006,0,0x0c4,0x0c8,0x0cc } ;
816static const int page[8] = { 0x087,0x083,0x081,0x082,0,0x08b,0x089,0x08a } ;
817
818void init_dma(struct s_smc *smc, int dma)
819{
820 /*
821 * extended mode register
822 * 32 bit IO
823 * type c
824 * TC output
825 * disable stop
826 */
827
828 /* mode read (write) demand */
829 smc->hw.dma_rmode = (dma & 3) | 0x08 | 0x0 ;
830 smc->hw.dma_wmode = (dma & 3) | 0x04 | 0x0 ;
831
832 /* 32 bit IO's, burst DMA mode (type "C") */
833 smc->hw.dma_emode = (dma & 3) | 0x08 | 0x30 ;
834
835 outp((dma < 4) ? 0x40b : 0x4d6,smc->hw.dma_emode) ;
836
837 /* disable chaining */
838 outp((dma < 4) ? 0x40a : 0x4d4,(dma&3)) ;
839
840 /*load dma controller addresses for fast access during set dma*/
841 smc->hw.dma_base_word_count = cntr[smc->hw.dma];
842 smc->hw.dma_base_address = base[smc->hw.dma];
843 smc->hw.dma_base_address_page = page[smc->hw.dma];
844
845}
846
847void dis_dma(struct s_smc *smc, int dma)
848{
849 SK_UNUSED(smc) ;
850
851 outp((dma < 4) ? 0x0a : 0xd4,(dma&3)|4) ;/* mask bit */
852}
853#endif /* EISA */
854
855#ifdef MCA
856void init_dma(struct s_smc *smc, int dma)
857{
858 SK_UNUSED(smc) ;
859 SK_UNUSED(dma) ;
860}
861
862void dis_dma(struct s_smc *smc, int dma)
863{
864 SK_UNUSED(smc) ;
865 SK_UNUSED(dma) ;
866}
867#endif
868
869#ifdef PCI
870void init_dma(struct s_smc *smc, int dma)
871{
872 SK_UNUSED(smc) ;
873 SK_UNUSED(dma) ;
874}
875
876void dis_dma(struct s_smc *smc, int dma)
877{
878 SK_UNUSED(smc) ;
879 SK_UNUSED(dma) ;
880}
881#endif
882
883#ifdef MULT_OEM
884static int is_equal_num(char comp1[], char comp2[], int num)
885{
886 int i ;
887
888 for (i = 0 ; i < num ; i++) {
889 if (comp1[i] != comp2[i])
890 return (0) ;
891 }
892 return (1) ;
893} /* is_equal_num */
894
895
896/*
897 * set the OEM ID defaults, and test the contents of the OEM data base
898 * The default OEM is the first ACTIVE entry in the OEM data base
899 *
900 * returns: 0 success
901 * 1 error in data base
902 * 2 data base empty
903 * 3 no active entry
904 */
905int set_oi_id_def(struct s_smc *smc)
906{
907 int sel_id ;
908 int i ;
909 int act_entries ;
910
911 i = 0 ;
912 sel_id = -1 ;
913 act_entries = FALSE ;
914 smc->hw.oem_id = 0 ;
915 smc->hw.oem_min_status = OI_STAT_ACTIVE ;
916
917 /* check OEM data base */
918 while (oem_ids[i].oi_status) {
919 switch (oem_ids[i].oi_status) {
920 case OI_STAT_ACTIVE:
921 act_entries = TRUE ; /* we have active IDs */
922 if (sel_id == -1)
923 sel_id = i ; /* save the first active ID */
924 case OI_STAT_VALID:
925 case OI_STAT_PRESENT:
926 i++ ;
927 break ; /* entry ok */
928 default:
929 return (1) ; /* invalid oi_status */
930 }
931 }
932
933 if (i == 0)
934 return (2) ;
935 if (!act_entries)
936 return (3) ;
937
938 /* ok, we have a valid OEM data base with an active entry */
939 smc->hw.oem_id = (struct s_oem_ids *) &oem_ids[sel_id] ;
940 return (0) ;
941}
942#endif /* MULT_OEM */
943
944
945#ifdef MCA
946/************************
947 *
948 * BEGIN_MANUAL_ENTRY()
949 *
950 * exist_board
951 *
952 * Check if an MCA board is present in the specified slot.
953 *
954 * int exist_board(
955 * struct s_smc *smc,
956 * int slot) ;
957 * In
958 * smc - A pointer to the SMT Context struct.
959 *
960 * slot - The number of the slot to inspect.
961 * Out
962 * 0 = No adapter present.
963 * 1 = Found FM1 adapter.
964 *
965 * Pseudo
966 * Read MCA ID
967 * for all valid OEM_IDs
968 * compare with ID read
969 * if equal, return 1
970 * return(0
971 *
972 * Note
973 * The smc pointer must be valid now.
974 *
975 * END_MANUAL_ENTRY()
976 *
977 ************************/
978#define LONG_CARD_ID(lo, hi) ((((hi) & 0xff) << 8) | ((lo) & 0xff))
979int exist_board(struct s_smc *smc, int slot)
980{
981#ifdef MULT_OEM
982 SK_LOC_DECL(u_char,id[2]) ;
983 int idi ;
984#endif /* MULT_OEM */
985
986 /* No longer valid. */
987 if (smc == NULL)
988 return(0) ;
989
990#ifndef MULT_OEM
991 if (read_card_id(smc, slot)
992 == LONG_CARD_ID(OEMID(smc,0), OEMID(smc,1)))
993 return (1) ; /* Found FM adapter. */
994
995#else /* MULT_OEM */
996 idi = read_card_id(smc, slot) ;
997 id[0] = idi & 0xff ;
998 id[1] = idi >> 8 ;
999
1000 smc->hw.oem_id = (struct s_oem_ids *) &oem_ids[0] ;
1001 for (; smc->hw.oem_id->oi_status != OI_STAT_LAST; smc->hw.oem_id++) {
1002 if (smc->hw.oem_id->oi_status < smc->hw.oem_min_status)
1003 continue ;
1004
1005 if (is_equal_num(&id[0],&OEMID(smc,0),2))
1006 return (1) ;
1007 }
1008#endif /* MULT_OEM */
1009 return (0) ; /* No adapter found. */
1010}
1011
1012/************************
1013 *
1014 * read_card_id
1015 *
1016 * Read the MCA card id from the specified slot.
1017 * In
1018 * smc - A pointer to the SMT Context struct.
1019 * CAVEAT: This pointer may be NULL and *must not* be used within this
1020 * function. It's only purpose is for drivers that need some information
1021 * for the inp() and outp() macros.
1022 *
1023 * slot - The number of the slot for which the card id is returned.
1024 * Out
1025 * Returns the card id read from the specified slot. If an illegal slot
1026 * number is specified, the function returns zero.
1027 *
1028 ************************/
1029static int read_card_id(struct s_smc *smc, int slot)
1030/* struct s_smc *smc ; Do not use. */
1031{
1032 int card_id ;
1033
1034 SK_UNUSED(smc) ; /* Make LINT happy. */
1035 if ((slot < 1) || (slot > 15)) /* max 16 slots, 0 = motherboard */
1036 return (0) ; /* Illegal slot number specified. */
1037
1038 EnableSlotAccess(smc, slot) ;
1039
1040 card_id = ((read_POS(smc,POS_ID_HIGH,slot - 1) & 0xff) << 8) |
1041 (read_POS(smc,POS_ID_LOW,slot - 1) & 0xff) ;
1042
1043 DisableSlotAccess(smc) ;
1044
1045 return (card_id) ;
1046}
1047
1048/************************
1049 *
1050 * BEGIN_MANUAL_ENTRY()
1051 *
1052 * get_board_para
1053 *
1054 * Get adapter configuration information. Fill all board specific
1055 * parameters within the 'smc' structure.
1056 *
1057 * int get_board_para(
1058 * struct s_smc *smc,
1059 * int slot) ;
1060 * In
1061 * smc - A pointer to the SMT Context struct, to which this function will
1062 * write some adapter configuration data.
1063 *
1064 * slot - The number of the slot, in which the adapter is installed.
1065 * Out
1066 * 0 = No adapter present.
1067 * 1 = Ok.
1068 * 2 = Adapter present, but card enable bit not set.
1069 *
1070 * END_MANUAL_ENTRY()
1071 *
1072 ************************/
1073int get_board_para(struct s_smc *smc, int slot)
1074{
1075 int val ;
1076 int i ;
1077
1078 /* Check if adapter present & get type of adapter. */
1079 switch (exist_board(smc, slot)) {
1080 case 0: /* Adapter not present. */
1081 return (0) ;
1082 case 1: /* FM Rev. 1 */
1083 smc->hw.rev = FM1_REV ;
1084 smc->hw.VFullRead = 0x0a ;
1085 smc->hw.VFullWrite = 0x05 ;
1086 smc->hw.DmaWriteExtraBytes = 8 ; /* 2 extra words. */
1087 break ;
1088 }
1089 smc->hw.slot = slot ;
1090
1091 EnableSlotAccess(smc, slot) ;
1092
1093 if (!(read_POS(smc,POS_102, slot - 1) & POS_CARD_EN)) {
1094 DisableSlotAccess(smc) ;
1095 return (2) ; /* Card enable bit not set. */
1096 }
1097
1098 val = read_POS(smc,POS_104, slot - 1) ; /* I/O, IRQ */
1099
1100#ifndef MEM_MAPPED_IO /* is defined by the operating system */
1101 i = val & POS_IOSEL ; /* I/O base addr. (0x0200 .. 0xfe00) */
1102 smc->hw.iop = (i + 1) * 0x0400 - 0x200 ;
1103#endif
1104 i = ((val & POS_IRQSEL) >> 6) & 0x03 ; /* IRQ <0, 1> */
1105 smc->hw.irq = opt_ints[i] ;
1106
1107 /* FPROM base addr. */
1108 i = ((read_POS(smc,POS_103, slot - 1) & POS_MSEL) >> 4) & 0x07 ;
1109 smc->hw.eprom = opt_eproms[i] ;
1110
1111 DisableSlotAccess(smc) ;
1112
1113 /* before this, the smc->hw.iop must be set !!! */
1114 smc->hw.slot_32 = inpw(CSF_A) & SLOT_32 ;
1115
1116 return (1) ;
1117}
1118
1119/* Enable access to specified MCA slot. */
1120static void EnableSlotAccess(struct s_smc *smc, int slot)
1121{
1122 SK_UNUSED(slot) ;
1123
1124#ifndef AIX
1125 SK_UNUSED(smc) ;
1126
1127 /* System mode. */
1128 outp(POS_SYS_SETUP, POS_SYSTEM) ;
1129
1130 /* Select slot. */
1131 outp(POS_CHANNEL_POS, POS_CHANNEL_BIT | (slot-1)) ;
1132#else
1133 attach_POS_addr (smc) ;
1134#endif
1135}
1136
1137/* Disable access to MCA slot formerly enabled via EnableSlotAccess(). */
1138static void DisableSlotAccess(struct s_smc *smc)
1139{
1140#ifndef AIX
1141 SK_UNUSED(smc) ;
1142
1143 outp(POS_CHANNEL_POS, 0) ;
1144#else
1145 detach_POS_addr (smc) ;
1146#endif
1147}
1148#endif /* MCA */
1149
1150#ifdef EISA
1151#ifndef MEM_MAPPED_IO
1152#define SADDR(slot) (((slot)<<12)&0xf000)
1153#else /* MEM_MAPPED_IO */
1154#define SADDR(slot) (smc->hw.iop)
1155#endif /* MEM_MAPPED_IO */
1156
1157/************************
1158 *
1159 * BEGIN_MANUAL_ENTRY()
1160 *
1161 * exist_board
1162 *
1163 * Check if an EISA board is present in the specified slot.
1164 *
1165 * int exist_board(
1166 * struct s_smc *smc,
1167 * int slot) ;
1168 * In
1169 * smc - A pointer to the SMT Context struct.
1170 *
1171 * slot - The number of the slot to inspect.
1172 * Out
1173 * 0 = No adapter present.
1174 * 1 = Found adapter.
1175 *
1176 * Pseudo
1177 * Read EISA ID
1178 * for all valid OEM_IDs
1179 * compare with ID read
1180 * if equal, return 1
1181 * return(0
1182 *
1183 * Note
1184 * The smc pointer must be valid now.
1185 *
1186 ************************/
1187int exist_board(struct s_smc *smc, int slot)
1188{
1189 int i ;
1190#ifdef MULT_OEM
1191 SK_LOC_DECL(u_char,id[4]) ;
1192#endif /* MULT_OEM */
1193
1194 /* No longer valid. */
1195 if (smc == NULL)
1196 return(0);
1197
1198 SK_UNUSED(slot) ;
1199
1200#ifndef MULT_OEM
1201 for (i = 0 ; i < 4 ; i++) {
1202 if (inp(SADDR(slot)+PRA(i)) != OEMID(smc,i))
1203 return(0) ;
1204 }
1205 return(1) ;
1206#else /* MULT_OEM */
1207 for (i = 0 ; i < 4 ; i++)
1208 id[i] = inp(SADDR(slot)+PRA(i)) ;
1209
1210 smc->hw.oem_id = (struct s_oem_ids *) &oem_ids[0] ;
1211
1212 for (; smc->hw.oem_id->oi_status != OI_STAT_LAST; smc->hw.oem_id++) {
1213 if (smc->hw.oem_id->oi_status < smc->hw.oem_min_status)
1214 continue ;
1215
1216 if (is_equal_num(&id[0],&OEMID(smc,0),4))
1217 return (1) ;
1218 }
1219 return (0) ; /* No adapter found. */
1220#endif /* MULT_OEM */
1221}
1222
1223
1224int get_board_para(struct s_smc *smc, int slot)
1225{
1226 int i ;
1227
1228 if (!exist_board(smc,slot))
1229 return(0) ;
1230
1231 smc->hw.slot = slot ;
1232#ifndef MEM_MAPPED_IO /* if defined by the operating system */
1233 smc->hw.iop = SADDR(slot) ;
1234#endif
1235
1236 if (!(inp(C0_A(0))&CFG_CARD_EN)) {
1237 return(2) ; /* CFG_CARD_EN bit not set! */
1238 }
1239
1240 smc->hw.irq = opt_ints[(inp(C1_A(0)) & CFG_IRQ_SEL)] ;
1241 smc->hw.dma = opt_dmas[((inp(C1_A(0)) & CFG_DRQ_SEL)>>3)] ;
1242
1243 if ((i = inp(C2_A(0)) & CFG_EPROM_SEL) != 0x0f)
1244 smc->hw.eprom = opt_eproms[i] ;
1245 else
1246 smc->hw.eprom = 0 ;
1247
1248 smc->hw.DmaWriteExtraBytes = 8 ;
1249
1250 return(1) ;
1251}
1252#endif /* EISA */
1253
1254#ifdef ISA
1255#ifndef MULT_OEM
1256const u_char sklogo[6] = SKLOGO_STR ;
1257#define SIZE_SKLOGO(smc) sizeof(sklogo)
1258#define SKLOGO(smc,i) sklogo[i]
1259#else /* MULT_OEM */
1260#define SIZE_SKLOGO(smc) smc->hw.oem_id->oi_logo_len
1261#define SKLOGO(smc,i) smc->hw.oem_id->oi_logo[i]
1262#endif /* MULT_OEM */
1263
1264
1265int exist_board(struct s_smc *smc, HW_PTR port)
1266{
1267 int i ;
1268#ifdef MULT_OEM
1269 int bytes_read ;
1270 u_char board_logo[15] ;
1271 SK_LOC_DECL(u_char,id[4]) ;
1272#endif /* MULT_OEM */
1273
1274 /* No longer valid. */
1275 if (smc == NULL)
1276 return(0);
1277
1278 SK_UNUSED(smc) ;
1279#ifndef MULT_OEM
1280 for (i = SADDRL ; i < (signed) (SADDRL+SIZE_SKLOGO(smc)) ; i++) {
1281 if ((u_char)inpw((PRA(i)+port)) != SKLOGO(smc,i-SADDRL)) {
1282 return(0) ;
1283 }
1284 }
1285
1286 /* check MAC address (S&K or other) */
1287 for (i = 0 ; i < 3 ; i++) {
1288 if ((u_char)inpw((PRA(i)+port)) != OEMID(smc,i))
1289 return(0) ;
1290 }
1291 return(1) ;
1292#else /* MULT_OEM */
1293 smc->hw.oem_id = (struct s_oem_ids *) &oem_ids[0] ;
1294 board_logo[0] = (u_char)inpw((PRA(SADDRL)+port)) ;
1295 bytes_read = 1 ;
1296
1297 for (; smc->hw.oem_id->oi_status != OI_STAT_LAST; smc->hw.oem_id++) {
1298 if (smc->hw.oem_id->oi_status < smc->hw.oem_min_status)
1299 continue ;
1300
1301 /* Test all read bytes with current OEM_entry */
1302 /* for (i=0; (i<bytes_read) && (i < SIZE_SKLOGO(smc)); i++) { */
1303 for (i = 0; i < bytes_read; i++) {
1304 if (board_logo[i] != SKLOGO(smc,i))
1305 break ;
1306 }
1307
1308 /* If mismatch, switch to next OEM entry */
1309 if ((board_logo[i] != SKLOGO(smc,i)) && (i < bytes_read))
1310 continue ;
1311
1312 --i ;
1313 while (bytes_read < SIZE_SKLOGO(smc)) {
1314 // inpw next byte SK_Logo
1315 i++ ;
1316 board_logo[i] = (u_char)inpw((PRA(SADDRL+i)+port)) ;
1317 bytes_read++ ;
1318 if (board_logo[i] != SKLOGO(smc,i))
1319 break ;
1320 }
1321
1322 for (i = 0 ; i < 3 ; i++)
1323 id[i] = (u_char)inpw((PRA(i)+port)) ;
1324
1325 if ((board_logo[i] == SKLOGO(smc,i))
1326 && (bytes_read == SIZE_SKLOGO(smc))) {
1327
1328 if (is_equal_num(&id[0],&OEMID(smc,0),3))
1329 return(1);
1330 }
1331 } /* for */
1332 return(0) ;
1333#endif /* MULT_OEM */
1334}
1335
1336int get_board_para(struct s_smc *smc, int slot)
1337{
1338 SK_UNUSED(smc) ;
1339 SK_UNUSED(slot) ;
1340 return(0) ; /* for ISA not supported */
1341}
1342#endif /* ISA */
1343
1344#ifdef PCI
1345#ifdef USE_BIOS_FUN
1346int exist_board(struct s_smc *smc, int slot)
1347{
1348 u_short dev_id ;
1349 u_short ven_id ;
1350 int found ;
1351 int i ;
1352
1353 found = FALSE ; /* make sure we returned with adatper not found*/
1354 /* if an empty oemids.h was included */
1355
1356#ifdef MULT_OEM
1357 smc->hw.oem_id = (struct s_oem_ids *) &oem_ids[0] ;
1358 for (; smc->hw.oem_id->oi_status != OI_STAT_LAST; smc->hw.oem_id++) {
1359 if (smc->hw.oem_id->oi_status < smc->hw.oem_min_status)
1360 continue ;
1361#endif
1362 ven_id = OEMID(smc,0) + (OEMID(smc,1) << 8) ;
1363 dev_id = OEMID(smc,2) + (OEMID(smc,3) << 8) ;
1364 for (i = 0; i < slot; i++) {
1365 if (pci_find_device(i,&smc->hw.pci_handle,
1366 dev_id,ven_id) != 0) {
1367
1368 found = FALSE ;
1369 } else {
1370 found = TRUE ;
1371 }
1372 }
1373 if (found) {
1374 return(1) ; /* adapter was found */
1375 }
1376#ifdef MULT_OEM
1377 }
1378#endif
1379 return(0) ; /* adapter was not found */
1380}
1381#endif /* PCI */
1382#endif /* USE_BIOS_FUNC */
1383
1384void driver_get_bia(struct s_smc *smc, struct fddi_addr *bia_addr)
1385{
1386 int i ;
1387
1388 extern const u_char canonical[256] ;
1389
1390 for (i = 0 ; i < 6 ; i++) {
1391 bia_addr->a[i] = canonical[smc->hw.fddi_phys_addr.a[i]] ;
1392 }
1393}
1394
1395void smt_start_watchdog(struct s_smc *smc)
1396{
1397 SK_UNUSED(smc) ; /* Make LINT happy. */
1398
1399#ifndef DEBUG
1400
1401#ifdef PCI
1402 if (smc->hw.wdog_used) {
1403 outpw(ADDR(B2_WDOG_CRTL),TIM_START) ; /* Start timer. */
1404 }
1405#endif
1406
1407#endif /* DEBUG */
1408}
1409
1410void smt_stop_watchdog(struct s_smc *smc)
1411{
1412 SK_UNUSED(smc) ; /* Make LINT happy. */
1413#ifndef DEBUG
1414
1415#ifdef PCI
1416 if (smc->hw.wdog_used) {
1417 outpw(ADDR(B2_WDOG_CRTL),TIM_STOP) ; /* Stop timer. */
1418 }
1419#endif
1420
1421#endif /* DEBUG */
1422}
1423
1424#ifdef PCI
1425static char get_rom_byte(struct s_smc *smc, u_short addr)
1426{
1427 GET_PAGE(addr) ;
1428 return (READ_PROM(ADDR(B2_FDP))) ;
1429}
1430
1431/*
1432 * ROM image defines
1433 */
1434#define ROM_SIG_1 0
1435#define ROM_SIG_2 1
1436#define PCI_DATA_1 0x18
1437#define PCI_DATA_2 0x19
1438
1439/*
1440 * PCI data structure defines
1441 */
1442#define VPD_DATA_1 0x08
1443#define VPD_DATA_2 0x09
1444#define IMAGE_LEN_1 0x10
1445#define IMAGE_LEN_2 0x11
1446#define CODE_TYPE 0x14
1447#define INDICATOR 0x15
1448
1449/*
1450 * BEGIN_MANUAL_ENTRY(mac_drv_vpd_read)
1451 * mac_drv_vpd_read(smc,buf,size,image)
1452 *
1453 * function DOWNCALL (FDDIWARE)
1454 * reads the VPD data of the FPROM and writes it into the
1455 * buffer
1456 *
1457 * para buf points to the buffer for the VPD data
1458 * size size of the VPD data buffer
1459 * image boot image; code type of the boot image
1460 * image = 0 Intel x86, PC-AT compatible
1461 * 1 OPENBOOT standard for PCI
1462 * 2-FF reserved
1463 *
1464 * returns len number of VPD data bytes read form the FPROM
1465 * <0 number of read bytes
1466 * >0 error: data invalid
1467 *
1468 * END_MANUAL_ENTRY
1469 */
1470int mac_drv_vpd_read(struct s_smc *smc, char *buf, int size, char image)
1471{
1472 u_short ibase ;
1473 u_short pci_base ;
1474 u_short vpd ;
1475 int len ;
1476
1477 len = 0 ;
1478 ibase = 0 ;
1479 /*
1480 * as long images defined
1481 */
1482 while (get_rom_byte(smc,ibase+ROM_SIG_1) == 0x55 &&
1483 (u_char) get_rom_byte(smc,ibase+ROM_SIG_2) == 0xaa) {
1484 /*
1485 * get the pointer to the PCI data structure
1486 */
1487 pci_base = ibase + get_rom_byte(smc,ibase+PCI_DATA_1) +
1488 (get_rom_byte(smc,ibase+PCI_DATA_2) << 8) ;
1489
1490 if (image == get_rom_byte(smc,pci_base+CODE_TYPE)) {
1491 /*
1492 * we have the right image, read the VPD data
1493 */
1494 vpd = ibase + get_rom_byte(smc,pci_base+VPD_DATA_1) +
1495 (get_rom_byte(smc,pci_base+VPD_DATA_2) << 8) ;
1496 if (vpd == ibase) {
1497 break ; /* no VPD data */
1498 }
1499 for (len = 0; len < size; len++,buf++,vpd++) {
1500 *buf = get_rom_byte(smc,vpd) ;
1501 }
1502 break ;
1503 }
1504 else {
1505 /*
1506 * try the next image
1507 */
1508 if (get_rom_byte(smc,pci_base+INDICATOR) & 0x80) {
1509 break ; /* this was the last image */
1510 }
1511 ibase = ibase + get_rom_byte(smc,ibase+IMAGE_LEN_1) +
1512 (get_rom_byte(smc,ibase+IMAGE_LEN_2) << 8) ;
1513 }
1514 }
1515
1516 return(len) ;
1517}
1518
1519void mac_drv_pci_fix(struct s_smc *smc, u_long fix_value)
1520{
1521 smc->hw.pci_fix_value = fix_value ;
1522}
1523
1524void mac_do_pci_fix(struct s_smc *smc)
1525{
1526 SK_UNUSED(smc) ;
1527}
1528#endif /* PCI */
1529
diff --git a/drivers/net/skfp/ecm.c b/drivers/net/skfp/ecm.c
new file mode 100644
index 000000000000..47d922cb3c08
--- /dev/null
+++ b/drivers/net/skfp/ecm.c
@@ -0,0 +1,536 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * See the file "skfddi.c" for further information.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * The information in this file is provided "AS IS" without warranty.
14 *
15 ******************************************************************************/
16
17/*
18 SMT ECM
19 Entity Coordination Management
20 Hardware independent state machine
21*/
22
23/*
24 * Hardware independent state machine implemantation
25 * The following external SMT functions are referenced :
26 *
27 * queue_event()
28 * smt_timer_start()
29 * smt_timer_stop()
30 *
31 * The following external HW dependent functions are referenced :
32 * sm_pm_bypass_req()
33 * sm_pm_ls_latch()
34 * sm_pm_get_ls()
35 *
36 * The following HW dependent events are required :
37 * NONE
38 *
39 */
40
41#include "h/types.h"
42#include "h/fddi.h"
43#include "h/smc.h"
44
45#define KERNEL
46#include "h/smtstate.h"
47
48#ifndef lint
49static const char ID_sccs[] = "@(#)ecm.c 2.7 99/08/05 (C) SK " ;
50#endif
51
52/*
53 * FSM Macros
54 */
55#define AFLAG 0x10
56#define GO_STATE(x) (smc->mib.fddiSMTECMState = (x)|AFLAG)
57#define ACTIONS_DONE() (smc->mib.fddiSMTECMState &= ~AFLAG)
58#define ACTIONS(x) (x|AFLAG)
59
60#define EC0_OUT 0 /* not inserted */
61#define EC1_IN 1 /* inserted */
62#define EC2_TRACE 2 /* tracing */
63#define EC3_LEAVE 3 /* leaving the ring */
64#define EC4_PATH_TEST 4 /* performing path test */
65#define EC5_INSERT 5 /* bypass being turned on */
66#define EC6_CHECK 6 /* checking bypass */
67#define EC7_DEINSERT 7 /* bypass being turnde off */
68
69#ifdef DEBUG
70/*
71 * symbolic state names
72 */
73static const char * const ecm_states[] = {
74 "EC0_OUT","EC1_IN","EC2_TRACE","EC3_LEAVE","EC4_PATH_TEST",
75 "EC5_INSERT","EC6_CHECK","EC7_DEINSERT"
76} ;
77
78/*
79 * symbolic event names
80 */
81static const char * const ecm_events[] = {
82 "NONE","EC_CONNECT","EC_DISCONNECT","EC_TRACE_PROP","EC_PATH_TEST",
83 "EC_TIMEOUT_TD","EC_TIMEOUT_TMAX",
84 "EC_TIMEOUT_IMAX","EC_TIMEOUT_INMAX","EC_TEST_DONE"
85} ;
86#endif
87
88/*
89 * all Globals are defined in smc.h
90 * struct s_ecm
91 */
92
93/*
94 * function declarations
95 */
96
97static void ecm_fsm(struct s_smc *smc, int cmd);
98static void start_ecm_timer(struct s_smc *smc, u_long value, int event);
99static void stop_ecm_timer(struct s_smc *smc);
100static void prop_actions(struct s_smc *smc);
101
102/*
103 init ECM state machine
104 clear all ECM vars and flags
105*/
106void ecm_init(struct s_smc *smc)
107{
108 smc->e.path_test = PT_PASSED ;
109 smc->e.trace_prop = 0 ;
110 smc->e.sb_flag = 0 ;
111 smc->mib.fddiSMTECMState = ACTIONS(EC0_OUT) ;
112 smc->e.ecm_line_state = FALSE ;
113}
114
115/*
116 ECM state machine
117 called by dispatcher
118
119 do
120 display state change
121 process event
122 until SM is stable
123*/
124void ecm(struct s_smc *smc, int event)
125{
126 int state ;
127
128 do {
129 DB_ECM("ECM : state %s%s",
130 (smc->mib.fddiSMTECMState & AFLAG) ? "ACTIONS " : "",
131 ecm_states[smc->mib.fddiSMTECMState & ~AFLAG]) ;
132 DB_ECM(" event %s\n",ecm_events[event],0) ;
133 state = smc->mib.fddiSMTECMState ;
134 ecm_fsm(smc,event) ;
135 event = 0 ;
136 } while (state != smc->mib.fddiSMTECMState) ;
137 ecm_state_change(smc,(int)smc->mib.fddiSMTECMState) ;
138}
139
140/*
141 process ECM event
142*/
143static void ecm_fsm(struct s_smc *smc, int cmd)
144{
145 int ls_a ; /* current line state PHY A */
146 int ls_b ; /* current line state PHY B */
147 int p ; /* ports */
148
149
150 smc->mib.fddiSMTBypassPresent = sm_pm_bypass_present(smc) ;
151 if (cmd == EC_CONNECT)
152 smc->mib.fddiSMTRemoteDisconnectFlag = FALSE ;
153
154 /* For AIX event notification: */
155 /* Is a disconnect command remotely issued ? */
156 if (cmd == EC_DISCONNECT &&
157 smc->mib.fddiSMTRemoteDisconnectFlag == TRUE)
158 AIX_EVENT (smc, (u_long) CIO_HARD_FAIL, (u_long)
159 FDDI_REMOTE_DISCONNECT, smt_get_event_word(smc),
160 smt_get_error_word(smc) );
161
162 /*jd 05-Aug-1999 Bug #10419 "Port Disconnect fails at Dup MAc Cond."*/
163 if (cmd == EC_CONNECT) {
164 smc->e.DisconnectFlag = FALSE ;
165 }
166 else if (cmd == EC_DISCONNECT) {
167 smc->e.DisconnectFlag = TRUE ;
168 }
169
170 switch(smc->mib.fddiSMTECMState) {
171 case ACTIONS(EC0_OUT) :
172 /*
173 * We do not perform a path test
174 */
175 smc->e.path_test = PT_PASSED ;
176 smc->e.ecm_line_state = FALSE ;
177 stop_ecm_timer(smc) ;
178 ACTIONS_DONE() ;
179 break ;
180 case EC0_OUT:
181 /*EC01*/
182 if (cmd == EC_CONNECT && !smc->mib.fddiSMTBypassPresent
183 && smc->e.path_test==PT_PASSED) {
184 GO_STATE(EC1_IN) ;
185 break ;
186 }
187 /*EC05*/
188 else if (cmd == EC_CONNECT && (smc->e.path_test==PT_PASSED) &&
189 smc->mib.fddiSMTBypassPresent &&
190 (smc->s.sas == SMT_DAS)) {
191 GO_STATE(EC5_INSERT) ;
192 break ;
193 }
194 break;
195 case ACTIONS(EC1_IN) :
196 stop_ecm_timer(smc) ;
197 smc->e.trace_prop = 0 ;
198 sm_ma_control(smc,MA_TREQ) ;
199 for (p = 0 ; p < NUMPHYS ; p++)
200 if (smc->mib.p[p].fddiPORTHardwarePresent)
201 queue_event(smc,EVENT_PCMA+p,PC_START) ;
202 ACTIONS_DONE() ;
203 break ;
204 case EC1_IN:
205 /*EC12*/
206 if (cmd == EC_TRACE_PROP) {
207 prop_actions(smc) ;
208 GO_STATE(EC2_TRACE) ;
209 break ;
210 }
211 /*EC13*/
212 else if (cmd == EC_DISCONNECT) {
213 GO_STATE(EC3_LEAVE) ;
214 break ;
215 }
216 break;
217 case ACTIONS(EC2_TRACE) :
218 start_ecm_timer(smc,MIB2US(smc->mib.fddiSMTTrace_MaxExpiration),
219 EC_TIMEOUT_TMAX) ;
220 ACTIONS_DONE() ;
221 break ;
222 case EC2_TRACE :
223 /*EC22*/
224 if (cmd == EC_TRACE_PROP) {
225 prop_actions(smc) ;
226 GO_STATE(EC2_TRACE) ;
227 break ;
228 }
229 /*EC23a*/
230 else if (cmd == EC_DISCONNECT) {
231 smc->e.path_test = PT_EXITING ;
232 GO_STATE(EC3_LEAVE) ;
233 break ;
234 }
235 /*EC23b*/
236 else if (smc->e.path_test == PT_PENDING) {
237 GO_STATE(EC3_LEAVE) ;
238 break ;
239 }
240 /*EC23c*/
241 else if (cmd == EC_TIMEOUT_TMAX) {
242 /* Trace_Max is expired */
243 /* -> send AIX_EVENT */
244 AIX_EVENT(smc, (u_long) FDDI_RING_STATUS,
245 (u_long) FDDI_SMT_ERROR, (u_long)
246 FDDI_TRACE_MAX, smt_get_error_word(smc));
247 smc->e.path_test = PT_PENDING ;
248 GO_STATE(EC3_LEAVE) ;
249 break ;
250 }
251 break ;
252 case ACTIONS(EC3_LEAVE) :
253 start_ecm_timer(smc,smc->s.ecm_td_min,EC_TIMEOUT_TD) ;
254 for (p = 0 ; p < NUMPHYS ; p++)
255 queue_event(smc,EVENT_PCMA+p,PC_STOP) ;
256 ACTIONS_DONE() ;
257 break ;
258 case EC3_LEAVE:
259 /*EC30*/
260 if (cmd == EC_TIMEOUT_TD && !smc->mib.fddiSMTBypassPresent &&
261 (smc->e.path_test != PT_PENDING)) {
262 GO_STATE(EC0_OUT) ;
263 break ;
264 }
265 /*EC34*/
266 else if (cmd == EC_TIMEOUT_TD &&
267 (smc->e.path_test == PT_PENDING)) {
268 GO_STATE(EC4_PATH_TEST) ;
269 break ;
270 }
271 /*EC31*/
272 else if (cmd == EC_CONNECT && smc->e.path_test == PT_PASSED) {
273 GO_STATE(EC1_IN) ;
274 break ;
275 }
276 /*EC33*/
277 else if (cmd == EC_DISCONNECT &&
278 smc->e.path_test == PT_PENDING) {
279 smc->e.path_test = PT_EXITING ;
280 /*
281 * stay in state - state will be left via timeout
282 */
283 }
284 /*EC37*/
285 else if (cmd == EC_TIMEOUT_TD &&
286 smc->mib.fddiSMTBypassPresent &&
287 smc->e.path_test != PT_PENDING) {
288 GO_STATE(EC7_DEINSERT) ;
289 break ;
290 }
291 break ;
292 case ACTIONS(EC4_PATH_TEST) :
293 stop_ecm_timer(smc) ;
294 smc->e.path_test = PT_TESTING ;
295 start_ecm_timer(smc,smc->s.ecm_test_done,EC_TEST_DONE) ;
296 /* now perform path test ... just a simulation */
297 ACTIONS_DONE() ;
298 break ;
299 case EC4_PATH_TEST :
300 /* path test done delay */
301 if (cmd == EC_TEST_DONE)
302 smc->e.path_test = PT_PASSED ;
303
304 if (smc->e.path_test == PT_FAILED)
305 RS_SET(smc,RS_PATHTEST) ;
306
307 /*EC40a*/
308 if (smc->e.path_test == PT_FAILED &&
309 !smc->mib.fddiSMTBypassPresent) {
310 GO_STATE(EC0_OUT) ;
311 break ;
312 }
313 /*EC40b*/
314 else if (cmd == EC_DISCONNECT &&
315 !smc->mib.fddiSMTBypassPresent) {
316 GO_STATE(EC0_OUT) ;
317 break ;
318 }
319 /*EC41*/
320 else if (smc->e.path_test == PT_PASSED) {
321 GO_STATE(EC1_IN) ;
322 break ;
323 }
324 /*EC47a*/
325 else if (smc->e.path_test == PT_FAILED &&
326 smc->mib.fddiSMTBypassPresent) {
327 GO_STATE(EC7_DEINSERT) ;
328 break ;
329 }
330 /*EC47b*/
331 else if (cmd == EC_DISCONNECT &&
332 smc->mib.fddiSMTBypassPresent) {
333 GO_STATE(EC7_DEINSERT) ;
334 break ;
335 }
336 break ;
337 case ACTIONS(EC5_INSERT) :
338 sm_pm_bypass_req(smc,BP_INSERT);
339 start_ecm_timer(smc,smc->s.ecm_in_max,EC_TIMEOUT_INMAX) ;
340 ACTIONS_DONE() ;
341 break ;
342 case EC5_INSERT :
343 /*EC56*/
344 if (cmd == EC_TIMEOUT_INMAX) {
345 GO_STATE(EC6_CHECK) ;
346 break ;
347 }
348 /*EC57*/
349 else if (cmd == EC_DISCONNECT) {
350 GO_STATE(EC7_DEINSERT) ;
351 break ;
352 }
353 break ;
354 case ACTIONS(EC6_CHECK) :
355 /*
356 * in EC6_CHECK, we *POLL* the line state !
357 * check whether both bypass switches have switched.
358 */
359 start_ecm_timer(smc,smc->s.ecm_check_poll,0) ;
360 smc->e.ecm_line_state = TRUE ; /* flag to pcm: report Q/HLS */
361 (void) sm_pm_ls_latch(smc,PA,1) ; /* enable line state latch */
362 (void) sm_pm_ls_latch(smc,PB,1) ; /* enable line state latch */
363 ACTIONS_DONE() ;
364 break ;
365 case EC6_CHECK :
366 ls_a = sm_pm_get_ls(smc,PA) ;
367 ls_b = sm_pm_get_ls(smc,PB) ;
368
369 /*EC61*/
370 if (((ls_a == PC_QLS) || (ls_a == PC_HLS)) &&
371 ((ls_b == PC_QLS) || (ls_b == PC_HLS)) ) {
372 smc->e.sb_flag = FALSE ;
373 smc->e.ecm_line_state = FALSE ;
374 GO_STATE(EC1_IN) ;
375 break ;
376 }
377 /*EC66*/
378 else if (!smc->e.sb_flag &&
379 (((ls_a == PC_ILS) && (ls_b == PC_QLS)) ||
380 ((ls_a == PC_QLS) && (ls_b == PC_ILS)))){
381 smc->e.sb_flag = TRUE ;
382 DB_ECMN(1,"ECM : EC6_CHECK - stuck bypass\n",0,0) ;
383 AIX_EVENT(smc, (u_long) FDDI_RING_STATUS, (u_long)
384 FDDI_SMT_ERROR, (u_long) FDDI_BYPASS_STUCK,
385 smt_get_error_word(smc));
386 }
387 /*EC67*/
388 else if (cmd == EC_DISCONNECT) {
389 smc->e.ecm_line_state = FALSE ;
390 GO_STATE(EC7_DEINSERT) ;
391 break ;
392 }
393 else {
394 /*
395 * restart poll
396 */
397 start_ecm_timer(smc,smc->s.ecm_check_poll,0) ;
398 }
399 break ;
400 case ACTIONS(EC7_DEINSERT) :
401 sm_pm_bypass_req(smc,BP_DEINSERT);
402 start_ecm_timer(smc,smc->s.ecm_i_max,EC_TIMEOUT_IMAX) ;
403 ACTIONS_DONE() ;
404 break ;
405 case EC7_DEINSERT:
406 /*EC70*/
407 if (cmd == EC_TIMEOUT_IMAX) {
408 GO_STATE(EC0_OUT) ;
409 break ;
410 }
411 /*EC75*/
412 else if (cmd == EC_CONNECT && smc->e.path_test == PT_PASSED) {
413 GO_STATE(EC5_INSERT) ;
414 break ;
415 }
416 break;
417 default:
418 SMT_PANIC(smc,SMT_E0107, SMT_E0107_MSG) ;
419 break;
420 }
421}
422
423#ifndef CONCENTRATOR
424/*
425 * trace propagation actions for SAS & DAS
426 */
427static void prop_actions(struct s_smc *smc)
428{
429 int port_in = 0 ;
430 int port_out = 0 ;
431
432 RS_SET(smc,RS_EVENT) ;
433 switch (smc->s.sas) {
434 case SMT_SAS :
435 port_in = port_out = pcm_get_s_port(smc) ;
436 break ;
437 case SMT_DAS :
438 port_in = cfm_get_mac_input(smc) ; /* PA or PB */
439 port_out = cfm_get_mac_output(smc) ; /* PA or PB */
440 break ;
441 case SMT_NAC :
442 SMT_PANIC(smc,SMT_E0108, SMT_E0108_MSG) ;
443 return ;
444 }
445
446 DB_ECM("ECM : prop_actions - trace_prop %d\n", smc->e.trace_prop,0) ;
447 DB_ECM("ECM : prop_actions - in %d out %d\n", port_in,port_out) ;
448
449 if (smc->e.trace_prop & ENTITY_BIT(ENTITY_MAC)) {
450 /* trace initiatior */
451 DB_ECM("ECM : initiate TRACE on PHY %c\n",'A'+port_in-PA,0) ;
452 queue_event(smc,EVENT_PCM+port_in,PC_TRACE) ;
453 }
454 else if ((smc->e.trace_prop & ENTITY_BIT(ENTITY_PHY(PA))) &&
455 port_out != PA) {
456 /* trace propagate upstream */
457 DB_ECM("ECM : propagate TRACE on PHY B\n",0,0) ;
458 queue_event(smc,EVENT_PCMB,PC_TRACE) ;
459 }
460 else if ((smc->e.trace_prop & ENTITY_BIT(ENTITY_PHY(PB))) &&
461 port_out != PB) {
462 /* trace propagate upstream */
463 DB_ECM("ECM : propagate TRACE on PHY A\n",0,0) ;
464 queue_event(smc,EVENT_PCMA,PC_TRACE) ;
465 }
466 else {
467 /* signal trace termination */
468 DB_ECM("ECM : TRACE terminated\n",0,0) ;
469 smc->e.path_test = PT_PENDING ;
470 }
471 smc->e.trace_prop = 0 ;
472}
473#else
474/*
475 * trace propagation actions for Concentrator
476 */
477static void prop_actions(struct s_smc *smc)
478{
479 int initiator ;
480 int upstream ;
481 int p ;
482
483 RS_SET(smc,RS_EVENT) ;
484 while (smc->e.trace_prop) {
485 DB_ECM("ECM : prop_actions - trace_prop %d\n",
486 smc->e.trace_prop,0) ;
487
488 if (smc->e.trace_prop & ENTITY_BIT(ENTITY_MAC)) {
489 initiator = ENTITY_MAC ;
490 smc->e.trace_prop &= ~ENTITY_BIT(ENTITY_MAC) ;
491 DB_ECM("ECM: MAC initiates trace\n",0,0) ;
492 }
493 else {
494 for (p = NUMPHYS-1 ; p >= 0 ; p--) {
495 if (smc->e.trace_prop &
496 ENTITY_BIT(ENTITY_PHY(p)))
497 break ;
498 }
499 initiator = ENTITY_PHY(p) ;
500 smc->e.trace_prop &= ~ENTITY_BIT(ENTITY_PHY(p)) ;
501 }
502 upstream = cem_get_upstream(smc,initiator) ;
503
504 if (upstream == ENTITY_MAC) {
505 /* signal trace termination */
506 DB_ECM("ECM : TRACE terminated\n",0,0) ;
507 smc->e.path_test = PT_PENDING ;
508 }
509 else {
510 /* trace propagate upstream */
511 DB_ECM("ECM : propagate TRACE on PHY %d\n",upstream,0) ;
512 queue_event(smc,EVENT_PCM+upstream,PC_TRACE) ;
513 }
514 }
515}
516#endif
517
518
519/*
520 * SMT timer interface
521 * start ECM timer
522 */
523static void start_ecm_timer(struct s_smc *smc, u_long value, int event)
524{
525 smt_timer_start(smc,&smc->e.ecm_timer,value,EV_TOKEN(EVENT_ECM,event));
526}
527
528/*
529 * SMT timer interface
530 * stop ECM timer
531 */
532static void stop_ecm_timer(struct s_smc *smc)
533{
534 if (smc->e.ecm_timer.tm_active)
535 smt_timer_stop(smc,&smc->e.ecm_timer) ;
536}
diff --git a/drivers/net/skfp/ess.c b/drivers/net/skfp/ess.c
new file mode 100644
index 000000000000..fd39b4b2ef7d
--- /dev/null
+++ b/drivers/net/skfp/ess.c
@@ -0,0 +1,720 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * See the file "skfddi.c" for further information.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * The information in this file is provided "AS IS" without warranty.
14 *
15 ******************************************************************************/
16
17/*
18 * *******************************************************************
19 * This SBA code implements the Synchronous Bandwidth Allocation
20 * functions described in the "FDDI Synchronous Forum Implementer's
21 * Agreement" dated December 1th, 1993.
22 * *******************************************************************
23 *
24 * PURPOSE: The purpose of this function is to control
25 * synchronous allocations on a single FDDI segment.
26 * Allocations are limited to the primary FDDI ring.
27 * The SBM provides recovery mechanisms to recover
28 * unused bandwidth also resolves T_Neg and
29 * reconfiguration changes. Many of the SBM state
30 * machine inputs are sourced by the underlying
31 * FDDI sub-system supporting the SBA application.
32 *
33 * *******************************************************************
34 */
35
36#include "h/types.h"
37#include "h/fddi.h"
38#include "h/smc.h"
39#include "h/smt_p.h"
40
41
42#ifndef SLIM_SMT
43
44#ifdef ESS
45
46#ifndef lint
47static const char ID_sccs[] = "@(#)ess.c 1.10 96/02/23 (C) SK" ;
48#define LINT_USE(x)
49#else
50#define LINT_USE(x) (x)=(x)
51#endif
52#define MS2BCLK(x) ((x)*12500L)
53
54/*
55 -------------------------------------------------------------
56 LOCAL VARIABLES:
57 -------------------------------------------------------------
58*/
59
60static const u_short plist_raf_alc_res[] = { SMT_P0012, SMT_P320B, SMT_P320F,
61 SMT_P3210, SMT_P0019, SMT_P001A,
62 SMT_P001D, 0 } ;
63
64static const u_short plist_raf_chg_req[] = { SMT_P320B, SMT_P320F, SMT_P3210,
65 SMT_P001A, 0 } ;
66
67static const struct fddi_addr smt_sba_da = {{0x80,0x01,0x43,0x00,0x80,0x0C}} ;
68static const struct fddi_addr null_addr = {{0,0,0,0,0,0}} ;
69
70/*
71 -------------------------------------------------------------
72 GLOBAL VARIABLES:
73 -------------------------------------------------------------
74*/
75
76
77/*
78 -------------------------------------------------------------
79 LOCAL FUNCTIONS:
80 -------------------------------------------------------------
81*/
82
83static void ess_send_response(struct s_smc *smc, struct smt_header *sm,
84 int sba_cmd);
85static void ess_config_fifo(struct s_smc *smc);
86static void ess_send_alc_req(struct s_smc *smc);
87static void ess_send_frame(struct s_smc *smc, SMbuf *mb);
88
89/*
90 -------------------------------------------------------------
91 EXTERNAL FUNCTIONS:
92 -------------------------------------------------------------
93*/
94
95/*
96 -------------------------------------------------------------
97 PUBLIC FUNCTIONS:
98 -------------------------------------------------------------
99*/
100
101void ess_timer_poll(struct s_smc *smc);
102void ess_para_change(struct s_smc *smc);
103int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm,
104 int fs);
105int process_bw_alloc(struct s_smc *smc, long int payload, long int overhead);
106
107
108/*
109 * --------------------------------------------------------------------------
110 * End Station Support (ESS)
111 * --------------------------------------------------------------------------
112 */
113
114/*
115 * evaluate the RAF frame
116 */
117int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm,
118 int fs)
119{
120 void *p ; /* universal pointer */
121 struct smt_p_0016 *cmd ; /* para: command for the ESS */
122 SMbuf *db ;
123 u_long msg_res_type ; /* recource type */
124 u_long payload, overhead ;
125 int local ;
126 int i ;
127
128 /*
129 * Message Processing Code
130 */
131 local = ((fs & L_INDICATOR) != 0) ;
132
133 /*
134 * get the resource type
135 */
136 if (!(p = (void *) sm_to_para(smc,sm,SMT_P0015))) {
137 DB_ESS("ESS: RAF frame error, parameter type not found\n",0,0) ;
138 return(fs) ;
139 }
140 msg_res_type = ((struct smt_p_0015 *)p)->res_type ;
141
142 /*
143 * get the pointer to the ESS command
144 */
145 if (!(cmd = (struct smt_p_0016 *) sm_to_para(smc,sm,SMT_P0016))) {
146 /*
147 * error in frame: para ESS command was not found
148 */
149 DB_ESS("ESS: RAF frame error, parameter command not found\n",0,0);
150 return(fs) ;
151 }
152
153 DB_ESSN(2,"fc %x ft %x\n",sm->smt_class,sm->smt_type) ;
154 DB_ESSN(2,"ver %x tran %lx\n",sm->smt_version,sm->smt_tid) ;
155 DB_ESSN(2,"stn_id %s\n",addr_to_string(&sm->smt_source),0) ;
156
157 DB_ESSN(2,"infolen %x res %x\n",sm->smt_len, msg_res_type) ;
158 DB_ESSN(2,"sbacmd %x\n",cmd->sba_cmd,0) ;
159
160 /*
161 * evaluate the ESS command
162 */
163 switch (cmd->sba_cmd) {
164
165 /*
166 * Process an ESS Allocation Request
167 */
168 case REQUEST_ALLOCATION :
169 /*
170 * check for an RAF Request (Allocation Request)
171 */
172 if (sm->smt_type == SMT_REQUEST) {
173 /*
174 * process the Allocation request only if the frame is
175 * local and no static allocation is used
176 */
177 if (!local || smc->mib.fddiESSPayload)
178 return(fs) ;
179
180 p = (void *) sm_to_para(smc,sm,SMT_P0019) ;
181 for (i = 0; i < 5; i++) {
182 if (((struct smt_p_0019 *)p)->alloc_addr.a[i]) {
183 return(fs) ;
184 }
185 }
186
187 /*
188 * Note: The Application should send a LAN_LOC_FRAME.
189 * The ESS do not send the Frame to the network!
190 */
191 smc->ess.alloc_trans_id = sm->smt_tid ;
192 DB_ESS("ESS: save Alloc Req Trans ID %lx\n",sm->smt_tid,0);
193 p = (void *) sm_to_para(smc,sm,SMT_P320F) ;
194 ((struct smt_p_320f *)p)->mib_payload =
195 smc->mib.a[PATH0].fddiPATHSbaPayload ;
196 p = (void *) sm_to_para(smc,sm,SMT_P3210) ;
197 ((struct smt_p_3210 *)p)->mib_overhead =
198 smc->mib.a[PATH0].fddiPATHSbaOverhead ;
199 sm->smt_dest = smt_sba_da ;
200
201 if (smc->ess.local_sba_active)
202 return(fs | I_INDICATOR) ;
203
204 if (!(db = smt_get_mbuf(smc)))
205 return(fs) ;
206
207 db->sm_len = mb->sm_len ;
208 db->sm_off = mb->sm_off ;
209 memcpy(((char *)(db->sm_data+db->sm_off)),(char *)sm,
210 (int)db->sm_len) ;
211 dump_smt(smc,
212 (struct smt_header *)(db->sm_data+db->sm_off),
213 "RAF") ;
214 smt_send_frame(smc,db,FC_SMT_INFO,0) ;
215 return(fs) ;
216 }
217
218 /*
219 * The RAF frame is an Allocation Response !
220 * check the parameters
221 */
222 if (smt_check_para(smc,sm,plist_raf_alc_res)) {
223 DB_ESS("ESS: RAF with para problem, ignoring\n",0,0) ;
224 return(fs) ;
225 }
226
227 /*
228 * VERIFY THE FRAME IS WELL BUILT:
229 *
230 * 1. path index = primary ring only
231 * 2. resource type = sync bw only
232 * 3. trans action id = alloc_trans_id
233 * 4. reason code = success
234 *
235 * If any are violated, discard the RAF frame
236 */
237 if ((((struct smt_p_320b *)sm_to_para(smc,sm,SMT_P320B))->path_index
238 != PRIMARY_RING) ||
239 (msg_res_type != SYNC_BW) ||
240 (((struct smt_p_reason *)sm_to_para(smc,sm,SMT_P0012))->rdf_reason
241 != SMT_RDF_SUCCESS) ||
242 (sm->smt_tid != smc->ess.alloc_trans_id)) {
243
244 DB_ESS("ESS: Allocation Responce not accepted\n",0,0) ;
245 return(fs) ;
246 }
247
248 /*
249 * Extract message parameters
250 */
251 p = (void *) sm_to_para(smc,sm,SMT_P320F) ;
252 if (!p) {
253 printk(KERN_ERR "ESS: sm_to_para failed");
254 return fs;
255 }
256 payload = ((struct smt_p_320f *)p)->mib_payload ;
257 p = (void *) sm_to_para(smc,sm,SMT_P3210) ;
258 if (!p) {
259 printk(KERN_ERR "ESS: sm_to_para failed");
260 return fs;
261 }
262 overhead = ((struct smt_p_3210 *)p)->mib_overhead ;
263
264 DB_ESSN(2,"payload= %lx overhead= %lx\n",payload,overhead) ;
265
266 /*
267 * process the bandwidth allocation
268 */
269 (void)process_bw_alloc(smc,(long)payload,(long)overhead) ;
270
271 return(fs) ;
272 /* end of Process Allocation Request */
273
274 /*
275 * Process an ESS Change Request
276 */
277 case CHANGE_ALLOCATION :
278 /*
279 * except only replies
280 */
281 if (sm->smt_type != SMT_REQUEST) {
282 DB_ESS("ESS: Do not process Change Responses\n",0,0) ;
283 return(fs) ;
284 }
285
286 /*
287 * check the para for the Change Request
288 */
289 if (smt_check_para(smc,sm,plist_raf_chg_req)) {
290 DB_ESS("ESS: RAF with para problem, ignoring\n",0,0) ;
291 return(fs) ;
292 }
293
294 /*
295 * Verify the path index and resource
296 * type are correct. If any of
297 * these are false, don't process this
298 * change request frame.
299 */
300 if ((((struct smt_p_320b *)sm_to_para(smc,sm,SMT_P320B))->path_index
301 != PRIMARY_RING) || (msg_res_type != SYNC_BW)) {
302 DB_ESS("ESS: RAF frame with para problem, ignoring\n",0,0) ;
303 return(fs) ;
304 }
305
306 /*
307 * Extract message queue parameters
308 */
309 p = (void *) sm_to_para(smc,sm,SMT_P320F) ;
310 payload = ((struct smt_p_320f *)p)->mib_payload ;
311 p = (void *) sm_to_para(smc,sm,SMT_P3210) ;
312 overhead = ((struct smt_p_3210 *)p)->mib_overhead ;
313
314 DB_ESSN(2,"ESS: Change Request from %s\n",
315 addr_to_string(&sm->smt_source),0) ;
316 DB_ESSN(2,"payload= %lx overhead= %lx\n",payload,overhead) ;
317
318 /*
319 * process the bandwidth allocation
320 */
321 if(!process_bw_alloc(smc,(long)payload,(long)overhead))
322 return(fs) ;
323
324 /*
325 * send an RAF Change Reply
326 */
327 ess_send_response(smc,sm,CHANGE_ALLOCATION) ;
328
329 return(fs) ;
330 /* end of Process Change Request */
331
332 /*
333 * Process Report Response
334 */
335 case REPORT_ALLOCATION :
336 /*
337 * except only requests
338 */
339 if (sm->smt_type != SMT_REQUEST) {
340 DB_ESS("ESS: Do not process a Report Reply\n",0,0) ;
341 return(fs) ;
342 }
343
344 DB_ESSN(2,"ESS: Report Request from %s\n",
345 addr_to_string(&(sm->smt_source)),0) ;
346
347 /*
348 * verify that the resource type is sync bw only
349 */
350 if (msg_res_type != SYNC_BW) {
351 DB_ESS("ESS: ignoring RAF with para problem\n",0,0) ;
352 return(fs) ;
353 }
354
355 /*
356 * send an RAF Change Reply
357 */
358 ess_send_response(smc,sm,REPORT_ALLOCATION) ;
359
360 return(fs) ;
361 /* end of Process Report Request */
362
363 default:
364 /*
365 * error in frame
366 */
367 DB_ESS("ESS: ignoring RAF with bad sba_cmd\n",0,0) ;
368 break ;
369 }
370
371 return(fs) ;
372}
373
374/*
375 * determines the synchronous bandwidth, set the TSYNC register and the
376 * mib variables SBAPayload, SBAOverhead and fddiMACT-NEG.
377 */
378int process_bw_alloc(struct s_smc *smc, long int payload, long int overhead)
379{
380 /*
381 * determine the synchronous bandwidth (sync_bw) in bytes per T-NEG,
382 * if the payload is greater than zero.
383 * For the SBAPayload and the SBAOverhead we have the following
384 * unite quations
385 * _ _
386 * | bytes |
387 * SBAPayload = | 8000 ------ |
388 * | s |
389 * - -
390 * _ _
391 * | bytes |
392 * SBAOverhead = | ------ |
393 * | T-NEG |
394 * - -
395 *
396 * T-NEG is discribed by the equation:
397 *
398 * (-) fddiMACT-NEG
399 * T-NEG = -------------------
400 * 12500000 1/s
401 *
402 * The number of bytes we are able to send is the payload
403 * plus the overhead.
404 *
405 * bytes T-NEG SBAPayload 8000 bytes/s
406 * sync_bw = SBAOverhead ------ + -----------------------------
407 * T-NEG T-NEG
408 *
409 *
410 * 1
411 * sync_bw = SBAOverhead + ---- (-)fddiMACT-NEG * SBAPayload
412 * 1562
413 *
414 */
415
416 /*
417 * set the mib attributes fddiPATHSbaOverhead, fddiPATHSbaPayload
418 */
419/* if (smt_set_obj(smc,SMT_P320F,payload,S_SET)) {
420 DB_ESS("ESS: SMT does not accept the payload value\n",0,0) ;
421 return(FALSE) ;
422 }
423 if (smt_set_obj(smc,SMT_P3210,overhead,S_SET)) {
424 DB_ESS("ESS: SMT does not accept the overhead value\n",0,0) ;
425 return(FALSE) ;
426 } */
427
428 /* premliminary */
429 if (payload > MAX_PAYLOAD || overhead > 5000) {
430 DB_ESS("ESS: payload / overhead not accepted\n",0,0) ;
431 return(FALSE) ;
432 }
433
434 /*
435 * start the iterative allocation process if the payload or the overhead
436 * are smaller than the parsed values
437 */
438 if (smc->mib.fddiESSPayload &&
439 ((u_long)payload != smc->mib.fddiESSPayload ||
440 (u_long)overhead != smc->mib.fddiESSOverhead)) {
441 smc->ess.raf_act_timer_poll = TRUE ;
442 smc->ess.timer_count = 0 ;
443 }
444
445 /*
446 * evulate the Payload
447 */
448 if (payload) {
449 DB_ESSN(2,"ESS: turn SMT_ST_SYNC_SERVICE bit on\n",0,0) ;
450 smc->ess.sync_bw_available = TRUE ;
451
452 smc->ess.sync_bw = overhead -
453 (long)smc->mib.m[MAC0].fddiMACT_Neg *
454 payload / 1562 ;
455 }
456 else {
457 DB_ESSN(2,"ESS: turn SMT_ST_SYNC_SERVICE bit off\n",0,0) ;
458 smc->ess.sync_bw_available = FALSE ;
459 smc->ess.sync_bw = 0 ;
460 overhead = 0 ;
461 }
462
463 smc->mib.a[PATH0].fddiPATHSbaPayload = payload ;
464 smc->mib.a[PATH0].fddiPATHSbaOverhead = overhead ;
465
466
467 DB_ESSN(2,"tsync = %lx\n",smc->ess.sync_bw,0) ;
468
469 ess_config_fifo(smc) ;
470 set_formac_tsync(smc,smc->ess.sync_bw) ;
471 return(TRUE) ;
472}
473
474static void ess_send_response(struct s_smc *smc, struct smt_header *sm,
475 int sba_cmd)
476{
477 struct smt_sba_chg *chg ;
478 SMbuf *mb ;
479 void *p ;
480
481 /*
482 * get and initialize the responce frame
483 */
484 if (sba_cmd == CHANGE_ALLOCATION) {
485 if (!(mb=smt_build_frame(smc,SMT_RAF,SMT_REPLY,
486 sizeof(struct smt_sba_chg))))
487 return ;
488 }
489 else {
490 if (!(mb=smt_build_frame(smc,SMT_RAF,SMT_REPLY,
491 sizeof(struct smt_sba_rep_res))))
492 return ;
493 }
494
495 chg = smtod(mb,struct smt_sba_chg *) ;
496 chg->smt.smt_tid = sm->smt_tid ;
497 chg->smt.smt_dest = sm->smt_source ;
498
499 /* set P15 */
500 chg->s_type.para.p_type = SMT_P0015 ;
501 chg->s_type.para.p_len = sizeof(struct smt_p_0015) - PARA_LEN ;
502 chg->s_type.res_type = SYNC_BW ;
503
504 /* set P16 */
505 chg->cmd.para.p_type = SMT_P0016 ;
506 chg->cmd.para.p_len = sizeof(struct smt_p_0016) - PARA_LEN ;
507 chg->cmd.sba_cmd = sba_cmd ;
508
509 /* set P320B */
510 chg->path.para.p_type = SMT_P320B ;
511 chg->path.para.p_len = sizeof(struct smt_p_320b) - PARA_LEN ;
512 chg->path.mib_index = SBAPATHINDEX ;
513 chg->path.path_pad = (u_short)NULL ;
514 chg->path.path_index = PRIMARY_RING ;
515
516 /* set P320F */
517 chg->payload.para.p_type = SMT_P320F ;
518 chg->payload.para.p_len = sizeof(struct smt_p_320f) - PARA_LEN ;
519 chg->payload.mib_index = SBAPATHINDEX ;
520 chg->payload.mib_payload = smc->mib.a[PATH0].fddiPATHSbaPayload ;
521
522 /* set P3210 */
523 chg->overhead.para.p_type = SMT_P3210 ;
524 chg->overhead.para.p_len = sizeof(struct smt_p_3210) - PARA_LEN ;
525 chg->overhead.mib_index = SBAPATHINDEX ;
526 chg->overhead.mib_overhead = smc->mib.a[PATH0].fddiPATHSbaOverhead ;
527
528 if (sba_cmd == CHANGE_ALLOCATION) {
529 /* set P1A */
530 chg->cat.para.p_type = SMT_P001A ;
531 chg->cat.para.p_len = sizeof(struct smt_p_001a) - PARA_LEN ;
532 p = (void *) sm_to_para(smc,sm,SMT_P001A) ;
533 chg->cat.category = ((struct smt_p_001a *)p)->category ;
534 }
535 dump_smt(smc,(struct smt_header *)chg,"RAF") ;
536 ess_send_frame(smc,mb) ;
537}
538
539void ess_timer_poll(struct s_smc *smc)
540{
541 if (!smc->ess.raf_act_timer_poll)
542 return ;
543
544 DB_ESSN(2,"ESS: timer_poll\n",0,0) ;
545
546 smc->ess.timer_count++ ;
547 if (smc->ess.timer_count == 10) {
548 smc->ess.timer_count = 0 ;
549 ess_send_alc_req(smc) ;
550 }
551}
552
553static void ess_send_alc_req(struct s_smc *smc)
554{
555 struct smt_sba_alc_req *req ;
556 SMbuf *mb ;
557
558 /*
559 * send never allocation request where the requested payload and
560 * overhead is zero or deallocate bandwidht when no bandwidth is
561 * parsed
562 */
563 if (!smc->mib.fddiESSPayload) {
564 smc->mib.fddiESSOverhead = 0 ;
565 }
566 else {
567 if (!smc->mib.fddiESSOverhead)
568 smc->mib.fddiESSOverhead = DEFAULT_OV ;
569 }
570
571 if (smc->mib.fddiESSOverhead ==
572 smc->mib.a[PATH0].fddiPATHSbaOverhead &&
573 smc->mib.fddiESSPayload ==
574 smc->mib.a[PATH0].fddiPATHSbaPayload){
575 smc->ess.raf_act_timer_poll = FALSE ;
576 smc->ess.timer_count = 7 ; /* next RAF alc req after 3 s */
577 return ;
578 }
579
580 /*
581 * get and initialize the responce frame
582 */
583 if (!(mb=smt_build_frame(smc,SMT_RAF,SMT_REQUEST,
584 sizeof(struct smt_sba_alc_req))))
585 return ;
586 req = smtod(mb,struct smt_sba_alc_req *) ;
587 req->smt.smt_tid = smc->ess.alloc_trans_id = smt_get_tid(smc) ;
588 req->smt.smt_dest = smt_sba_da ;
589
590 /* set P15 */
591 req->s_type.para.p_type = SMT_P0015 ;
592 req->s_type.para.p_len = sizeof(struct smt_p_0015) - PARA_LEN ;
593 req->s_type.res_type = SYNC_BW ;
594
595 /* set P16 */
596 req->cmd.para.p_type = SMT_P0016 ;
597 req->cmd.para.p_len = sizeof(struct smt_p_0016) - PARA_LEN ;
598 req->cmd.sba_cmd = REQUEST_ALLOCATION ;
599
600 /*
601 * set the parameter type and parameter lenght of all used
602 * parameters
603 */
604
605 /* set P320B */
606 req->path.para.p_type = SMT_P320B ;
607 req->path.para.p_len = sizeof(struct smt_p_320b) - PARA_LEN ;
608 req->path.mib_index = SBAPATHINDEX ;
609 req->path.path_pad = (u_short)NULL ;
610 req->path.path_index = PRIMARY_RING ;
611
612 /* set P0017 */
613 req->pl_req.para.p_type = SMT_P0017 ;
614 req->pl_req.para.p_len = sizeof(struct smt_p_0017) - PARA_LEN ;
615 req->pl_req.sba_pl_req = smc->mib.fddiESSPayload -
616 smc->mib.a[PATH0].fddiPATHSbaPayload ;
617
618 /* set P0018 */
619 req->ov_req.para.p_type = SMT_P0018 ;
620 req->ov_req.para.p_len = sizeof(struct smt_p_0018) - PARA_LEN ;
621 req->ov_req.sba_ov_req = smc->mib.fddiESSOverhead -
622 smc->mib.a[PATH0].fddiPATHSbaOverhead ;
623
624 /* set P320F */
625 req->payload.para.p_type = SMT_P320F ;
626 req->payload.para.p_len = sizeof(struct smt_p_320f) - PARA_LEN ;
627 req->payload.mib_index = SBAPATHINDEX ;
628 req->payload.mib_payload = smc->mib.a[PATH0].fddiPATHSbaPayload ;
629
630 /* set P3210 */
631 req->overhead.para.p_type = SMT_P3210 ;
632 req->overhead.para.p_len = sizeof(struct smt_p_3210) - PARA_LEN ;
633 req->overhead.mib_index = SBAPATHINDEX ;
634 req->overhead.mib_overhead = smc->mib.a[PATH0].fddiPATHSbaOverhead ;
635
636 /* set P19 */
637 req->a_addr.para.p_type = SMT_P0019 ;
638 req->a_addr.para.p_len = sizeof(struct smt_p_0019) - PARA_LEN ;
639 req->a_addr.sba_pad = (u_short)NULL ;
640 req->a_addr.alloc_addr = null_addr ;
641
642 /* set P1A */
643 req->cat.para.p_type = SMT_P001A ;
644 req->cat.para.p_len = sizeof(struct smt_p_001a) - PARA_LEN ;
645 req->cat.category = smc->mib.fddiESSCategory ;
646
647 /* set P1B */
648 req->tneg.para.p_type = SMT_P001B ;
649 req->tneg.para.p_len = sizeof(struct smt_p_001b) - PARA_LEN ;
650 req->tneg.max_t_neg = smc->mib.fddiESSMaxTNeg ;
651
652 /* set P1C */
653 req->segm.para.p_type = SMT_P001C ;
654 req->segm.para.p_len = sizeof(struct smt_p_001c) - PARA_LEN ;
655 req->segm.min_seg_siz = smc->mib.fddiESSMinSegmentSize ;
656
657 dump_smt(smc,(struct smt_header *)req,"RAF") ;
658 ess_send_frame(smc,mb) ;
659}
660
661static void ess_send_frame(struct s_smc *smc, SMbuf *mb)
662{
663 /*
664 * check if the frame must be send to the own ESS
665 */
666 if (smc->ess.local_sba_active) {
667 /*
668 * Send the Change Reply to the local SBA
669 */
670 DB_ESS("ESS:Send to the local SBA\n",0,0) ;
671 if (!smc->ess.sba_reply_pend)
672 smc->ess.sba_reply_pend = mb ;
673 else {
674 DB_ESS("Frame is lost - another frame was pending\n",0,0);
675 smt_free_mbuf(smc,mb) ;
676 }
677 }
678 else {
679 /*
680 * Send the SBA RAF Change Reply to the network
681 */
682 DB_ESS("ESS:Send to the network\n",0,0) ;
683 smt_send_frame(smc,mb,FC_SMT_INFO,0) ;
684 }
685}
686
687void ess_para_change(struct s_smc *smc)
688{
689 (void)process_bw_alloc(smc,(long)smc->mib.a[PATH0].fddiPATHSbaPayload,
690 (long)smc->mib.a[PATH0].fddiPATHSbaOverhead) ;
691}
692
693static void ess_config_fifo(struct s_smc *smc)
694{
695 /*
696 * if nothing to do exit
697 */
698 if (smc->mib.a[PATH0].fddiPATHSbaPayload) {
699 if (smc->hw.fp.fifo.fifo_config_mode & SYNC_TRAFFIC_ON &&
700 (smc->hw.fp.fifo.fifo_config_mode&SEND_ASYNC_AS_SYNC) ==
701 smc->mib.fddiESSSynchTxMode) {
702 return ;
703 }
704 }
705 else {
706 if (!(smc->hw.fp.fifo.fifo_config_mode & SYNC_TRAFFIC_ON)) {
707 return ;
708 }
709 }
710
711 /*
712 * split up the FIFO and reinitialize the queues
713 */
714 formac_reinit_tx(smc) ;
715}
716
717#endif /* ESS */
718
719#endif /* no SLIM_SMT */
720
diff --git a/drivers/net/skfp/fplustm.c b/drivers/net/skfp/fplustm.c
new file mode 100644
index 000000000000..76e78442fc24
--- /dev/null
+++ b/drivers/net/skfp/fplustm.c
@@ -0,0 +1,1561 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * See the file "skfddi.c" for further information.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * The information in this file is provided "AS IS" without warranty.
14 *
15 ******************************************************************************/
16
17/*
18 * FORMAC+ Driver for tag mode
19 */
20
21#include "h/types.h"
22#include "h/fddi.h"
23#include "h/smc.h"
24#include "h/supern_2.h"
25#include "can.c"
26
27#ifndef lint
28static const char ID_sccs[] = "@(#)fplustm.c 1.32 99/02/23 (C) SK " ;
29#endif
30
31#ifndef UNUSED
32#ifdef lint
33#define UNUSED(x) (x) = (x)
34#else
35#define UNUSED(x)
36#endif
37#endif
38
39#define FM_ADDRX (FM_ADDET|FM_EXGPA0|FM_EXGPA1)
40#define MS2BCLK(x) ((x)*12500L)
41#define US2BCLK(x) ((x)*1250L)
42
43/*
44 * prototypes for static function
45 */
46static void build_claim_beacon(struct s_smc *smc, u_long t_request);
47static int init_mac(struct s_smc *smc, int all);
48static void rtm_init(struct s_smc *smc);
49static void smt_split_up_fifo(struct s_smc *smc);
50
51#if (!defined(NO_SMT_PANIC) || defined(DEBUG))
52static char write_mdr_warning [] = "E350 write_mdr() FM_SNPPND is set\n";
53static char cam_warning [] = "E_SMT_004: CAM still busy\n";
54#endif
55
56#define DUMMY_READ() smc->hw.mc_dummy = (u_short) inp(ADDR(B0_RAP))
57
58#define CHECK_NPP() { unsigned k = 10000 ;\
59 while ((inpw(FM_A(FM_STMCHN)) & FM_SNPPND) && k) k--;\
60 if (!k) { \
61 SMT_PANIC(smc,SMT_E0130, SMT_E0130_MSG) ; \
62 } \
63 }
64
65#define CHECK_CAM() { unsigned k = 10 ;\
66 while (!(inpw(FM_A(FM_AFSTAT)) & FM_DONE) && k) k--;\
67 if (!k) { \
68 SMT_PANIC(smc,SMT_E0131, SMT_E0131_MSG) ; \
69 } \
70 }
71
72const struct fddi_addr fddi_broadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
73static const struct fddi_addr null_addr = {{0,0,0,0,0,0}};
74static const struct fddi_addr dbeacon_multi = {{0x01,0x80,0xc2,0x00,0x01,0x00}};
75
76static const u_short my_said = 0xffff ; /* short address (n.u.) */
77static const u_short my_sagp = 0xffff ; /* short group address (n.u.) */
78
79/*
80 * define my address
81 */
82#ifdef USE_CAN_ADDR
83#define MA smc->hw.fddi_canon_addr
84#else
85#define MA smc->hw.fddi_home_addr
86#endif
87
88
89/*
90 * useful interrupt bits
91 */
92static int mac_imsk1u = FM_STXABRS | FM_STXABRA0 | FM_SXMTABT ;
93static int mac_imsk1l = FM_SQLCKS | FM_SQLCKA0 | FM_SPCEPDS | FM_SPCEPDA0|
94 FM_STBURS | FM_STBURA0 ;
95
96 /* delete FM_SRBFL after tests */
97static int mac_imsk2u = FM_SERRSF | FM_SNFSLD | FM_SRCVOVR | FM_SRBFL |
98 FM_SMYCLM ;
99static int mac_imsk2l = FM_STRTEXR | FM_SDUPCLM | FM_SFRMCTR |
100 FM_SERRCTR | FM_SLSTCTR |
101 FM_STRTEXP | FM_SMULTDA | FM_SRNGOP ;
102
103static int mac_imsk3u = FM_SRCVOVR2 | FM_SRBFL2 ;
104static int mac_imsk3l = FM_SRPERRQ2 | FM_SRPERRQ1 ;
105
106static int mac_beacon_imsk2u = FM_SOTRBEC | FM_SMYBEC | FM_SBEC |
107 FM_SLOCLM | FM_SHICLM | FM_SMYCLM | FM_SCLM ;
108
109
110static u_long mac_get_tneg(struct s_smc *smc)
111{
112 u_long tneg ;
113
114 tneg = (u_long)((long)inpw(FM_A(FM_TNEG))<<5) ;
115 return((u_long)((tneg + ((inpw(FM_A(FM_TMRS))>>10)&0x1f)) |
116 0xffe00000L)) ;
117}
118
119void mac_update_counter(struct s_smc *smc)
120{
121 smc->mib.m[MAC0].fddiMACFrame_Ct =
122 (smc->mib.m[MAC0].fddiMACFrame_Ct & 0xffff0000L)
123 + (u_short) inpw(FM_A(FM_FCNTR)) ;
124 smc->mib.m[MAC0].fddiMACLost_Ct =
125 (smc->mib.m[MAC0].fddiMACLost_Ct & 0xffff0000L)
126 + (u_short) inpw(FM_A(FM_LCNTR)) ;
127 smc->mib.m[MAC0].fddiMACError_Ct =
128 (smc->mib.m[MAC0].fddiMACError_Ct & 0xffff0000L)
129 + (u_short) inpw(FM_A(FM_ECNTR)) ;
130 smc->mib.m[MAC0].fddiMACT_Neg = mac_get_tneg(smc) ;
131#ifdef SMT_REAL_TOKEN_CT
132 /*
133 * If the token counter is emulated it is updated in smt_event.
134 */
135 TBD
136#else
137 smt_emulate_token_ct( smc, MAC0 );
138#endif
139}
140
141/*
142 * write long value into buffer memory over memory data register (MDR),
143 */
144static void write_mdr(struct s_smc *smc, u_long val)
145{
146 CHECK_NPP() ;
147 MDRW(val) ;
148}
149
150#if 0
151/*
152 * read long value from buffer memory over memory data register (MDR),
153 */
154static u_long read_mdr(struct s_smc *smc, unsigned int addr)
155{
156 long p ;
157 CHECK_NPP() ;
158 MARR(addr) ;
159 outpw(FM_A(FM_CMDREG1),FM_IRMEMWO) ;
160 CHECK_NPP() ; /* needed for PCI to prevent from timeing violations */
161/* p = MDRR() ; */ /* bad read values if the workaround */
162 /* smc->hw.mc_dummy = *((short volatile far *)(addr)))*/
163 /* is used */
164 p = (u_long)inpw(FM_A(FM_MDRU))<<16 ;
165 p += (u_long)inpw(FM_A(FM_MDRL)) ;
166 return(p) ;
167}
168#endif
169
170/*
171 * clear buffer memory
172 */
173static void init_ram(struct s_smc *smc)
174{
175 u_short i ;
176
177 smc->hw.fp.fifo.rbc_ram_start = 0 ;
178 smc->hw.fp.fifo.rbc_ram_end =
179 smc->hw.fp.fifo.rbc_ram_start + RBC_MEM_SIZE ;
180 CHECK_NPP() ;
181 MARW(smc->hw.fp.fifo.rbc_ram_start) ;
182 for (i = smc->hw.fp.fifo.rbc_ram_start;
183 i < (u_short) (smc->hw.fp.fifo.rbc_ram_end-1); i++)
184 write_mdr(smc,0L) ;
185 /* Erase the last byte too */
186 write_mdr(smc,0L) ;
187}
188
189/*
190 * set receive FIFO pointer
191 */
192static void set_recvptr(struct s_smc *smc)
193{
194 /*
195 * initialize the pointer for receive queue 1
196 */
197 outpw(FM_A(FM_RPR1),smc->hw.fp.fifo.rx1_fifo_start) ; /* RPR1 */
198 outpw(FM_A(FM_SWPR1),smc->hw.fp.fifo.rx1_fifo_start) ; /* SWPR1 */
199 outpw(FM_A(FM_WPR1),smc->hw.fp.fifo.rx1_fifo_start) ; /* WPR1 */
200 outpw(FM_A(FM_EARV1),smc->hw.fp.fifo.tx_s_start-1) ; /* EARV1 */
201
202 /*
203 * initialize the pointer for receive queue 2
204 */
205 if (smc->hw.fp.fifo.rx2_fifo_size) {
206 outpw(FM_A(FM_RPR2),smc->hw.fp.fifo.rx2_fifo_start) ;
207 outpw(FM_A(FM_SWPR2),smc->hw.fp.fifo.rx2_fifo_start) ;
208 outpw(FM_A(FM_WPR2),smc->hw.fp.fifo.rx2_fifo_start) ;
209 outpw(FM_A(FM_EARV2),smc->hw.fp.fifo.rbc_ram_end-1) ;
210 }
211 else {
212 outpw(FM_A(FM_RPR2),smc->hw.fp.fifo.rbc_ram_end-1) ;
213 outpw(FM_A(FM_SWPR2),smc->hw.fp.fifo.rbc_ram_end-1) ;
214 outpw(FM_A(FM_WPR2),smc->hw.fp.fifo.rbc_ram_end-1) ;
215 outpw(FM_A(FM_EARV2),smc->hw.fp.fifo.rbc_ram_end-1) ;
216 }
217}
218
219/*
220 * set transmit FIFO pointer
221 */
222static void set_txptr(struct s_smc *smc)
223{
224 outpw(FM_A(FM_CMDREG2),FM_IRSTQ) ; /* reset transmit queues */
225
226 /*
227 * initialize the pointer for asynchronous transmit queue
228 */
229 outpw(FM_A(FM_RPXA0),smc->hw.fp.fifo.tx_a0_start) ; /* RPXA0 */
230 outpw(FM_A(FM_SWPXA0),smc->hw.fp.fifo.tx_a0_start) ; /* SWPXA0 */
231 outpw(FM_A(FM_WPXA0),smc->hw.fp.fifo.tx_a0_start) ; /* WPXA0 */
232 outpw(FM_A(FM_EAA0),smc->hw.fp.fifo.rx2_fifo_start-1) ; /* EAA0 */
233
234 /*
235 * initialize the pointer for synchronous transmit queue
236 */
237 if (smc->hw.fp.fifo.tx_s_size) {
238 outpw(FM_A(FM_RPXS),smc->hw.fp.fifo.tx_s_start) ;
239 outpw(FM_A(FM_SWPXS),smc->hw.fp.fifo.tx_s_start) ;
240 outpw(FM_A(FM_WPXS),smc->hw.fp.fifo.tx_s_start) ;
241 outpw(FM_A(FM_EAS),smc->hw.fp.fifo.tx_a0_start-1) ;
242 }
243 else {
244 outpw(FM_A(FM_RPXS),smc->hw.fp.fifo.tx_a0_start-1) ;
245 outpw(FM_A(FM_SWPXS),smc->hw.fp.fifo.tx_a0_start-1) ;
246 outpw(FM_A(FM_WPXS),smc->hw.fp.fifo.tx_a0_start-1) ;
247 outpw(FM_A(FM_EAS),smc->hw.fp.fifo.tx_a0_start-1) ;
248 }
249}
250
251/*
252 * init memory buffer management registers
253 */
254static void init_rbc(struct s_smc *smc)
255{
256 u_short rbc_ram_addr ;
257
258 /*
259 * set unused pointers or permanent pointers
260 */
261 rbc_ram_addr = smc->hw.fp.fifo.rx2_fifo_start - 1 ;
262
263 outpw(FM_A(FM_RPXA1),rbc_ram_addr) ; /* a1-send pointer */
264 outpw(FM_A(FM_WPXA1),rbc_ram_addr) ;
265 outpw(FM_A(FM_SWPXA1),rbc_ram_addr) ;
266 outpw(FM_A(FM_EAA1),rbc_ram_addr) ;
267
268 set_recvptr(smc) ;
269 set_txptr(smc) ;
270}
271
272/*
273 * init rx pointer
274 */
275static void init_rx(struct s_smc *smc)
276{
277 struct s_smt_rx_queue *queue ;
278
279 /*
280 * init all tx data structures for receive queue 1
281 */
282 smc->hw.fp.rx[QUEUE_R1] = queue = &smc->hw.fp.rx_q[QUEUE_R1] ;
283 queue->rx_bmu_ctl = (HW_PTR) ADDR(B0_R1_CSR) ;
284 queue->rx_bmu_dsc = (HW_PTR) ADDR(B4_R1_DA) ;
285
286 /*
287 * init all tx data structures for receive queue 2
288 */
289 smc->hw.fp.rx[QUEUE_R2] = queue = &smc->hw.fp.rx_q[QUEUE_R2] ;
290 queue->rx_bmu_ctl = (HW_PTR) ADDR(B0_R2_CSR) ;
291 queue->rx_bmu_dsc = (HW_PTR) ADDR(B4_R2_DA) ;
292}
293
294/*
295 * set the TSYNC register of the FORMAC to regulate synchronous transmission
296 */
297void set_formac_tsync(struct s_smc *smc, long sync_bw)
298{
299 outpw(FM_A(FM_TSYNC),(unsigned int) (((-sync_bw) >> 5) & 0xffff) ) ;
300}
301
302/*
303 * init all tx data structures
304 */
305static void init_tx(struct s_smc *smc)
306{
307 struct s_smt_tx_queue *queue ;
308
309 /*
310 * init all tx data structures for the synchronous queue
311 */
312 smc->hw.fp.tx[QUEUE_S] = queue = &smc->hw.fp.tx_q[QUEUE_S] ;
313 queue->tx_bmu_ctl = (HW_PTR) ADDR(B0_XS_CSR) ;
314 queue->tx_bmu_dsc = (HW_PTR) ADDR(B5_XS_DA) ;
315
316#ifdef ESS
317 set_formac_tsync(smc,smc->ess.sync_bw) ;
318#endif
319
320 /*
321 * init all tx data structures for the asynchronous queue 0
322 */
323 smc->hw.fp.tx[QUEUE_A0] = queue = &smc->hw.fp.tx_q[QUEUE_A0] ;
324 queue->tx_bmu_ctl = (HW_PTR) ADDR(B0_XA_CSR) ;
325 queue->tx_bmu_dsc = (HW_PTR) ADDR(B5_XA_DA) ;
326
327
328 llc_recover_tx(smc) ;
329}
330
331static void mac_counter_init(struct s_smc *smc)
332{
333 int i ;
334 u_long *ec ;
335
336 /*
337 * clear FORMAC+ frame-, lost- and error counter
338 */
339 outpw(FM_A(FM_FCNTR),0) ;
340 outpw(FM_A(FM_LCNTR),0) ;
341 outpw(FM_A(FM_ECNTR),0) ;
342 /*
343 * clear internal error counter stucture
344 */
345 ec = (u_long *)&smc->hw.fp.err_stats ;
346 for (i = (sizeof(struct err_st)/sizeof(long)) ; i ; i--)
347 *ec++ = 0L ;
348 smc->mib.m[MAC0].fddiMACRingOp_Ct = 0 ;
349}
350
351/*
352 * set FORMAC address, and t_request
353 */
354static void set_formac_addr(struct s_smc *smc)
355{
356 long t_requ = smc->mib.m[MAC0].fddiMACT_Req ;
357
358 outpw(FM_A(FM_SAID),my_said) ; /* set short address */
359 outpw(FM_A(FM_LAIL),(unsigned)((smc->hw.fddi_home_addr.a[4]<<8) +
360 smc->hw.fddi_home_addr.a[5])) ;
361 outpw(FM_A(FM_LAIC),(unsigned)((smc->hw.fddi_home_addr.a[2]<<8) +
362 smc->hw.fddi_home_addr.a[3])) ;
363 outpw(FM_A(FM_LAIM),(unsigned)((smc->hw.fddi_home_addr.a[0]<<8) +
364 smc->hw.fddi_home_addr.a[1])) ;
365
366 outpw(FM_A(FM_SAGP),my_sagp) ; /* set short group address */
367
368 outpw(FM_A(FM_LAGL),(unsigned)((smc->hw.fp.group_addr.a[4]<<8) +
369 smc->hw.fp.group_addr.a[5])) ;
370 outpw(FM_A(FM_LAGC),(unsigned)((smc->hw.fp.group_addr.a[2]<<8) +
371 smc->hw.fp.group_addr.a[3])) ;
372 outpw(FM_A(FM_LAGM),(unsigned)((smc->hw.fp.group_addr.a[0]<<8) +
373 smc->hw.fp.group_addr.a[1])) ;
374
375 /* set r_request regs. (MSW & LSW of TRT ) */
376 outpw(FM_A(FM_TREQ1),(unsigned)(t_requ>>16)) ;
377 outpw(FM_A(FM_TREQ0),(unsigned)t_requ) ;
378}
379
380static void set_int(char *p, int l)
381{
382 p[0] = (char)(l >> 24) ;
383 p[1] = (char)(l >> 16) ;
384 p[2] = (char)(l >> 8) ;
385 p[3] = (char)(l >> 0) ;
386}
387
388/*
389 * copy TX descriptor to buffer mem
390 * append FC field and MAC frame
391 * if more bit is set in descr
392 * append pointer to descriptor (endless loop)
393 * else
394 * append 'end of chain' pointer
395 */
396static void copy_tx_mac(struct s_smc *smc, u_long td, struct fddi_mac *mac,
397 unsigned off, int len)
398/* u_long td; transmit descriptor */
399/* struct fddi_mac *mac; mac frame pointer */
400/* unsigned off; start address within buffer memory */
401/* int len ; lenght of the frame including the FC */
402{
403 int i ;
404 u_int *p ;
405
406 CHECK_NPP() ;
407 MARW(off) ; /* set memory address reg for writes */
408
409 p = (u_int *) mac ;
410 for (i = (len + 3)/4 ; i ; i--) {
411 if (i == 1) {
412 /* last word, set the tag bit */
413 outpw(FM_A(FM_CMDREG2),FM_ISTTB) ;
414 }
415 write_mdr(smc,MDR_REVERSE(*p)) ;
416 p++ ;
417 }
418
419 outpw(FM_A(FM_CMDREG2),FM_ISTTB) ; /* set the tag bit */
420 write_mdr(smc,td) ; /* write over memory data reg to buffer */
421}
422
423/*
424 BEGIN_MANUAL_ENTRY(module;tests;3)
425 How to test directed beacon frames
426 ----------------------------------------------------------------
427
428 o Insert a break point in the function build_claim_beacon()
429 before calling copy_tx_mac() for building the claim frame.
430 o Modify the RM3_DETECT case so that the RM6_DETECT state
431 will always entered from the RM3_DETECT state (function rmt_fsm(),
432 rmt.c)
433 o Compile the driver.
434 o Set the parameter TREQ in the protocol.ini or net.cfg to a
435 small value to make sure your station will win the claim
436 process.
437 o Start the driver.
438 o When you reach the break point, modify the SA and DA address
439 of the claim frame (e.g. SA = DA = 10005affffff).
440 o When you see RM3_DETECT and RM6_DETECT, observe the direct
441 beacon frames on the UPPSLANA.
442
443 END_MANUAL_ENTRY
444 */
445static void directed_beacon(struct s_smc *smc)
446{
447 SK_LOC_DECL(u_int,a[2]) ;
448
449 /*
450 * set UNA in frame
451 * enable FORMAC to send endless queue of directed beacon
452 * important: the UNA starts at byte 1 (not at byte 0)
453 */
454 * (char *) a = (char) ((long)DBEACON_INFO<<24L) ;
455 a[1] = 0 ;
456 memcpy((char *)a+1,(char *) &smc->mib.m[MAC0].fddiMACUpstreamNbr,6) ;
457
458 CHECK_NPP() ;
459 /* set memory address reg for writes */
460 MARW(smc->hw.fp.fifo.rbc_ram_start+DBEACON_FRAME_OFF+4) ;
461 write_mdr(smc,MDR_REVERSE(a[0])) ;
462 outpw(FM_A(FM_CMDREG2),FM_ISTTB) ; /* set the tag bit */
463 write_mdr(smc,MDR_REVERSE(a[1])) ;
464
465 outpw(FM_A(FM_SABC),smc->hw.fp.fifo.rbc_ram_start + DBEACON_FRAME_OFF) ;
466}
467
468/*
469 setup claim & beacon pointer
470 NOTE :
471 special frame packets end with a pointer to their own
472 descriptor, and the MORE bit is set in the descriptor
473*/
474static void build_claim_beacon(struct s_smc *smc, u_long t_request)
475{
476 u_int td ;
477 int len ;
478 struct fddi_mac_sf *mac ;
479
480 /*
481 * build claim packet
482 */
483 len = 17 ;
484 td = TX_DESCRIPTOR | ((((u_int)len-1)&3)<<27) ;
485 mac = &smc->hw.fp.mac_sfb ;
486 mac->mac_fc = FC_CLAIM ;
487 /* DA == SA in claim frame */
488 mac->mac_source = mac->mac_dest = MA ;
489 /* 2's complement */
490 set_int((char *)mac->mac_info,(int)t_request) ;
491
492 copy_tx_mac(smc,td,(struct fddi_mac *)mac,
493 smc->hw.fp.fifo.rbc_ram_start + CLAIM_FRAME_OFF,len) ;
494 /* set CLAIM start pointer */
495 outpw(FM_A(FM_SACL),smc->hw.fp.fifo.rbc_ram_start + CLAIM_FRAME_OFF) ;
496
497 /*
498 * build beacon packet
499 */
500 len = 17 ;
501 td = TX_DESCRIPTOR | ((((u_int)len-1)&3)<<27) ;
502 mac->mac_fc = FC_BEACON ;
503 mac->mac_source = MA ;
504 mac->mac_dest = null_addr ; /* DA == 0 in beacon frame */
505 set_int((char *) mac->mac_info,((int)BEACON_INFO<<24) + 0 ) ;
506
507 copy_tx_mac(smc,td,(struct fddi_mac *)mac,
508 smc->hw.fp.fifo.rbc_ram_start + BEACON_FRAME_OFF,len) ;
509 /* set beacon start pointer */
510 outpw(FM_A(FM_SABC),smc->hw.fp.fifo.rbc_ram_start + BEACON_FRAME_OFF) ;
511
512 /*
513 * build directed beacon packet
514 * contains optional UNA
515 */
516 len = 23 ;
517 td = TX_DESCRIPTOR | ((((u_int)len-1)&3)<<27) ;
518 mac->mac_fc = FC_BEACON ;
519 mac->mac_source = MA ;
520 mac->mac_dest = dbeacon_multi ; /* multicast */
521 set_int((char *) mac->mac_info,((int)DBEACON_INFO<<24) + 0 ) ;
522 set_int((char *) mac->mac_info+4,0) ;
523 set_int((char *) mac->mac_info+8,0) ;
524
525 copy_tx_mac(smc,td,(struct fddi_mac *)mac,
526 smc->hw.fp.fifo.rbc_ram_start + DBEACON_FRAME_OFF,len) ;
527
528 /* end of claim/beacon queue */
529 outpw(FM_A(FM_EACB),smc->hw.fp.fifo.rx1_fifo_start-1) ;
530
531 outpw(FM_A(FM_WPXSF),0) ;
532 outpw(FM_A(FM_RPXSF),0) ;
533}
534
535static void formac_rcv_restart(struct s_smc *smc)
536{
537 /* enable receive function */
538 SETMASK(FM_A(FM_MDREG1),smc->hw.fp.rx_mode,FM_ADDRX) ;
539
540 outpw(FM_A(FM_CMDREG1),FM_ICLLR) ; /* clear receive lock */
541}
542
543void formac_tx_restart(struct s_smc *smc)
544{
545 outpw(FM_A(FM_CMDREG1),FM_ICLLS) ; /* clear s-frame lock */
546 outpw(FM_A(FM_CMDREG1),FM_ICLLA0) ; /* clear a-frame lock */
547}
548
549static void enable_formac(struct s_smc *smc)
550{
551 /* set formac IMSK : 0 enables irq */
552 outpw(FM_A(FM_IMSK1U),~mac_imsk1u) ;
553 outpw(FM_A(FM_IMSK1L),~mac_imsk1l) ;
554 outpw(FM_A(FM_IMSK2U),~mac_imsk2u) ;
555 outpw(FM_A(FM_IMSK2L),~mac_imsk2l) ;
556 outpw(FM_A(FM_IMSK3U),~mac_imsk3u) ;
557 outpw(FM_A(FM_IMSK3L),~mac_imsk3l) ;
558}
559
560#if 0 /* Removed because the driver should use the ASICs TX complete IRQ. */
561 /* The FORMACs tx complete IRQ should be used any longer */
562
563/*
564 BEGIN_MANUAL_ENTRY(if,func;others;4)
565
566 void enable_tx_irq(smc, queue)
567 struct s_smc *smc ;
568 u_short queue ;
569
570Function DOWNCALL (SMT, fplustm.c)
571 enable_tx_irq() enables the FORMACs transmit complete
572 interrupt of the queue.
573
574Para queue = QUEUE_S: synchronous queue
575 = QUEUE_A0: asynchronous queue
576
577Note After any ring operational change the transmit complete
578 interrupts are disabled.
579 The operating system dependent module must enable
580 the transmit complete interrupt of a queue,
581 - when it queues the first frame,
582 because of no transmit resources are beeing
583 available and
584 - when it escapes from the function llc_restart_tx
585 while some frames are still queued.
586
587 END_MANUAL_ENTRY
588 */
589void enable_tx_irq(struct s_smc *smc, u_short queue)
590/* u_short queue; 0 = synchronous queue, 1 = asynchronous queue 0 */
591{
592 u_short imask ;
593
594 imask = ~(inpw(FM_A(FM_IMSK1U))) ;
595
596 if (queue == 0) {
597 outpw(FM_A(FM_IMSK1U),~(imask|FM_STEFRMS)) ;
598 }
599 if (queue == 1) {
600 outpw(FM_A(FM_IMSK1U),~(imask|FM_STEFRMA0)) ;
601 }
602}
603
604/*
605 BEGIN_MANUAL_ENTRY(if,func;others;4)
606
607 void disable_tx_irq(smc, queue)
608 struct s_smc *smc ;
609 u_short queue ;
610
611Function DOWNCALL (SMT, fplustm.c)
612 disable_tx_irq disables the FORMACs transmit complete
613 interrupt of the queue
614
615Para queue = QUEUE_S: synchronous queue
616 = QUEUE_A0: asynchronous queue
617
618Note The operating system dependent module should disable
619 the transmit complete interrupts if it escapes from the
620 function llc_restart_tx and no frames are queued.
621
622 END_MANUAL_ENTRY
623 */
624void disable_tx_irq(struct s_smc *smc, u_short queue)
625/* u_short queue; 0 = synchronous queue, 1 = asynchronous queue 0 */
626{
627 u_short imask ;
628
629 imask = ~(inpw(FM_A(FM_IMSK1U))) ;
630
631 if (queue == 0) {
632 outpw(FM_A(FM_IMSK1U),~(imask&~FM_STEFRMS)) ;
633 }
634 if (queue == 1) {
635 outpw(FM_A(FM_IMSK1U),~(imask&~FM_STEFRMA0)) ;
636 }
637}
638#endif
639
640static void disable_formac(struct s_smc *smc)
641{
642 /* clear formac IMSK : 1 disables irq */
643 outpw(FM_A(FM_IMSK1U),MW) ;
644 outpw(FM_A(FM_IMSK1L),MW) ;
645 outpw(FM_A(FM_IMSK2U),MW) ;
646 outpw(FM_A(FM_IMSK2L),MW) ;
647 outpw(FM_A(FM_IMSK3U),MW) ;
648 outpw(FM_A(FM_IMSK3L),MW) ;
649}
650
651
652static void mac_ring_up(struct s_smc *smc, int up)
653{
654 if (up) {
655 formac_rcv_restart(smc) ; /* enable receive function */
656 smc->hw.mac_ring_is_up = TRUE ;
657 llc_restart_tx(smc) ; /* TX queue */
658 }
659 else {
660 /* disable receive function */
661 SETMASK(FM_A(FM_MDREG1),FM_MDISRCV,FM_ADDET) ;
662
663 /* abort current transmit activity */
664 outpw(FM_A(FM_CMDREG2),FM_IACTR) ;
665
666 smc->hw.mac_ring_is_up = FALSE ;
667 }
668}
669
670/*--------------------------- ISR handling ----------------------------------*/
671/*
672 * mac1_irq is in drvfbi.c
673 */
674
675/*
676 * mac2_irq: status bits for the receive queue 1, and ring status
677 * ring status indication bits
678 */
679void mac2_irq(struct s_smc *smc, u_short code_s2u, u_short code_s2l)
680{
681 u_short change_s2l ;
682 u_short change_s2u ;
683
684 /* (jd) 22-Feb-1999
685 * Restart 2_DMax Timer after end of claiming or beaconing
686 */
687 if (code_s2u & (FM_SCLM|FM_SHICLM|FM_SBEC|FM_SOTRBEC)) {
688 queue_event(smc,EVENT_RMT,RM_TX_STATE_CHANGE) ;
689 }
690 else if (code_s2l & (FM_STKISS)) {
691 queue_event(smc,EVENT_RMT,RM_TX_STATE_CHANGE) ;
692 }
693
694 /*
695 * XOR current st bits with the last to avoid useless RMT event queuing
696 */
697 change_s2l = smc->hw.fp.s2l ^ code_s2l ;
698 change_s2u = smc->hw.fp.s2u ^ code_s2u ;
699
700 if ((change_s2l & FM_SRNGOP) ||
701 (!smc->hw.mac_ring_is_up && ((code_s2l & FM_SRNGOP)))) {
702 if (code_s2l & FM_SRNGOP) {
703 mac_ring_up(smc,1) ;
704 queue_event(smc,EVENT_RMT,RM_RING_OP) ;
705 smc->mib.m[MAC0].fddiMACRingOp_Ct++ ;
706 }
707 else {
708 mac_ring_up(smc,0) ;
709 queue_event(smc,EVENT_RMT,RM_RING_NON_OP) ;
710 }
711 goto mac2_end ;
712 }
713 if (code_s2l & FM_SMISFRM) { /* missed frame */
714 smc->mib.m[MAC0].fddiMACNotCopied_Ct++ ;
715 }
716 if (code_s2u & (FM_SRCVOVR | /* recv. FIFO overflow */
717 FM_SRBFL)) { /* recv. buffer full */
718 smc->hw.mac_ct.mac_r_restart_counter++ ;
719/* formac_rcv_restart(smc) ; */
720 smt_stat_counter(smc,1) ;
721/* goto mac2_end ; */
722 }
723 if (code_s2u & FM_SOTRBEC)
724 queue_event(smc,EVENT_RMT,RM_OTHER_BEACON) ;
725 if (code_s2u & FM_SMYBEC)
726 queue_event(smc,EVENT_RMT,RM_MY_BEACON) ;
727 if (change_s2u & code_s2u & FM_SLOCLM) {
728 DB_RMTN(2,"RMT : lower claim received\n",0,0) ;
729 }
730 if ((code_s2u & FM_SMYCLM) && !(code_s2l & FM_SDUPCLM)) {
731 /*
732 * This is my claim and that claim is not detected as a
733 * duplicate one.
734 */
735 queue_event(smc,EVENT_RMT,RM_MY_CLAIM) ;
736 }
737 if (code_s2l & FM_SDUPCLM) {
738 /*
739 * If a duplicate claim frame (same SA but T_Bid != T_Req)
740 * this flag will be set.
741 * In the RMT state machine we need a RM_VALID_CLAIM event
742 * to do the appropriate state change.
743 * RM(34c)
744 */
745 queue_event(smc,EVENT_RMT,RM_VALID_CLAIM) ;
746 }
747 if (change_s2u & code_s2u & FM_SHICLM) {
748 DB_RMTN(2,"RMT : higher claim received\n",0,0) ;
749 }
750 if ( (code_s2l & FM_STRTEXP) ||
751 (code_s2l & FM_STRTEXR) )
752 queue_event(smc,EVENT_RMT,RM_TRT_EXP) ;
753 if (code_s2l & FM_SMULTDA) {
754 /*
755 * The MAC has found a 2. MAC with the same address.
756 * Signal dup_addr_test = failed to RMT state machine.
757 * RM(25)
758 */
759 smc->r.dup_addr_test = DA_FAILED ;
760 queue_event(smc,EVENT_RMT,RM_DUP_ADDR) ;
761 }
762 if (code_s2u & FM_SBEC)
763 smc->hw.fp.err_stats.err_bec_stat++ ;
764 if (code_s2u & FM_SCLM)
765 smc->hw.fp.err_stats.err_clm_stat++ ;
766 if (code_s2l & FM_STVXEXP)
767 smc->mib.m[MAC0].fddiMACTvxExpired_Ct++ ;
768 if ((code_s2u & (FM_SBEC|FM_SCLM))) {
769 if (!(change_s2l & FM_SRNGOP) && (smc->hw.fp.s2l & FM_SRNGOP)) {
770 mac_ring_up(smc,0) ;
771 queue_event(smc,EVENT_RMT,RM_RING_NON_OP) ;
772
773 mac_ring_up(smc,1) ;
774 queue_event(smc,EVENT_RMT,RM_RING_OP) ;
775 smc->mib.m[MAC0].fddiMACRingOp_Ct++ ;
776 }
777 }
778 if (code_s2l & FM_SPHINV)
779 smc->hw.fp.err_stats.err_phinv++ ;
780 if (code_s2l & FM_SSIFG)
781 smc->hw.fp.err_stats.err_sifg_det++ ;
782 if (code_s2l & FM_STKISS)
783 smc->hw.fp.err_stats.err_tkiss++ ;
784 if (code_s2l & FM_STKERR)
785 smc->hw.fp.err_stats.err_tkerr++ ;
786 if (code_s2l & FM_SFRMCTR)
787 smc->mib.m[MAC0].fddiMACFrame_Ct += 0x10000L ;
788 if (code_s2l & FM_SERRCTR)
789 smc->mib.m[MAC0].fddiMACError_Ct += 0x10000L ;
790 if (code_s2l & FM_SLSTCTR)
791 smc->mib.m[MAC0].fddiMACLost_Ct += 0x10000L ;
792 if (code_s2u & FM_SERRSF) {
793 SMT_PANIC(smc,SMT_E0114, SMT_E0114_MSG) ;
794 }
795mac2_end:
796 /* notice old status */
797 smc->hw.fp.s2l = code_s2l ;
798 smc->hw.fp.s2u = code_s2u ;
799 outpw(FM_A(FM_IMSK2U),~mac_imsk2u) ;
800}
801
802/*
803 * mac3_irq: receive queue 2 bits and address detection bits
804 */
805void mac3_irq(struct s_smc *smc, u_short code_s3u, u_short code_s3l)
806{
807 UNUSED(code_s3l) ;
808
809 if (code_s3u & (FM_SRCVOVR2 | /* recv. FIFO overflow */
810 FM_SRBFL2)) { /* recv. buffer full */
811 smc->hw.mac_ct.mac_r_restart_counter++ ;
812 smt_stat_counter(smc,1);
813 }
814
815
816 if (code_s3u & FM_SRPERRQ2) { /* parity error receive queue 2 */
817 SMT_PANIC(smc,SMT_E0115, SMT_E0115_MSG) ;
818 }
819 if (code_s3u & FM_SRPERRQ1) { /* parity error receive queue 2 */
820 SMT_PANIC(smc,SMT_E0116, SMT_E0116_MSG) ;
821 }
822}
823
824
825/*
826 * take formac offline
827 */
828static void formac_offline(struct s_smc *smc)
829{
830 outpw(FM_A(FM_CMDREG2),FM_IACTR) ;/* abort current transmit activity */
831
832 /* disable receive function */
833 SETMASK(FM_A(FM_MDREG1),FM_MDISRCV,FM_ADDET) ;
834
835 /* FORMAC+ 'Initialize Mode' */
836 SETMASK(FM_A(FM_MDREG1),FM_MINIT,FM_MMODE) ;
837
838 disable_formac(smc) ;
839 smc->hw.mac_ring_is_up = FALSE ;
840 smc->hw.hw_state = STOPPED ;
841}
842
843/*
844 * bring formac online
845 */
846static void formac_online(struct s_smc *smc)
847{
848 enable_formac(smc) ;
849 SETMASK(FM_A(FM_MDREG1),FM_MONLINE | FM_SELRA | MDR1INIT |
850 smc->hw.fp.rx_mode, FM_MMODE | FM_SELRA | FM_ADDRX) ;
851}
852
853/*
854 * FORMAC+ full init. (tx, rx, timer, counter, claim & beacon)
855 */
856int init_fplus(struct s_smc *smc)
857{
858 smc->hw.fp.nsa_mode = FM_MRNNSAFNMA ;
859 smc->hw.fp.rx_mode = FM_MDAMA ;
860 smc->hw.fp.group_addr = fddi_broadcast ;
861 smc->hw.fp.func_addr = 0 ;
862 smc->hw.fp.frselreg_init = 0 ;
863
864 init_driver_fplus(smc) ;
865 if (smc->s.sas == SMT_DAS)
866 smc->hw.fp.mdr3init |= FM_MENDAS ;
867
868 smc->hw.mac_ct.mac_nobuf_counter = 0 ;
869 smc->hw.mac_ct.mac_r_restart_counter = 0 ;
870
871 smc->hw.fp.fm_st1u = (HW_PTR) ADDR(B0_ST1U) ;
872 smc->hw.fp.fm_st1l = (HW_PTR) ADDR(B0_ST1L) ;
873 smc->hw.fp.fm_st2u = (HW_PTR) ADDR(B0_ST2U) ;
874 smc->hw.fp.fm_st2l = (HW_PTR) ADDR(B0_ST2L) ;
875 smc->hw.fp.fm_st3u = (HW_PTR) ADDR(B0_ST3U) ;
876 smc->hw.fp.fm_st3l = (HW_PTR) ADDR(B0_ST3L) ;
877
878 smc->hw.fp.s2l = smc->hw.fp.s2u = 0 ;
879 smc->hw.mac_ring_is_up = 0 ;
880
881 mac_counter_init(smc) ;
882
883 /* convert BCKL units to symbol time */
884 smc->hw.mac_pa.t_neg = (u_long)0 ;
885 smc->hw.mac_pa.t_pri = (u_long)0 ;
886
887 /* make sure all PCI settings are correct */
888 mac_do_pci_fix(smc) ;
889
890 return(init_mac(smc,1)) ;
891 /* enable_formac(smc) ; */
892}
893
894static int init_mac(struct s_smc *smc, int all)
895{
896 u_short t_max,x ;
897 u_long time=0 ;
898
899 /*
900 * clear memory
901 */
902 outpw(FM_A(FM_MDREG1),FM_MINIT) ; /* FORMAC+ init mode */
903 set_formac_addr(smc) ;
904 outpw(FM_A(FM_MDREG1),FM_MMEMACT) ; /* FORMAC+ memory activ mode */
905 /* Note: Mode register 2 is set here, incase parity is enabled. */
906 outpw(FM_A(FM_MDREG2),smc->hw.fp.mdr2init) ;
907
908 if (all) {
909 init_ram(smc) ;
910 }
911 else {
912 /*
913 * reset the HPI, the Master and the BMUs
914 */
915 outp(ADDR(B0_CTRL), CTRL_HPI_SET) ;
916 time = hwt_quick_read(smc) ;
917 }
918
919 /*
920 * set all pointers, frames etc
921 */
922 smt_split_up_fifo(smc) ;
923
924 init_tx(smc) ;
925 init_rx(smc) ;
926 init_rbc(smc) ;
927
928 build_claim_beacon(smc,smc->mib.m[MAC0].fddiMACT_Req) ;
929
930 /* set RX threshold */
931 /* see Errata #SN2 Phantom receive overflow */
932 outpw(FM_A(FM_FRMTHR),14<<12) ; /* switch on */
933
934 /* set formac work mode */
935 outpw(FM_A(FM_MDREG1),MDR1INIT | FM_SELRA | smc->hw.fp.rx_mode) ;
936 outpw(FM_A(FM_MDREG2),smc->hw.fp.mdr2init) ;
937 outpw(FM_A(FM_MDREG3),smc->hw.fp.mdr3init) ;
938 outpw(FM_A(FM_FRSELREG),smc->hw.fp.frselreg_init) ;
939
940 /* set timer */
941 /*
942 * errata #22 fplus:
943 * T_MAX must not be FFFE
944 * or one of FFDF, FFB8, FF91 (-0x27 etc..)
945 */
946 t_max = (u_short)(smc->mib.m[MAC0].fddiMACT_Max/32) ;
947 x = t_max/0x27 ;
948 x *= 0x27 ;
949 if ((t_max == 0xfffe) || (t_max - x == 0x16))
950 t_max-- ;
951 outpw(FM_A(FM_TMAX),(u_short)t_max) ;
952
953 /* BugFix for report #10204 */
954 if (smc->mib.m[MAC0].fddiMACTvxValue < (u_long) (- US2BCLK(52))) {
955 outpw(FM_A(FM_TVX), (u_short) (- US2BCLK(52))/255 & MB) ;
956 } else {
957 outpw(FM_A(FM_TVX),
958 (u_short)((smc->mib.m[MAC0].fddiMACTvxValue/255) & MB)) ;
959 }
960
961 outpw(FM_A(FM_CMDREG1),FM_ICLLS) ; /* clear s-frame lock */
962 outpw(FM_A(FM_CMDREG1),FM_ICLLA0) ; /* clear a-frame lock */
963 outpw(FM_A(FM_CMDREG1),FM_ICLLR); /* clear receive lock */
964
965 /* Auto unlock receice threshold for receive queue 1 and 2 */
966 outpw(FM_A(FM_UNLCKDLY),(0xff|(0xff<<8))) ;
967
968 rtm_init(smc) ; /* RT-Monitor */
969
970 if (!all) {
971 /*
972 * after 10ms, reset the BMUs and repair the rings
973 */
974 hwt_wait_time(smc,time,MS2BCLK(10)) ;
975 outpd(ADDR(B0_R1_CSR),CSR_SET_RESET) ;
976 outpd(ADDR(B0_XA_CSR),CSR_SET_RESET) ;
977 outpd(ADDR(B0_XS_CSR),CSR_SET_RESET) ;
978 outp(ADDR(B0_CTRL), CTRL_HPI_CLR) ;
979 outpd(ADDR(B0_R1_CSR),CSR_CLR_RESET) ;
980 outpd(ADDR(B0_XA_CSR),CSR_CLR_RESET) ;
981 outpd(ADDR(B0_XS_CSR),CSR_CLR_RESET) ;
982 if (!smc->hw.hw_is_64bit) {
983 outpd(ADDR(B4_R1_F), RX_WATERMARK) ;
984 outpd(ADDR(B5_XA_F), TX_WATERMARK) ;
985 outpd(ADDR(B5_XS_F), TX_WATERMARK) ;
986 }
987 smc->hw.hw_state = STOPPED ;
988 mac_drv_repair_descr(smc) ;
989 }
990 smc->hw.hw_state = STARTED ;
991
992 return(0) ;
993}
994
995
996/*
997 * called by CFM
998 */
999void config_mux(struct s_smc *smc, int mux)
1000{
1001 plc_config_mux(smc,mux) ;
1002
1003 SETMASK(FM_A(FM_MDREG1),FM_SELRA,FM_SELRA) ;
1004}
1005
1006/*
1007 * called by RMT
1008 * enable CLAIM/BEACON interrupts
1009 * (only called if these events are of interest, e.g. in DETECT state
1010 * the interrupt must not be permanently enabled
1011 * RMT calls this function periodically (timer driven polling)
1012 */
1013void sm_mac_check_beacon_claim(struct s_smc *smc)
1014{
1015 /* set formac IMSK : 0 enables irq */
1016 outpw(FM_A(FM_IMSK2U),~(mac_imsk2u | mac_beacon_imsk2u)) ;
1017 /* the driver must receive the directed beacons */
1018 formac_rcv_restart(smc) ;
1019 process_receive(smc) ;
1020}
1021
1022/*-------------------------- interface functions ----------------------------*/
1023/*
1024 * control MAC layer (called by RMT)
1025 */
1026void sm_ma_control(struct s_smc *smc, int mode)
1027{
1028 switch(mode) {
1029 case MA_OFFLINE :
1030 /* Add to make the MAC offline in RM0_ISOLATED state */
1031 formac_offline(smc) ;
1032 break ;
1033 case MA_RESET :
1034 (void)init_mac(smc,0) ;
1035 break ;
1036 case MA_BEACON :
1037 formac_online(smc) ;
1038 break ;
1039 case MA_DIRECTED :
1040 directed_beacon(smc) ;
1041 break ;
1042 case MA_TREQ :
1043 /*
1044 * no actions necessary, TREQ is already set
1045 */
1046 break ;
1047 }
1048}
1049
1050int sm_mac_get_tx_state(struct s_smc *smc)
1051{
1052 return((inpw(FM_A(FM_STMCHN))>>4)&7) ;
1053}
1054
1055/*
1056 * multicast functions
1057 */
1058
1059static struct s_fpmc* mac_get_mc_table(struct s_smc *smc,
1060 struct fddi_addr *user,
1061 struct fddi_addr *own,
1062 int del, int can)
1063{
1064 struct s_fpmc *tb ;
1065 struct s_fpmc *slot ;
1066 u_char *p ;
1067 int i ;
1068
1069 /*
1070 * set own = can(user)
1071 */
1072 *own = *user ;
1073 if (can) {
1074 p = own->a ;
1075 for (i = 0 ; i < 6 ; i++, p++)
1076 *p = canonical[*p] ;
1077 }
1078 slot = NULL;
1079 for (i = 0, tb = smc->hw.fp.mc.table ; i < FPMAX_MULTICAST ; i++, tb++){
1080 if (!tb->n) { /* not used */
1081 if (!del && !slot) /* if !del save first free */
1082 slot = tb ;
1083 continue ;
1084 }
1085 if (memcmp((char *)&tb->a,(char *)own,6))
1086 continue ;
1087 return(tb) ;
1088 }
1089 return(slot) ; /* return first free or NULL */
1090}
1091
1092/*
1093 BEGIN_MANUAL_ENTRY(if,func;others;2)
1094
1095 void mac_clear_multicast(smc)
1096 struct s_smc *smc ;
1097
1098Function DOWNCALL (SMT, fplustm.c)
1099 Clear all multicast entries
1100
1101 END_MANUAL_ENTRY()
1102 */
1103void mac_clear_multicast(struct s_smc *smc)
1104{
1105 struct s_fpmc *tb ;
1106 int i ;
1107
1108 smc->hw.fp.os_slots_used = 0 ; /* note the SMT addresses */
1109 /* will not be deleted */
1110 for (i = 0, tb = smc->hw.fp.mc.table ; i < FPMAX_MULTICAST ; i++, tb++){
1111 if (!tb->perm) {
1112 tb->n = 0 ;
1113 }
1114 }
1115}
1116
1117/*
1118 BEGIN_MANUAL_ENTRY(if,func;others;2)
1119
1120 int mac_set_func_addr(smc,f_addr)
1121 struct s_smc *smc ;
1122 u_long f_addr ;
1123
1124Function DOWNCALL (SMT, fplustm.c)
1125 Set a Token-Ring functional address, the address will
1126 be activated after calling mac_update_multicast()
1127
1128Para f_addr functional bits in non-canonical format
1129
1130Returns 0: always success
1131
1132 END_MANUAL_ENTRY()
1133 */
1134int mac_set_func_addr(struct s_smc *smc, u_long f_addr)
1135{
1136 smc->hw.fp.func_addr = f_addr ;
1137 return(0) ;
1138}
1139
1140
1141/*
1142 BEGIN_MANUAL_ENTRY(if,func;others;2)
1143
1144 int mac_add_multicast(smc,addr,can)
1145 struct s_smc *smc ;
1146 struct fddi_addr *addr ;
1147 int can ;
1148
1149Function DOWNCALL (SMC, fplustm.c)
1150 Add an entry to the multicast table
1151
1152Para addr pointer to a multicast address
1153 can = 0: the multicast address has the physical format
1154 = 1: the multicast address has the canonical format
1155 | 0x80 permanent
1156
1157Returns 0: success
1158 1: address table full
1159
1160Note After a 'driver reset' or a 'station set address' all
1161 entries of the multicast table are cleared.
1162 In this case the driver has to fill the multicast table again.
1163 After the operating system dependent module filled
1164 the multicast table it must call mac_update_multicast
1165 to activate the new multicast addresses!
1166
1167 END_MANUAL_ENTRY()
1168 */
1169int mac_add_multicast(struct s_smc *smc, struct fddi_addr *addr, int can)
1170{
1171 SK_LOC_DECL(struct fddi_addr,own) ;
1172 struct s_fpmc *tb ;
1173
1174 /*
1175 * check if there are free table entries
1176 */
1177 if (can & 0x80) {
1178 if (smc->hw.fp.smt_slots_used >= SMT_MAX_MULTI) {
1179 return(1) ;
1180 }
1181 }
1182 else {
1183 if (smc->hw.fp.os_slots_used >= FPMAX_MULTICAST-SMT_MAX_MULTI) {
1184 return(1) ;
1185 }
1186 }
1187
1188 /*
1189 * find empty slot
1190 */
1191 if (!(tb = mac_get_mc_table(smc,addr,&own,0,can & ~0x80)))
1192 return(1) ;
1193 tb->n++ ;
1194 tb->a = own ;
1195 tb->perm = (can & 0x80) ? 1 : 0 ;
1196
1197 if (can & 0x80)
1198 smc->hw.fp.smt_slots_used++ ;
1199 else
1200 smc->hw.fp.os_slots_used++ ;
1201
1202 return(0) ;
1203}
1204
1205/*
1206 BEGIN_MANUAL_ENTRY(if,func;others;2)
1207
1208 void mac_del_multicast(smc,addr,can)
1209 struct s_smc *smc ;
1210 struct fddi_addr *addr ;
1211 int can ;
1212
1213Function DOWNCALL (SMT, fplustm.c)
1214 Delete an entry from the multicast table
1215
1216Para addr pointer to a multicast address
1217 can = 0: the multicast address has the physical format
1218 = 1: the multicast address has the canonical format
1219 | 0x80 permanent
1220
1221 END_MANUAL_ENTRY()
1222 */
1223void mac_del_multicast(struct s_smc *smc, struct fddi_addr *addr, int can)
1224{
1225 SK_LOC_DECL(struct fddi_addr,own) ;
1226 struct s_fpmc *tb ;
1227
1228 if (!(tb = mac_get_mc_table(smc,addr,&own,1,can & ~0x80)))
1229 return ;
1230 /*
1231 * permanent addresses must be deleted with perm bit
1232 * and vice versa
1233 */
1234 if (( tb->perm && (can & 0x80)) ||
1235 (!tb->perm && !(can & 0x80))) {
1236 /*
1237 * delete it
1238 */
1239 if (tb->n) {
1240 tb->n-- ;
1241 if (tb->perm) {
1242 smc->hw.fp.smt_slots_used-- ;
1243 }
1244 else {
1245 smc->hw.fp.os_slots_used-- ;
1246 }
1247 }
1248 }
1249}
1250
1251/*
1252 * mode
1253 */
1254
1255#define RX_MODE_PROM 0x1
1256#define RX_MODE_ALL_MULTI 0x2
1257
1258/*
1259 BEGIN_MANUAL_ENTRY(if,func;others;2)
1260
1261 void mac_update_multicast(smc)
1262 struct s_smc *smc ;
1263
1264Function DOWNCALL (SMT, fplustm.c)
1265 Update FORMAC multicast registers
1266
1267 END_MANUAL_ENTRY()
1268 */
1269void mac_update_multicast(struct s_smc *smc)
1270{
1271 struct s_fpmc *tb ;
1272 u_char *fu ;
1273 int i ;
1274
1275 /*
1276 * invalidate the CAM
1277 */
1278 outpw(FM_A(FM_AFCMD),FM_IINV_CAM) ;
1279
1280 /*
1281 * set the functional address
1282 */
1283 if (smc->hw.fp.func_addr) {
1284 fu = (u_char *) &smc->hw.fp.func_addr ;
1285 outpw(FM_A(FM_AFMASK2),0xffff) ;
1286 outpw(FM_A(FM_AFMASK1),(u_short) ~((fu[0] << 8) + fu[1])) ;
1287 outpw(FM_A(FM_AFMASK0),(u_short) ~((fu[2] << 8) + fu[3])) ;
1288 outpw(FM_A(FM_AFPERS),FM_VALID|FM_DA) ;
1289 outpw(FM_A(FM_AFCOMP2), 0xc000) ;
1290 outpw(FM_A(FM_AFCOMP1), 0x0000) ;
1291 outpw(FM_A(FM_AFCOMP0), 0x0000) ;
1292 outpw(FM_A(FM_AFCMD),FM_IWRITE_CAM) ;
1293 }
1294
1295 /*
1296 * set the mask and the personality register(s)
1297 */
1298 outpw(FM_A(FM_AFMASK0),0xffff) ;
1299 outpw(FM_A(FM_AFMASK1),0xffff) ;
1300 outpw(FM_A(FM_AFMASK2),0xffff) ;
1301 outpw(FM_A(FM_AFPERS),FM_VALID|FM_DA) ;
1302
1303 for (i = 0, tb = smc->hw.fp.mc.table; i < FPMAX_MULTICAST; i++, tb++) {
1304 if (tb->n) {
1305 CHECK_CAM() ;
1306
1307 /*
1308 * write the multicast address into the CAM
1309 */
1310 outpw(FM_A(FM_AFCOMP2),
1311 (u_short)((tb->a.a[0]<<8)+tb->a.a[1])) ;
1312 outpw(FM_A(FM_AFCOMP1),
1313 (u_short)((tb->a.a[2]<<8)+tb->a.a[3])) ;
1314 outpw(FM_A(FM_AFCOMP0),
1315 (u_short)((tb->a.a[4]<<8)+tb->a.a[5])) ;
1316 outpw(FM_A(FM_AFCMD),FM_IWRITE_CAM) ;
1317 }
1318 }
1319}
1320
1321/*
1322 BEGIN_MANUAL_ENTRY(if,func;others;3)
1323
1324 void mac_set_rx_mode(smc,mode)
1325 struct s_smc *smc ;
1326 int mode ;
1327
1328Function DOWNCALL/INTERN (SMT, fplustm.c)
1329 This function enables / disables the selected receive.
1330 Don't call this function if the hardware module is
1331 used -- use mac_drv_rx_mode() instead of.
1332
1333Para mode = 1 RX_ENABLE_ALLMULTI enable all multicasts
1334 2 RX_DISABLE_ALLMULTI disable "enable all multicasts"
1335 3 RX_ENABLE_PROMISC enable promiscous
1336 4 RX_DISABLE_PROMISC disable promiscous
1337 5 RX_ENABLE_NSA enable reception of NSA frames
1338 6 RX_DISABLE_NSA disable reception of NSA frames
1339
1340Note The selected receive modes will be lost after 'driver reset'
1341 or 'set station address'
1342
1343 END_MANUAL_ENTRY
1344 */
1345void mac_set_rx_mode(struct s_smc *smc, int mode)
1346{
1347 switch (mode) {
1348 case RX_ENABLE_ALLMULTI :
1349 smc->hw.fp.rx_prom |= RX_MODE_ALL_MULTI ;
1350 break ;
1351 case RX_DISABLE_ALLMULTI :
1352 smc->hw.fp.rx_prom &= ~RX_MODE_ALL_MULTI ;
1353 break ;
1354 case RX_ENABLE_PROMISC :
1355 smc->hw.fp.rx_prom |= RX_MODE_PROM ;
1356 break ;
1357 case RX_DISABLE_PROMISC :
1358 smc->hw.fp.rx_prom &= ~RX_MODE_PROM ;
1359 break ;
1360 case RX_ENABLE_NSA :
1361 smc->hw.fp.nsa_mode = FM_MDAMA ;
1362 smc->hw.fp.rx_mode = (smc->hw.fp.rx_mode & ~FM_ADDET) |
1363 smc->hw.fp.nsa_mode ;
1364 break ;
1365 case RX_DISABLE_NSA :
1366 smc->hw.fp.nsa_mode = FM_MRNNSAFNMA ;
1367 smc->hw.fp.rx_mode = (smc->hw.fp.rx_mode & ~FM_ADDET) |
1368 smc->hw.fp.nsa_mode ;
1369 break ;
1370 }
1371 if (smc->hw.fp.rx_prom & RX_MODE_PROM) {
1372 smc->hw.fp.rx_mode = FM_MLIMPROM ;
1373 }
1374 else if (smc->hw.fp.rx_prom & RX_MODE_ALL_MULTI) {
1375 smc->hw.fp.rx_mode = smc->hw.fp.nsa_mode | FM_EXGPA0 ;
1376 }
1377 else
1378 smc->hw.fp.rx_mode = smc->hw.fp.nsa_mode ;
1379 SETMASK(FM_A(FM_MDREG1),smc->hw.fp.rx_mode,FM_ADDRX) ;
1380 mac_update_multicast(smc) ;
1381}
1382
1383/*
1384 BEGIN_MANUAL_ENTRY(module;tests;3)
1385 How to test the Restricted Token Monitor
1386 ----------------------------------------------------------------
1387
1388 o Insert a break point in the function rtm_irq()
1389 o Remove all stations with a restricted token monitor from the
1390 network.
1391 o Connect a UPPS ISA or EISA station to the network.
1392 o Give the FORMAC of UPPS station the command to send
1393 restricted tokens until the ring becomes instable.
1394 o Now connect your test test client.
1395 o The restricted token monitor should detect the restricted token,
1396 and your break point will be reached.
1397 o You can ovserve how the station will clean the ring.
1398
1399 END_MANUAL_ENTRY
1400 */
1401void rtm_irq(struct s_smc *smc)
1402{
1403 outpw(ADDR(B2_RTM_CRTL),TIM_CL_IRQ) ; /* clear IRQ */
1404 if (inpw(ADDR(B2_RTM_CRTL)) & TIM_RES_TOK) {
1405 outpw(FM_A(FM_CMDREG1),FM_ICL) ; /* force claim */
1406 DB_RMT("RMT: fddiPATHT_Rmode expired\n",0,0) ;
1407 AIX_EVENT(smc, (u_long) FDDI_RING_STATUS,
1408 (u_long) FDDI_SMT_EVENT,
1409 (u_long) FDDI_RTT, smt_get_event_word(smc));
1410 }
1411 outpw(ADDR(B2_RTM_CRTL),TIM_START) ; /* enable RTM monitoring */
1412}
1413
1414static void rtm_init(struct s_smc *smc)
1415{
1416 outpd(ADDR(B2_RTM_INI),0) ; /* timer = 0 */
1417 outpw(ADDR(B2_RTM_CRTL),TIM_START) ; /* enable IRQ */
1418}
1419
1420void rtm_set_timer(struct s_smc *smc)
1421{
1422 /*
1423 * MIB timer and hardware timer have the same resolution of 80nS
1424 */
1425 DB_RMT("RMT: setting new fddiPATHT_Rmode, t = %d ns \n",
1426 (int) smc->mib.a[PATH0].fddiPATHT_Rmode,0) ;
1427 outpd(ADDR(B2_RTM_INI),smc->mib.a[PATH0].fddiPATHT_Rmode) ;
1428}
1429
1430static void smt_split_up_fifo(struct s_smc *smc)
1431{
1432
1433/*
1434 BEGIN_MANUAL_ENTRY(module;mem;1)
1435 -------------------------------------------------------------
1436 RECEIVE BUFFER MEMORY DIVERSION
1437 -------------------------------------------------------------
1438
1439 R1_RxD == SMT_R1_RXD_COUNT
1440 R2_RxD == SMT_R2_RXD_COUNT
1441
1442 SMT_R1_RXD_COUNT must be unequal zero
1443
1444 | R1_RxD R2_RxD |R1_RxD R2_RxD | R1_RxD R2_RxD
1445 | x 0 | x 1-3 | x < 3
1446 ----------------------------------------------------------------------
1447 | 63,75 kB | 54,75 | R1_RxD
1448 rx queue 1 | RX_FIFO_SPACE | RX_LARGE_FIFO| ------------- * 63,75 kB
1449 | | | R1_RxD+R2_RxD
1450 ----------------------------------------------------------------------
1451 | | 9 kB | R2_RxD
1452 rx queue 2 | 0 kB | RX_SMALL_FIFO| ------------- * 63,75 kB
1453 | (not used) | | R1_RxD+R2_RxD
1454
1455 END_MANUAL_ENTRY
1456*/
1457
1458 if (SMT_R1_RXD_COUNT == 0) {
1459 SMT_PANIC(smc,SMT_E0117, SMT_E0117_MSG) ;
1460 }
1461
1462 switch(SMT_R2_RXD_COUNT) {
1463 case 0:
1464 smc->hw.fp.fifo.rx1_fifo_size = RX_FIFO_SPACE ;
1465 smc->hw.fp.fifo.rx2_fifo_size = 0 ;
1466 break ;
1467 case 1:
1468 case 2:
1469 case 3:
1470 smc->hw.fp.fifo.rx1_fifo_size = RX_LARGE_FIFO ;
1471 smc->hw.fp.fifo.rx2_fifo_size = RX_SMALL_FIFO ;
1472 break ;
1473 default: /* this is not the real defaule */
1474 smc->hw.fp.fifo.rx1_fifo_size = RX_FIFO_SPACE *
1475 SMT_R1_RXD_COUNT/(SMT_R1_RXD_COUNT+SMT_R2_RXD_COUNT) ;
1476 smc->hw.fp.fifo.rx2_fifo_size = RX_FIFO_SPACE *
1477 SMT_R2_RXD_COUNT/(SMT_R1_RXD_COUNT+SMT_R2_RXD_COUNT) ;
1478 break ;
1479 }
1480
1481/*
1482 BEGIN_MANUAL_ENTRY(module;mem;1)
1483 -------------------------------------------------------------
1484 TRANSMIT BUFFER MEMORY DIVERSION
1485 -------------------------------------------------------------
1486
1487
1488 | no sync bw | sync bw available and | sync bw available and
1489 | available | SynchTxMode = SPLIT | SynchTxMode = ALL
1490 -----------------------------------------------------------------------
1491 sync tx | 0 kB | 32 kB | 55 kB
1492 queue | | TX_MEDIUM_FIFO | TX_LARGE_FIFO
1493 -----------------------------------------------------------------------
1494 async tx | 64 kB | 32 kB | 9 k
1495 queue | TX_FIFO_SPACE| TX_MEDIUM_FIFO | TX_SMALL_FIFO
1496
1497 END_MANUAL_ENTRY
1498*/
1499
1500 /*
1501 * set the tx mode bits
1502 */
1503 if (smc->mib.a[PATH0].fddiPATHSbaPayload) {
1504#ifdef ESS
1505 smc->hw.fp.fifo.fifo_config_mode |=
1506 smc->mib.fddiESSSynchTxMode | SYNC_TRAFFIC_ON ;
1507#endif
1508 }
1509 else {
1510 smc->hw.fp.fifo.fifo_config_mode &=
1511 ~(SEND_ASYNC_AS_SYNC|SYNC_TRAFFIC_ON) ;
1512 }
1513
1514 /*
1515 * split up the FIFO
1516 */
1517 if (smc->hw.fp.fifo.fifo_config_mode & SYNC_TRAFFIC_ON) {
1518 if (smc->hw.fp.fifo.fifo_config_mode & SEND_ASYNC_AS_SYNC) {
1519 smc->hw.fp.fifo.tx_s_size = TX_LARGE_FIFO ;
1520 smc->hw.fp.fifo.tx_a0_size = TX_SMALL_FIFO ;
1521 }
1522 else {
1523 smc->hw.fp.fifo.tx_s_size = TX_MEDIUM_FIFO ;
1524 smc->hw.fp.fifo.tx_a0_size = TX_MEDIUM_FIFO ;
1525 }
1526 }
1527 else {
1528 smc->hw.fp.fifo.tx_s_size = 0 ;
1529 smc->hw.fp.fifo.tx_a0_size = TX_FIFO_SPACE ;
1530 }
1531
1532 smc->hw.fp.fifo.rx1_fifo_start = smc->hw.fp.fifo.rbc_ram_start +
1533 RX_FIFO_OFF ;
1534 smc->hw.fp.fifo.tx_s_start = smc->hw.fp.fifo.rx1_fifo_start +
1535 smc->hw.fp.fifo.rx1_fifo_size ;
1536 smc->hw.fp.fifo.tx_a0_start = smc->hw.fp.fifo.tx_s_start +
1537 smc->hw.fp.fifo.tx_s_size ;
1538 smc->hw.fp.fifo.rx2_fifo_start = smc->hw.fp.fifo.tx_a0_start +
1539 smc->hw.fp.fifo.tx_a0_size ;
1540
1541 DB_SMT("FIFO split: mode = %x\n",smc->hw.fp.fifo.fifo_config_mode,0) ;
1542 DB_SMT("rbc_ram_start = %x rbc_ram_end = %x\n",
1543 smc->hw.fp.fifo.rbc_ram_start, smc->hw.fp.fifo.rbc_ram_end) ;
1544 DB_SMT("rx1_fifo_start = %x tx_s_start = %x\n",
1545 smc->hw.fp.fifo.rx1_fifo_start, smc->hw.fp.fifo.tx_s_start) ;
1546 DB_SMT("tx_a0_start = %x rx2_fifo_start = %x\n",
1547 smc->hw.fp.fifo.tx_a0_start, smc->hw.fp.fifo.rx2_fifo_start) ;
1548}
1549
1550void formac_reinit_tx(struct s_smc *smc)
1551{
1552 /*
1553 * Split up the FIFO and reinitialize the MAC if synchronous
1554 * bandwidth becomes available but no synchronous queue is
1555 * configured.
1556 */
1557 if (!smc->hw.fp.fifo.tx_s_size && smc->mib.a[PATH0].fddiPATHSbaPayload){
1558 (void)init_mac(smc,0) ;
1559 }
1560}
1561
diff --git a/drivers/net/skfp/h/cmtdef.h b/drivers/net/skfp/h/cmtdef.h
new file mode 100644
index 000000000000..603982debc71
--- /dev/null
+++ b/drivers/net/skfp/h/cmtdef.h
@@ -0,0 +1,763 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * The information in this file is provided "AS IS" without warranty.
12 *
13 ******************************************************************************/
14
15#ifndef _CMTDEF_
16#define _CMTDEF_
17
18/* **************************************************************** */
19
20/*
21 * implementation specific constants
22 * MODIIFY THE FOLLWOING THREE DEFINES
23 */
24#define AMDPLC /* if Amd PLC chip used */
25#ifdef CONC
26#define NUMPHYS 12 /* 2 for SAS or DAS, more for Concentrator */
27#else
28#ifdef CONC_II
29#define NUMPHYS 24 /* 2 for SAS or DAS, more for Concentrator */
30#else
31#define NUMPHYS 2 /* 2 for SAS or DAS, more for Concentrator */
32#endif
33#endif
34#define NUMMACS 1 /* only 1 supported at the moment */
35#define NUMPATHS 2 /* primary and secondary path supported */
36
37/*
38 * DO NOT MODIFY BEYOND THIS POINT
39 */
40
41/* **************************************************************** */
42
43#if NUMPHYS > 2
44#define CONCENTRATOR
45#endif
46
47/*
48 * Definitions for comfortable LINT usage
49 */
50#ifdef lint
51#define LINT_USE(x) (x)=(x)
52#else
53#define LINT_USE(x)
54#endif
55
56#ifdef DEBUG
57#define DB_PR(flag,a,b,c) { if (flag) printf(a,b,c) ; }
58#else
59#define DB_PR(flag,a,b,c)
60#endif
61
62#ifdef DEBUG_BRD
63#define DB_ECM(a,b,c) DB_PR((smc->debug.d_smt&1),a,b,c)
64#define DB_ECMN(n,a,b,c) DB_PR((smc->debug.d_ecm >=(n)),a,b,c)
65#define DB_RMT(a,b,c) DB_PR((smc->debug.d_smt&2),a,b,c)
66#define DB_RMTN(n,a,b,c) DB_PR((smc->debug.d_rmt >=(n)),a,b,c)
67#define DB_CFM(a,b,c) DB_PR((smc->debug.d_smt&4),a,b,c)
68#define DB_CFMN(n,a,b,c) DB_PR((smc->debug.d_cfm >=(n)),a,b,c)
69#define DB_PCM(a,b,c) DB_PR((smc->debug.d_smt&8),a,b,c)
70#define DB_PCMN(n,a,b,c) DB_PR((smc->debug.d_pcm >=(n)),a,b,c)
71#define DB_SMT(a,b,c) DB_PR((smc->debug.d_smtf),a,b,c)
72#define DB_SMTN(n,a,b,c) DB_PR((smc->debug.d_smtf >=(n)),a,b,c)
73#define DB_SBA(a,b,c) DB_PR((smc->debug.d_sba),a,b,c)
74#define DB_SBAN(n,a,b,c) DB_PR((smc->debug.d_sba >=(n)),a,b,c)
75#define DB_ESS(a,b,c) DB_PR((smc->debug.d_ess),a,b,c)
76#define DB_ESSN(n,a,b,c) DB_PR((smc->debug.d_ess >=(n)),a,b,c)
77#else
78#define DB_ECM(a,b,c) DB_PR((debug.d_smt&1),a,b,c)
79#define DB_ECMN(n,a,b,c) DB_PR((debug.d_ecm >=(n)),a,b,c)
80#define DB_RMT(a,b,c) DB_PR((debug.d_smt&2),a,b,c)
81#define DB_RMTN(n,a,b,c) DB_PR((debug.d_rmt >=(n)),a,b,c)
82#define DB_CFM(a,b,c) DB_PR((debug.d_smt&4),a,b,c)
83#define DB_CFMN(n,a,b,c) DB_PR((debug.d_cfm >=(n)),a,b,c)
84#define DB_PCM(a,b,c) DB_PR((debug.d_smt&8),a,b,c)
85#define DB_PCMN(n,a,b,c) DB_PR((debug.d_pcm >=(n)),a,b,c)
86#define DB_SMT(a,b,c) DB_PR((debug.d_smtf),a,b,c)
87#define DB_SMTN(n,a,b,c) DB_PR((debug.d_smtf >=(n)),a,b,c)
88#define DB_SBA(a,b,c) DB_PR((debug.d_sba),a,b,c)
89#define DB_SBAN(n,a,b,c) DB_PR((debug.d_sba >=(n)),a,b,c)
90#define DB_ESS(a,b,c) DB_PR((debug.d_ess),a,b,c)
91#define DB_ESSN(n,a,b,c) DB_PR((debug.d_ess >=(n)),a,b,c)
92#endif
93
94#ifndef SS_NOT_DS
95#define SK_LOC_DECL(type,var) type var
96#else
97#define SK_LOC_DECL(type,var) static type var
98#endif
99/*
100 * PHYs and PORTS
101 * Note: Don't touch the definition of PA and PB. Those might be used
102 * by some "for" loops.
103 */
104#define PA 0
105#define PB 1
106#if defined(SUPERNET_3) || defined(CONC_II)
107/*
108 * The port indices have to be different,
109 * because the MAC output goes through the 2. PLC
110 * Conc II: It has to be the first port in the row.
111 */
112#define PS 0 /* Internal PLC which is the same as PA */
113#else
114#define PS 1
115#endif
116#define PM 2 /* PM .. PA+NUM_PHYS-1 */
117
118/*
119 * PHY types - as in path descriptor 'fddiPHYType'
120 */
121#define TA 0 /* A port */
122#define TB 1 /* B port */
123#define TS 2 /* S port */
124#define TM 3 /* M port */
125#define TNONE 4
126
127
128/*
129 * indexes in MIB
130 */
131#define INDEX_MAC 1
132#define INDEX_PATH 1
133#define INDEX_PORT 1
134
135
136/*
137 * policies
138 */
139#define POLICY_AA (1<<0) /* reject AA */
140#define POLICY_AB (1<<1) /* reject AB */
141#define POLICY_AS (1<<2) /* reject AS */
142#define POLICY_AM (1<<3) /* reject AM */
143#define POLICY_BA (1<<4) /* reject BA */
144#define POLICY_BB (1<<5) /* reject BB */
145#define POLICY_BS (1<<6) /* reject BS */
146#define POLICY_BM (1<<7) /* reject BM */
147#define POLICY_SA (1<<8) /* reject SA */
148#define POLICY_SB (1<<9) /* reject SB */
149#define POLICY_SS (1<<10) /* reject SS */
150#define POLICY_SM (1<<11) /* reject SM */
151#define POLICY_MA (1<<12) /* reject MA */
152#define POLICY_MB (1<<13) /* reject MB */
153#define POLICY_MS (1<<14) /* reject MS */
154#define POLICY_MM (1<<15) /* reject MM */
155
156/*
157 * commands
158 */
159
160/*
161 * EVENTS
162 * event classes
163 */
164#define EVENT_ECM 1 /* event class ECM */
165#define EVENT_CFM 2 /* event class CFM */
166#define EVENT_RMT 3 /* event class RMT */
167#define EVENT_SMT 4 /* event class SMT */
168#define EVENT_PCM 5 /* event class PCM */
169#define EVENT_PCMA 5 /* event class PCMA */
170#define EVENT_PCMB 6 /* event class PCMB */
171
172/* WARNING :
173 * EVENT_PCM* must be last in the above list
174 * if more than two ports are used, EVENT_PCM .. EVENT_PCMA+NUM_PHYS-1
175 * are used !
176 */
177
178#define EV_TOKEN(class,event) (((u_long)(class)<<16L)|((u_long)(event)))
179#define EV_T_CLASS(token) ((int)((token)>>16)&0xffff)
180#define EV_T_EVENT(token) ((int)(token)&0xffff)
181
182/*
183 * ECM events
184 */
185#define EC_CONNECT 1 /* connect request */
186#define EC_DISCONNECT 2 /* disconnect request */
187#define EC_TRACE_PROP 3 /* trace propagation */
188#define EC_PATH_TEST 4 /* path test */
189#define EC_TIMEOUT_TD 5 /* timer TD_min */
190#define EC_TIMEOUT_TMAX 6 /* timer trace_max */
191#define EC_TIMEOUT_IMAX 7 /* timer I_max */
192#define EC_TIMEOUT_INMAX 8 /* timer IN_max */
193#define EC_TEST_DONE 9 /* path test done */
194
195/*
196 * CFM events
197 */
198#define CF_LOOP 1 /* cf_loop flag from PCM */
199#define CF_LOOP_A 1 /* cf_loop flag from PCM */
200#define CF_LOOP_B 2 /* cf_loop flag from PCM */
201#define CF_JOIN 3 /* cf_join flag from PCM */
202#define CF_JOIN_A 3 /* cf_join flag from PCM */
203#define CF_JOIN_B 4 /* cf_join flag from PCM */
204
205/*
206 * PCM events
207 */
208#define PC_START 1
209#define PC_STOP 2
210#define PC_LOOP 3
211#define PC_JOIN 4
212#define PC_SIGNAL 5
213#define PC_REJECT 6
214#define PC_MAINT 7
215#define PC_TRACE 8
216#define PC_PDR 9
217#define PC_ENABLE 10
218#define PC_DISABLE 11
219
220/*
221 * must be ordered as in LineStateType
222 */
223#define PC_QLS 12
224#define PC_ILS 13
225#define PC_MLS 14
226#define PC_HLS 15
227#define PC_LS_PDR 16
228#define PC_LS_NONE 17
229#define LS2MIB(x) ((x)-PC_QLS)
230#define MIB2LS(x) ((x)+PC_QLS)
231
232#define PC_TIMEOUT_TB_MAX 18 /* timer TB_max */
233#define PC_TIMEOUT_TB_MIN 19 /* timer TB_min */
234#define PC_TIMEOUT_C_MIN 20 /* timer C_Min */
235#define PC_TIMEOUT_T_OUT 21 /* timer T_Out */
236#define PC_TIMEOUT_TL_MIN 22 /* timer TL_Min */
237#define PC_TIMEOUT_T_NEXT 23 /* timer t_next[] */
238#define PC_TIMEOUT_LCT 24
239#define PC_NSE 25 /* NOISE hardware timer */
240#define PC_LEM 26 /* LEM done */
241
242/*
243 * RMT events meaning from
244 */
245#define RM_RING_OP 1 /* ring operational MAC */
246#define RM_RING_NON_OP 2 /* ring not operational MAC */
247#define RM_MY_BEACON 3 /* recvd my beacon MAC */
248#define RM_OTHER_BEACON 4 /* recvd other beacon MAC */
249#define RM_MY_CLAIM 5 /* recvd my claim MAC */
250#define RM_TRT_EXP 6 /* TRT exp MAC */
251#define RM_VALID_CLAIM 7 /* claim from dup addr MAC */
252#define RM_JOIN 8 /* signal rm_join CFM */
253#define RM_LOOP 9 /* signal rm_loop CFM */
254#define RM_DUP_ADDR 10 /* dup_addr_test hange SMT-NIF */
255#define RM_ENABLE_FLAG 11 /* enable flag */
256
257#define RM_TIMEOUT_NON_OP 12 /* timeout T_Non_OP */
258#define RM_TIMEOUT_T_STUCK 13 /* timeout T_Stuck */
259#define RM_TIMEOUT_ANNOUNCE 14 /* timeout T_Announce */
260#define RM_TIMEOUT_T_DIRECT 15 /* timeout T_Direct */
261#define RM_TIMEOUT_D_MAX 16 /* timeout D_Max */
262#define RM_TIMEOUT_POLL 17 /* claim/beacon poller */
263#define RM_TX_STATE_CHANGE 18 /* To restart timer for D_Max */
264
265/*
266 * SMT events
267 */
268#define SM_TIMER 1 /* timer */
269#define SM_FAST 2 /* smt_force_irq */
270
271/* PC modes */
272#define PM_NONE 0
273#define PM_PEER 1
274#define PM_TREE 2
275
276/*
277 * PCM withhold codes
278 * MIB PC-WithholdType ENUM
279 */
280#define PC_WH_NONE 0 /* ok */
281#define PC_WH_M_M 1 /* M to M */
282#define PC_WH_OTHER 2 /* other incompatible phys */
283#define PC_WH_PATH 3 /* path not available */
284/*
285 * LCT duration
286 */
287#define LC_SHORT 1 /* short LCT */
288#define LC_MEDIUM 2 /* medium LCT */
289#define LC_LONG 3 /* long LCT */
290#define LC_EXTENDED 4 /* extended LCT */
291
292/*
293 * path_test values
294 */
295#define PT_NONE 0
296#define PT_TESTING 1 /* test is running */
297#define PT_PASSED 2 /* test passed */
298#define PT_FAILED 3 /* test failed */
299#define PT_PENDING 4 /* path test follows */
300#define PT_EXITING 5 /* disconnected while in trace/leave */
301
302/*
303 * duplicate address test
304 * MIB DupAddressTest ENUM
305 */
306#define DA_NONE 0 /* */
307#define DA_PASSED 1 /* test passed */
308#define DA_FAILED 2 /* test failed */
309
310
311/*
312 * optical bypass
313 */
314#define BP_DEINSERT 0 /* disable bypass */
315#define BP_INSERT 1 /* enable bypass */
316
317/*
318 * ODL enable/disable
319 */
320#define PM_TRANSMIT_DISABLE 0 /* disable xmit */
321#define PM_TRANSMIT_ENABLE 1 /* enable xmit */
322
323/*
324 * parameter for config_mux
325 * note : number is index in config_endec table !
326 */
327#define MUX_THRUA 0 /* through A */
328#define MUX_THRUB 1 /* through B */
329#define MUX_WRAPA 2 /* wrap A */
330#define MUX_WRAPB 3 /* wrap B */
331#define MUX_ISOLATE 4 /* isolated */
332#define MUX_WRAPS 5 /* SAS */
333
334/*
335 * MAC control
336 */
337#define MA_RESET 0
338#define MA_BEACON 1
339#define MA_CLAIM 2
340#define MA_DIRECTED 3 /* directed beacon */
341#define MA_TREQ 4 /* change T_Req */
342#define MA_OFFLINE 5 /* switch MAC to offline */
343
344
345/*
346 * trace prop
347 * bit map for trace propagation
348 */
349#define ENTITY_MAC (NUMPHYS)
350#define ENTITY_PHY(p) (p)
351#define ENTITY_BIT(m) (1<<(m))
352
353/*
354 * Resource Tag Types
355 */
356#define PATH_ISO 0 /* isolated */
357#define PATH_PRIM 3 /* primary path */
358#define PATH_THRU 5 /* through path */
359
360#define RES_MAC 2 /* resource type MAC */
361#define RES_PORT 4 /* resource type PORT */
362
363
364/*
365 * CFM state
366 * oops: MUST MATCH CF-StateType in SMT7.2 !
367 */
368#define SC0_ISOLATED 0 /* isolated */
369#define SC1_WRAP_A 5 /* wrap A (not used) */
370#define SC2_WRAP_B 6 /* wrap B (not used) */
371#define SC4_THRU_A 12 /* through A */
372#define SC5_THRU_B 7 /* through B (used in SMT 6.2) */
373#define SC7_WRAP_S 8 /* SAS (not used) */
374#define SC9_C_WRAP_A 9 /* c wrap A */
375#define SC10_C_WRAP_B 10 /* c wrap B */
376#define SC11_C_WRAP_S 11 /* c wrap S */
377
378/*
379 * convert MIB time in units of 80nS to uS
380 */
381#define MIB2US(t) ((t)/12)
382#define SEC2MIB(s) ((s)*12500000L)
383/*
384 * SMT timer
385 */
386struct smt_timer {
387 struct smt_timer *tm_next ; /* linked list */
388 struct s_smc *tm_smc ; /* pointer to context */
389 u_long tm_delta ; /* delta time */
390 u_long tm_token ; /* token value */
391 u_short tm_active ; /* flag : active/inactive */
392 u_short tm_pad ; /* pad field */
393} ;
394
395/*
396 * communication structures
397 */
398struct mac_parameter {
399 u_long t_neg ; /* T_Neg parameter */
400 u_long t_pri ; /* T_Pri register in MAC */
401} ;
402
403/*
404 * MAC counters
405 */
406struct mac_counter {
407 u_long mac_nobuf_counter ; /* MAC SW counter: no buffer */
408 u_long mac_r_restart_counter ; /* MAC SW counter: rx restarted */
409} ;
410
411/*
412 * para struct context for SMT parameters
413 */
414struct s_pcon {
415 int pc_len ;
416 int pc_err ;
417 int pc_badset ;
418 void *pc_p ;
419} ;
420
421/*
422 * link error monitor
423 */
424#define LEM_AVG 5
425struct lem_counter {
426#ifdef AM29K
427 int lem_on ;
428 u_long lem_errors ;
429 u_long lem_symbols ;
430 u_long lem_tsymbols ;
431 int lem_s_count ;
432 int lem_n_s ;
433 int lem_values ;
434 int lem_index ;
435 int lem_avg_ber[LEM_AVG] ;
436 int lem_sum ;
437#else
438 u_short lem_float_ber ; /* 10E-nn bit error rate */
439 u_long lem_errors ; /* accumulated error count */
440 u_short lem_on ;
441#endif
442} ;
443
444#define NUMBITS 10
445
446#ifdef AMDPLC
447
448/*
449 * PLC state table
450 */
451struct s_plc {
452 u_short p_state ; /* current state */
453 u_short p_bits ; /* number of bits to send */
454 u_short p_start ; /* first bit pos */
455 u_short p_pad ; /* padding for alignment */
456 u_long soft_err ; /* error counter */
457 u_long parity_err ; /* error counter */
458 u_long ebuf_err ; /* error counter */
459 u_long ebuf_cont ; /* continous error counter */
460 u_long phyinv ; /* error counter */
461 u_long vsym_ctr ; /* error counter */
462 u_long mini_ctr ; /* error counter */
463 u_long tpc_exp ; /* error counter */
464 u_long np_err ; /* error counter */
465 u_long b_pcs ; /* error counter */
466 u_long b_tpc ; /* error counter */
467 u_long b_tne ; /* error counter */
468 u_long b_qls ; /* error counter */
469 u_long b_ils ; /* error counter */
470 u_long b_hls ; /* error counter */
471} ;
472#endif
473
474#ifdef PROTOTYP_INC
475#include "fddi/driver.pro"
476#else /* PROTOTYP_INC */
477/*
478 * function prototypes
479 */
480#include "h/mbuf.h" /* Type definitions for MBUFs */
481#include "h/smtstate.h" /* struct smt_state */
482
483void hwt_restart(struct s_smc *smc); /* hwt.c */
484SMbuf *smt_build_frame(struct s_smc *smc, int class, int type,
485 int length); /* smt.c */
486SMbuf *smt_get_mbuf(struct s_smc *smc); /* drvsr.c */
487void *sm_to_para(struct s_smc *smc, struct smt_header *sm,
488 int para); /* smt.c */
489
490#ifndef SK_UNUSED
491#define SK_UNUSED(var) (void)(var)
492#endif
493
494void queue_event(struct s_smc *smc, int class, int event);
495void ecm(struct s_smc *smc, int event);
496void ecm_init(struct s_smc *smc);
497void rmt(struct s_smc *smc, int event);
498void rmt_init(struct s_smc *smc);
499void pcm(struct s_smc *smc, const int np, int event);
500void pcm_init(struct s_smc *smc);
501void cfm(struct s_smc *smc, int event);
502void cfm_init(struct s_smc *smc);
503void smt_timer_start(struct s_smc *smc, struct smt_timer *timer, u_long time,
504 u_long token);
505void smt_timer_stop(struct s_smc *smc, struct smt_timer *timer);
506void pcm_status_state(struct s_smc *smc, int np, int *type, int *state,
507 int *remote, int *mac);
508void plc_config_mux(struct s_smc *smc, int mux);
509void sm_lem_evaluate(struct s_smc *smc);
510void smt_clear_una_dna(struct s_smc *smc);
511void mac_update_counter(struct s_smc *smc);
512void sm_pm_ls_latch(struct s_smc *smc, int phy, int on_off);
513void sm_ma_control(struct s_smc *smc, int mode);
514void sm_mac_check_beacon_claim(struct s_smc *smc);
515void config_mux(struct s_smc *smc, int mux);
516void smt_agent_init(struct s_smc *smc);
517void smt_timer_init(struct s_smc *smc);
518void smt_received_pack(struct s_smc *smc, SMbuf *mb, int fs);
519void smt_add_para(struct s_smc *smc, struct s_pcon *pcon, u_short para,
520 int index, int local);
521void smt_swap_para(struct smt_header *sm, int len, int direction);
522void ev_init(struct s_smc *smc);
523void hwt_init(struct s_smc *smc);
524u_long hwt_read(struct s_smc *smc);
525void hwt_stop(struct s_smc *smc);
526void hwt_start(struct s_smc *smc, u_long time);
527void smt_send_mbuf(struct s_smc *smc, SMbuf *mb, int fc);
528void smt_free_mbuf(struct s_smc *smc, SMbuf *mb);
529void sm_pm_bypass_req(struct s_smc *smc, int mode);
530void rmt_indication(struct s_smc *smc, int i);
531void cfm_state_change(struct s_smc *smc, int c_state);
532
533#if defined(DEBUG) || !defined(NO_SMT_PANIC)
534void smt_panic(struct s_smc *smc, char *text);
535#else
536#define smt_panic(smc,text)
537#endif /* DEBUG || !NO_SMT_PANIC */
538
539void smt_stat_counter(struct s_smc *smc, int stat);
540void smt_timer_poll(struct s_smc *smc);
541u_long smt_get_time(void);
542u_long smt_get_tid(struct s_smc *smc);
543void smt_timer_done(struct s_smc *smc);
544void smt_set_defaults(struct s_smc *smc);
545void smt_fixup_mib(struct s_smc *smc);
546void smt_reset_defaults(struct s_smc *smc, int level);
547void smt_agent_task(struct s_smc *smc);
548void smt_please_reconnect(struct s_smc *smc, int reconn_time);
549int smt_check_para(struct s_smc *smc, struct smt_header *sm,
550 const u_short list[]);
551void driver_get_bia(struct s_smc *smc, struct fddi_addr *bia_addr);
552
553#ifdef SUPERNET_3
554void drv_reset_indication(struct s_smc *smc);
555#endif /* SUPERNET_3 */
556
557void smt_start_watchdog(struct s_smc *smc);
558void smt_event(struct s_smc *smc, int event);
559void timer_event(struct s_smc *smc, u_long token);
560void ev_dispatcher(struct s_smc *smc);
561void pcm_get_state(struct s_smc *smc, struct smt_state *state);
562void ecm_state_change(struct s_smc *smc, int e_state);
563int sm_pm_bypass_present(struct s_smc *smc);
564void pcm_state_change(struct s_smc *smc, int plc, int p_state);
565void rmt_state_change(struct s_smc *smc, int r_state);
566int sm_pm_get_ls(struct s_smc *smc, int phy);
567int pcm_get_s_port(struct s_smc *smc);
568int pcm_rooted_station(struct s_smc *smc);
569int cfm_get_mac_input(struct s_smc *smc);
570int cfm_get_mac_output(struct s_smc *smc);
571int port_to_mib(struct s_smc *smc, int p);
572int cem_build_path(struct s_smc *smc, char *to, int path_index);
573int sm_mac_get_tx_state(struct s_smc *smc);
574char *get_pcmstate(struct s_smc *smc, int np);
575int smt_action(struct s_smc *smc, int class, int code, int index);
576u_short smt_online(struct s_smc *smc, int on);
577void smt_force_irq(struct s_smc *smc);
578void smt_pmf_received_pack(struct s_smc *smc, SMbuf *mb, int local);
579void smt_send_frame(struct s_smc *smc, SMbuf *mb, int fc, int local);
580void smt_set_timestamp(struct s_smc *smc, u_char *p);
581void mac_set_rx_mode(struct s_smc *smc, int mode);
582int mac_add_multicast(struct s_smc *smc, struct fddi_addr *addr, int can);
583int mac_set_func_addr(struct s_smc *smc, u_long f_addr);
584void mac_del_multicast(struct s_smc *smc, struct fddi_addr *addr, int can);
585void mac_update_multicast(struct s_smc *smc);
586void mac_clear_multicast(struct s_smc *smc);
587void set_formac_tsync(struct s_smc *smc, long sync_bw);
588void formac_reinit_tx(struct s_smc *smc);
589void formac_tx_restart(struct s_smc *smc);
590void process_receive(struct s_smc *smc);
591void init_driver_fplus(struct s_smc *smc);
592void rtm_irq(struct s_smc *smc);
593void rtm_set_timer(struct s_smc *smc);
594void ring_status_indication(struct s_smc *smc, u_long status);
595void llc_recover_tx(struct s_smc *smc);
596void llc_restart_tx(struct s_smc *smc);
597void plc_clear_irq(struct s_smc *smc, int p);
598void plc_irq(struct s_smc *smc, int np, unsigned int cmd);
599int smt_set_mac_opvalues(struct s_smc *smc);
600
601#ifdef TAG_MODE
602void mac_drv_pci_fix(struct s_smc *smc, u_long fix_value);
603void mac_do_pci_fix(struct s_smc *smc);
604void mac_drv_clear_tx_queue(struct s_smc *smc);
605void mac_drv_repair_descr(struct s_smc *smc);
606u_long hwt_quick_read(struct s_smc *smc);
607void hwt_wait_time(struct s_smc *smc, u_long start, long duration);
608#endif
609
610#ifdef SMT_PNMI
611int pnmi_init(struct s_smc* smc);
612int pnmi_process_ndis_id(struct s_smc *smc, u_long ndis_oid, void *buf, int len,
613 int *BytesAccessed, int *BytesNeeded, u_char action);
614#endif
615
616#ifdef SBA
617#ifndef _H2INC
618void sba();
619#endif
620void sba_raf_received_pack();
621void sba_timer_poll();
622void smt_init_sba();
623#endif
624
625#ifdef ESS
626int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm,
627 int fs);
628void ess_timer_poll(struct s_smc *smc);
629void ess_para_change(struct s_smc *smc);
630#endif
631
632#ifndef BOOT
633void smt_init_evc(struct s_smc *smc);
634void smt_srf_event(struct s_smc *smc, int code, int index, int cond);
635#else
636#define smt_init_evc(smc)
637#define smt_srf_event(smc,code,index,cond)
638#endif
639
640#ifndef SMT_REAL_TOKEN_CT
641void smt_emulate_token_ct(struct s_smc *smc, int mac_index);
642#endif
643
644#if defined(DEBUG) && !defined(BOOT)
645void dump_smt(struct s_smc *smc, struct smt_header *sm, char *text);
646#else
647#define dump_smt(smc,sm,text)
648#endif
649
650#ifdef DEBUG
651char* addr_to_string(struct fddi_addr *addr);
652void dump_hex(char *p, int len);
653#endif
654
655#endif /* PROTOTYP_INC */
656
657/* PNMI default defines */
658#ifndef PNMI_INIT
659#define PNMI_INIT(smc) /* Nothing */
660#endif
661#ifndef PNMI_GET_ID
662#define PNMI_GET_ID( smc, ndis_oid, buf, len, BytesWritten, BytesNeeded ) \
663 ( 1 ? (-1) : (-1) )
664#endif
665#ifndef PNMI_SET_ID
666#define PNMI_SET_ID( smc, ndis_oid, buf, len, BytesRead, BytesNeeded, \
667 set_type) ( 1 ? (-1) : (-1) )
668#endif
669
670/*
671 * SMT_PANIC defines
672 */
673#ifndef SMT_PANIC
674#define SMT_PANIC(smc,nr,msg) smt_panic (smc, msg)
675#endif
676
677#ifndef SMT_ERR_LOG
678#define SMT_ERR_LOG(smc,nr,msg) SMT_PANIC (smc, nr, msg)
679#endif
680
681#ifndef SMT_EBASE
682#define SMT_EBASE 100
683#endif
684
685#define SMT_E0100 SMT_EBASE + 0
686#define SMT_E0100_MSG "cfm FSM: invalid ce_type"
687#define SMT_E0101 SMT_EBASE + 1
688#define SMT_E0101_MSG "CEM: case ???"
689#define SMT_E0102 SMT_EBASE + 2
690#define SMT_E0102_MSG "CEM A: invalid state"
691#define SMT_E0103 SMT_EBASE + 3
692#define SMT_E0103_MSG "CEM B: invalid state"
693#define SMT_E0104 SMT_EBASE + 4
694#define SMT_E0104_MSG "CEM M: invalid state"
695#define SMT_E0105 SMT_EBASE + 5
696#define SMT_E0105_MSG "CEM S: invalid state"
697#define SMT_E0106 SMT_EBASE + 6
698#define SMT_E0106_MSG "CFM : invalid state"
699#define SMT_E0107 SMT_EBASE + 7
700#define SMT_E0107_MSG "ECM : invalid state"
701#define SMT_E0108 SMT_EBASE + 8
702#define SMT_E0108_MSG "prop_actions : NAC in DAS CFM"
703#define SMT_E0109 SMT_EBASE + 9
704#define SMT_E0109_MSG "ST2U.FM_SERRSF error in special frame"
705#define SMT_E0110 SMT_EBASE + 10
706#define SMT_E0110_MSG "ST2U.FM_SRFRCTOV recv. count. overflow"
707#define SMT_E0111 SMT_EBASE + 11
708#define SMT_E0111_MSG "ST2U.FM_SNFSLD NP & FORMAC simult. load"
709#define SMT_E0112 SMT_EBASE + 12
710#define SMT_E0112_MSG "ST2U.FM_SRCVFRM single-frame recv.-mode"
711#define SMT_E0113 SMT_EBASE + 13
712#define SMT_E0113_MSG "FPLUS: Buffer Memory Error"
713#define SMT_E0114 SMT_EBASE + 14
714#define SMT_E0114_MSG "ST2U.FM_SERRSF error in special frame"
715#define SMT_E0115 SMT_EBASE + 15
716#define SMT_E0115_MSG "ST3L: parity error in receive queue 2"
717#define SMT_E0116 SMT_EBASE + 16
718#define SMT_E0116_MSG "ST3L: parity error in receive queue 1"
719#define SMT_E0117 SMT_EBASE + 17
720#define SMT_E0117_MSG "E_SMT_001: RxD count for receive queue 1 = 0"
721#define SMT_E0118 SMT_EBASE + 18
722#define SMT_E0118_MSG "PCM : invalid state"
723#define SMT_E0119 SMT_EBASE + 19
724#define SMT_E0119_MSG "smt_add_para"
725#define SMT_E0120 SMT_EBASE + 20
726#define SMT_E0120_MSG "smt_set_para"
727#define SMT_E0121 SMT_EBASE + 21
728#define SMT_E0121_MSG "invalid event in dispatcher"
729#define SMT_E0122 SMT_EBASE + 22
730#define SMT_E0122_MSG "RMT : invalid state"
731#define SMT_E0123 SMT_EBASE + 23
732#define SMT_E0123_MSG "SBA: state machine has invalid state"
733#define SMT_E0124 SMT_EBASE + 24
734#define SMT_E0124_MSG "sba_free_session() called with NULL pointer"
735#define SMT_E0125 SMT_EBASE + 25
736#define SMT_E0125_MSG "SBA : invalid session pointer"
737#define SMT_E0126 SMT_EBASE + 26
738#define SMT_E0126_MSG "smt_free_mbuf() called with NULL pointer\n"
739#define SMT_E0127 SMT_EBASE + 27
740#define SMT_E0127_MSG "sizeof evcs"
741#define SMT_E0128 SMT_EBASE + 28
742#define SMT_E0128_MSG "evc->evc_cond_state = 0"
743#define SMT_E0129 SMT_EBASE + 29
744#define SMT_E0129_MSG "evc->evc_multiple = 0"
745#define SMT_E0130 SMT_EBASE + 30
746#define SMT_E0130_MSG write_mdr_warning
747#define SMT_E0131 SMT_EBASE + 31
748#define SMT_E0131_MSG cam_warning
749#define SMT_E0132 SMT_EBASE + 32
750#define SMT_E0132_MSG "ST1L.FM_SPCEPDx parity/coding error"
751#define SMT_E0133 SMT_EBASE + 33
752#define SMT_E0133_MSG "ST1L.FM_STBURx tx buffer underrun"
753#define SMT_E0134 SMT_EBASE + 34
754#define SMT_E0134_MSG "ST1L.FM_SPCEPDx parity error"
755#define SMT_E0135 SMT_EBASE + 35
756#define SMT_E0135_MSG "RMT: duplicate MAC address detected. Ring left!"
757#define SMT_E0136 SMT_EBASE + 36
758#define SMT_E0136_MSG "Elasticity Buffer hang-up"
759#define SMT_E0137 SMT_EBASE + 37
760#define SMT_E0137_MSG "SMT: queue overrun"
761#define SMT_E0138 SMT_EBASE + 38
762#define SMT_E0138_MSG "RMT: duplicate MAC address detected. Ring NOT left!"
763#endif /* _CMTDEF_ */
diff --git a/drivers/net/skfp/h/fddi.h b/drivers/net/skfp/h/fddi.h
new file mode 100644
index 000000000000..c9a28a8a383b
--- /dev/null
+++ b/drivers/net/skfp/h/fddi.h
@@ -0,0 +1,69 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * The information in this file is provided "AS IS" without warranty.
12 *
13 ******************************************************************************/
14
15#ifndef _FDDI_
16#define _FDDI_
17
18struct fddi_addr {
19 u_char a[6] ;
20} ;
21
22#define GROUP_ADDR 0x80 /* MSB in a[0] */
23
24struct fddi_mac {
25 struct fddi_addr mac_dest ;
26 struct fddi_addr mac_source ;
27 u_char mac_info[4478] ;
28} ;
29
30#define FDDI_MAC_SIZE (12)
31#define FDDI_RAW_MTU (4500-5) /* exl. Pr,SD, ED/FS */
32#define FDDI_RAW (4500)
33
34/*
35 * FC values
36 */
37#define FC_VOID 0x40 /* void frame */
38#define FC_TOKEN 0x80 /* token */
39#define FC_RES_TOKEN 0xc0 /* restricted token */
40#define FC_SMT_INFO 0x41 /* SMT Info frame */
41/*
42 * FC_SMT_LAN_LOC && FC_SMT_LOC are SK specific !
43 */
44#define FC_SMT_LAN_LOC 0x42 /* local SMT Info frame */
45#define FC_SMT_LOC 0x43 /* local SMT Info frame */
46#define FC_SMT_NSA 0x4f /* SMT NSA frame */
47#define FC_MAC 0xc0 /* MAC frame */
48#define FC_BEACON 0xc2 /* MAC beacon frame */
49#define FC_CLAIM 0xc3 /* MAC claim frame */
50#define FC_SYNC_LLC 0xd0 /* sync. LLC frame */
51#define FC_ASYNC_LLC 0x50 /* async. LLC frame */
52#define FC_SYNC_BIT 0x80 /* sync. bit in FC */
53
54#define FC_LLC_PRIOR 0x07 /* priority bits */
55
56#define BEACON_INFO 0 /* beacon type */
57#define DBEACON_INFO 1 /* beacon type DIRECTED */
58
59
60/*
61 * indicator bits
62 */
63#define C_INDICATOR (1<<0)
64#define A_INDICATOR (1<<1)
65#define E_INDICATOR (1<<2)
66#define I_INDICATOR (1<<6) /* SK specific */
67#define L_INDICATOR (1<<7) /* SK specific */
68
69#endif /* _FDDI_ */
diff --git a/drivers/net/skfp/h/fddimib.h b/drivers/net/skfp/h/fddimib.h
new file mode 100644
index 000000000000..d1acdc773950
--- /dev/null
+++ b/drivers/net/skfp/h/fddimib.h
@@ -0,0 +1,349 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * The information in this file is provided "AS IS" without warranty.
12 *
13 ******************************************************************************/
14
15/*
16 * FDDI MIB
17 */
18
19/*
20 * typedefs
21 */
22
23typedef u_long Counter ;
24typedef u_char TimeStamp[8] ;
25typedef struct fddi_addr LongAddr ;
26typedef u_long Timer_2 ;
27typedef u_long Timer ;
28typedef u_short ResId ;
29typedef u_short SMTEnum ;
30typedef u_char SMTFlag ;
31
32typedef struct {
33 Counter count ;
34 TimeStamp timestamp ;
35} SetCountType ;
36
37/*
38 * bits for bit string "available_path"
39 */
40#define MIB_PATH_P (1<<0)
41#define MIB_PATH_S (1<<1)
42#define MIB_PATH_L (1<<2)
43
44/*
45 * bits for bit string PermittedPaths & RequestedPaths (SIZE(8))
46 */
47#define MIB_P_PATH_LOCAL (1<<0)
48#define MIB_P_PATH_SEC_ALTER (1<<1)
49#define MIB_P_PATH_PRIM_ALTER (1<<2)
50#define MIB_P_PATH_CON_ALTER (1<<3)
51#define MIB_P_PATH_SEC_PREFER (1<<4)
52#define MIB_P_PATH_PRIM_PREFER (1<<5)
53#define MIB_P_PATH_CON_PREFER (1<<6)
54#define MIB_P_PATH_THRU (1<<7)
55
56/*
57 * enum current path
58 */
59#define MIB_PATH_ISOLATED 0
60#define MIB_PATH_LOCAL 1
61#define MIB_PATH_SECONDARY 2
62#define MIB_PATH_PRIMARY 3
63#define MIB_PATH_CONCATENATED 4
64#define MIB_PATH_THRU 5
65
66/*
67 * enum PMDClass
68 */
69#define MIB_PMDCLASS_MULTI 0
70#define MIB_PMDCLASS_SINGLE1 1
71#define MIB_PMDCLASS_SINGLE2 2
72#define MIB_PMDCLASS_SONET 3
73#define MIB_PMDCLASS_LCF 4
74#define MIB_PMDCLASS_TP 5
75#define MIB_PMDCLASS_UNKNOWN 6
76#define MIB_PMDCLASS_UNSPEC 7
77
78/*
79 * enum SMTStationStatus
80 */
81#define MIB_SMT_STASTA_CON 0
82#define MIB_SMT_STASTA_SEPA 1
83#define MIB_SMT_STASTA_THRU 2
84
85
86struct fddi_mib {
87 /*
88 * private
89 */
90 u_char fddiPRPMFPasswd[8] ;
91 struct smt_sid fddiPRPMFStation ;
92
93#ifdef ESS
94 /*
95 * private variables for static allocation of the
96 * End Station Support
97 */
98 u_long fddiESSPayload ; /* payload for static alloc */
99 u_long fddiESSOverhead ; /* frame ov for static alloc */
100 u_long fddiESSMaxTNeg ; /* maximum of T-NEG */
101 u_long fddiESSMinSegmentSize ; /* min size of the sync frames */
102 u_long fddiESSCategory ; /* category for the Alloc req */
103 short fddiESSSynchTxMode ; /* send all LLC frames as sync */
104#endif /* ESS */
105#ifdef SBA
106 /*
107 * private variables for the Synchronous Bandwidth Allocator
108 */
109 char fddiSBACommand ; /* holds the parsed SBA cmd */
110 u_char fddiSBAAvailable ; /* SBA allocatable value */
111#endif /* SBA */
112
113 /*
114 * SMT standard mib
115 */
116 struct smt_sid fddiSMTStationId ;
117 u_short fddiSMTOpVersionId ;
118 u_short fddiSMTHiVersionId ;
119 u_short fddiSMTLoVersionId ;
120 u_char fddiSMTManufacturerData[32] ;
121 u_char fddiSMTUserData[32] ;
122 u_short fddiSMTMIBVersionId ;
123
124 /*
125 * ConfigGrp
126 */
127 u_char fddiSMTMac_Ct ;
128 u_char fddiSMTNonMaster_Ct ;
129 u_char fddiSMTMaster_Ct ;
130 u_char fddiSMTAvailablePaths ;
131 u_short fddiSMTConfigCapabilities ;
132 u_short fddiSMTConfigPolicy ;
133 u_short fddiSMTConnectionPolicy ;
134 u_short fddiSMTTT_Notify ;
135 u_char fddiSMTStatRptPolicy ;
136 u_long fddiSMTTrace_MaxExpiration ;
137 u_short fddiSMTPORTIndexes[NUMPHYS] ;
138 u_short fddiSMTMACIndexes ;
139 u_char fddiSMTBypassPresent ;
140
141 /*
142 * StatusGrp
143 */
144 SMTEnum fddiSMTECMState ;
145 SMTEnum fddiSMTCF_State ;
146 SMTEnum fddiSMTStationStatus ;
147 u_char fddiSMTRemoteDisconnectFlag ;
148 u_char fddiSMTPeerWrapFlag ;
149
150 /*
151 * MIBOperationGrp
152 */
153 TimeStamp fddiSMTTimeStamp ;
154 TimeStamp fddiSMTTransitionTimeStamp ;
155 SetCountType fddiSMTSetCount ;
156 struct smt_sid fddiSMTLastSetStationId ;
157
158 struct fddi_mib_m {
159 u_short fddiMACFrameStatusFunctions ;
160 Timer_2 fddiMACT_MaxCapabilitiy ;
161 Timer_2 fddiMACTVXCapabilitiy ;
162
163 /* ConfigGrp */
164 u_char fddiMACMultiple_N ; /* private */
165 u_char fddiMACMultiple_P ; /* private */
166 u_char fddiMACDuplicateAddressCond ;/* private */
167 u_char fddiMACAvailablePaths ;
168 u_short fddiMACCurrentPath ;
169 LongAddr fddiMACUpstreamNbr ;
170 LongAddr fddiMACDownstreamNbr ;
171 LongAddr fddiMACOldUpstreamNbr ;
172 LongAddr fddiMACOldDownstreamNbr ;
173 SMTEnum fddiMACDupAddressTest ;
174 u_short fddiMACRequestedPaths ;
175 SMTEnum fddiMACDownstreamPORTType ;
176 ResId fddiMACIndex ;
177
178 /* AddressGrp */
179 LongAddr fddiMACSMTAddress ;
180
181 /* OperationGrp */
182 Timer_2 fddiMACT_Min ; /* private */
183 Timer_2 fddiMACT_ReqMIB ;
184 Timer_2 fddiMACT_Req ; /* private */
185 Timer_2 fddiMACT_Neg ;
186 Timer_2 fddiMACT_MaxMIB ;
187 Timer_2 fddiMACT_Max ; /* private */
188 Timer_2 fddiMACTvxValueMIB ;
189 Timer_2 fddiMACTvxValue ; /* private */
190 Timer_2 fddiMACT_Pri0 ;
191 Timer_2 fddiMACT_Pri1 ;
192 Timer_2 fddiMACT_Pri2 ;
193 Timer_2 fddiMACT_Pri3 ;
194 Timer_2 fddiMACT_Pri4 ;
195 Timer_2 fddiMACT_Pri5 ;
196 Timer_2 fddiMACT_Pri6 ;
197
198 /* CountersGrp */
199 Counter fddiMACFrame_Ct ;
200 Counter fddiMACCopied_Ct ;
201 Counter fddiMACTransmit_Ct ;
202 Counter fddiMACToken_Ct ;
203 Counter fddiMACError_Ct ;
204 Counter fddiMACLost_Ct ;
205 Counter fddiMACTvxExpired_Ct ;
206 Counter fddiMACNotCopied_Ct ;
207 Counter fddiMACRingOp_Ct ;
208
209 Counter fddiMACSMTCopied_Ct ; /* private */
210 Counter fddiMACSMTTransmit_Ct ; /* private */
211
212 /* private for delta ratio */
213 Counter fddiMACOld_Frame_Ct ;
214 Counter fddiMACOld_Copied_Ct ;
215 Counter fddiMACOld_Error_Ct ;
216 Counter fddiMACOld_Lost_Ct ;
217 Counter fddiMACOld_NotCopied_Ct ;
218
219 /* FrameErrorConditionGrp */
220 u_short fddiMACFrameErrorThreshold ;
221 u_short fddiMACFrameErrorRatio ;
222
223 /* NotCopiedConditionGrp */
224 u_short fddiMACNotCopiedThreshold ;
225 u_short fddiMACNotCopiedRatio ;
226
227 /* StatusGrp */
228 SMTEnum fddiMACRMTState ;
229 SMTFlag fddiMACDA_Flag ;
230 SMTFlag fddiMACUNDA_Flag ;
231 SMTFlag fddiMACFrameErrorFlag ;
232 SMTFlag fddiMACNotCopiedFlag ;
233 SMTFlag fddiMACMA_UnitdataAvailable ;
234 SMTFlag fddiMACHardwarePresent ;
235 SMTFlag fddiMACMA_UnitdataEnable ;
236
237 } m[NUMMACS] ;
238#define MAC0 0
239
240 struct fddi_mib_a {
241 ResId fddiPATHIndex ;
242 u_long fddiPATHSbaPayload ;
243 u_long fddiPATHSbaOverhead ;
244 /* fddiPATHConfiguration is built on demand */
245 /* u_long fddiPATHConfiguration ; */
246 Timer fddiPATHT_Rmode ;
247 u_long fddiPATHSbaAvailable ;
248 Timer_2 fddiPATHTVXLowerBound ;
249 Timer_2 fddiPATHT_MaxLowerBound ;
250 Timer_2 fddiPATHMaxT_Req ;
251 } a[NUMPATHS] ;
252#define PATH0 0
253
254 struct fddi_mib_p {
255 /* ConfigGrp */
256 SMTEnum fddiPORTMy_Type ;
257 SMTEnum fddiPORTNeighborType ;
258 u_char fddiPORTConnectionPolicies ;
259 struct {
260 u_char T_val ;
261 u_char R_val ;
262 } fddiPORTMacIndicated ;
263 SMTEnum fddiPORTCurrentPath ;
264 /* must be 4: is 32 bit in SMT format
265 * indices :
266 * 1 none
267 * 2 tree
268 * 3 peer
269 */
270 u_char fddiPORTRequestedPaths[4] ;
271 u_short fddiPORTMACPlacement ;
272 u_char fddiPORTAvailablePaths ;
273 u_char fddiPORTConnectionCapabilities ;
274 SMTEnum fddiPORTPMDClass ;
275 ResId fddiPORTIndex ;
276
277 /* OperationGrp */
278 SMTEnum fddiPORTMaint_LS ;
279 SMTEnum fddiPORTPC_LS ;
280 u_char fddiPORTBS_Flag ;
281
282 /* ErrorCtrsGrp */
283 Counter fddiPORTLCTFail_Ct ;
284 Counter fddiPORTEBError_Ct ;
285 Counter fddiPORTOldEBError_Ct ;
286
287 /* LerGrp */
288 Counter fddiPORTLem_Reject_Ct ;
289 Counter fddiPORTLem_Ct ;
290 u_char fddiPORTLer_Estimate ;
291 u_char fddiPORTLer_Cutoff ;
292 u_char fddiPORTLer_Alarm ;
293
294 /* StatusGrp */
295 SMTEnum fddiPORTConnectState ;
296 SMTEnum fddiPORTPCMState ; /* real value */
297 SMTEnum fddiPORTPCMStateX ; /* value for MIB */
298 SMTEnum fddiPORTPC_Withhold ;
299 SMTFlag fddiPORTHardwarePresent ;
300 u_char fddiPORTLerFlag ;
301
302 u_char fddiPORTMultiple_U ; /* private */
303 u_char fddiPORTMultiple_P ; /* private */
304 u_char fddiPORTEB_Condition ; /* private */
305 } p[NUMPHYS] ;
306 struct {
307 Counter fddiPRIVECF_Req_Rx ; /* ECF req received */
308 Counter fddiPRIVECF_Reply_Rx ; /* ECF repl received */
309 Counter fddiPRIVECF_Req_Tx ; /* ECF req transm */
310 Counter fddiPRIVECF_Reply_Tx ; /* ECF repl transm */
311 Counter fddiPRIVPMF_Get_Rx ; /* PMF Get rec */
312 Counter fddiPRIVPMF_Set_Rx ; /* PMF Set rec */
313 Counter fddiPRIVRDF_Rx ; /* RDF received */
314 Counter fddiPRIVRDF_Tx ; /* RDF transmitted */
315 } priv ;
316} ;
317
318/*
319 * OIDs for statistics
320 */
321#define SMT_OID_CF_STATE 1 /* fddiSMTCF_State */
322#define SMT_OID_PCM_STATE_A 2 /* fddiPORTPCMState port A */
323#define SMT_OID_PCM_STATE_B 17 /* fddiPORTPCMState port B */
324#define SMT_OID_RMT_STATE 3 /* fddiMACRMTState */
325#define SMT_OID_UNA 4 /* fddiMACUpstreamNbr */
326#define SMT_OID_DNA 5 /* fddiMACOldDownstreamNbr */
327#define SMT_OID_ERROR_CT 6 /* fddiMACError_Ct */
328#define SMT_OID_LOST_CT 7 /* fddiMACLost_Ct */
329#define SMT_OID_LEM_CT 8 /* fddiPORTLem_Ct */
330#define SMT_OID_LEM_CT_A 11 /* fddiPORTLem_Ct port A */
331#define SMT_OID_LEM_CT_B 12 /* fddiPORTLem_Ct port B */
332#define SMT_OID_LCT_FAIL_CT 9 /* fddiPORTLCTFail_Ct */
333#define SMT_OID_LCT_FAIL_CT_A 13 /* fddiPORTLCTFail_Ct port A */
334#define SMT_OID_LCT_FAIL_CT_B 14 /* fddiPORTLCTFail_Ct port B */
335#define SMT_OID_LEM_REJECT_CT 10 /* fddiPORTLem_Reject_Ct */
336#define SMT_OID_LEM_REJECT_CT_A 15 /* fddiPORTLem_Reject_Ct port A */
337#define SMT_OID_LEM_REJECT_CT_B 16 /* fddiPORTLem_Reject_Ct port B */
338
339/*
340 * SK MIB
341 */
342#define SMT_OID_ECF_REQ_RX 20 /* ECF requests received */
343#define SMT_OID_ECF_REPLY_RX 21 /* ECF replies received */
344#define SMT_OID_ECF_REQ_TX 22 /* ECF requests transmitted */
345#define SMT_OID_ECF_REPLY_TX 23 /* ECF replies transmitted */
346#define SMT_OID_PMF_GET_RX 24 /* PMF get requests received */
347#define SMT_OID_PMF_SET_RX 25 /* PMF set requests received */
348#define SMT_OID_RDF_RX 26 /* RDF received */
349#define SMT_OID_RDF_TX 27 /* RDF transmitted */
diff --git a/drivers/net/skfp/h/fplustm.h b/drivers/net/skfp/h/fplustm.h
new file mode 100644
index 000000000000..98bbf654d12f
--- /dev/null
+++ b/drivers/net/skfp/h/fplustm.h
@@ -0,0 +1,274 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * The information in this file is provided "AS IS" without warranty.
12 *
13 ******************************************************************************/
14
15/*
16 * AMD Fplus in tag mode data structs
17 * defs for fplustm.c
18 */
19
20#ifndef _FPLUS_
21#define _FPLUS_
22
23#ifndef HW_PTR
24#define HW_PTR void __iomem *
25#endif
26
27/*
28 * fplus error statistic structure
29 */
30struct err_st {
31 u_long err_valid ; /* memory status valid */
32 u_long err_abort ; /* memory status receive abort */
33 u_long err_e_indicator ; /* error indicator */
34 u_long err_crc ; /* error detected (CRC or length) */
35 u_long err_llc_frame ; /* LLC frame */
36 u_long err_mac_frame ; /* MAC frame */
37 u_long err_smt_frame ; /* SMT frame */
38 u_long err_imp_frame ; /* implementer frame */
39 u_long err_no_buf ; /* no buffer available */
40 u_long err_too_long ; /* longer than max. buffer */
41 u_long err_bec_stat ; /* beacon state entered */
42 u_long err_clm_stat ; /* claim state entered */
43 u_long err_sifg_det ; /* short interframe gap detect */
44 u_long err_phinv ; /* PHY invalid */
45 u_long err_tkiss ; /* token issued */
46 u_long err_tkerr ; /* token error */
47} ;
48
49/*
50 * Transmit Descriptor struct
51 */
52struct s_smt_fp_txd {
53 u_int txd_tbctrl ; /* transmit buffer control */
54 u_int txd_txdscr ; /* transmit frame status word */
55 u_int txd_tbadr ; /* physical tx buffer address */
56 u_int txd_ntdadr ; /* physical pointer to the next TxD */
57#ifdef ENA_64BIT_SUP
58 u_int txd_tbadr_hi ; /* physical tx buffer addr (high dword)*/
59#endif
60 char far *txd_virt ; /* virtual pointer to the data frag */
61 /* virt pointer to the next TxD */
62 struct s_smt_fp_txd volatile far *txd_next ;
63 struct s_txd_os txd_os ; /* OS - specific struct */
64} ;
65
66/*
67 * Receive Descriptor struct
68 */
69struct s_smt_fp_rxd {
70 u_int rxd_rbctrl ; /* receive buffer control */
71 u_int rxd_rfsw ; /* receive frame status word */
72 u_int rxd_rbadr ; /* physical rx buffer address */
73 u_int rxd_nrdadr ; /* physical pointer to the next RxD */
74#ifdef ENA_64BIT_SUP
75 u_int rxd_rbadr_hi ; /* physical tx buffer addr (high dword)*/
76#endif
77 char far *rxd_virt ; /* virtual pointer to the data frag */
78 /* virt pointer to the next RxD */
79 struct s_smt_fp_rxd volatile far *rxd_next ;
80 struct s_rxd_os rxd_os ; /* OS - specific struct */
81} ;
82
83/*
84 * Descriptor Union Definition
85 */
86union s_fp_descr {
87 struct s_smt_fp_txd t ; /* pointer to the TxD */
88 struct s_smt_fp_rxd r ; /* pointer to the RxD */
89} ;
90
91/*
92 * TxD Ring Control struct
93 */
94struct s_smt_tx_queue {
95 struct s_smt_fp_txd volatile *tx_curr_put ; /* next free TxD */
96 struct s_smt_fp_txd volatile *tx_prev_put ; /* shadow put pointer */
97 struct s_smt_fp_txd volatile *tx_curr_get ; /* next TxD to release*/
98 u_short tx_free ; /* count of free TxD's */
99 u_short tx_used ; /* count of used TxD's */
100 HW_PTR tx_bmu_ctl ; /* BMU addr for tx start */
101 HW_PTR tx_bmu_dsc ; /* BMU addr for curr dsc. */
102} ;
103
104/*
105 * RxD Ring Control struct
106 */
107struct s_smt_rx_queue {
108 struct s_smt_fp_rxd volatile *rx_curr_put ; /* next RxD to queue into */
109 struct s_smt_fp_rxd volatile *rx_prev_put ; /* shadow put pointer */
110 struct s_smt_fp_rxd volatile *rx_curr_get ; /* next RxD to fill */
111 u_short rx_free ; /* count of free RxD's */
112 u_short rx_used ; /* count of used RxD's */
113 HW_PTR rx_bmu_ctl ; /* BMU addr for rx start */
114 HW_PTR rx_bmu_dsc ; /* BMU addr for curr dsc. */
115} ;
116
117#define VOID_FRAME_OFF 0x00
118#define CLAIM_FRAME_OFF 0x08
119#define BEACON_FRAME_OFF 0x10
120#define DBEACON_FRAME_OFF 0x18
121#define RX_FIFO_OFF 0x21 /* to get a prime number for */
122 /* the RX_FIFO_SPACE */
123
124#define RBC_MEM_SIZE 0x8000
125#define SEND_ASYNC_AS_SYNC 0x1
126#define SYNC_TRAFFIC_ON 0x2
127
128/* big FIFO memory */
129#define RX_FIFO_SPACE 0x4000 - RX_FIFO_OFF
130#define TX_FIFO_SPACE 0x4000
131
132#define TX_SMALL_FIFO 0x0900
133#define TX_MEDIUM_FIFO TX_FIFO_SPACE / 2
134#define TX_LARGE_FIFO TX_FIFO_SPACE - TX_SMALL_FIFO
135
136#define RX_SMALL_FIFO 0x0900
137#define RX_LARGE_FIFO RX_FIFO_SPACE - RX_SMALL_FIFO
138
139struct s_smt_fifo_conf {
140 u_short rbc_ram_start ; /* FIFO start address */
141 u_short rbc_ram_end ; /* FIFO size */
142 u_short rx1_fifo_start ; /* rx queue start address */
143 u_short rx1_fifo_size ; /* rx queue size */
144 u_short rx2_fifo_start ; /* rx queue start address */
145 u_short rx2_fifo_size ; /* rx queue size */
146 u_short tx_s_start ; /* sync queue start address */
147 u_short tx_s_size ; /* sync queue size */
148 u_short tx_a0_start ; /* async queue A0 start address */
149 u_short tx_a0_size ; /* async queue A0 size */
150 u_short fifo_config_mode ; /* FIFO configuration mode */
151} ;
152
153#define FM_ADDRX (FM_ADDET|FM_EXGPA0|FM_EXGPA1)
154
155struct s_smt_fp {
156 u_short mdr2init ; /* mode register 2 init value */
157 u_short mdr3init ; /* mode register 3 init value */
158 u_short frselreg_init ; /* frame selection register init val */
159 u_short rx_mode ; /* address mode broad/multi/promisc */
160 u_short nsa_mode ;
161 u_short rx_prom ;
162 u_short exgpa ;
163
164 struct err_st err_stats ; /* error statistics */
165
166 /*
167 * MAC buffers
168 */
169 struct fddi_mac_sf { /* special frame build buffer */
170 u_char mac_fc ;
171 struct fddi_addr mac_dest ;
172 struct fddi_addr mac_source ;
173 u_char mac_info[0x20] ;
174 } mac_sfb ;
175
176
177 /*
178 * queues
179 */
180#define QUEUE_S 0
181#define QUEUE_A0 1
182#define QUEUE_R1 0
183#define QUEUE_R2 1
184#define USED_QUEUES 2
185
186 /*
187 * queue pointers; points to the queue dependent variables
188 */
189 struct s_smt_tx_queue *tx[USED_QUEUES] ;
190 struct s_smt_rx_queue *rx[USED_QUEUES] ;
191
192 /*
193 * queue dependent variables
194 */
195 struct s_smt_tx_queue tx_q[USED_QUEUES] ;
196 struct s_smt_rx_queue rx_q[USED_QUEUES] ;
197
198 /*
199 * FIFO configuration struct
200 */
201 struct s_smt_fifo_conf fifo ;
202
203 /* last formac status */
204 u_short s2u ;
205 u_short s2l ;
206
207 /* calculated FORMAC+ reg.addr. */
208 HW_PTR fm_st1u ;
209 HW_PTR fm_st1l ;
210 HW_PTR fm_st2u ;
211 HW_PTR fm_st2l ;
212 HW_PTR fm_st3u ;
213 HW_PTR fm_st3l ;
214
215
216 /*
217 * multicast table
218 */
219#define FPMAX_MULTICAST 32
220#define SMT_MAX_MULTI 4
221 struct {
222 struct s_fpmc {
223 struct fddi_addr a ; /* mc address */
224 u_char n ; /* usage counter */
225 u_char perm ; /* flag: permanent */
226 } table[FPMAX_MULTICAST] ;
227 } mc ;
228 struct fddi_addr group_addr ;
229 u_long func_addr ; /* functional address */
230 int smt_slots_used ; /* count of table entries for the SMT */
231 int os_slots_used ; /* count of table entries */
232 /* used by the os-specific module */
233} ;
234
235/*
236 * modes for mac_set_rx_mode()
237 */
238#define RX_ENABLE_ALLMULTI 1 /* enable all multicasts */
239#define RX_DISABLE_ALLMULTI 2 /* disable "enable all multicasts" */
240#define RX_ENABLE_PROMISC 3 /* enable promiscous */
241#define RX_DISABLE_PROMISC 4 /* disable promiscous */
242#define RX_ENABLE_NSA 5 /* enable reception of NSA frames */
243#define RX_DISABLE_NSA 6 /* disable reception of NSA frames */
244
245
246/*
247 * support for byte reversal in AIX
248 * (descriptors and pointers must be byte reversed in memory
249 * CPU is big endian; M-Channel is little endian)
250 */
251#ifdef AIX
252#define MDR_REV
253#define AIX_REVERSE(x) ((((x)<<24L)&0xff000000L) + \
254 (((x)<< 8L)&0x00ff0000L) + \
255 (((x)>> 8L)&0x0000ff00L) + \
256 (((x)>>24L)&0x000000ffL))
257#else
258#ifndef AIX_REVERSE
259#define AIX_REVERSE(x) (x)
260#endif
261#endif
262
263#ifdef MDR_REV
264#define MDR_REVERSE(x) ((((x)<<24L)&0xff000000L) + \
265 (((x)<< 8L)&0x00ff0000L) + \
266 (((x)>> 8L)&0x0000ff00L) + \
267 (((x)>>24L)&0x000000ffL))
268#else
269#ifndef MDR_REVERSE
270#define MDR_REVERSE(x) (x)
271#endif
272#endif
273
274#endif
diff --git a/drivers/net/skfp/h/hwmtm.h b/drivers/net/skfp/h/hwmtm.h
new file mode 100644
index 000000000000..4e360af07d77
--- /dev/null
+++ b/drivers/net/skfp/h/hwmtm.h
@@ -0,0 +1,424 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * The information in this file is provided "AS IS" without warranty.
12 *
13 ******************************************************************************/
14
15#ifndef _HWM_
16#define _HWM_
17
18#include "h/mbuf.h"
19
20/*
21 * MACRO for DMA synchronization:
22 * The descriptor 'desc' is flushed for the device 'flag'.
23 * Devices are the CPU (DDI_DMA_SYNC_FORCPU) and the
24 * adapter (DDI_DMA_SYNC_FORDEV).
25 *
26 * 'desc' Pointer to a Rx or Tx descriptor.
27 * 'flag' Flag for direction (view for CPU or DEVICE) that
28 * should be synchronized.
29 *
30 * Empty macros and defines are specified here. The real macro
31 * is os-specific and should be defined in osdef1st.h.
32 */
33#ifndef DRV_BUF_FLUSH
34#define DRV_BUF_FLUSH(desc,flag)
35#define DDI_DMA_SYNC_FORCPU
36#define DDI_DMA_SYNC_FORDEV
37#endif
38
39 /*
40 * hardware modul dependent receive modes
41 */
42#define RX_ENABLE_PASS_SMT 21
43#define RX_DISABLE_PASS_SMT 22
44#define RX_ENABLE_PASS_NSA 23
45#define RX_DISABLE_PASS_NSA 24
46#define RX_ENABLE_PASS_DB 25
47#define RX_DISABLE_PASS_DB 26
48#define RX_DISABLE_PASS_ALL 27
49#define RX_DISABLE_LLC_PROMISC 28
50#define RX_ENABLE_LLC_PROMISC 29
51
52
53#ifndef DMA_RD
54#define DMA_RD 1 /* memory -> hw */
55#endif
56#ifndef DMA_WR
57#define DMA_WR 2 /* hw -> memory */
58#endif
59#define SMT_BUF 0x80
60
61 /*
62 * bits of the frame status byte
63 */
64#define EN_IRQ_EOF 0x02 /* get IRQ after end of frame transmission */
65#define LOC_TX 0x04 /* send frame to the local SMT */
66#define LAST_FRAG 0x08 /* last TxD of the frame */
67#define FIRST_FRAG 0x10 /* first TxD of the frame */
68#define LAN_TX 0x20 /* send frame to network if set */
69#define RING_DOWN 0x40 /* error: unable to send, ring down */
70#define OUT_OF_TXD 0x80 /* error: not enough TxDs available */
71
72
73#ifndef NULL
74#define NULL 0
75#endif
76
77#ifdef LITTLE_ENDIAN
78#define HWM_REVERSE(x) (x)
79#else
80#define HWM_REVERSE(x) ((((x)<<24L)&0xff000000L) + \
81 (((x)<< 8L)&0x00ff0000L) + \
82 (((x)>> 8L)&0x0000ff00L) + \
83 (((x)>>24L)&0x000000ffL))
84#endif
85
86#define C_INDIC (1L<<25)
87#define A_INDIC (1L<<26)
88#define RD_FS_LOCAL 0x80
89
90 /*
91 * DEBUG FLAGS
92 */
93#define DEBUG_SMTF 1
94#define DEBUG_SMT 2
95#define DEBUG_ECM 3
96#define DEBUG_RMT 4
97#define DEBUG_CFM 5
98#define DEBUG_PCM 6
99#define DEBUG_SBA 7
100#define DEBUG_ESS 8
101
102#define DB_HWM_RX 10
103#define DB_HWM_TX 11
104#define DB_HWM_GEN 12
105
106struct s_mbuf_pool {
107#ifndef MB_OUTSIDE_SMC
108 SMbuf mb[MAX_MBUF] ; /* mbuf pool */
109#endif
110 SMbuf *mb_start ; /* points to the first mb */
111 SMbuf *mb_free ; /* free queue */
112} ;
113
114struct hwm_r {
115 /*
116 * hardware modul specific receive variables
117 */
118 u_int len ; /* length of the whole frame */
119 char *mb_pos ; /* SMbuf receive position */
120} ;
121
122struct hw_modul {
123 /*
124 * All hardware modul specific variables
125 */
126 struct s_mbuf_pool mbuf_pool ;
127 struct hwm_r r ;
128
129 union s_fp_descr volatile *descr_p ; /* points to the desriptor area */
130
131 u_short pass_SMT ; /* pass SMT frames */
132 u_short pass_NSA ; /* pass all NSA frames */
133 u_short pass_DB ; /* pass Direct Beacon Frames */
134 u_short pass_llc_promisc ; /* pass all llc frames (default ON) */
135
136 SMbuf *llc_rx_pipe ; /* points to the first queued llc fr */
137 SMbuf *llc_rx_tail ; /* points to the last queued llc fr */
138 int queued_rx_frames ; /* number of queued frames */
139
140 SMbuf *txd_tx_pipe ; /* points to first mb in the txd ring */
141 SMbuf *txd_tx_tail ; /* points to last mb in the txd ring */
142 int queued_txd_mb ; /* number of SMT MBufs in txd ring */
143
144 int rx_break ; /* rev. was breaked because ind. off */
145 int leave_isr ; /* leave fddi_isr immedeately if set */
146 int isr_flag ; /* set, when HWM is entered from isr */
147 /*
148 * varaibles for the current transmit frame
149 */
150 struct s_smt_tx_queue *tx_p ; /* pointer to the transmit queue */
151 u_long tx_descr ; /* tx descriptor for FORMAC+ */
152 int tx_len ; /* tx frame length */
153 SMbuf *tx_mb ; /* SMT tx MBuf pointer */
154 char *tx_data ; /* data pointer to the SMT tx Mbuf */
155
156 int detec_count ; /* counter for out of RxD condition */
157 u_long rx_len_error ; /* rx len FORMAC != sum of fragments */
158} ;
159
160
161/*
162 * DEBUG structs and macros
163 */
164
165#ifdef DEBUG
166struct os_debug {
167 int hwm_rx ;
168 int hwm_tx ;
169 int hwm_gen ;
170} ;
171#endif
172
173#ifdef DEBUG
174#ifdef DEBUG_BRD
175#define DB_P smc->debug
176#else
177#define DB_P debug
178#endif
179
180#define DB_RX(a,b,c,lev) if (DB_P.d_os.hwm_rx >= (lev)) printf(a,b,c)
181#define DB_TX(a,b,c,lev) if (DB_P.d_os.hwm_tx >= (lev)) printf(a,b,c)
182#define DB_GEN(a,b,c,lev) if (DB_P.d_os.hwm_gen >= (lev)) printf(a,b,c)
183#else /* DEBUG */
184#define DB_RX(a,b,c,lev)
185#define DB_TX(a,b,c,lev)
186#define DB_GEN(a,b,c,lev)
187#endif /* DEBUG */
188
189#ifndef SK_BREAK
190#define SK_BREAK()
191#endif
192
193
194/*
195 * HWM Macros
196 */
197
198/*
199 * BEGIN_MANUAL_ENTRY(HWM_GET_TX_PHYS)
200 * u_long HWM_GET_TX_PHYS(txd)
201 *
202 * function MACRO (hardware module, hwmtm.h)
203 * This macro may be invoked by the OS-specific module to read
204 * the physical address of the specified TxD.
205 *
206 * para txd pointer to the TxD
207 *
208 * END_MANUAL_ENTRY
209 */
210#define HWM_GET_TX_PHYS(txd) (u_long)AIX_REVERSE((txd)->txd_tbadr)
211
212/*
213 * BEGIN_MANUAL_ENTRY(HWM_GET_TX_LEN)
214 * int HWM_GET_TX_LEN(txd)
215 *
216 * function MACRO (hardware module, hwmtm.h)
217 * This macro may be invoked by the OS-specific module to read
218 * the fragment length of the specified TxD
219 *
220 * para rxd pointer to the TxD
221 *
222 * return the length of the fragment in bytes
223 *
224 * END_MANUAL_ENTRY
225 */
226#define HWM_GET_TX_LEN(txd) ((int)AIX_REVERSE((txd)->txd_tbctrl)& RD_LENGTH)
227
228/*
229 * BEGIN_MANUAL_ENTRY(HWM_GET_TX_USED)
230 * txd *HWM_GET_TX_USED(smc,queue)
231 *
232 * function MACRO (hardware module, hwmtm.h)
233 * This macro may be invoked by the OS-specific module to get the
234 * number of used TxDs for the queue, specified by the index.
235 *
236 * para queue the number of the send queue: Can be specified by
237 * QUEUE_A0, QUEUE_S or (frame_status & QUEUE_A0)
238 *
239 * return number of used TxDs for this send queue
240 *
241 * END_MANUAL_ENTRY
242 */
243#define HWM_GET_TX_USED(smc,queue) (int) (smc)->hw.fp.tx_q[queue].tx_used
244
245/*
246 * BEGIN_MANUAL_ENTRY(HWM_GET_CURR_TXD)
247 * txd *HWM_GET_CURR_TXD(smc,queue)
248 *
249 * function MACRO (hardware module, hwmtm.h)
250 * This macro may be invoked by the OS-specific module to get the
251 * pointer to the TxD which points to the current queue put
252 * position.
253 *
254 * para queue the number of the send queue: Can be specified by
255 * QUEUE_A0, QUEUE_S or (frame_status & QUEUE_A0)
256 *
257 * return pointer to the current TxD
258 *
259 * END_MANUAL_ENTRY
260 */
261#define HWM_GET_CURR_TXD(smc,queue) (struct s_smt_fp_txd volatile *)\
262 (smc)->hw.fp.tx_q[queue].tx_curr_put
263
264/*
265 * BEGIN_MANUAL_ENTRY(HWM_TX_CHECK)
266 * void HWM_TX_CHECK(smc,frame_status,low_water)
267 *
268 * function MACRO (hardware module, hwmtm.h)
269 * This macro is invoked by the OS-specific before it left it's
270 * driver_send function. This macro calls mac_drv_clear_txd
271 * if the free TxDs of the current transmit queue is equal or
272 * lower than the given low water mark.
273 *
274 * para frame_status status of the frame, see design description
275 * low_water low water mark of free TxD's
276 *
277 * END_MANUAL_ENTRY
278 */
279#ifndef HWM_NO_FLOW_CTL
280#define HWM_TX_CHECK(smc,frame_status,low_water) {\
281 if ((low_water)>=(smc)->hw.fp.tx_q[(frame_status)&QUEUE_A0].tx_free) {\
282 mac_drv_clear_txd(smc) ;\
283 }\
284}
285#else
286#define HWM_TX_CHECK(smc,frame_status,low_water) mac_drv_clear_txd(smc)
287#endif
288
289/*
290 * BEGIN_MANUAL_ENTRY(HWM_GET_RX_FRAG_LEN)
291 * int HWM_GET_RX_FRAG_LEN(rxd)
292 *
293 * function MACRO (hardware module, hwmtm.h)
294 * This macro may be invoked by the OS-specific module to read
295 * the fragment length of the specified RxD
296 *
297 * para rxd pointer to the RxD
298 *
299 * return the length of the fragment in bytes
300 *
301 * END_MANUAL_ENTRY
302 */
303#define HWM_GET_RX_FRAG_LEN(rxd) ((int)AIX_REVERSE((rxd)->rxd_rbctrl)& \
304 RD_LENGTH)
305
306/*
307 * BEGIN_MANUAL_ENTRY(HWM_GET_RX_PHYS)
308 * u_long HWM_GET_RX_PHYS(rxd)
309 *
310 * function MACRO (hardware module, hwmtm.h)
311 * This macro may be invoked by the OS-specific module to read
312 * the physical address of the specified RxD.
313 *
314 * para rxd pointer to the RxD
315 *
316 * return the RxD's physical pointer to the data fragment
317 *
318 * END_MANUAL_ENTRY
319 */
320#define HWM_GET_RX_PHYS(rxd) (u_long)AIX_REVERSE((rxd)->rxd_rbadr)
321
322/*
323 * BEGIN_MANUAL_ENTRY(HWM_GET_RX_USED)
324 * int HWM_GET_RX_USED(smc)
325 *
326 * function MACRO (hardware module, hwmtm.h)
327 * This macro may be invoked by the OS-specific module to get
328 * the count of used RXDs in receive queue 1.
329 *
330 * return the used RXD count of receive queue 1
331 *
332 * NOTE: Remember, because of an ASIC bug at least one RXD should be unused
333 * in the descriptor ring !
334 *
335 * END_MANUAL_ENTRY
336 */
337#define HWM_GET_RX_USED(smc) ((int)(smc)->hw.fp.rx_q[QUEUE_R1].rx_used)
338
339/*
340 * BEGIN_MANUAL_ENTRY(HWM_GET_RX_FREE)
341 * int HWM_GET_RX_FREE(smc)
342 *
343 * function MACRO (hardware module, hwmtm.h)
344 * This macro may be invoked by the OS-specific module to get
345 * the rxd_free count of receive queue 1.
346 *
347 * return the rxd_free count of receive queue 1
348 *
349 * END_MANUAL_ENTRY
350 */
351#define HWM_GET_RX_FREE(smc) ((int)(smc)->hw.fp.rx_q[QUEUE_R1].rx_free-1)
352
353/*
354 * BEGIN_MANUAL_ENTRY(HWM_GET_CURR_RXD)
355 * rxd *HWM_GET_CURR_RXD(smc)
356 *
357 * function MACRO (hardware module, hwmtm.h)
358 * This macro may be invoked by the OS-specific module to get the
359 * pointer to the RxD which points to the current queue put
360 * position.
361 *
362 * return pointer to the current RxD
363 *
364 * END_MANUAL_ENTRY
365 */
366#define HWM_GET_CURR_RXD(smc) (struct s_smt_fp_rxd volatile *)\
367 (smc)->hw.fp.rx_q[QUEUE_R1].rx_curr_put
368
369/*
370 * BEGIN_MANUAL_ENTRY(HWM_RX_CHECK)
371 * void HWM_RX_CHECK(smc,low_water)
372 *
373 * function MACRO (hardware module, hwmtm.h)
374 * This macro is invoked by the OS-specific before it left the
375 * function mac_drv_rx_complete. This macro calls mac_drv_fill_rxd
376 * if the number of used RxDs is equal or lower than the
377 * the given low water mark.
378 *
379 * para low_water low water mark of used RxD's
380 *
381 * END_MANUAL_ENTRY
382 */
383#ifndef HWM_NO_FLOW_CTL
384#define HWM_RX_CHECK(smc,low_water) {\
385 if ((low_water) >= (smc)->hw.fp.rx_q[QUEUE_R1].rx_used) {\
386 mac_drv_fill_rxd(smc) ;\
387 }\
388}
389#else
390#define HWM_RX_CHECK(smc,low_water) mac_drv_fill_rxd(smc)
391#endif
392
393#ifndef HWM_EBASE
394#define HWM_EBASE 500
395#endif
396
397#define HWM_E0001 HWM_EBASE + 1
398#define HWM_E0001_MSG "HWM: Wrong size of s_rxd_os struct"
399#define HWM_E0002 HWM_EBASE + 2
400#define HWM_E0002_MSG "HWM: Wrong size of s_txd_os struct"
401#define HWM_E0003 HWM_EBASE + 3
402#define HWM_E0003_MSG "HWM: smt_free_mbuf() called with NULL pointer"
403#define HWM_E0004 HWM_EBASE + 4
404#define HWM_E0004_MSG "HWM: Parity error rx queue 1"
405#define HWM_E0005 HWM_EBASE + 5
406#define HWM_E0005_MSG "HWM: Encoding error rx queue 1"
407#define HWM_E0006 HWM_EBASE + 6
408#define HWM_E0006_MSG "HWM: Encoding error async tx queue"
409#define HWM_E0007 HWM_EBASE + 7
410#define HWM_E0007_MSG "HWM: Encoding error sync tx queue"
411#define HWM_E0008 HWM_EBASE + 8
412#define HWM_E0008_MSG ""
413#define HWM_E0009 HWM_EBASE + 9
414#define HWM_E0009_MSG "HWM: Out of RxD condition detected"
415#define HWM_E0010 HWM_EBASE + 10
416#define HWM_E0010_MSG "HWM: A protocol layer has tried to send a frame with an invalid frame control"
417#define HWM_E0011 HWM_EBASE + 11
418#define HWM_E0011_MSG "HWM: mac_drv_clear_tx_queue was called although the hardware wasn't stopped"
419#define HWM_E0012 HWM_EBASE + 12
420#define HWM_E0012_MSG "HWM: mac_drv_clear_rx_queue was called although the hardware wasn't stopped"
421#define HWM_E0013 HWM_EBASE + 13
422#define HWM_E0013_MSG "HWM: mac_drv_repair_descr was called although the hardware wasn't stopped"
423
424#endif
diff --git a/drivers/net/skfp/h/lnkstat.h b/drivers/net/skfp/h/lnkstat.h
new file mode 100644
index 000000000000..c73dcd96a40f
--- /dev/null
+++ b/drivers/net/skfp/h/lnkstat.h
@@ -0,0 +1,84 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * The information in this file is provided "AS IS" without warranty.
12 *
13 ******************************************************************************/
14
15/*
16 * Definition of the Error Log Structure
17 * This structure will be copied into the Error Log buffer
18 * during the NDIS General Request ReadErrorLog by the MAC Driver
19 */
20
21struct s_error_log {
22
23 /*
24 * place holder for token ring adapter error log (zeros)
25 */
26 u_char reserved_0 ; /* byte 0 inside Error Log */
27 u_char reserved_1 ; /* byte 1 */
28 u_char reserved_2 ; /* byte 2 */
29 u_char reserved_3 ; /* byte 3 */
30 u_char reserved_4 ; /* byte 4 */
31 u_char reserved_5 ; /* byte 5 */
32 u_char reserved_6 ; /* byte 6 */
33 u_char reserved_7 ; /* byte 7 */
34 u_char reserved_8 ; /* byte 8 */
35 u_char reserved_9 ; /* byte 9 */
36 u_char reserved_10 ; /* byte 10 */
37 u_char reserved_11 ; /* byte 11 */
38 u_char reserved_12 ; /* byte 12 */
39 u_char reserved_13 ; /* byte 13 */
40
41 /*
42 * FDDI link statistics
43 */
44/*
45 * smt error low
46 */
47#define SMT_ERL_AEB (1<<15) /* A elast. buffer */
48#define SMT_ERL_BLC (1<<14) /* B link error condition */
49#define SMT_ERL_ALC (1<<13) /* A link error condition */
50#define SMT_ERL_NCC (1<<12) /* not copied condition */
51#define SMT_ERL_FEC (1<<11) /* frame error condition */
52
53/*
54 * smt event low
55 */
56#define SMT_EVL_NCE (1<<5)
57
58 u_short smt_error_low ; /* byte 14/15 */
59 u_short smt_error_high ; /* byte 16/17 */
60 u_short smt_event_low ; /* byte 18/19 */
61 u_short smt_event_high ; /* byte 20/21 */
62 u_short connection_policy_violation ; /* byte 22/23 */
63 u_short port_event ; /* byte 24/25 */
64 u_short set_count_low ; /* byte 26/27 */
65 u_short set_count_high ; /* byte 28/29 */
66 u_short aci_id_code ; /* byte 30/31 */
67 u_short purge_frame_counter ; /* byte 32/33 */
68
69 /*
70 * CMT and RMT state machines
71 */
72 u_short ecm_state ; /* byte 34/35 */
73 u_short pcm_a_state ; /* byte 36/37 */
74 u_short pcm_b_state ; /* byte 38/39 */
75 u_short cfm_state ; /* byte 40/41 */
76 u_short rmt_state ; /* byte 42/43 */
77
78 u_short not_used[30] ; /* byte 44-103 */
79
80 u_short ucode_version_level ; /* byte 104/105 */
81
82 u_short not_used_1 ; /* byte 106/107 */
83 u_short not_used_2 ; /* byte 108/109 */
84} ;
diff --git a/drivers/net/skfp/h/mbuf.h b/drivers/net/skfp/h/mbuf.h
new file mode 100644
index 000000000000..b339d1f2e0e5
--- /dev/null
+++ b/drivers/net/skfp/h/mbuf.h
@@ -0,0 +1,54 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * The information in this file is provided "AS IS" without warranty.
12 *
13 ******************************************************************************/
14
15#ifndef _MBUF_
16#define _MBUF_
17
18#ifndef PCI
19#define M_SIZE 4550
20#else
21#define M_SIZE 4504
22#endif
23
24#ifndef MAX_MBUF
25#define MAX_MBUF 4
26#endif
27
28#ifndef NO_STD_MBUF
29#define sm_next m_next
30#define sm_off m_off
31#define sm_len m_len
32#define sm_data m_data
33#define SMbuf Mbuf
34#define mtod smtod
35#define mtodoff smtodoff
36#endif
37
38struct s_mbuf {
39 struct s_mbuf *sm_next ; /* low level linked list */
40 short sm_off ; /* offset in m_data */
41 u_int sm_len ; /* len of data */
42#ifdef PCI
43 int sm_use_count ;
44#endif
45 char sm_data[M_SIZE] ;
46} ;
47
48typedef struct s_mbuf SMbuf ;
49
50/* mbuf head, to typed data */
51#define smtod(x,t) ((t)((x)->sm_data + (x)->sm_off))
52#define smtodoff(x,t,o) ((t)((x)->sm_data + (o)))
53
54#endif /* _MBUF_ */
diff --git a/drivers/net/skfp/h/osdef1st.h b/drivers/net/skfp/h/osdef1st.h
new file mode 100644
index 000000000000..5359eb53008d
--- /dev/null
+++ b/drivers/net/skfp/h/osdef1st.h
@@ -0,0 +1,123 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * The information in this file is provided "AS IS" without warranty.
12 *
13 ******************************************************************************/
14
15/*
16 * Operating system-dependent definitions that have to be defined
17 * before any other header files are included.
18 */
19
20// HWM (HardWare Module) Definitions
21// -----------------------
22
23#ifdef __LITTLE_ENDIAN
24#define LITTLE_ENDIAN
25#else
26#define BIG_ENDIAN
27#endif
28
29// this is set in the makefile
30// #define PCI /* only PCI adapters supported by this driver */
31// #define MEM_MAPPED_IO /* use memory mapped I/O */
32
33
34#define USE_CAN_ADDR /* DA and SA in MAC header are canonical. */
35
36#define MB_OUTSIDE_SMC /* SMT Mbufs outside of smc struct. */
37
38// -----------------------
39
40
41// SMT Definitions
42// -----------------------
43#define SYNC /* allow synchronous frames */
44
45// #define SBA /* Synchronous Bandwidth Allocator support */
46 /* not available as free source */
47
48#define ESS /* SBA End Station Support */
49
50#define SMT_PANIC(smc, nr, msg) printk(KERN_INFO "SMT PANIC: code: %d, msg: %s\n",nr,msg)
51
52
53#ifdef DEBUG
54#define printf(s,args...) printk(KERN_INFO s, ## args)
55#endif
56
57// #define HW_PTR u_long
58// -----------------------
59
60
61
62// HWM and OS-specific buffer definitions
63// -----------------------
64
65// default number of receive buffers.
66#define NUM_RECEIVE_BUFFERS 10
67
68// default number of transmit buffers.
69#define NUM_TRANSMIT_BUFFERS 10
70
71// Number of SMT buffers (Mbufs).
72#define NUM_SMT_BUF 4
73
74// Number of TXDs for asynchronous transmit queue.
75#define HWM_ASYNC_TXD_COUNT (NUM_TRANSMIT_BUFFERS + NUM_SMT_BUF)
76
77// Number of TXDs for synchronous transmit queue.
78#define HWM_SYNC_TXD_COUNT HWM_ASYNC_TXD_COUNT
79
80
81// Number of RXDs for receive queue #1.
82// Note: Workaround for ASIC Errata #7: One extra RXD is required.
83#if (NUM_RECEIVE_BUFFERS > 100)
84#define SMT_R1_RXD_COUNT (1 + 100)
85#else
86#define SMT_R1_RXD_COUNT (1 + NUM_RECEIVE_BUFFERS)
87#endif
88
89// Number of RXDs for receive queue #2.
90#define SMT_R2_RXD_COUNT 0 // Not used.
91// -----------------------
92
93
94
95/*
96 * OS-specific part of the transmit/receive descriptor structure (TXD/RXD).
97 *
98 * Note: The size of these structures must follow this rule:
99 *
100 * sizeof(struct) + 2*sizeof(void*) == n * 16, n >= 1
101 *
102 * We use the dma_addr fields under Linux to keep track of the
103 * DMA address of the packet data, for later pci_unmap_single. -DaveM
104 */
105
106struct s_txd_os { // os-specific part of transmit descriptor
107 struct sk_buff *skb;
108 dma_addr_t dma_addr;
109} ;
110
111struct s_rxd_os { // os-specific part of receive descriptor
112 struct sk_buff *skb;
113 dma_addr_t dma_addr;
114} ;
115
116
117/*
118 * So we do not need to make too many modifications to the generic driver
119 * parts, we take advantage of the AIX byte swapping macro interface.
120 */
121
122#define AIX_REVERSE(x) ((u32)le32_to_cpu((u32)(x)))
123#define MDR_REVERSE(x) ((u32)le32_to_cpu((u32)(x)))
diff --git a/drivers/net/skfp/h/sba.h b/drivers/net/skfp/h/sba.h
new file mode 100644
index 000000000000..df716cd5784a
--- /dev/null
+++ b/drivers/net/skfp/h/sba.h
@@ -0,0 +1,142 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * The information in this file is provided "AS IS" without warranty.
12 *
13 ******************************************************************************/
14
15/*
16 * Synchronous Bandwith Allocation (SBA) structs
17 */
18
19#ifndef _SBA_
20#define _SBA_
21
22#include "h/mbuf.h"
23#include "h/sba_def.h"
24
25#ifdef SBA
26
27/* Timer Cell Template */
28struct timer_cell {
29 struct timer_cell *next_ptr ;
30 struct timer_cell *prev_ptr ;
31 u_long start_time ;
32 struct s_sba_node_vars *node_var ;
33} ;
34
35/*
36 * Node variables
37 */
38struct s_sba_node_vars {
39 u_char change_resp_flag ;
40 u_char report_resp_flag ;
41 u_char change_req_flag ;
42 u_char report_req_flag ;
43 long change_amount ;
44 long node_overhead ;
45 long node_payload ;
46 u_long node_status ;
47 u_char deallocate_status ;
48 u_char timer_state ;
49 u_short report_cnt ;
50 long lastrep_req_tranid ;
51 struct fddi_addr mac_address ;
52 struct s_sba_sessions *node_sessions ;
53 struct timer_cell timer ;
54} ;
55
56/*
57 * Session variables
58 */
59struct s_sba_sessions {
60 u_long deallocate_status ;
61 long session_overhead ;
62 u_long min_segment_size ;
63 long session_payload ;
64 u_long session_status ;
65 u_long sba_category ;
66 long lastchg_req_tranid ;
67 u_short session_id ;
68 u_char class ;
69 u_char fddi2 ;
70 u_long max_t_neg ;
71 struct s_sba_sessions *next_session ;
72} ;
73
74struct s_sba {
75
76 struct s_sba_node_vars node[MAX_NODES] ;
77 struct s_sba_sessions session[MAX_SESSIONS] ;
78
79 struct s_sba_sessions *free_session ; /* points to the first */
80 /* free session */
81
82 struct timer_cell *tail_timer ; /* points to the last timer cell */
83
84 /*
85 * variables for allocation actions
86 */
87 long total_payload ; /* Total Payload */
88 long total_overhead ; /* Total Overhead */
89 long sba_allocatable ; /* allocatable sync bandwidth */
90
91 /*
92 * RAF message receive parameters
93 */
94 long msg_path_index ; /* Path Type */
95 long msg_sba_pl_req ; /* Payload Request */
96 long msg_sba_ov_req ; /* Overhead Request */
97 long msg_mib_pl ; /* Current Payload for this Path */
98 long msg_mib_ov ; /* Current Overhead for this Path*/
99 long msg_category ; /* Category of the Allocation */
100 u_long msg_max_t_neg ; /* longest T_Neg acceptable */
101 u_long msg_min_seg_siz ; /* minimum segement size */
102 struct smt_header *sm ; /* points to the rec message */
103 struct fddi_addr *msg_alloc_addr ; /* Allocation Address */
104
105 /*
106 * SBA variables
107 */
108 u_long sba_t_neg ; /* holds the last T_NEG */
109 long sba_max_alloc ; /* the parsed value of SBAAvailable */
110
111 /*
112 * SBA state machine variables
113 */
114 short sba_next_state ; /* the next state of the SBA */
115 char sba_command ; /* holds the execuded SBA cmd */
116 u_char sba_available ; /* parsed value after possible check */
117} ;
118
119#endif /* SBA */
120
121 /*
122 * variables for the End Station Support
123 */
124struct s_ess {
125
126 /*
127 * flags and counters
128 */
129 u_char sync_bw_available ; /* is set if sync bw is allocated */
130 u_char local_sba_active ; /* set when a local sba is available */
131 char raf_act_timer_poll ; /* activate the timer to send allc req */
132 char timer_count ; /* counts every timer function call */
133
134 SMbuf *sba_reply_pend ; /* local reply for the sba is pending */
135
136 /*
137 * variables for the ess bandwidth control
138 */
139 long sync_bw ; /* holds the allocaed sync bw */
140 u_long alloc_trans_id ; /* trans id of the last alloc req */
141} ;
142#endif
diff --git a/drivers/net/skfp/h/sba_def.h b/drivers/net/skfp/h/sba_def.h
new file mode 100644
index 000000000000..0459a095d0cd
--- /dev/null
+++ b/drivers/net/skfp/h/sba_def.h
@@ -0,0 +1,76 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * The information in this file is provided "AS IS" without warranty.
12 *
13 ******************************************************************************/
14
15#define PHYS 0 /* physical addr */
16#define PERM_ADDR 0x80 /* permanet address */
17#define SB_STATIC 0x00000001
18#define MAX_PAYLOAD 1562
19#define PRIMARY_RING 0x00000001
20#ifndef NULL
21#define NULL 0x00
22#endif
23
24/*********************** SB_Input Variable Values ***********************/
25/* may be needed when ever the SBA state machine is called */
26
27#define UNKNOWN_SYNC_SOURCE 0x0001
28#define REQ_ALLOCATION 0x0002
29#define REPORT_RESP 0x0003
30#define CHANGE_RESP 0x0004
31#define TNEG 0x0005
32#define NIF 0x0006
33#define SB_STOP 0x0007
34#define SB_START 0x0008
35#define REPORT_TIMER 0x0009
36#define CHANGE_REQUIRED 0x000A
37
38#define DEFAULT_OV 50
39
40#ifdef SBA
41/**************************** SBA STATES *****************************/
42
43#define SBA_STANDBY 0x00000000
44#define SBA_ACTIVE 0x00000001
45#define SBA_RECOVERY 0x00000002
46#define SBA_REPORT 0x00000003
47#define SBA_CHANGE 0x00000004
48
49/**************************** OTHERS *********************************/
50
51#define FIFTY_PERCENT 50 /* bytes per second */
52#define MAX_SESSIONS 150
53#define TWO_MINUTES 13079 /* 9.175 ms/tick */
54#define FIFTY_BYTES 50
55#define SBA_DENIED 0x0000000D
56#define I_NEED_ONE 0x00000000
57#define MAX_NODES 50
58/*#define T_REPORT 0x59682F00L*/ /* 120s/80ns in Hex */
59#define TWO_MIN 120 /* seconds */
60#define SBA_ST_UNKNOWN 0x00000002
61#define SBA_ST_ACTIVE 0x00000001
62#define S_CLEAR 0x00000000L
63#define ZERO 0x00000000
64#define FULL 0x00000000 /* old: 0xFFFFFFFFF */
65#define S_SET 0x00000001L
66#define LOW_PRIO 0x02 /* ??????? */
67#define OK 0x01 /* ??????? */
68#define NOT_OK 0x00 /* ??????? */
69
70/****************************************/
71/* deallocate_status[ni][si] values */
72/****************************************/
73#define TX_CHANGE 0X00000001L
74#define PENDING 0x00000002L
75#define NONE 0X00000000L
76#endif
diff --git a/drivers/net/skfp/h/skfbi.h b/drivers/net/skfp/h/skfbi.h
new file mode 100644
index 000000000000..ba347d6910f1
--- /dev/null
+++ b/drivers/net/skfp/h/skfbi.h
@@ -0,0 +1,1919 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * The information in this file is provided "AS IS" without warranty.
12 *
13 ******************************************************************************/
14
15#ifndef _SKFBI_H_
16#define _SKFBI_H_
17
18#ifdef SYNC
19#define exist_board_far exist_board
20#define get_board_para_far get_board_para
21#endif
22
23/*
24 * physical address offset + IO-Port base address
25 */
26#ifndef PCI
27#define ADDR(a) ((a)+smc->hw.iop)
28#define ADDRS(smc,a) ((a)+(smc)->hw.iop)
29#endif
30
31/*
32 * FDDI-Fx (x := {I(SA), E(ISA), M(CA), P(CI)})
33 * address calculation & function defines
34 */
35
36#ifdef EISA
37
38/*
39 * Configuration PROM: !! all 8-Bit IO's !!
40 * |<- MAC-Address ->|
41 * /-+--+--+--+--+-//-+--+--+--+--+-//-+--+--+--+--+-//-+--+--+--+--+-/
42 * val: |PROD_ID0..3| | free | |00|00|5A|40| |nn|mm|00|00|
43 * /-+--+--+--+--+-//-+--+--+--+--+-//-+--+--+--+--+-//-+--+--+--+--+-/
44 * IO- ^ ^ ^ ^ ^
45 * port 0C80 0C83 0C88 0C90 0C98
46 * | \
47 * | \
48 * | \______________________________________________
49 * EISA Expansion Board Product ID: \
50 * BIT: |7 6 5 4 3 2 1 0| \
51 * | PROD_ID0 | PROD_ID1 | PROD_ID2 | PROD_ID3 |
52 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
53 * |0| MAN_C0 | MAN_C1 | MAN_C2 | PROD1 | PROD0 | REV1 | REV0 |
54 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
55 * ^=reserved | product numb. | revision numb |
56 * MAN_Cx = compressed manufacterer code (x:=0..2)
57 * ASCII : 'A'..'Z' : 0x41..0x5A -> compr.(c-0x40) : 0x01..0x1A (5Bits!)
58 */
59
60#ifndef MULT_OEM
61#ifndef OEM_CONCEPT
62#define MAN_C0 ('S'-0x40)
63#define MAN_C1 ('K'-0x40)
64#define MAN_C2 ('D'-0x40)
65#define PROD_ID0 (u_char)((MAN_C0<<2) | (MAN_C1>>3))
66#define PROD_ID1 (u_char)(((MAN_C1<<5) & 0xff) | MAN_C2)
67#define PROD_ID2 (u_char)(1) /* prod. nr. */
68#define PROD_ID3 (u_char)(0) /* rev. nr. */
69
70#ifndef OEM_USER_DATA
71#define OEM_USER_DATA "SK-NET FDDI V2.0 Userdata"
72#endif
73#else /* OEM_CONCEPT */
74
75/* MAN_C(0|1|2) no longer present (ra). */
76#define PROD_ID0 (u_char)OEM_PROD_ID0
77#define PROD_ID1 (u_char)OEM_PROD_ID1
78#define PROD_ID2 (u_char)OEM_PROD_ID2
79#define PROD_ID3 (u_char)OEM_PROD_ID3
80#endif /* OEM_CONCEPT */
81
82#define SKLOGO PROD_ID0, PROD_ID1, PROD_ID2, PROD_ID3
83#endif /* MULT_OEM */
84
85#define SADDRL (0) /* start address SKLOGO */
86#define SA_MAC (0x10) /* start addr. MAC_AD within the PROM */
87#define PRA_OFF (4)
88#define SA_PMD_TYPE (8) /* start addr. PMD-Type */
89
90#define SKFDDI_PSZ 32 /* address PROM size */
91
92/*
93 * address transmission from logical to physical offset address on board
94 */
95#define FMA(a) (0x0400|((a)<<1)) /* FORMAC+ (r/w) */
96#define P1A(a) (0x0800|((a)<<1)) /* PLC1 (r/w) */
97#define P2A(a) (0x0840|((a)<<1)) /* PLC2 (r/w) */
98#define TIA(a) (0x0880|((a)<<1)) /* Timer (r/w) */
99#define PRA(a) (0x0c80| (a)) /* configuration PROM */
100#define C0A(a) (0x0c84| (a)) /* config. RAM */
101#define C1A(a) (0x0ca0| (a)) /* IRQ-, DMA-nr., EPROM type */
102#define C2A(a) (0x0ca4| (a)) /* EPROM and PAGE selector */
103
104#define CONF C0A(0) /* config RAM (card enable bit port) */
105#define PGRA C2A(0) /* Flash page register */
106#define CDID PRA(0) /* Card ID I/O port addr. offset */
107
108
109/*
110 * physical address offset + slot specific IO-Port base address
111 */
112#define FM_A(a) (FMA(a)+smc->hw.iop) /* FORMAC Plus physical addr */
113#define P1_A(a) (P1A(a)+smc->hw.iop) /* PLC1 (r/w) */
114#define P2_A(a) (P2A(a)+smc->hw.iop) /* PLC2 (r/w) */
115#define TI_A(a) (TIA(a)+smc->hw.iop) /* Timer (r/w) */
116#define PR_A(a) (PRA(a)+smc->hw.iop) /* config. PROM */
117#define C0_A(a) (C0A(a)+smc->hw.iop) /* config. RAM */
118#define C1_A(a) (C1A(a)+smc->hw.iop) /* config. RAM */
119#define C2_A(a) (C2A(a)+smc->hw.iop) /* config. RAM */
120
121
122#define CSRA 0x0008 /* control/status register address (r/w) */
123#define ISRA 0x0008 /* int. source register address (upper 8Bits) */
124#define PLC1I 0x001a /* clear PLC1 interrupt (write only) */
125#define PLC2I 0x0020 /* clear PLC2 interrupt (write only) */
126#define CSFA 0x001c /* control/status FIFO BUSY flags (read only) */
127#define RQAA 0x001c /* Request reg. (write only) */
128#define WCTA 0x001e /* word counter (r/w) */
129#define FFLAG 0x005e /* FLAG/V_FULL (FIFO almost full, write only)*/
130
131#define CSR_A (CSRA+smc->hw.iop) /* control/status register address (r/w) */
132#ifdef UNIX
133#define CSR_AS(smc) (CSRA+(smc)->hw.iop) /* control/status register address (r/w) */
134#endif
135#define ISR_A (ISRA+smc->hw.iop) /* int. source register address (upper 8Bits) */
136#define PLC1_I (PLC1I+smc->hw.iop) /* clear PLC1 internupt (write only) */
137#define PLC2_I (PLC2I+smc->hw.iop) /* clear PLC2 interrupt (write only) */
138#define CSF_A (CSFA+smc->hw.iop) /* control/status FIFO BUSY flags (r/w) */
139#define RQA_A (RQAA+smc->hw.iop) /* Request reg. (write only) */
140#define WCT_A (WCTA+smc->hw.iop) /* word counter (r/w) */
141#define FFLAG_A (FFLAG+smc->hw.iop) /* FLAG/V_FULL (FIFO almost full, write only)*/
142
143/*
144 * control/status register CSRA bits
145 */
146/* write */
147#define CS_CRESET 0x01 /* Card reset (0=reset) */
148#define CS_RESET_FIFO 0x02 /* FIFO reset (0=reset) */
149#define CS_IMSK 0x04 /* enable IRQ (1=enable, 0=disable) */
150#define CS_EN_IRQ_TC 0x08 /* enable IRQ from transfer counter */
151#define CS_BYPASS 0x20 /* bypass switch (0=remove, 1=insert)*/
152#define CS_LED_0 0x40 /* switch LED 0 */
153#define CS_LED_1 0x80 /* switch LED 1 */
154/* read */
155#define CS_BYSTAT 0x40 /* 0=Bypass exist, 1= ..not */
156#define CS_SAS 0x80 /* single attachement station (=1) */
157
158/*
159 * control/status register CSFA bits (FIFO)
160 */
161#define CSF_MUX0 0x01
162#define CSF_MUX1 0x02
163#define CSF_HSREQ0 0x04
164#define CSF_HSREQ1 0x08
165#define CSF_HSREQ2 0x10
166#define CSF_BUSY_DMA 0x40
167#define CSF_BUSY_FIFO 0x80
168
169/*
170 * Interrupt source register ISRA (upper 8 data bits) read only & low activ.
171 */
172#define IS_MINTR1 0x0100 /* FORMAC ST1U/L & ~IMSK1U/L*/
173#define IS_MINTR2 0x0200 /* FORMAC ST2U/L & ~IMSK2U/L*/
174#define IS_PLINT1 0x0400 /* PLC1 */
175#define IS_PLINT2 0x0800 /* PLC2 */
176#define IS_TIMINT 0x1000 /* Timer 82C54-2 */
177#define IS_TC 0x2000 /* transf. counter */
178
179#define ALL_IRSR (IS_MINTR1|IS_MINTR2|IS_PLINT1|IS_PLINT2|IS_TIMINT|IS_TC)
180
181/*
182 * CONFIG<0> RAM (C0_A())
183 */
184#define CFG_CARD_EN 0x01 /* card enable */
185
186/*
187 * CONFIG<1> RAM (C1_A())
188 */
189#define CFG_IRQ_SEL 0x03 /* IRQ select (4 nr.) */
190#define CFG_IRQ_TT 0x04 /* IRQ trigger type (LEVEL/EDGE) */
191#define CFG_DRQ_SEL 0x18 /* DMA requ. (4 nr.) */
192#define CFG_BOOT_EN 0x20 /* 0=BOOT-, 1=Application Software */
193#define CFG_PROG_EN 0x40 /* V_Prog for FLASH_PROM (1=on) */
194
195/*
196 * CONFIG<2> RAM (C2_A())
197 */
198#define CFG_EPROM_SEL 0x0f /* FPROM start address selection */
199#define CFG_PAGE 0xf0 /* FPROM page selection */
200
201
202#define READ_PROM(a) ((u_char)inp(a))
203#define GET_PAGE(i) outp(C2_A(0),((int)(i)<<4) | (inp(C2_A(0)) & ~CFG_PAGE))
204#define FPROM_SW() (inp(C1_A(0)) & CFG_BOOT_EN)
205
206#define MAX_PAGES 16 /* 16 pages */
207#define MAX_FADDR 0x2000 /* 8K per page */
208#define VPP_ON() outp(C1_A(0),inp(C1_A(0)) | CFG_PROG_EN)
209#define VPP_OFF() outp(C1_A(0),inp(C1_A(0)) & ~CFG_PROG_EN)
210
211#define DMA_BUSY() (inpw(CSF_A) & CSF_BUSY_DMA)
212#define FIFO_BUSY() (inpw(CSF_A) & CSF_BUSY_FIFO)
213#define DMA_FIFO_BUSY() (inpw(CSF_A) & (CSF_BUSY_DMA | CSF_BUSY_FIFO))
214#define BUS_CHECK()
215
216#ifdef UNISYS
217/* For UNISYS use another macro with drv_usecewait function */
218#define CHECK_DMA() {u_long k = 1000000; \
219 while (k && (DMA_BUSY())) { k--; drv_usecwait(20); } \
220 if (!k) SMT_PANIC(smc,HWM_E0003,HWM_E0003_MSG) ; }
221#else
222#define CHECK_DMA() {u_long k = 1000000 ;\
223 while (k && (DMA_BUSY())) k-- ;\
224 if (!k) SMT_PANIC(smc,HWM_E0003,HWM_E0003_MSG) ; }
225#endif
226
227#define CHECK_FIFO() {u_long k = 1000000 ;\
228 while (k && (FIFO_BUSY())) k-- ;\
229 if (!k) SMT_PANIC(smc,HWM_E0019,HWM_E0019_MSG) ; }
230
231#define CHECK_DMA_FIFO() {u_long k = 1000000 ;\
232 while (k && (DMA_FIFO_BUSY())) k-- ;\
233 if (!k) SMT_PANIC(smc,HWM_E0004,HWM_E0004_MSG) ; }
234
235#define GET_ISR() ~inpw(ISR_A)
236#define CHECK_ISR() ~inpw(ISR_A)
237
238#ifndef UNIX
239#ifndef WINNT
240#define CLI_FBI() outpw(CSR_A,(inpw(CSR_A)&\
241 (CS_CRESET|CS_BYPASS))|CS_RESET_FIFO|smc->hw.led)
242#else /* WINNT */
243#define CLI_FBI() outpw(CSR_A,(l_inpw(CSR_A)&\
244 (CS_CRESET|CS_BYPASS))|CS_RESET_FIFO|smc->hw.led)
245#endif /* WINNT */
246#else /* UNIX */
247#define CLI_FBI(smc) outpw(CSR_AS(smc),(inpw(CSR_AS(smc))&\
248 (CS_CRESET|CS_BYPASS))|CS_RESET_FIFO|(smc)->hw.led)
249#endif
250
251#ifndef UNIX
252#define STI_FBI() outpw(CSR_A,(inpw(CSR_A)&\
253 (CS_CRESET|CS_BYPASS|CS_RESET_FIFO))|CS_IMSK|smc->hw.led)
254#else
255#define STI_FBI(smc) outpw(CSR_AS(smc),(inpw(CSR_AS(smc))&\
256 (CS_CRESET|CS_BYPASS|CS_RESET_FIFO))|CS_IMSK|(smc)->hw.led)
257#endif
258
259/* EISA DMA Controller */
260#define DMA_WRITE_SINGLE_MASK_BIT_M 0x0a /* Master DMA Controller */
261#define DMA_WRITE_SINGLE_MASK_BIT_S 0xd4 /* Slave DMA Controller */
262#define DMA_CLEAR_BYTE_POINTER_M 0x0c
263#define DMA_CLEAR_BYTE_POINTER_S 0xd8
264
265#endif /* EISA */
266
267#ifdef MCA
268
269/*
270 * POS Register: !! all I/O's are 8-Bit !!
271 */
272#define POS_SYS_SETUP 0x94 /* system setup register */
273#define POS_SYSTEM 0xff /* system mode */
274
275#define POS_CHANNEL_POS 0x96 /* register slot ID */
276#define POS_CHANNEL_BIT 0x08 /* mask for -"- */
277
278#define POS_BASE 0x100 /* POS base address */
279#define POS_ID_LOW POS_BASE /* card ID low */
280#define POS_ID_HIGH (POS_BASE+1) /* card ID high */
281#define POS_102 (POS_BASE+2) /* card en., arbitration level .. */
282#define POS_103 (POS_BASE+3) /* FPROM addr, page */
283#define POS_104 (POS_BASE+4) /* I/O, IRQ */
284#define POS_105 (POS_BASE+5) /* POS_CHCK */
285#define POS_106 (POS_BASE+6) /* to read VPD */
286#define POS_107 (POS_BASE+7) /* added without function */
287
288/* FM1 card IDs */
289#define FM1_CARD_ID0 0x83
290#define FM1_CARD_ID1 0
291
292#define FM1_IBM_ID0 0x9c
293#define FM1_IBM_ID1 0x8f
294
295
296/* FM2 card IDs */
297#define FM2_CARD_ID0 0xab
298#define FM2_CARD_ID1 0
299
300#define FM2_IBM_ID0 0x7e
301#define FM2_IBM_ID1 0x8f
302
303/* Board revision. */
304#define FM1_REV 0
305#define FM2_REV 1
306
307#define MAX_SLOT 8
308
309/*
310 * POS_102
311 */
312#define POS_CARD_EN 0x01 /* card enable =1 */
313#define POS_SDAT_EN 0x02 /* enable 32-bit streaming data mode */
314#define POS_EN_CHKINT 0x04 /* enable int. from check line asserted */
315#define POS_EN_BUS_ERR 0x08 /* enable int. on invalid busmaster transf. */
316#define POS_FAIRNESS 0x10 /* fairnes on =1 */
317/* attention: arbitration level used with bit 0 POS 105 */
318#define POS_LARBIT 0xe0 /* arbitration level (0,0,0)->level = 0x8
319 (1,1,1)->level = 0xf */
320/*
321 * POS_103
322 */
323#define POS_PAGE 0x07 /* FPROM page selection */
324#define POS_BOOT_EN 0x08 /* boot PROM enable =1 */
325#define POS_MSEL 0x70 /* memory start address for FPROM mapping */
326#define PROG_EN 0x80 /* FM1: Vpp prog on/off */
327#define POS_SDR 0x80 /* FM2: Streaming data bit */
328
329/*
330 * POS_104
331 */
332#define POS_IOSEL 0x3f /* selected I/O base address */
333#define POS_IRQSEL 0xc0 /* selected interrupt */
334
335/*
336 * POS_105
337 */
338#define POS_CHCK 0x80
339#define POS_SYNC_ERR 0x20 /* FM2: synchronous error reporting */
340#define POS_PAR_DATA 0x10 /* FM2: data parity enable bit */
341#define POS_PAR_ADDR 0x08 /* FM2: address parity enable bit */
342#define POS_IRQHSEL 0x02 /* FM2: Highest bit for IRQ_selection */
343#define POS_HARBIT 0x01 /* Highest bit in Bus arbitration selection */
344
345#define SA_MAC (0) /* start addr. MAC_AD within the PROM */
346#define PRA_OFF (0)
347#define SA_PMD_TYPE (8) /* start addr. PMD-Type */
348
349/*
350 * address transmission from logical to physical offset address on board
351 */
352#define FMA(a) (0x0100|((a)<<1)) /* FORMAC+ (r/w) */
353#define P2(a) (0x00c0|((a)<<1)) /* PLC2 (r/w) (DAS) */
354#define P1(a) (0x0080|((a)<<1)) /* PLC1 (r/w) */
355#define TI(a) (0x0060|((a)<<1)) /* Timer (r/w) */
356#define PR(a) (0x0040|((a)<<1)) /* configuration PROM */
357#define CS(a) (0x0020| (a)) /* control/status */
358#define FF(a) (0x0010|((a)<<1)) /* FIFO ASIC */
359#define CT(a) (0x0000|((a)<<1)) /* counter */
360
361/*
362 * counter
363 */
364#define ACLA CT(0) /* address counter low */
365#define ACHA CT(1) /* address counter high */
366#define BCN CT(2) /* byte counter */
367#define MUX CT(3) /* MUX-register */
368#define WCN CT(0x08) /* word counter */
369#define FFLG CT(0x09) /* FIFO Flags */
370
371/*
372 * test/control register (FM2 only)
373 */
374#define CNT_TST 0x018 /* Counter test control register */
375#define CNT_STP 0x01a /* Counter test step reg. (8 Bit) */
376
377/*
378 * CS register (read only)
379 */
380#define CSRA CS(0) /* control/status register address */
381#define CSFA CS(2) /* control/status FIFO BUSY ... */
382#define ISRA CS(4) /* first int. source register address */
383#define ISR2 CS(6) /* second int. source register address */
384#define LEDR CS(0x0c) /* LED register r/w */
385#define CSIL CS(0x10) /* I/O mapped POS_ID_low (100) */
386#define CSIH CS(0x12) /* - " - POS_ID_HIGH (101) */
387#define CSA CS(0x14) /* - " - POS_102 */
388#define CSM CS(0x0e) /* - " - POS_103 */
389#define CSM_FM1 CS(0x16) /* - " - POS_103 (copy in FM1) */
390#define CSI CS(0x18) /* - " - POS_104 */
391#define CSS CS(0x1a) /* - " - POS_105 */
392#define CSP_06 CS(0x1c) /* - " - POS_106 */
393#define WDOG_ST 0x1c /* Watchdog status (FM2 only) */
394#define WDOG_EN 0x1c /* Watchdog enabling (FM2 only, 8Bit) */
395#define WDOG_DIS 0x1e /* Watchdog disabling (FM2 only, 8Bit) */
396
397#define PGRA CSM /* Flash page register */
398
399
400#define WCTA FF(0) /* word counter */
401#define FFLAG FF(1) /* FLAG/V_FULL (FIFO almost full, write only)*/
402
403/*
404 * Timer register (FM2 only)
405 */
406#define RTM_CNT 0x28 /* RTM Counter */
407#define TI_DIV 0x60 /* Timer Prescaler */
408#define TI_CH1 0x62 /* Timer channel 1 counter */
409#define TI_STOP 0x64 /* Stop timer on channel 1 */
410#define TI_STRT 0x66 /* Start timer on channel 1 */
411#define TI_INI2 0x68 /* Timer: Bus master preemption */
412#define TI_CNT2 0x6a /* Timer */
413#define TI_INI3 0x6c /* Timer: Streaming data */
414#define TI_CNT3 0x6e /* Timer */
415#define WDOG_LO 0x70 /* Watchdog counter low */
416#define WDOG_HI 0x72 /* Watchdog counter high */
417#define RTM_PRE 0x74 /* restr. token prescaler */
418#define RTM_TIM 0x76 /* restr. token timer */
419
420/*
421 * Recommended Timeout values (for FM2 timer only)
422 */
423#define TOUT_BM_PRE 188 /* 3.76 usec */
424#define TOUT_S_DAT 374 /* 7.48 usec */
425
426/*
427 * CS register (write only)
428 */
429#define HSR(p) CS(0x18|(p)) /* Host request register */
430
431#define RTM_PUT 0x36 /* restr. token counter write */
432#define RTM_GET 0x28 /* - " - clear */
433#define RTM_CLEAR 0x34 /* - " - read */
434
435/*
436 * BCN Bit definitions
437 */
438#define BCN_BUSY 0x8000 /* DMA Busy flag */
439#define BCN_AZERO 0x4000 /* Almost zero flag (BCN < 4) */
440#define BCN_STREAM 0x2000 /* Allow streaming data (BCN >= 8) */
441
442/*
443 * WCN Bit definitions
444 */
445#define WCN_ZERO 0x2000 /* Zero flag (counted to zero) */
446#define WCN_AZERO 0x1000 /* Almost zero flag (BCN < 4) */
447
448/*
449 * CNT_TST Bit definitions
450 */
451#define CNT_MODE 0x01 /* Go into test mode */
452#define CNT_D32 0x02 /* 16/32 BIT test mode */
453
454/*
455 * FIFO Flag FIFO Flags/Vfull register
456 */
457#define FF_VFULL 0x003f /* V_full value mask */
458#define FFLG_FULL 0x2000 /* FULL flag */
459#define FFLG_A_FULL 0x1000 /* Almost full flag */
460#define FFLG_VFULL 0x0800 /* V_full Flag */
461#define FFLG_A_EMP 0x0400 /* almost empty flag */
462#define FFLG_EMP 0x0200 /* empty flag */
463#define FFLG_T_EMP 0x0100 /* totally empty flag */
464
465/*
466 * WDOG Watchdog status register
467 */
468#define WDOG_ALM 0x01 /* Watchdog alarm Bit */
469#define WDOG_ACT 0x02 /* Watchdog active Bit */
470
471/*
472 * CS(0) CONTROLS
473 */
474#define CS_CRESET 0x0001
475#define FIFO_RST 0x0002
476#define CS_IMSK 0x0004
477#define EN_IRQ_CHCK 0x0008
478#define EN_IRQ_TOKEN 0x0010
479#define EN_IRQ_TC 0x0020
480#define TOKEN_STATUS 0x0040
481#define RTM_CHANGE 0x0080
482
483#define CS_SAS 0x0100
484#define CS_BYSTAT 0x0200 /* bypass connected (0=conn.) */
485#define CS_BYPASS 0x0400 /* bypass on/off indication */
486
487/*
488 * CS(2) FIFOSTAT
489 */
490#define HSREQ 0x0007
491#define BIGDIR 0x0008
492#define CSF_BUSY_FIFO 0x0010
493#define CSF_BUSY_DMA 0x0020
494#define SLOT_32 0x0040
495
496#define LED_0 0x0001
497#define LED_1 0x0002
498#define LED_2 0x0100
499
500#define MAX_PAGES 8 /* pages */
501#define MAX_FADDR 0x4000 /* 16K per page */
502
503/*
504 * IRQ = ISRA || ISR2 ;
505 *
506 * ISRA = IRQ_OTH_EN && (IS_LAN | IS_BUS) ;
507 * ISR2 = IRQ_TC_EN && IS_TC ;
508 *
509 * IS_LAN = (IS_MINTR1 | IS_MINTR2 | IS_PLINT1 | IS_PLINT2 | IS_TIMINT) ||
510 * (IRQ_EN_TOKEN && IS_TOKEN) ;
511 * IS_BUS = IRQ_CHCK_EN && (IS_BUSERR | IS_CHCK_L) ;
512 */
513/*
514 * ISRA !!! activ high !!!
515 */
516#define IS_MINTR1 0x0001 /* FORMAC ST1U/L & ~IMSK1U/L*/
517#define IS_MINTR2 0x0002 /* FORMAC ST2U/L & ~IMSK2U/L*/
518#define IS_PLINT1 0x0004 /* PLC1 */
519#define IS_PLINT2 0x0008 /* PLC2 */
520#define IS_TIMINT 0x0010 /* Timer 82C54-2 */
521#define IS_TOKEN 0x0020 /* restrictet token monitoring */
522#define IS_CHCK_L 0x0040 /* check line asserted */
523#define IS_BUSERR 0x0080 /* bus error */
524/*
525 * ISR2
526 */
527#define IS_TC 0x0001 /* terminal count irq */
528#define IS_SFDBKRTN 0x0002 /* selected feedback return */
529#define IS_D16 0x0004 /* DS16 */
530#define IS_D32 0x0008 /* DS32 */
531#define IS_DPEI 0x0010 /* Data Parity Indication */
532
533#define ALL_IRSR 0x00ff
534
535#define FM_A(a) ADDR(FMA(a)) /* FORMAC Plus physical addr */
536#define P1_A(a) ADDR(P1(a)) /* PLC1 (r/w) */
537#define P2_A(a) ADDR(P2(a)) /* PLC2 (r/w) (DAS) */
538#define TI_A(a) ADDR(TI(a)) /* Timer (r/w) FM1 only! */
539#define PR_A(a) ADDR(PR(a)) /* config. PROM */
540#define CS_A(a) ADDR(CS(a)) /* control/status */
541
542#define ISR1_A ADDR(ISRA) /* first int. source register address */
543#define ISR2_A ADDR(ISR2) /* second -"- */
544#define CSR_A ADDR(CSRA) /* control/status register address */
545#define CSF_A ADDR(CSFA) /* control/status FIFO BUSY flags (r/w) */
546
547#define CSIL_A ADDR(CSIL) /* I/O mapped POS_ID_low (102) */
548#define CSIH_A ADDR(CSIH) /* - " - POS_ID_HIGH (101) */
549#define CSA_A ADDR(CSA) /* - " - POS_102 */
550#define CSI_A ADDR(CSI) /* - " - POS_104 */
551#define CSM_A ADDR(CSM) /* - " - POS_103 */
552#define CSM_FM1_A ADDR(CSM_FM1) /* - " - POS_103 (2nd copy, FM1) */
553#define CSP_06_A ADDR(CSP_06) /* - " - POS_106 */
554
555#define WCT_A ADDR(WCTA) /* word counter (r/w) */
556#define FFLAG_A ADDR(FFLAG) /* FLAG/V_FULL (FIFO almost full, write only)*/
557
558#define ACL_A ADDR(ACLA) /* address counter low */
559#define ACH_A ADDR(ACHA) /* address counter high */
560#define BCN_A ADDR(BCN) /* byte counter */
561#define MUX_A ADDR(MUX) /* MUX-register */
562
563#define ISR_A ADDR(ISRA) /* Interrupt Source Register */
564#define FIFO_RESET_A ADDR(FIFO_RESET) /* reset the FIFO */
565#define FIFO_EN_A ADDR(FIFO_EN) /* enable the FIFO */
566
567#define WDOG_EN_A ADDR(WDOG_EN) /* reset and start the WDOG */
568#define WDOG_DIS_A ADDR(WDOG_DIS) /* disable the WDOG */
569/*
570 * all control reg. (read!) are 8 bit (except PAGE_RG_A and LEDR_A)
571 */
572#define HSR_A(p) ADDR(HSR(p)) /* Host request register */
573
574#define STAT_BYP 0 /* bypass station */
575#define STAT_INS 2 /* insert station */
576#define BYPASS(o) CS(0x10|(o)) /* o=STAT_BYP || STAT_INS */
577
578#define IRQ_TC_EN CS(0x0b) /* enable/disable IRQ on TC */
579#define IRQ_TC_DIS CS(0x0a)
580#define IRQ_TOKEN_EN CS(9) /* enable/disable IRQ on restr. Token */
581#define IRQ_TOKEN_DIS CS(8)
582#define IRQ_CHCK_EN CS(7) /* -"- IRQ after CHCK line */
583#define IRQ_CHCK_DIS CS(6)
584#define IRQ_OTH_EN CS(5) /* -"- other IRQ's */
585#define IRQ_OTH_DIS CS(4)
586#define FIFO_EN CS(3) /* disable (reset), enable FIFO */
587#define FIFO_RESET CS(2)
588#define CARD_EN CS(1) /* disable (reset), enable card */
589#define CARD_DIS CS(0)
590
591#define LEDR_A ADDR(LEDR) /* D0=green, D1=yellow, D8=L2 */
592#define PAGE_RG_A ADDR(CSM) /* D<2..0> */
593#define IRQ_CHCK_EN_A ADDR(IRQ_CHCK_EN)
594#define IRQ_CHCK_DIS_A ADDR(IRQ_CHCK_DIS)
595
596#define GET_PAGE(bank) outpw(PAGE_RG_A,(inpw(PAGE_RG_A) &\
597 (~POS_PAGE)) |(int) (bank))
598#define VPP_ON() if (smc->hw.rev == FM1_REV) { \
599 outpw(PAGE_RG_A, \
600 (inpw(PAGE_RG_A) & POS_PAGE) | PROG_EN); \
601 }
602#define VPP_OFF() if (smc->hw.rev == FM1_REV) { \
603 outpw(PAGE_RG_A,(inpw(PAGE_RG_A) & POS_PAGE)); \
604 }
605
606#define SKFDDI_PSZ 16 /* address PROM size */
607
608#define READ_PROM(a) ((u_char)inp(a))
609
610#define GET_ISR() ~inpw(ISR1_A)
611#ifndef TCI
612#define CHECK_ISR() ~inpw(ISR1_A)
613#define CHECK_ISR_SMP(iop) ~inpw((iop)+ISRA)
614#else
615#define CHECK_ISR() (~inpw(ISR1_A) | ~inpw(ISR2_A))
616#define CHECK_ISR_SMP(iop) (~inpw((iop)+ISRA) | ~inpw((iop)+ISR2))
617#endif
618
619#define DMA_BUSY() (inpw(CSF_A) & CSF_BUSY_DMA)
620#define FIFO_BUSY() (inpw(CSF_A) & CSF_BUSY_FIFO)
621#define DMA_FIFO_BUSY() (inpw(CSF_A) & (CSF_BUSY_DMA | CSF_BUSY_FIFO))
622#define BUS_CHECK() { int i ; \
623 if ((i = GET_ISR()) & IS_BUSERR) \
624 SMT_PANIC(smc,HWM_E0020,HWM_E0020_MSG) ; \
625 if (i & IS_CHCK_L) \
626 SMT_PANIC(smc,HWM_E0014,HWM_E0014_MSG) ; \
627 }
628
629#define CHECK_DMA() { u_long k = 10000 ; \
630 while (k && (DMA_BUSY())) { \
631 k-- ; \
632 BUS_CHECK() ; \
633 } \
634 if (!k) SMT_PANIC(smc,HWM_E0003,HWM_E0003_MSG) ; }
635
636#define CHECK_FIFO() {u_long k = 1000000 ;\
637 while (k && (FIFO_BUSY())) k-- ;\
638 if (!k) SMT_PANIC(smc,HWM_E0019,HWM_E0019_MSG) ; }
639
640#define CHECK_DMA_FIFO() {u_long k = 1000000 ;\
641 while (k && (DMA_FIFO_BUSY())) { \
642 k-- ;\
643 BUS_CHECK() ; \
644 } \
645 if (!k) SMT_PANIC(smc,HWM_E0004,HWM_E0004_MSG) ; }
646
647#ifndef UNIX
648#define CLI_FBI() outp(ADDR(IRQ_OTH_DIS),0)
649#else
650#define CLI_FBI(smc) outp(ADDRS((smc),IRQ_OTH_DIS),0)
651#endif
652
653#ifndef TCI
654#define CLI_FBI_SMP(iop) outp((iop)+IRQ_OTH_DIS,0)
655#else
656#define CLI_FBI_SMP(iop) outp((iop)+IRQ_OTH_DIS,0) ;\
657 outp((iop)+IRQ_TC_DIS,0)
658#endif
659
660#ifndef UNIX
661#define STI_FBI() outp(ADDR(IRQ_OTH_EN),0)
662#else
663#define STI_FBI(smc) outp(ADDRS((smc),IRQ_OTH_EN),0)
664#endif
665
666/*
667 * Terminal count primitives
668 */
669#define CLI_TCI(smc) outp(ADDRS((smc),IRQ_TC_DIS),0)
670#define STI_TCI(smc) outp(ADDRS((smc),IRQ_TC_EN),0)
671#define CHECK_TC(smc,k) {(k) = 10000 ;\
672 while ((k) && (~inpw(ISR2_A) & IS_TC)) (k)-- ;\
673 if (!k) SMT_PANIC(smc,HWM_E0018,HWM_E0018_MSG) ; }
674
675#endif /* MCA */
676
677#ifdef ISA
678
679/*
680 * address transmission from logic NPADDR6-0 to physical offset address on board
681 */
682#define FMA(a) (0x8000|(((a)&0x07)<<1)|(((a)&0x78)<<7)) /* FORMAC+ (r/w) */
683#define PRA(a) (0x1000|(((a)&0x07)<<1)|(((a)&0x18)<<7)) /* PROM (read only)*/
684#define P1A(a) (0x4000|(((a)&0x07)<<1)|(((a)&0x18)<<7)) /* PLC1 (r/w) */
685#define P2A(a) (0x5000|(((a)&0x07)<<1)|(((a)&0x18)<<7)) /* PLC2 (r/w) */
686#define TIA(a) (0x6000|(((a)&0x03)<<1)) /* Timer (r/w) */
687
688#define ISRA 0x0000 /* int. source register address (read only) */
689#define ACLA 0x0000 /* address counter low address (write only) */
690#define ACHA 0x0002 /* address counter high address (write only) */
691#define TRCA 0x0004 /* transfer counter address (write only) */
692#define PGRA 0x0006 /* page register address (write only) */
693#define RQAA 0x2000 /* Request reg. (write only) */
694#define CSRA 0x3000 /* control/status register address (r/w) */
695
696/*
697 * physical address offset + IO-Port base address
698 */
699#define FM_A(a) (FMA(a)+smc->hw.iop) /* FORMAC Plus physical addr */
700#define PR_A(a) (PRA(a)+smc->hw.iop) /* PROM (read only)*/
701#define P1_A(a) (P1A(a)+smc->hw.iop) /* PLC1 (r/w) */
702#define P2_A(a) (P2A(a)+smc->hw.iop) /* PLC2 (r/w) */
703#define TI_A(a) (TIA(a)+smc->hw.iop) /* Timer (r/w) */
704
705#define ISR_A (0x0000+smc->hw.iop) /* int. source register address (read only) */
706#define ACL_A (0x0000+smc->hw.iop) /* address counter low address (write only) */
707#define ACH_A (0x0002+smc->hw.iop) /* address counter high address (write only)*/
708#define TRC_A (0x0004+smc->hw.iop) /* transfer counter address (write only) */
709#define PGR_A (0x0006+smc->hw.iop) /* page register address (write only) */
710#define RQA_A (0x2000+smc->hw.iop) /* Request reg. (write only) */
711#define CSR_A (0x3000+smc->hw.iop) /* control/status register address (r/w) */
712#ifdef UNIX
713#define CSR_AS(smc) (0x3000+(smc)->hw.iop) /* control/status register address */
714#endif
715#define PLC1_I (0x3400+smc->hw.iop) /* clear PLC1 interrupt bit */
716#define PLC2_I (0x3800+smc->hw.iop) /* clear PLC2 interrupt bit */
717
718#ifndef MULT_OEM
719#ifndef OEM_CONCEPT
720#define SKLOGO_STR "SKFDDI"
721#else /* OEM_CONCEPT */
722#define SKLOGO_STR OEM_FDDI_LOGO
723#endif /* OEM_CONCEPT */
724#endif /* MULT_OEM */
725#define SADDRL (24) /* start address SKLOGO */
726#define SA_MAC (0) /* start addr. MAC_AD within the PROM */
727#define PRA_OFF (0)
728#define SA_PMD_TYPE (8) /* start addr. PMD-Type */
729
730#define CDID (PRA(SADDRL)) /* Card ID int/O port addr. offset */
731#define NEXT_CDID ((PRA(SADDRL+1)) - CDID)
732
733#define SKFDDI_PSZ 32 /* address PROM size */
734
735#define READ_PROM(a) ((u_char)inpw(a))
736#define GET_PAGE(i) outpw(PGR_A,(int)(i))
737
738#define MAX_PAGES 16 /* 16 pages */
739#define MAX_FADDR 0x2000 /* 8K per page */
740#define VPP_OFF() outpw(CSR_A,(inpw(CSR_A) & (CS_CRESET|CS_BYPASS)))
741#define VPP_ON() outpw(CSR_A,(inpw(CSR_A) & (CS_CRESET|CS_BYPASS)) | \
742 CS_VPPSW)
743
744/*
745 * control/status register CSRA bits (log. addr: 0x3000)
746 */
747/* write */
748#define CS_CRESET 0x01 /* Card reset (0=reset) */
749#define CS_IMSK 0x02 /* enable IRQ (1=enable, 0=disable) */
750#define CS_RESINT1 0x04 /* PLINT1 reset */
751#define CS_VPPSW 0x10 /* 12V power switch (0=off, 1=on) */
752#define CS_BYPASS 0x20 /* bypass switch (0=remove, 1=insert)*/
753#define CS_RESINT2 0x40 /* PLINT2 reset */
754/* read */
755#define CS_BUSY 0x04 /* master transfer activ (=1) */
756#define CS_SW_EPROM 0x08 /* 0=Application Soft. 1=BOOT-EPROM */
757#define CS_BYSTAT 0x40 /* 0=Bypass exist, 1= ..not */
758#define CS_SAS 0x80 /* single attachement station (=1) */
759
760/*
761 * Interrupt source register ISRA (log. addr: 0x0000) read only & low activ.
762 */
763#define IS_MINTR1 0x01 /* FORMAC ST1U/L && ~IMSK1U/L*/
764#define IS_MINTR2 0x02 /* FORMAC ST2U/L && ~IMSK2U/L*/
765#define IS_PLINT1 0x04 /* PLC1 */
766#define IS_PLINT2 0x08 /* PLC2 */
767#define IS_TIMINT 0x10 /* Timer 82C54-2 */
768
769#define ALL_IRSR (IS_MINTR1|IS_MINTR2|IS_PLINT1|IS_PLINT2|IS_TIMINT)
770
771#define FPROM_SW() (inpw(CSR_A)&CS_SW_EPROM)
772#define DMA_BUSY() (inpw(CSR_A)&CS_BUSY)
773#define CHECK_FIFO()
774#define BUS_CHECK()
775
776/*
777 * set Host Request register (wr.)
778 */
779#define SET_HRQ(qup) outpw(RQA_A+((qup)<<1),0)
780
781#ifndef UNIX
782#ifndef WINNT
783#define CLI_FBI() outpw(CSR_A,(inpw(CSR_A)&(CS_CRESET|CS_BYPASS|CS_VPPSW)))
784#else
785#define CLI_FBI() outpw(CSR_A,(l_inpw(CSR_A) & \
786 (CS_CRESET|CS_BYPASS|CS_VPPSW)))
787#endif
788#else
789#define CLI_FBI(smc) outpw(CSR_AS(smc),(inpw(CSR_AS(smc))& \
790 (CS_CRESET|CS_BYPASS|CS_VPPSW)))
791#endif
792
793#ifndef UNIX
794#define STI_FBI() outpw(CSR_A,(inpw(CSR_A) & \
795 (CS_CRESET|CS_BYPASS|CS_VPPSW)) | CS_IMSK)
796#else
797#define STI_FBI(smc) outpw(CSR_AS(smc),(inpw(CSR_AS(smc)) & \
798 (CS_CRESET|CS_BYPASS|CS_VPPSW)) | CS_IMSK)
799#endif
800
801#define CHECK_DMA() {unsigned k = 10000 ;\
802 while (k && (DMA_BUSY())) k-- ;\
803 if (!k) SMT_PANIC(smc,HWM_E0003,HWM_E0003_MSG) ; }
804
805#define GET_ISR() ~inpw(ISR_A)
806
807#endif /* ISA */
808
809/*--------------------------------------------------------------------------*/
810#ifdef PCI
811
812/*
813 * (DV) = only defined for Da Vinci
814 * (ML) = only defined for Monalisa
815 */
816
817/*
818 * Configuration Space header
819 */
820#define PCI_VENDOR_ID 0x00 /* 16 bit Vendor ID */
821#define PCI_DEVICE_ID 0x02 /* 16 bit Device ID */
822#define PCI_COMMAND 0x04 /* 16 bit Command */
823#define PCI_STATUS 0x06 /* 16 bit Status */
824#define PCI_REV_ID 0x08 /* 8 bit Revision ID */
825#define PCI_CLASS_CODE 0x09 /* 24 bit Class Code */
826#define PCI_CACHE_LSZ 0x0c /* 8 bit Cache Line Size */
827#define PCI_LAT_TIM 0x0d /* 8 bit Latency Timer */
828#define PCI_HEADER_T 0x0e /* 8 bit Header Type */
829#define PCI_BIST 0x0f /* 8 bit Built-in selftest */
830#define PCI_BASE_1ST 0x10 /* 32 bit 1st Base address */
831#define PCI_BASE_2ND 0x14 /* 32 bit 2nd Base address */
832/* Byte 18..2b: Reserved */
833#define PCI_SUB_VID 0x2c /* 16 bit Subsystem Vendor ID */
834#define PCI_SUB_ID 0x2e /* 16 bit Subsystem ID */
835#define PCI_BASE_ROM 0x30 /* 32 bit Expansion ROM Base Address */
836/* Byte 34..33: Reserved */
837#define PCI_CAP_PTR 0x34 /* 8 bit (ML) Capabilities Ptr */
838/* Byte 35..3b: Reserved */
839#define PCI_IRQ_LINE 0x3c /* 8 bit Interrupt Line */
840#define PCI_IRQ_PIN 0x3d /* 8 bit Interrupt Pin */
841#define PCI_MIN_GNT 0x3e /* 8 bit Min_Gnt */
842#define PCI_MAX_LAT 0x3f /* 8 bit Max_Lat */
843/* Device Dependent Region */
844#define PCI_OUR_REG 0x40 /* 32 bit (DV) Our Register */
845#define PCI_OUR_REG_1 0x40 /* 32 bit (ML) Our Register 1 */
846#define PCI_OUR_REG_2 0x44 /* 32 bit (ML) Our Register 2 */
847/* Power Management Region */
848#define PCI_PM_CAP_ID 0x48 /* 8 bit (ML) Power Management Cap. ID */
849#define PCI_PM_NITEM 0x49 /* 8 bit (ML) Next Item Ptr */
850#define PCI_PM_CAP_REG 0x4a /* 16 bit (ML) Power Management Capabilities */
851#define PCI_PM_CTL_STS 0x4c /* 16 bit (ML) Power Manag. Control/Status */
852/* Byte 0x4e: Reserved */
853#define PCI_PM_DAT_REG 0x4f /* 8 bit (ML) Power Manag. Data Register */
854/* VPD Region */
855#define PCI_VPD_CAP_ID 0x50 /* 8 bit (ML) VPD Cap. ID */
856#define PCI_VPD_NITEM 0x51 /* 8 bit (ML) Next Item Ptr */
857#define PCI_VPD_ADR_REG 0x52 /* 16 bit (ML) VPD Address Register */
858#define PCI_VPD_DAT_REG 0x54 /* 32 bit (ML) VPD Data Register */
859/* Byte 58..ff: Reserved */
860
861/*
862 * I2C Address (PCI Config)
863 *
864 * Note: The temperature and voltage sensors are relocated on a different
865 * I2C bus.
866 */
867#define I2C_ADDR_VPD 0xA0 /* I2C address for the VPD EEPROM */
868
869/*
870 * Define Bits and Values of the registers
871 */
872/* PCI_VENDOR_ID 16 bit Vendor ID */
873/* PCI_DEVICE_ID 16 bit Device ID */
874/* Values for Vendor ID and Device ID shall be patched into the code */
875/* PCI_COMMAND 16 bit Command */
876#define PCI_FBTEN 0x0200 /* Bit 9: Fast Back-To-Back enable */
877#define PCI_SERREN 0x0100 /* Bit 8: SERR enable */
878#define PCI_ADSTEP 0x0080 /* Bit 7: Address Stepping */
879#define PCI_PERREN 0x0040 /* Bit 6: Parity Report Response enable */
880#define PCI_VGA_SNOOP 0x0020 /* Bit 5: VGA palette snoop */
881#define PCI_MWIEN 0x0010 /* Bit 4: Memory write an inv cycl ena */
882#define PCI_SCYCEN 0x0008 /* Bit 3: Special Cycle enable */
883#define PCI_BMEN 0x0004 /* Bit 2: Bus Master enable */
884#define PCI_MEMEN 0x0002 /* Bit 1: Memory Space Access enable */
885#define PCI_IOEN 0x0001 /* Bit 0: IO Space Access enable */
886
887/* PCI_STATUS 16 bit Status */
888#define PCI_PERR 0x8000 /* Bit 15: Parity Error */
889#define PCI_SERR 0x4000 /* Bit 14: Signaled SERR */
890#define PCI_RMABORT 0x2000 /* Bit 13: Received Master Abort */
891#define PCI_RTABORT 0x1000 /* Bit 12: Received Target Abort */
892#define PCI_STABORT 0x0800 /* Bit 11: Sent Target Abort */
893#define PCI_DEVSEL 0x0600 /* Bit 10..9: DEVSEL Timing */
894#define PCI_DEV_FAST (0<<9) /* fast */
895#define PCI_DEV_MEDIUM (1<<9) /* medium */
896#define PCI_DEV_SLOW (2<<9) /* slow */
897#define PCI_DATAPERR 0x0100 /* Bit 8: DATA Parity error detected */
898#define PCI_FB2BCAP 0x0080 /* Bit 7: Fast Back-to-Back Capability */
899#define PCI_UDF 0x0040 /* Bit 6: User Defined Features */
900#define PCI_66MHZCAP 0x0020 /* Bit 5: 66 MHz PCI bus clock capable */
901#define PCI_NEWCAP 0x0010 /* Bit 4: New cap. list implemented */
902
903#define PCI_ERRBITS (PCI_PERR|PCI_SERR|PCI_RMABORT|PCI_STABORT|PCI_DATAPERR)
904
905/* PCI_REV_ID 8 bit Revision ID */
906/* PCI_CLASS_CODE 24 bit Class Code */
907/* Byte 2: Base Class (02) */
908/* Byte 1: SubClass (02) */
909/* Byte 0: Programming Interface (00) */
910
911/* PCI_CACHE_LSZ 8 bit Cache Line Size */
912/* Possible values: 0,2,4,8,16 */
913
914/* PCI_LAT_TIM 8 bit Latency Timer */
915
916/* PCI_HEADER_T 8 bit Header Type */
917#define PCI_HD_MF_DEV 0x80 /* Bit 7: 0= single, 1= multi-func dev */
918#define PCI_HD_TYPE 0x7f /* Bit 6..0: Header Layout 0= normal */
919
920/* PCI_BIST 8 bit Built-in selftest */
921#define PCI_BIST_CAP 0x80 /* Bit 7: BIST Capable */
922#define PCI_BIST_ST 0x40 /* Bit 6: Start BIST */
923#define PCI_BIST_RET 0x0f /* Bit 3..0: Completion Code */
924
925/* PCI_BASE_1ST 32 bit 1st Base address */
926#define PCI_MEMSIZE 0x800L /* use 2 kB Memory Base */
927#define PCI_MEMBASE_BITS 0xfffff800L /* Bit 31..11: Memory Base Address */
928#define PCI_MEMSIZE_BIIS 0x000007f0L /* Bit 10..4: Memory Size Req. */
929#define PCI_PREFEN 0x00000008L /* Bit 3: Prefetchable */
930#define PCI_MEM_TYP 0x00000006L /* Bit 2..1: Memory Type */
931#define PCI_MEM32BIT (0<<1) /* Base addr anywhere in 32 Bit range */
932#define PCI_MEM1M (1<<1) /* Base addr below 1 MegaByte */
933#define PCI_MEM64BIT (2<<1) /* Base addr anywhere in 64 Bit range */
934#define PCI_MEMSPACE 0x00000001L /* Bit 0: Memory Space Indic. */
935
936/* PCI_BASE_2ND 32 bit 2nd Base address */
937#define PCI_IOBASE 0xffffff00L /* Bit 31..8: I/O Base address */
938#define PCI_IOSIZE 0x000000fcL /* Bit 7..2: I/O Size Requirements */
939#define PCI_IOSPACE 0x00000001L /* Bit 0: I/O Space Indicator */
940
941/* PCI_SUB_VID 16 bit Subsystem Vendor ID */
942/* PCI_SUB_ID 16 bit Subsystem ID */
943
944/* PCI_BASE_ROM 32 bit Expansion ROM Base Address */
945#define PCI_ROMBASE 0xfffe0000L /* Bit 31..17: ROM BASE address (1st) */
946#define PCI_ROMBASZ 0x0001c000L /* Bit 16..14: Treat as BASE or SIZE */
947#define PCI_ROMSIZE 0x00003800L /* Bit 13..11: ROM Size Requirements */
948#define PCI_ROMEN 0x00000001L /* Bit 0: Address Decode enable */
949
950/* PCI_CAP_PTR 8 bit New Capabilities Pointers */
951/* PCI_IRQ_LINE 8 bit Interrupt Line */
952/* PCI_IRQ_PIN 8 bit Interrupt Pin */
953/* PCI_MIN_GNT 8 bit Min_Gnt */
954/* PCI_MAX_LAT 8 bit Max_Lat */
955/* Device Dependent Region */
956/* PCI_OUR_REG (DV) 32 bit Our Register */
957/* PCI_OUR_REG_1 (ML) 32 bit Our Register 1 */
958 /* Bit 31..29: reserved */
959#define PCI_PATCH_DIR (3L<<27) /*(DV) Bit 28..27: Ext Patchs direction */
960#define PCI_PATCH_DIR_0 (1L<<27) /*(DV) Type of the pins EXT_PATCHS<1..0> */
961#define PCI_PATCH_DIR_1 (1L<<28) /* 0 = input */
962 /* 1 = output */
963#define PCI_EXT_PATCHS (3L<<25) /*(DV) Bit 26..25: Extended Patches */
964#define PCI_EXT_PATCH_0 (1L<<25) /*(DV) */
965#define PCI_EXT_PATCH_1 (1L<<26) /* CLK for MicroWire (ML) */
966#define PCI_VIO (1L<<25) /*(ML) */
967#define PCI_EN_BOOT (1L<<24) /* Bit 24: Enable BOOT via ROM */
968 /* 1 = Don't boot with ROM */
969 /* 0 = Boot with ROM */
970#define PCI_EN_IO (1L<<23) /* Bit 23: Mapping to IO space */
971#define PCI_EN_FPROM (1L<<22) /* Bit 22: FLASH mapped to mem? */
972 /* 1 = Map Flash to Memory */
973 /* 0 = Disable all addr. decoding */
974#define PCI_PAGESIZE (3L<<20) /* Bit 21..20: FLASH Page Size */
975#define PCI_PAGE_16 (0L<<20) /* 16 k pages */
976#define PCI_PAGE_32K (1L<<20) /* 32 k pages */
977#define PCI_PAGE_64K (2L<<20) /* 64 k pages */
978#define PCI_PAGE_128K (3L<<20) /* 128 k pages */
979 /* Bit 19: reserved (ML) and (DV) */
980#define PCI_PAGEREG (7L<<16) /* Bit 18..16: Page Register */
981 /* Bit 15: reserved */
982#define PCI_FORCE_BE (1L<<14) /* Bit 14: Assert all BEs on MR */
983#define PCI_DIS_MRL (1L<<13) /* Bit 13: Disable Mem R Line */
984#define PCI_DIS_MRM (1L<<12) /* Bit 12: Disable Mem R multip */
985#define PCI_DIS_MWI (1L<<11) /* Bit 11: Disable Mem W & inv */
986#define PCI_DISC_CLS (1L<<10) /* Bit 10: Disc: cacheLsz bound */
987#define PCI_BURST_DIS (1L<<9) /* Bit 9: Burst Disable */
988#define PCI_BYTE_SWAP (1L<<8) /*(DV) Bit 8: Byte Swap in DATA */
989#define PCI_SKEW_DAS (0xfL<<4) /* Bit 7..4: Skew Ctrl, DAS Ext */
990#define PCI_SKEW_BASE (0xfL<<0) /* Bit 3..0: Skew Ctrl, Base */
991
992/* PCI_OUR_REG_2 (ML) 32 bit Our Register 2 (Monalisa only) */
993#define PCI_VPD_WR_TH (0xffL<<24) /* Bit 24..31 VPD Write Threshold */
994#define PCI_DEV_SEL (0x7fL<<17) /* Bit 17..23 EEPROM Device Select */
995#define PCI_VPD_ROM_SZ (7L<<14) /* Bit 14..16 VPD ROM Size */
996 /* Bit 12..13 reserved */
997#define PCI_PATCH_DIR2 (0xfL<<8) /* Bit 8..11 Ext Patchs dir 2..5 */
998#define PCI_PATCH_DIR_2 (1L<<8) /* Bit 8 CS for MicroWire */
999#define PCI_PATCH_DIR_3 (1L<<9)
1000#define PCI_PATCH_DIR_4 (1L<<10)
1001#define PCI_PATCH_DIR_5 (1L<<11)
1002#define PCI_EXT_PATCHS2 (0xfL<<4) /* Bit 4..7 Extended Patches */
1003#define PCI_EXT_PATCH_2 (1L<<4) /* Bit 4 CS for MicroWire */
1004#define PCI_EXT_PATCH_3 (1L<<5)
1005#define PCI_EXT_PATCH_4 (1L<<6)
1006#define PCI_EXT_PATCH_5 (1L<<7)
1007#define PCI_EN_DUMMY_RD (1L<<3) /* Bit 3 Enable Dummy Read */
1008#define PCI_REV_DESC (1L<<2) /* Bit 2 Reverse Desc. Bytes */
1009#define PCI_USEADDR64 (1L<<1) /* Bit 1 Use 64 Bit Addresse */
1010#define PCI_USEDATA64 (1L<<0) /* Bit 0 Use 64 Bit Data bus ext*/
1011
1012/* Power Management Region */
1013/* PCI_PM_CAP_ID 8 bit (ML) Power Management Cap. ID */
1014/* PCI_PM_NITEM 8 bit (ML) Next Item Ptr */
1015/* PCI_PM_CAP_REG 16 bit (ML) Power Management Capabilities*/
1016#define PCI_PME_SUP (0x1f<<11) /* Bit 11..15 PM Manag. Event Support*/
1017#define PCI_PM_D2_SUB (1<<10) /* Bit 10 D2 Support Bit */
1018#define PCI_PM_D1_SUB (1<<9) /* Bit 9 D1 Support Bit */
1019 /* Bit 6..8 reserved */
1020#define PCI_PM_DSI (1<<5) /* Bit 5 Device Specific Init.*/
1021#define PCI_PM_APS (1<<4) /* Bit 4 Auxialiary Power Src */
1022#define PCI_PME_CLOCK (1<<3) /* Bit 3 PM Event Clock */
1023#define PCI_PM_VER (7<<0) /* Bit 0..2 PM PCI Spec. version */
1024
1025/* PCI_PM_CTL_STS 16 bit (ML) Power Manag. Control/Status */
1026#define PCI_PME_STATUS (1<<15) /* Bit 15 PFA doesn't sup. PME#*/
1027#define PCI_PM_DAT_SCL (3<<13) /* Bit 13..14 dat reg Scaling factor */
1028#define PCI_PM_DAT_SEL (0xf<<9) /* Bit 9..12 PM data selector field */
1029 /* Bit 7.. 2 reserved */
1030#define PCI_PM_STATE (3<<0) /* Bit 0.. 1 Power Management State */
1031#define PCI_PM_STATE_D0 (0<<0) /* D0: Operational (default) */
1032#define PCI_PM_STATE_D1 (1<<0) /* D1: not supported */
1033#define PCI_PM_STATE_D2 (2<<0) /* D2: not supported */
1034#define PCI_PM_STATE_D3 (3<<0) /* D3: HOT, Power Down and Reset */
1035
1036/* PCI_PM_DAT_REG 8 bit (ML) Power Manag. Data Register */
1037/* VPD Region */
1038/* PCI_VPD_CAP_ID 8 bit (ML) VPD Cap. ID */
1039/* PCI_VPD_NITEM 8 bit (ML) Next Item Ptr */
1040/* PCI_VPD_ADR_REG 16 bit (ML) VPD Address Register */
1041#define PCI_VPD_FLAG (1<<15) /* Bit 15 starts VPD rd/wd cycle*/
1042
1043/* PCI_VPD_DAT_REG 32 bit (ML) VPD Data Register */
1044
1045/*
1046 * Control Register File:
1047 * Bank 0
1048 */
1049#define B0_RAP 0x0000 /* 8 bit register address port */
1050 /* 0x0001 - 0x0003: reserved */
1051#define B0_CTRL 0x0004 /* 8 bit control register */
1052#define B0_DAS 0x0005 /* 8 Bit control register (DAS) */
1053#define B0_LED 0x0006 /* 8 Bit LED register */
1054#define B0_TST_CTRL 0x0007 /* 8 bit test control register */
1055#define B0_ISRC 0x0008 /* 32 bit Interrupt source register */
1056#define B0_IMSK 0x000c /* 32 bit Interrupt mask register */
1057
1058/* 0x0010 - 0x006b: formac+ (supernet_3) fequently used registers */
1059#define B0_CMDREG1 0x0010 /* write command reg 1 instruction */
1060#define B0_CMDREG2 0x0014 /* write command reg 2 instruction */
1061#define B0_ST1U 0x0010 /* read upper 16-bit of status reg 1 */
1062#define B0_ST1L 0x0014 /* read lower 16-bit of status reg 1 */
1063#define B0_ST2U 0x0018 /* read upper 16-bit of status reg 2 */
1064#define B0_ST2L 0x001c /* read lower 16-bit of status reg 2 */
1065
1066#define B0_MARR 0x0020 /* r/w the memory read addr register */
1067#define B0_MARW 0x0024 /* r/w the memory write addr register*/
1068#define B0_MDRU 0x0028 /* r/w upper 16-bit of mem. data reg */
1069#define B0_MDRL 0x002c /* r/w lower 16-bit of mem. data reg */
1070
1071#define B0_MDREG3 0x0030 /* r/w Mode Register 3 */
1072#define B0_ST3U 0x0034 /* read upper 16-bit of status reg 3 */
1073#define B0_ST3L 0x0038 /* read lower 16-bit of status reg 3 */
1074#define B0_IMSK3U 0x003c /* r/w upper 16-bit of IMSK reg 3 */
1075#define B0_IMSK3L 0x0040 /* r/w lower 16-bit of IMSK reg 3 */
1076#define B0_IVR 0x0044 /* read Interrupt Vector register */
1077#define B0_IMR 0x0048 /* r/w Interrupt mask register */
1078/* 0x4c Hidden */
1079
1080#define B0_CNTRL_A 0x0050 /* control register A (r/w) */
1081#define B0_CNTRL_B 0x0054 /* control register B (r/w) */
1082#define B0_INTR_MASK 0x0058 /* interrupt mask (r/w) */
1083#define B0_XMIT_VECTOR 0x005c /* transmit vector register (r/w) */
1084
1085#define B0_STATUS_A 0x0060 /* status register A (read only) */
1086#define B0_STATUS_B 0x0064 /* status register B (read only) */
1087#define B0_CNTRL_C 0x0068 /* control register C (r/w) */
1088#define B0_MDREG1 0x006c /* r/w Mode Register 1 */
1089
1090#define B0_R1_CSR 0x0070 /* 32 bit BMU control/status reg (rec q 1) */
1091#define B0_R2_CSR 0x0074 /* 32 bit BMU control/status reg (rec q 2)(DV)*/
1092#define B0_XA_CSR 0x0078 /* 32 bit BMU control/status reg (a xmit q) */
1093#define B0_XS_CSR 0x007c /* 32 bit BMU control/status reg (s xmit q) */
1094
1095/*
1096 * Bank 1
1097 * - completely empty (this is the RAP Block window)
1098 * Note: if RAP = 1 this page is reserved
1099 */
1100
1101/*
1102 * Bank 2
1103 */
1104#define B2_MAC_0 0x0100 /* 8 bit MAC address Byte 0 */
1105#define B2_MAC_1 0x0101 /* 8 bit MAC address Byte 1 */
1106#define B2_MAC_2 0x0102 /* 8 bit MAC address Byte 2 */
1107#define B2_MAC_3 0x0103 /* 8 bit MAC address Byte 3 */
1108#define B2_MAC_4 0x0104 /* 8 bit MAC address Byte 4 */
1109#define B2_MAC_5 0x0105 /* 8 bit MAC address Byte 5 */
1110#define B2_MAC_6 0x0106 /* 8 bit MAC address Byte 6 (== 0) (DV) */
1111#define B2_MAC_7 0x0107 /* 8 bit MAC address Byte 7 (== 0) (DV) */
1112
1113#define B2_CONN_TYP 0x0108 /* 8 bit Connector type */
1114#define B2_PMD_TYP 0x0109 /* 8 bit PMD type */
1115 /* 0x010a - 0x010b: reserved */
1116 /* Eprom registers are currently of no use */
1117#define B2_E_0 0x010c /* 8 bit EPROM Byte 0 */
1118#define B2_E_1 0x010d /* 8 bit EPROM Byte 1 */
1119#define B2_E_2 0x010e /* 8 bit EPROM Byte 2 */
1120#define B2_E_3 0x010f /* 8 bit EPROM Byte 3 */
1121#define B2_FAR 0x0110 /* 32 bit Flash-Prom Address Register/Counter */
1122#define B2_FDP 0x0114 /* 8 bit Flash-Prom Data Port */
1123 /* 0x0115 - 0x0117: reserved */
1124#define B2_LD_CRTL 0x0118 /* 8 bit loader control */
1125#define B2_LD_TEST 0x0119 /* 8 bit loader test */
1126 /* 0x011a - 0x011f: reserved */
1127#define B2_TI_INI 0x0120 /* 32 bit Timer init value */
1128#define B2_TI_VAL 0x0124 /* 32 bit Timer value */
1129#define B2_TI_CRTL 0x0128 /* 8 bit Timer control */
1130#define B2_TI_TEST 0x0129 /* 8 Bit Timer Test */
1131 /* 0x012a - 0x012f: reserved */
1132#define B2_WDOG_INI 0x0130 /* 32 bit Watchdog init value */
1133#define B2_WDOG_VAL 0x0134 /* 32 bit Watchdog value */
1134#define B2_WDOG_CRTL 0x0138 /* 8 bit Watchdog control */
1135#define B2_WDOG_TEST 0x0139 /* 8 Bit Watchdog Test */
1136 /* 0x013a - 0x013f: reserved */
1137#define B2_RTM_INI 0x0140 /* 32 bit RTM init value */
1138#define B2_RTM_VAL 0x0144 /* 32 bit RTM value */
1139#define B2_RTM_CRTL 0x0148 /* 8 bit RTM control */
1140#define B2_RTM_TEST 0x0149 /* 8 Bit RTM Test */
1141
1142#define B2_TOK_COUNT 0x014c /* (ML) 32 bit Token Counter */
1143#define B2_DESC_ADDR_H 0x0150 /* (ML) 32 bit Desciptor Base Addr Reg High */
1144#define B2_CTRL_2 0x0154 /* (ML) 8 bit Control Register 2 */
1145#define B2_IFACE_REG 0x0155 /* (ML) 8 bit Interface Register */
1146 /* 0x0156: reserved */
1147#define B2_TST_CTRL_2 0x0157 /* (ML) 8 bit Test Control Register 2 */
1148#define B2_I2C_CTRL 0x0158 /* (ML) 32 bit I2C Control Register */
1149#define B2_I2C_DATA 0x015c /* (ML) 32 bit I2C Data Register */
1150
1151#define B2_IRQ_MOD_INI 0x0160 /* (ML) 32 bit IRQ Moderation Timer Init Reg. */
1152#define B2_IRQ_MOD_VAL 0x0164 /* (ML) 32 bit IRQ Moderation Timer Value */
1153#define B2_IRQ_MOD_CTRL 0x0168 /* (ML) 8 bit IRQ Moderation Timer Control */
1154#define B2_IRQ_MOD_TEST 0x0169 /* (ML) 8 bit IRQ Moderation Timer Test */
1155 /* 0x016a - 0x017f: reserved */
1156
1157/*
1158 * Bank 3
1159 */
1160/*
1161 * This is a copy of the Configuration register file (lower half)
1162 */
1163#define B3_CFG_SPC 0x180
1164
1165/*
1166 * Bank 4
1167 */
1168#define B4_R1_D 0x0200 /* 4*32 bit current receive Descriptor */
1169#define B4_R1_DA 0x0210 /* 32 bit current rec desc address */
1170#define B4_R1_AC 0x0214 /* 32 bit current receive Address Count */
1171#define B4_R1_BC 0x0218 /* 32 bit current receive Byte Counter */
1172#define B4_R1_CSR 0x021c /* 32 bit BMU Control/Status Register */
1173#define B4_R1_F 0x0220 /* 32 bit flag register */
1174#define B4_R1_T1 0x0224 /* 32 bit Test Register 1 */
1175#define B4_R1_T1_TR 0x0224 /* 8 bit Test Register 1 TR */
1176#define B4_R1_T1_WR 0x0225 /* 8 bit Test Register 1 WR */
1177#define B4_R1_T1_RD 0x0226 /* 8 bit Test Register 1 RD */
1178#define B4_R1_T1_SV 0x0227 /* 8 bit Test Register 1 SV */
1179#define B4_R1_T2 0x0228 /* 32 bit Test Register 2 */
1180#define B4_R1_T3 0x022c /* 32 bit Test Register 3 */
1181#define B4_R1_DA_H 0x0230 /* (ML) 32 bit Curr Rx Desc Address High */
1182#define B4_R1_AC_H 0x0234 /* (ML) 32 bit Curr Addr Counter High dword */
1183 /* 0x0238 - 0x023f: reserved */
1184 /* Receive queue 2 is removed on Monalisa */
1185#define B4_R2_D 0x0240 /* 4*32 bit current receive Descriptor (q2) */
1186#define B4_R2_DA 0x0250 /* 32 bit current rec desc address (q2) */
1187#define B4_R2_AC 0x0254 /* 32 bit current receive Address Count (q2) */
1188#define B4_R2_BC 0x0258 /* 32 bit current receive Byte Counter (q2) */
1189#define B4_R2_CSR 0x025c /* 32 bit BMU Control/Status Register (q2) */
1190#define B4_R2_F 0x0260 /* 32 bit flag register (q2) */
1191#define B4_R2_T1 0x0264 /* 32 bit Test Register 1 (q2) */
1192#define B4_R2_T1_TR 0x0264 /* 8 bit Test Register 1 TR (q2) */
1193#define B4_R2_T1_WR 0x0265 /* 8 bit Test Register 1 WR (q2) */
1194#define B4_R2_T1_RD 0x0266 /* 8 bit Test Register 1 RD (q2) */
1195#define B4_R2_T1_SV 0x0267 /* 8 bit Test Register 1 SV (q2) */
1196#define B4_R2_T2 0x0268 /* 32 bit Test Register 2 (q2) */
1197#define B4_R2_T3 0x026c /* 32 bit Test Register 3 (q2) */
1198 /* 0x0270 - 0x027c: reserved */
1199
1200/*
1201 * Bank 5
1202 */
1203#define B5_XA_D 0x0280 /* 4*32 bit current transmit Descriptor (xa) */
1204#define B5_XA_DA 0x0290 /* 32 bit current tx desc address (xa) */
1205#define B5_XA_AC 0x0294 /* 32 bit current tx Address Count (xa) */
1206#define B5_XA_BC 0x0298 /* 32 bit current tx Byte Counter (xa) */
1207#define B5_XA_CSR 0x029c /* 32 bit BMU Control/Status Register (xa) */
1208#define B5_XA_F 0x02a0 /* 32 bit flag register (xa) */
1209#define B5_XA_T1 0x02a4 /* 32 bit Test Register 1 (xa) */
1210#define B5_XA_T1_TR 0x02a4 /* 8 bit Test Register 1 TR (xa) */
1211#define B5_XA_T1_WR 0x02a5 /* 8 bit Test Register 1 WR (xa) */
1212#define B5_XA_T1_RD 0x02a6 /* 8 bit Test Register 1 RD (xa) */
1213#define B5_XA_T1_SV 0x02a7 /* 8 bit Test Register 1 SV (xa) */
1214#define B5_XA_T2 0x02a8 /* 32 bit Test Register 2 (xa) */
1215#define B5_XA_T3 0x02ac /* 32 bit Test Register 3 (xa) */
1216#define B5_XA_DA_H 0x02b0 /* (ML) 32 bit Curr Tx Desc Address High */
1217#define B5_XA_AC_H 0x02b4 /* (ML) 32 bit Curr Addr Counter High dword */
1218 /* 0x02b8 - 0x02bc: reserved */
1219#define B5_XS_D 0x02c0 /* 4*32 bit current transmit Descriptor (xs) */
1220#define B5_XS_DA 0x02d0 /* 32 bit current tx desc address (xs) */
1221#define B5_XS_AC 0x02d4 /* 32 bit current transmit Address Count(xs) */
1222#define B5_XS_BC 0x02d8 /* 32 bit current transmit Byte Counter (xs) */
1223#define B5_XS_CSR 0x02dc /* 32 bit BMU Control/Status Register (xs) */
1224#define B5_XS_F 0x02e0 /* 32 bit flag register (xs) */
1225#define B5_XS_T1 0x02e4 /* 32 bit Test Register 1 (xs) */
1226#define B5_XS_T1_TR 0x02e4 /* 8 bit Test Register 1 TR (xs) */
1227#define B5_XS_T1_WR 0x02e5 /* 8 bit Test Register 1 WR (xs) */
1228#define B5_XS_T1_RD 0x02e6 /* 8 bit Test Register 1 RD (xs) */
1229#define B5_XS_T1_SV 0x02e7 /* 8 bit Test Register 1 SV (xs) */
1230#define B5_XS_T2 0x02e8 /* 32 bit Test Register 2 (xs) */
1231#define B5_XS_T3 0x02ec /* 32 bit Test Register 3 (xs) */
1232#define B5_XS_DA_H 0x02f0 /* (ML) 32 bit Curr Tx Desc Address High */
1233#define B5_XS_AC_H 0x02f4 /* (ML) 32 bit Curr Addr Counter High dword */
1234 /* 0x02f8 - 0x02fc: reserved */
1235
1236/*
1237 * Bank 6
1238 */
1239/* External PLC-S registers (SN2 compatibility for DV) */
1240/* External registers (ML) */
1241#define B6_EXT_REG 0x300
1242
1243/*
1244 * Bank 7
1245 */
1246/* DAS PLC-S Registers */
1247
1248/*
1249 * Bank 8 - 15
1250 */
1251/* IFCP registers */
1252
1253/*---------------------------------------------------------------------------*/
1254/* Definitions of the Bits in the registers */
1255
1256/* B0_RAP 16 bit register address port */
1257#define RAP_RAP 0x0f /* Bit 3..0: 0 = block0, .., f = block15 */
1258
1259/* B0_CTRL 8 bit control register */
1260#define CTRL_FDDI_CLR (1<<7) /* Bit 7: (ML) Clear FDDI Reset */
1261#define CTRL_FDDI_SET (1<<6) /* Bit 6: (ML) Set FDDI Reset */
1262#define CTRL_HPI_CLR (1<<5) /* Bit 5: Clear HPI SM reset */
1263#define CTRL_HPI_SET (1<<4) /* Bit 4: Set HPI SM reset */
1264#define CTRL_MRST_CLR (1<<3) /* Bit 3: Clear Master reset */
1265#define CTRL_MRST_SET (1<<2) /* Bit 2: Set Master reset */
1266#define CTRL_RST_CLR (1<<1) /* Bit 1: Clear Software reset */
1267#define CTRL_RST_SET (1<<0) /* Bit 0: Set Software reset */
1268
1269/* B0_DAS 8 Bit control register (DAS) */
1270#define BUS_CLOCK (1<<7) /* Bit 7: (ML) Bus Clock 0/1 = 33/66MHz */
1271#define BUS_SLOT_SZ (1<<6) /* Bit 6: (ML) Slot Size 0/1 = 32/64 bit slot*/
1272 /* Bit 5..4: reserved */
1273#define DAS_AVAIL (1<<3) /* Bit 3: 1 = DAS, 0 = SAS */
1274#define DAS_BYP_ST (1<<2) /* Bit 2: 1 = avail,SAS, 0 = not avail */
1275#define DAS_BYP_INS (1<<1) /* Bit 1: 1 = insert Bypass */
1276#define DAS_BYP_RMV (1<<0) /* Bit 0: 1 = remove Bypass */
1277
1278/* B0_LED 8 Bit LED register */
1279 /* Bit 7..6: reserved */
1280#define LED_2_ON (1<<5) /* Bit 5: 1 = switch LED_2 on (left,gn)*/
1281#define LED_2_OFF (1<<4) /* Bit 4: 1 = switch LED_2 off */
1282#define LED_1_ON (1<<3) /* Bit 3: 1 = switch LED_1 on (mid,yel)*/
1283#define LED_1_OFF (1<<2) /* Bit 2: 1 = switch LED_1 off */
1284#define LED_0_ON (1<<1) /* Bit 1: 1 = switch LED_0 on (rght,gn)*/
1285#define LED_0_OFF (1<<0) /* Bit 0: 1 = switch LED_0 off */
1286/* This hardware defines are very ugly therefore we define some others */
1287
1288#define LED_GA_ON LED_2_ON /* S port = A port */
1289#define LED_GA_OFF LED_2_OFF /* S port = A port */
1290#define LED_MY_ON LED_1_ON
1291#define LED_MY_OFF LED_1_OFF
1292#define LED_GB_ON LED_0_ON
1293#define LED_GB_OFF LED_0_OFF
1294
1295/* B0_TST_CTRL 8 bit test control register */
1296#define TST_FRC_DPERR_MR (1<<7) /* Bit 7: force DATAPERR on MST RE. */
1297#define TST_FRC_DPERR_MW (1<<6) /* Bit 6: force DATAPERR on MST WR. */
1298#define TST_FRC_DPERR_TR (1<<5) /* Bit 5: force DATAPERR on TRG RE. */
1299#define TST_FRC_DPERR_TW (1<<4) /* Bit 4: force DATAPERR on TRG WR. */
1300#define TST_FRC_APERR_M (1<<3) /* Bit 3: force ADDRPERR on MST */
1301#define TST_FRC_APERR_T (1<<2) /* Bit 2: force ADDRPERR on TRG */
1302#define TST_CFG_WRITE_ON (1<<1) /* Bit 1: ena configuration reg. WR */
1303#define TST_CFG_WRITE_OFF (1<<0) /* Bit 0: dis configuration reg. WR */
1304
1305/* B0_ISRC 32 bit Interrupt source register */
1306 /* Bit 31..28: reserved */
1307#define IS_I2C_READY (1L<<27) /* Bit 27: (ML) IRQ on end of I2C tx */
1308#define IS_IRQ_SW (1L<<26) /* Bit 26: (ML) SW forced IRQ */
1309#define IS_EXT_REG (1L<<25) /* Bit 25: (ML) IRQ from external reg*/
1310#define IS_IRQ_STAT (1L<<24) /* Bit 24: IRQ status exception */
1311 /* PERR, RMABORT, RTABORT DATAPERR */
1312#define IS_IRQ_MST_ERR (1L<<23) /* Bit 23: IRQ master error */
1313 /* RMABORT, RTABORT, DATAPERR */
1314#define IS_TIMINT (1L<<22) /* Bit 22: IRQ_TIMER */
1315#define IS_TOKEN (1L<<21) /* Bit 21: IRQ_RTM */
1316/*
1317 * Note: The DAS is our First Port (!=PA)
1318 */
1319#define IS_PLINT1 (1L<<20) /* Bit 20: IRQ_PHY_DAS */
1320#define IS_PLINT2 (1L<<19) /* Bit 19: IRQ_IFCP_4 */
1321#define IS_MINTR3 (1L<<18) /* Bit 18: IRQ_IFCP_3/IRQ_PHY */
1322#define IS_MINTR2 (1L<<17) /* Bit 17: IRQ_IFCP_2/IRQ_MAC_2 */
1323#define IS_MINTR1 (1L<<16) /* Bit 16: IRQ_IFCP_1/IRQ_MAC_1 */
1324/* Receive Queue 1 */
1325#define IS_R1_P (1L<<15) /* Bit 15: Parity Error (q1) */
1326#define IS_R1_B (1L<<14) /* Bit 14: End of Buffer (q1) */
1327#define IS_R1_F (1L<<13) /* Bit 13: End of Frame (q1) */
1328#define IS_R1_C (1L<<12) /* Bit 12: Encoding Error (q1) */
1329/* Receive Queue 2 */
1330#define IS_R2_P (1L<<11) /* Bit 11: (DV) Parity Error (q2) */
1331#define IS_R2_B (1L<<10) /* Bit 10: (DV) End of Buffer (q2) */
1332#define IS_R2_F (1L<<9) /* Bit 9: (DV) End of Frame (q2) */
1333#define IS_R2_C (1L<<8) /* Bit 8: (DV) Encoding Error (q2) */
1334/* Asynchronous Transmit queue */
1335 /* Bit 7: reserved */
1336#define IS_XA_B (1L<<6) /* Bit 6: End of Buffer (xa) */
1337#define IS_XA_F (1L<<5) /* Bit 5: End of Frame (xa) */
1338#define IS_XA_C (1L<<4) /* Bit 4: Encoding Error (xa) */
1339/* Synchronous Transmit queue */
1340 /* Bit 3: reserved */
1341#define IS_XS_B (1L<<2) /* Bit 2: End of Buffer (xs) */
1342#define IS_XS_F (1L<<1) /* Bit 1: End of Frame (xs) */
1343#define IS_XS_C (1L<<0) /* Bit 0: Encoding Error (xs) */
1344
1345/*
1346 * Define all valid interrupt source Bits from GET_ISR ()
1347 */
1348#define ALL_IRSR 0x01ffff77L /* (DV) */
1349#define ALL_IRSR_ML 0x0ffff077L /* (ML) */
1350
1351
1352/* B0_IMSK 32 bit Interrupt mask register */
1353/*
1354 * The Bit definnition of this register are the same as of the interrupt
1355 * source register. These definition are directly derived from the Hardware
1356 * spec.
1357 */
1358 /* Bit 31..28: reserved */
1359#define IRQ_I2C_READY (1L<<27) /* Bit 27: (ML) IRQ on end of I2C tx */
1360#define IRQ_SW (1L<<26) /* Bit 26: (ML) SW forced IRQ */
1361#define IRQ_EXT_REG (1L<<25) /* Bit 25: (ML) IRQ from external reg*/
1362#define IRQ_STAT (1L<<24) /* Bit 24: IRQ status exception */
1363 /* PERR, RMABORT, RTABORT DATAPERR */
1364#define IRQ_MST_ERR (1L<<23) /* Bit 23: IRQ master error */
1365 /* RMABORT, RTABORT, DATAPERR */
1366#define IRQ_TIMER (1L<<22) /* Bit 22: IRQ_TIMER */
1367#define IRQ_RTM (1L<<21) /* Bit 21: IRQ_RTM */
1368#define IRQ_DAS (1L<<20) /* Bit 20: IRQ_PHY_DAS */
1369#define IRQ_IFCP_4 (1L<<19) /* Bit 19: IRQ_IFCP_4 */
1370#define IRQ_IFCP_3 (1L<<18) /* Bit 18: IRQ_IFCP_3/IRQ_PHY */
1371#define IRQ_IFCP_2 (1L<<17) /* Bit 17: IRQ_IFCP_2/IRQ_MAC_2 */
1372#define IRQ_IFCP_1 (1L<<16) /* Bit 16: IRQ_IFCP_1/IRQ_MAC_1 */
1373/* Receive Queue 1 */
1374#define IRQ_R1_P (1L<<15) /* Bit 15: Parity Error (q1) */
1375#define IRQ_R1_B (1L<<14) /* Bit 14: End of Buffer (q1) */
1376#define IRQ_R1_F (1L<<13) /* Bit 13: End of Frame (q1) */
1377#define IRQ_R1_C (1L<<12) /* Bit 12: Encoding Error (q1) */
1378/* Receive Queue 2 */
1379#define IRQ_R2_P (1L<<11) /* Bit 11: (DV) Parity Error (q2) */
1380#define IRQ_R2_B (1L<<10) /* Bit 10: (DV) End of Buffer (q2) */
1381#define IRQ_R2_F (1L<<9) /* Bit 9: (DV) End of Frame (q2) */
1382#define IRQ_R2_C (1L<<8) /* Bit 8: (DV) Encoding Error (q2) */
1383/* Asynchronous Transmit queue */
1384 /* Bit 7: reserved */
1385#define IRQ_XA_B (1L<<6) /* Bit 6: End of Buffer (xa) */
1386#define IRQ_XA_F (1L<<5) /* Bit 5: End of Frame (xa) */
1387#define IRQ_XA_C (1L<<4) /* Bit 4: Encoding Error (xa) */
1388/* Synchronous Transmit queue */
1389 /* Bit 3: reserved */
1390#define IRQ_XS_B (1L<<2) /* Bit 2: End of Buffer (xs) */
1391#define IRQ_XS_F (1L<<1) /* Bit 1: End of Frame (xs) */
1392#define IRQ_XS_C (1L<<0) /* Bit 0: Encoding Error (xs) */
1393
1394/* 0x0010 - 0x006b: formac+ (supernet_3) fequently used registers */
1395/* B0_R1_CSR 32 bit BMU control/status reg (rec q 1 ) */
1396/* B0_R2_CSR 32 bit BMU control/status reg (rec q 2 ) */
1397/* B0_XA_CSR 32 bit BMU control/status reg (a xmit q ) */
1398/* B0_XS_CSR 32 bit BMU control/status reg (s xmit q ) */
1399/* The registers are the same as B4_R1_CSR, B4_R2_CSR, B5_Xa_CSR, B5_XS_CSR */
1400
1401/* B2_MAC_0 8 bit MAC address Byte 0 */
1402/* B2_MAC_1 8 bit MAC address Byte 1 */
1403/* B2_MAC_2 8 bit MAC address Byte 2 */
1404/* B2_MAC_3 8 bit MAC address Byte 3 */
1405/* B2_MAC_4 8 bit MAC address Byte 4 */
1406/* B2_MAC_5 8 bit MAC address Byte 5 */
1407/* B2_MAC_6 8 bit MAC address Byte 6 (== 0) (DV) */
1408/* B2_MAC_7 8 bit MAC address Byte 7 (== 0) (DV) */
1409
1410/* B2_CONN_TYP 8 bit Connector type */
1411/* B2_PMD_TYP 8 bit PMD type */
1412/* Values of connector and PMD type comply to SysKonnect internal std */
1413
1414/* The EPROM register are currently of no use */
1415/* B2_E_0 8 bit EPROM Byte 0 */
1416/* B2_E_1 8 bit EPROM Byte 1 */
1417/* B2_E_2 8 bit EPROM Byte 2 */
1418/* B2_E_3 8 bit EPROM Byte 3 */
1419
1420/* B2_FAR 32 bit Flash-Prom Address Register/Counter */
1421#define FAR_ADDR 0x1ffffL /* Bit 16..0: FPROM Address mask */
1422
1423/* B2_FDP 8 bit Flash-Prom Data Port */
1424
1425/* B2_LD_CRTL 8 bit loader control */
1426/* Bits are currently reserved */
1427
1428/* B2_LD_TEST 8 bit loader test */
1429#define LD_T_ON (1<<3) /* Bit 3: Loader Testmode on */
1430#define LD_T_OFF (1<<2) /* Bit 2: Loader Testmode off */
1431#define LD_T_STEP (1<<1) /* Bit 1: Decrement FPROM addr. Counter */
1432#define LD_START (1<<0) /* Bit 0: Start loading FPROM */
1433
1434/* B2_TI_INI 32 bit Timer init value */
1435/* B2_TI_VAL 32 bit Timer value */
1436/* B2_TI_CRTL 8 bit Timer control */
1437/* B2_TI_TEST 8 Bit Timer Test */
1438/* B2_WDOG_INI 32 bit Watchdog init value */
1439/* B2_WDOG_VAL 32 bit Watchdog value */
1440/* B2_WDOG_CRTL 8 bit Watchdog control */
1441/* B2_WDOG_TEST 8 Bit Watchdog Test */
1442/* B2_RTM_INI 32 bit RTM init value */
1443/* B2_RTM_VAL 32 bit RTM value */
1444/* B2_RTM_CRTL 8 bit RTM control */
1445/* B2_RTM_TEST 8 Bit RTM Test */
1446/* B2_<TIM>_CRTL 8 bit <TIM> control */
1447/* B2_IRQ_MOD_INI 32 bit IRQ Moderation Timer Init Reg. (ML) */
1448/* B2_IRQ_MOD_VAL 32 bit IRQ Moderation Timer Value (ML) */
1449/* B2_IRQ_MOD_CTRL 8 bit IRQ Moderation Timer Control (ML) */
1450/* B2_IRQ_MOD_TEST 8 bit IRQ Moderation Timer Test (ML) */
1451#define GET_TOK_CT (1<<4) /* Bit 4: Get the Token Counter (RTM) */
1452#define TIM_RES_TOK (1<<3) /* Bit 3: RTM Status: 1 == restricted */
1453#define TIM_ALARM (1<<3) /* Bit 3: Timer Alarm (WDOG) */
1454#define TIM_START (1<<2) /* Bit 2: Start Timer (TI,WDOG,RTM,IRQ_MOD)*/
1455#define TIM_STOP (1<<1) /* Bit 1: Stop Timer (TI,WDOG,RTM,IRQ_MOD) */
1456#define TIM_CL_IRQ (1<<0) /* Bit 0: Clear Timer IRQ (TI,WDOG,RTM) */
1457/* B2_<TIM>_TEST 8 Bit <TIM> Test */
1458#define TIM_T_ON (1<<2) /* Bit 2: Test mode on (TI,WDOG,RTM,IRQ_MOD) */
1459#define TIM_T_OFF (1<<1) /* Bit 1: Test mode off (TI,WDOG,RTM,IRQ_MOD) */
1460#define TIM_T_STEP (1<<0) /* Bit 0: Test step (TI,WDOG,RTM,IRQ_MOD) */
1461
1462/* B2_TOK_COUNT 0x014c (ML) 32 bit Token Counter */
1463/* B2_DESC_ADDR_H 0x0150 (ML) 32 bit Desciptor Base Addr Reg High */
1464/* B2_CTRL_2 0x0154 (ML) 8 bit Control Register 2 */
1465 /* Bit 7..5: reserved */
1466#define CTRL_CL_I2C_IRQ (1<<4) /* Bit 4: Clear I2C IRQ */
1467#define CTRL_ST_SW_IRQ (1<<3) /* Bit 3: Set IRQ SW Request */
1468#define CTRL_CL_SW_IRQ (1<<2) /* Bit 2: Clear IRQ SW Request */
1469#define CTRL_STOP_DONE (1<<1) /* Bit 1: Stop Master is finished */
1470#define CTRL_STOP_MAST (1<<0) /* Bit 0: Command Bit to stop the master*/
1471
1472/* B2_IFACE_REG 0x0155 (ML) 8 bit Interface Register */
1473 /* Bit 7..3: reserved */
1474#define IF_I2C_DATA_DIR (1<<2) /* Bit 2: direction of IF_I2C_DATA*/
1475#define IF_I2C_DATA (1<<1) /* Bit 1: I2C Data Port */
1476#define IF_I2C_CLK (1<<0) /* Bit 0: I2C Clock Port */
1477
1478 /* 0x0156: reserved */
1479/* B2_TST_CTRL_2 0x0157 (ML) 8 bit Test Control Register 2 */
1480 /* Bit 7..4: reserved */
1481 /* force the following error on */
1482 /* the next master read/write */
1483#define TST_FRC_DPERR_MR64 (1<<3) /* Bit 3: DataPERR RD 64 */
1484#define TST_FRC_DPERR_MW64 (1<<2) /* Bit 2: DataPERR WR 64 */
1485#define TST_FRC_APERR_1M64 (1<<1) /* Bit 1: AddrPERR on 1. phase */
1486#define TST_FRC_APERR_2M64 (1<<0) /* Bit 0: AddrPERR on 2. phase */
1487
1488/* B2_I2C_CTRL 0x0158 (ML) 32 bit I2C Control Register */
1489#define I2C_FLAG (1L<<31) /* Bit 31: Start read/write if WR */
1490#define I2C_ADDR (0x7fffL<<16) /* Bit 30..16: Addr to be read/written*/
1491#define I2C_DEV_SEL (0x7fL<<9) /* Bit 9..15: I2C Device Select */
1492 /* Bit 5.. 8: reserved */
1493#define I2C_BURST_LEN (1L<<4) /* Bit 4 Burst Len, 1/4 bytes */
1494#define I2C_DEV_SIZE (7L<<1) /* Bit 1.. 3: I2C Device Size */
1495#define I2C_025K_DEV (0L<<1) /* 0: 256 Bytes or smaller*/
1496#define I2C_05K_DEV (1L<<1) /* 1: 512 Bytes */
1497#define I2C_1K_DEV (2L<<1) /* 2: 1024 Bytes */
1498#define I2C_2K_DEV (3L<<1) /* 3: 2048 Bytes */
1499#define I2C_4K_DEV (4L<<1) /* 4: 4096 Bytes */
1500#define I2C_8K_DEV (5L<<1) /* 5: 8192 Bytes */
1501#define I2C_16K_DEV (6L<<1) /* 6: 16384 Bytes */
1502#define I2C_32K_DEV (7L<<1) /* 7: 32768 Bytes */
1503#define I2C_STOP_BIT (1<<0) /* Bit 0: Interrupt I2C transfer */
1504
1505/*
1506 * I2C Addresses
1507 *
1508 * The temperature sensor and the voltage sensor are on the same I2C bus.
1509 * Note: The voltage sensor (Micorwire) will be selected by PCI_EXT_PATCH_1
1510 * in PCI_OUR_REG 1.
1511 */
1512#define I2C_ADDR_TEMP 0x90 /* I2C Address Temperature Sensor */
1513
1514/* B2_I2C_DATA 0x015c (ML) 32 bit I2C Data Register */
1515
1516/* B4_R1_D 4*32 bit current receive Descriptor (q1) */
1517/* B4_R1_DA 32 bit current rec desc address (q1) */
1518/* B4_R1_AC 32 bit current receive Address Count (q1) */
1519/* B4_R1_BC 32 bit current receive Byte Counter (q1) */
1520/* B4_R1_CSR 32 bit BMU Control/Status Register (q1) */
1521/* B4_R1_F 32 bit flag register (q1) */
1522/* B4_R1_T1 32 bit Test Register 1 (q1) */
1523/* B4_R1_T2 32 bit Test Register 2 (q1) */
1524/* B4_R1_T3 32 bit Test Register 3 (q1) */
1525/* B4_R2_D 4*32 bit current receive Descriptor (q2) */
1526/* B4_R2_DA 32 bit current rec desc address (q2) */
1527/* B4_R2_AC 32 bit current receive Address Count (q2) */
1528/* B4_R2_BC 32 bit current receive Byte Counter (q2) */
1529/* B4_R2_CSR 32 bit BMU Control/Status Register (q2) */
1530/* B4_R2_F 32 bit flag register (q2) */
1531/* B4_R2_T1 32 bit Test Register 1 (q2) */
1532/* B4_R2_T2 32 bit Test Register 2 (q2) */
1533/* B4_R2_T3 32 bit Test Register 3 (q2) */
1534/* B5_XA_D 4*32 bit current receive Descriptor (xa) */
1535/* B5_XA_DA 32 bit current rec desc address (xa) */
1536/* B5_XA_AC 32 bit current receive Address Count (xa) */
1537/* B5_XA_BC 32 bit current receive Byte Counter (xa) */
1538/* B5_XA_CSR 32 bit BMU Control/Status Register (xa) */
1539/* B5_XA_F 32 bit flag register (xa) */
1540/* B5_XA_T1 32 bit Test Register 1 (xa) */
1541/* B5_XA_T2 32 bit Test Register 2 (xa) */
1542/* B5_XA_T3 32 bit Test Register 3 (xa) */
1543/* B5_XS_D 4*32 bit current receive Descriptor (xs) */
1544/* B5_XS_DA 32 bit current rec desc address (xs) */
1545/* B5_XS_AC 32 bit current receive Address Count (xs) */
1546/* B5_XS_BC 32 bit current receive Byte Counter (xs) */
1547/* B5_XS_CSR 32 bit BMU Control/Status Register (xs) */
1548/* B5_XS_F 32 bit flag register (xs) */
1549/* B5_XS_T1 32 bit Test Register 1 (xs) */
1550/* B5_XS_T2 32 bit Test Register 2 (xs) */
1551/* B5_XS_T3 32 bit Test Register 3 (xs) */
1552/* B5_<xx>_CSR 32 bit BMU Control/Status Register (xx) */
1553#define CSR_DESC_CLEAR (1L<<21) /* Bit 21: Clear Reset for Descr */
1554#define CSR_DESC_SET (1L<<20) /* Bit 20: Set Reset for Descr */
1555#define CSR_FIFO_CLEAR (1L<<19) /* Bit 19: Clear Reset for FIFO */
1556#define CSR_FIFO_SET (1L<<18) /* Bit 18: Set Reset for FIFO */
1557#define CSR_HPI_RUN (1L<<17) /* Bit 17: Release HPI SM */
1558#define CSR_HPI_RST (1L<<16) /* Bit 16: Reset HPI SM to Idle */
1559#define CSR_SV_RUN (1L<<15) /* Bit 15: Release Supervisor SM */
1560#define CSR_SV_RST (1L<<14) /* Bit 14: Reset Supervisor SM */
1561#define CSR_DREAD_RUN (1L<<13) /* Bit 13: Release Descr Read SM */
1562#define CSR_DREAD_RST (1L<<12) /* Bit 12: Reset Descr Read SM */
1563#define CSR_DWRITE_RUN (1L<<11) /* Bit 11: Rel. Descr Write SM */
1564#define CSR_DWRITE_RST (1L<<10) /* Bit 10: Reset Descr Write SM */
1565#define CSR_TRANS_RUN (1L<<9) /* Bit 9: Release Transfer SM */
1566#define CSR_TRANS_RST (1L<<8) /* Bit 8: Reset Transfer SM */
1567 /* Bit 7..5: reserved */
1568#define CSR_START (1L<<4) /* Bit 4: Start Rec/Xmit Queue */
1569#define CSR_IRQ_CL_P (1L<<3) /* Bit 3: Clear Parity IRQ, Rcv */
1570#define CSR_IRQ_CL_B (1L<<2) /* Bit 2: Clear EOB IRQ */
1571#define CSR_IRQ_CL_F (1L<<1) /* Bit 1: Clear EOF IRQ */
1572#define CSR_IRQ_CL_C (1L<<0) /* Bit 0: Clear ERR IRQ */
1573
1574#define CSR_SET_RESET (CSR_DESC_SET|CSR_FIFO_SET|CSR_HPI_RST|CSR_SV_RST|\
1575 CSR_DREAD_RST|CSR_DWRITE_RST|CSR_TRANS_RST)
1576#define CSR_CLR_RESET (CSR_DESC_CLEAR|CSR_FIFO_CLEAR|CSR_HPI_RUN|CSR_SV_RUN|\
1577 CSR_DREAD_RUN|CSR_DWRITE_RUN|CSR_TRANS_RUN)
1578
1579
1580/* B5_<xx>_F 32 bit flag register (xx) */
1581 /* Bit 28..31: reserved */
1582#define F_ALM_FULL (1L<<27) /* Bit 27: (ML) FIFO almost full */
1583#define F_FIFO_EOF (1L<<26) /* Bit 26: (ML) Fag bit in FIFO */
1584#define F_WM_REACHED (1L<<25) /* Bit 25: (ML) Watermark reached */
1585#define F_UP_DW_USED (1L<<24) /* Bit 24: (ML) Upper Dword used (bug)*/
1586 /* Bit 23: reserved */
1587#define F_FIFO_LEVEL (0x1fL<<16) /* Bit 16..22:(ML) # of Qwords in FIFO*/
1588 /* Bit 8..15: reserved */
1589#define F_ML_WATER_M 0x0000ffL /* Bit 0.. 7:(ML) Watermark */
1590#define FLAG_WATER 0x00001fL /* Bit 4..0:(DV) Level of req data tr.*/
1591
1592/* B5_<xx>_T1 32 bit Test Register 1 (xx) */
1593/* Holds four State Machine control Bytes */
1594#define SM_CRTL_SV (0xffL<<24) /* Bit 31..24: Control Supervisor SM */
1595#define SM_CRTL_RD (0xffL<<16) /* Bit 23..16: Control Read Desc SM */
1596#define SM_CRTL_WR (0xffL<<8) /* Bit 15..8: Control Write Desc SM */
1597#define SM_CRTL_TR (0xffL<<0) /* Bit 7..0: Control Transfer SM */
1598
1599/* B4_<xx>_T1_TR 8 bit Test Register 1 TR (xx) */
1600/* B4_<xx>_T1_WR 8 bit Test Register 1 WR (xx) */
1601/* B4_<xx>_T1_RD 8 bit Test Register 1 RD (xx) */
1602/* B4_<xx>_T1_SV 8 bit Test Register 1 SV (xx) */
1603/* The control status byte of each machine looks like ... */
1604#define SM_STATE 0xf0 /* Bit 7..4: State which shall be loaded */
1605#define SM_LOAD 0x08 /* Bit 3: Load the SM with SM_STATE */
1606#define SM_TEST_ON 0x04 /* Bit 2: Switch on SM Test Mode */
1607#define SM_TEST_OFF 0x02 /* Bit 1: Go off the Test Mode */
1608#define SM_STEP 0x01 /* Bit 0: Step the State Machine */
1609
1610/* The coding of the states */
1611#define SM_SV_IDLE 0x0 /* Supervisor Idle Tr/Re */
1612#define SM_SV_RES_START 0x1 /* Supervisor Res_Start Tr/Re */
1613#define SM_SV_GET_DESC 0x3 /* Supervisor Get_Desc Tr/Re */
1614#define SM_SV_CHECK 0x2 /* Supervisor Check Tr/Re */
1615#define SM_SV_MOV_DATA 0x6 /* Supervisor Move_Data Tr/Re */
1616#define SM_SV_PUT_DESC 0x7 /* Supervisor Put_Desc Tr/Re */
1617#define SM_SV_SET_IRQ 0x5 /* Supervisor Set_Irq Tr/Re */
1618
1619#define SM_RD_IDLE 0x0 /* Read Desc. Idle Tr/Re */
1620#define SM_RD_LOAD 0x1 /* Read Desc. Load Tr/Re */
1621#define SM_RD_WAIT_TC 0x3 /* Read Desc. Wait_TC Tr/Re */
1622#define SM_RD_RST_EOF 0x6 /* Read Desc. Reset_EOF Re */
1623#define SM_RD_WDONE_R 0x2 /* Read Desc. Wait_Done Re */
1624#define SM_RD_WDONE_T 0x4 /* Read Desc. Wait_Done Tr */
1625
1626#define SM_TR_IDLE 0x0 /* Trans. Data Idle Tr/Re */
1627#define SM_TR_LOAD 0x3 /* Trans. Data Load Tr/Re */
1628#define SM_TR_LOAD_R_ML 0x1 /* Trans. Data Load /Re (ML) */
1629#define SM_TR_WAIT_TC 0x2 /* Trans. Data Wait_TC Tr/Re */
1630#define SM_TR_WDONE 0x4 /* Trans. Data Wait_Done Tr/Re */
1631
1632#define SM_WR_IDLE 0x0 /* Write Desc. Idle Tr/Re */
1633#define SM_WR_ABLEN 0x1 /* Write Desc. Act_Buf_Length Tr/Re */
1634#define SM_WR_LD_A4 0x2 /* Write Desc. Load_A4 Re */
1635#define SM_WR_RES_OWN 0x2 /* Write Desc. Res_OWN Tr */
1636#define SM_WR_WAIT_EOF 0x3 /* Write Desc. Wait_EOF Re */
1637#define SM_WR_LD_N2C_R 0x4 /* Write Desc. Load_N2C Re */
1638#define SM_WR_WAIT_TC_R 0x5 /* Write Desc. Wait_TC Re */
1639#define SM_WR_WAIT_TC4 0x6 /* Write Desc. Wait_TC4 Re */
1640#define SM_WR_LD_A_T 0x6 /* Write Desc. Load_A Tr */
1641#define SM_WR_LD_A_R 0x7 /* Write Desc. Load_A Re */
1642#define SM_WR_WAIT_TC_T 0x7 /* Write Desc. Wait_TC Tr */
1643#define SM_WR_LD_N2C_T 0xc /* Write Desc. Load_N2C Tr */
1644#define SM_WR_WDONE_T 0x9 /* Write Desc. Wait_Done Tr */
1645#define SM_WR_WDONE_R 0xc /* Write Desc. Wait_Done Re */
1646#define SM_WR_LD_D_AD 0xe /* Write Desc. Load_Dumr_A Re (ML) */
1647#define SM_WR_WAIT_D_TC 0xf /* Write Desc. Wait_Dumr_TC Re (ML) */
1648
1649/* B5_<xx>_T2 32 bit Test Register 2 (xx) */
1650/* Note: This register is only defined for the transmit queues */
1651 /* Bit 31..8: reserved */
1652#define AC_TEST_ON (1<<7) /* Bit 7: Address Counter Test Mode on */
1653#define AC_TEST_OFF (1<<6) /* Bit 6: Address Counter Test Mode off*/
1654#define BC_TEST_ON (1<<5) /* Bit 5: Byte Counter Test Mode on */
1655#define BC_TEST_OFF (1<<4) /* Bit 4: Byte Counter Test Mode off */
1656#define TEST_STEP04 (1<<3) /* Bit 3: Inc AC/Dec BC by 4 */
1657#define TEST_STEP03 (1<<2) /* Bit 2: Inc AC/Dec BC by 3 */
1658#define TEST_STEP02 (1<<1) /* Bit 1: Inc AC/Dec BC by 2 */
1659#define TEST_STEP01 (1<<0) /* Bit 0: Inc AC/Dec BC by 1 */
1660
1661/* B5_<xx>_T3 32 bit Test Register 3 (xx) */
1662/* Note: This register is only defined for the transmit queues */
1663 /* Bit 31..8: reserved */
1664#define T3_MUX_2 (1<<7) /* Bit 7: (ML) Mux position MSB */
1665#define T3_VRAM_2 (1<<6) /* Bit 6: (ML) Virtual RAM buffer addr MSB */
1666#define T3_LOOP (1<<5) /* Bit 5: Set Loopback (Xmit) */
1667#define T3_UNLOOP (1<<4) /* Bit 4: Unset Loopback (Xmit) */
1668#define T3_MUX (3<<2) /* Bit 3..2: Mux position */
1669#define T3_VRAM (3<<0) /* Bit 1..0: Virtual RAM buffer Address */
1670
1671/* PCI card IDs */
1672/*
1673 * Note: The following 4 byte definitions shall not be used! Use OEM Concept!
1674 */
1675#define PCI_VEND_ID0 0x48 /* PCI vendor ID (SysKonnect) */
1676#define PCI_VEND_ID1 0x11 /* PCI vendor ID (SysKonnect) */
1677 /* (High byte) */
1678#define PCI_DEV_ID0 0x00 /* PCI device ID */
1679#define PCI_DEV_ID1 0x40 /* PCI device ID (High byte) */
1680
1681/*#define PCI_CLASS 0x02*/ /* PCI class code: network device */
1682#define PCI_NW_CLASS 0x02 /* PCI class code: network device */
1683#define PCI_SUB_CLASS 0x02 /* PCI subclass ID: FDDI device */
1684#define PCI_PROG_INTFC 0x00 /* PCI programming Interface (=0) */
1685
1686/*
1687 * address transmission from logical to physical offset address on board
1688 */
1689#define FMA(a) (0x0400|((a)<<2)) /* FORMAC+ (r/w) (SN3) */
1690#define P1(a) (0x0380|((a)<<2)) /* PLC1 (r/w) (DAS) */
1691#define P2(a) (0x0600|((a)<<2)) /* PLC2 (r/w) (covered by the SN3) */
1692#define PRA(a) (B2_MAC_0 + (a)) /* configuration PROM (MAC address) */
1693
1694/*
1695 * FlashProm specification
1696 */
1697#define MAX_PAGES 0x20000L /* Every byte has a single page */
1698#define MAX_FADDR 1 /* 1 byte per page */
1699
1700/*
1701 * Receive / Transmit Buffer Control word
1702 */
1703#define BMU_OWN (1UL<<31) /* OWN bit: 0 == host, 1 == adapter */
1704#define BMU_STF (1L<<30) /* Start of Frame ? */
1705#define BMU_EOF (1L<<29) /* End of Frame ? */
1706#define BMU_EN_IRQ_EOB (1L<<28) /* Enable "End of Buffer" IRQ */
1707#define BMU_EN_IRQ_EOF (1L<<27) /* Enable "End of Frame" IRQ */
1708#define BMU_DEV_0 (1L<<26) /* RX: don't transfer to system mem */
1709#define BMU_SMT_TX (1L<<25) /* TX: if set, buffer type SMT_MBuf */
1710#define BMU_ST_BUF (1L<<25) /* RX: copy of start of frame */
1711#define BMU_UNUSED (1L<<24) /* Set if the Descr is curr unused */
1712#define BMU_SW (3L<<24) /* 2 Bits reserved for SW usage */
1713#define BMU_CHECK 0x00550000L /* To identify the control word */
1714#define BMU_BBC 0x0000FFFFL /* R/T Buffer Byte Count */
1715
1716/*
1717 * physical address offset + IO-Port base address
1718 */
1719#ifdef MEM_MAPPED_IO
1720#define ADDR(a) (char far *) smc->hw.iop+(a)
1721#define ADDRS(smc,a) (char far *) (smc)->hw.iop+(a)
1722#else
1723#define ADDR(a) (((a)>>7) ? (outp(smc->hw.iop+B0_RAP,(a)>>7), \
1724 (smc->hw.iop+(((a)&0x7F)|((a)>>7 ? 0x80:0)))) : \
1725 (smc->hw.iop+(((a)&0x7F)|((a)>>7 ? 0x80:0))))
1726#define ADDRS(smc,a) (((a)>>7) ? (outp((smc)->hw.iop+B0_RAP,(a)>>7), \
1727 ((smc)->hw.iop+(((a)&0x7F)|((a)>>7 ? 0x80:0)))) : \
1728 ((smc)->hw.iop+(((a)&0x7F)|((a)>>7 ? 0x80:0))))
1729#endif
1730
1731/*
1732 * Define a macro to access the configuration space
1733 */
1734#define PCI_C(a) ADDR(B3_CFG_SPC + (a)) /* PCI Config Space */
1735
1736#define EXT_R(a) ADDR(B6_EXT_REG + (a)) /* External Registers */
1737
1738/*
1739 * Define some values needed for the MAC address (PROM)
1740 */
1741#define SA_MAC (0) /* start addr. MAC_AD within the PROM */
1742#define PRA_OFF (0) /* offset correction when 4th byte reading */
1743
1744#define SKFDDI_PSZ 8 /* address PROM size */
1745
1746#define FM_A(a) ADDR(FMA(a)) /* FORMAC Plus physical addr */
1747#define P1_A(a) ADDR(P1(a)) /* PLC1 (r/w) */
1748#define P2_A(a) ADDR(P2(a)) /* PLC2 (r/w) (DAS) */
1749#define PR_A(a) ADDR(PRA(a)) /* config. PROM (MAC address) */
1750
1751/*
1752 * Macro to read the PROM
1753 */
1754#define READ_PROM(a) ((u_char)inp(a))
1755
1756#define GET_PAGE(bank) outpd(ADDR(B2_FAR),bank)
1757#define VPP_ON()
1758#define VPP_OFF()
1759
1760/*
1761 * Note: Values of the Interrupt Source Register are defined above
1762 */
1763#define ISR_A ADDR(B0_ISRC)
1764#define GET_ISR() inpd(ISR_A)
1765#define GET_ISR_SMP(iop) inpd((iop)+B0_ISRC)
1766#define CHECK_ISR() (inpd(ISR_A) & inpd(ADDR(B0_IMSK)))
1767#define CHECK_ISR_SMP(iop) (inpd((iop)+B0_ISRC) & inpd((iop)+B0_IMSK))
1768
1769#define BUS_CHECK()
1770
1771/*
1772 * CLI_FBI: Disable Board Interrupts
1773 * STI_FBI: Enable Board Interrupts
1774 */
1775#ifndef UNIX
1776#define CLI_FBI() outpd(ADDR(B0_IMSK),0)
1777#else
1778#define CLI_FBI(smc) outpd(ADDRS((smc),B0_IMSK),0)
1779#endif
1780
1781#ifndef UNIX
1782#define STI_FBI() outpd(ADDR(B0_IMSK),smc->hw.is_imask)
1783#else
1784#define STI_FBI(smc) outpd(ADDRS((smc),B0_IMSK),(smc)->hw.is_imask)
1785#endif
1786
1787#define CLI_FBI_SMP(iop) outpd((iop)+B0_IMSK,0)
1788#define STI_FBI_SMP(smc,iop) outpd((iop)+B0_IMSK,(smc)->hw.is_imask)
1789
1790#endif /* PCI */
1791/*--------------------------------------------------------------------------*/
1792
1793/*
1794 * 12 bit transfer (dword) counter:
1795 * (ISA: 2*trc = number of byte)
1796 * (EISA: 4*trc = number of byte)
1797 * (MCA: 4*trc = number of byte)
1798 */
1799#define MAX_TRANS (0x0fff)
1800
1801/*
1802 * PC PIC
1803 */
1804#define MST_8259 (0x20)
1805#define SLV_8259 (0xA0)
1806
1807#define TPS (18) /* ticks per second */
1808
1809/*
1810 * error timer defs
1811 */
1812#define TN (4) /* number of supported timer = TN+1 */
1813#define SNPPND_TIME (5) /* buffer memory access over mem. data reg. */
1814
1815#define MAC_AD 0x405a0000
1816
1817#define MODR1 FM_A(FM_MDREG1) /* mode register 1 */
1818#define MODR2 FM_A(FM_MDREG2) /* mode register 2 */
1819
1820#define CMDR1 FM_A(FM_CMDREG1) /* command register 1 */
1821#define CMDR2 FM_A(FM_CMDREG2) /* command register 2 */
1822
1823
1824/*
1825 * function defines
1826 */
1827#define CLEAR(io,mask) outpw((io),inpw(io)&(~(mask)))
1828#define SET(io,mask) outpw((io),inpw(io)|(mask))
1829#define GET(io,mask) (inpw(io)&(mask))
1830#define SETMASK(io,val,mask) outpw((io),(inpw(io) & ~(mask)) | (val))
1831
1832/*
1833 * PHY Port A (PA) = PLC 1
1834 * With SuperNet 3 PHY-A and PHY S are identical.
1835 */
1836#define PLC(np,reg) (((np) == PA) ? P2_A(reg) : P1_A(reg))
1837
1838/*
1839 * set memory address register for write and read
1840 */
1841#define MARW(ma) outpw(FM_A(FM_MARW),(unsigned int)(ma))
1842#define MARR(ma) outpw(FM_A(FM_MARR),(unsigned int)(ma))
1843
1844/*
1845 * read/write from/to memory data register
1846 */
1847/* write double word */
1848#define MDRW(dd) outpw(FM_A(FM_MDRU),(unsigned int)((dd)>>16)) ;\
1849 outpw(FM_A(FM_MDRL),(unsigned int)(dd))
1850
1851#ifndef WINNT
1852/* read double word */
1853#define MDRR() (((long)inpw(FM_A(FM_MDRU))<<16) + inpw(FM_A(FM_MDRL)))
1854
1855/* read FORMAC+ 32-bit status register */
1856#define GET_ST1() (((long)inpw(FM_A(FM_ST1U))<<16) + inpw(FM_A(FM_ST1L)))
1857#define GET_ST2() (((long)inpw(FM_A(FM_ST2U))<<16) + inpw(FM_A(FM_ST2L)))
1858#ifdef SUPERNET_3
1859#define GET_ST3() (((long)inpw(FM_A(FM_ST3U))<<16) + inpw(FM_A(FM_ST3L)))
1860#endif
1861#else
1862/* read double word */
1863#define MDRR() inp2w((FM_A(FM_MDRU)),(FM_A(FM_MDRL)))
1864
1865/* read FORMAC+ 32-bit status register */
1866#define GET_ST1() inp2w((FM_A(FM_ST1U)),(FM_A(FM_ST1L)))
1867#define GET_ST2() inp2w((FM_A(FM_ST2U)),(FM_A(FM_ST2L)))
1868#ifdef SUPERNET_3
1869#define GET_ST3() inp2w((FM_A(FM_ST3U)),(FM_A(FM_ST3L)))
1870#endif
1871#endif
1872
1873/* Special timer macro for 82c54 */
1874 /* timer access over data bus bit 8..15 */
1875#define OUT_82c54_TIMER(port,val) outpw(TI_A(port),(val)<<8)
1876#define IN_82c54_TIMER(port) ((inpw(TI_A(port))>>8) & 0xff)
1877
1878
1879#ifdef DEBUG
1880#define DB_MAC(mac,st) {if (debug_mac & 0x1)\
1881 printf("M") ;\
1882 if (debug_mac & 0x2)\
1883 printf("\tMAC %d status 0x%08lx\n",mac,st) ;\
1884 if (debug_mac & 0x4)\
1885 dp_mac(mac,st) ;\
1886}
1887
1888#define DB_PLC(p,iev) { if (debug_plc & 0x1)\
1889 printf("P") ;\
1890 if (debug_plc & 0x2)\
1891 printf("\tPLC %s Int 0x%04x\n", \
1892 (p == PA) ? "A" : "B", iev) ;\
1893 if (debug_plc & 0x4)\
1894 dp_plc(p,iev) ;\
1895}
1896
1897#define DB_TIMER() { if (debug_timer & 0x1)\
1898 printf("T") ;\
1899 if (debug_timer & 0x2)\
1900 printf("\tTimer ISR\n") ;\
1901}
1902
1903#else /* no DEBUG */
1904
1905#define DB_MAC(mac,st)
1906#define DB_PLC(p,iev)
1907#define DB_TIMER()
1908
1909#endif /* no DEBUG */
1910
1911#define INC_PTR(sp,cp,ep) if (++cp == ep) cp = sp
1912/*
1913 * timer defs
1914 */
1915#define COUNT(t) ((t)<<6) /* counter */
1916#define RW_OP(o) ((o)<<4) /* read/write operation */
1917#define TMODE(m) ((m)<<1) /* timer mode */
1918
1919#endif
diff --git a/drivers/net/skfp/h/skfbiinc.h b/drivers/net/skfp/h/skfbiinc.h
new file mode 100644
index 000000000000..79d55ad2cd2a
--- /dev/null
+++ b/drivers/net/skfp/h/skfbiinc.h
@@ -0,0 +1,123 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * The information in this file is provided "AS IS" without warranty.
12 *
13 ******************************************************************************/
14
15#ifndef _SKFBIINC_
16#define _SKFBIINC_
17
18#include "h/supern_2.h"
19
20/*
21 * special defines for use into .asm files
22 */
23#define ERR_FLAGS (FS_MSRABT | FS_SEAC2 | FS_SFRMERR | FS_SFRMTY1)
24
25#ifdef ISA
26#define DMA_BUSY_CHECK CSRA
27#define IMASK_FAST (IS_PLINT1 | IS_PLINT2 | IS_TIMINT)
28#define HRQR (RQAA+(RQ_RRQ<<1))
29#define HRQW (RQAA+(RQ_WA2<<1))
30#define HRQA0 (RQAA+(RQ_WA0<<1))
31#define HRQSQ (RQAA+(RQ_WSQ<<1))
32#endif
33
34#ifdef EISA
35#define DMA_BUSY_CHECK CSRA
36#define DMA_HIGH_WORD 0x0400
37#define DMA_MASK_M 0x0a
38#define DMA_MODE_M 0x0b
39#define DMA_BYTE_PTR_M 0x0c
40#define DMA_MASK_S 0x0d4
41#define DMA_MODE_S 0x0d6
42#define DMA_BYTE_PTR_S 0x0d8
43#define IMASK_FAST (IS_PLINT1 | IS_PLINT2 | IS_TIMINT | IS_TC)
44#endif /* EISA */
45
46#ifdef MCA
47#define IMASK_FAST (IS_PLINT1 | IS_PLINT2 | IS_TIMINT | IS_TOKEN | \
48 IS_CHCK_L | IS_BUSERR)
49#endif
50
51#ifdef PCI
52#define IMASK_FAST (IS_PLINT1 | IS_PLINT2 | IS_TIMINT | IS_TOKEN | \
53 IS_MINTR2 | IS_MINTR3 | IS_R1_P | \
54 IS_R1_C | IS_XA_C | IS_XS_C)
55#endif
56
57#ifdef PCI
58#define ISR_MASK (IS_MINTR1 | IS_R1_F | IS_XS_F| IS_XA_F | IMASK_FAST)
59#else
60#define ISR_MASK (IS_MINTR1 | IS_MINTR2 | IMASK_FAST)
61#endif
62
63#define FMA_FM_CMDREG1 FMA(FM_CMDREG1)
64#define FMA_FM_CMDREG2 FMA(FM_CMDREG2)
65#define FMA_FM_STMCHN FMA(FM_STMCHN)
66#define FMA_FM_RPR FMA(FM_RPR)
67#define FMA_FM_WPXA0 FMA(FM_WPXA0)
68#define FMA_FM_WPXA2 FMA(FM_WPXA2)
69#define FMA_FM_MARR FMA(FM_MARR)
70#define FMA_FM_MARW FMA(FM_MARW)
71#define FMA_FM_MDRU FMA(FM_MDRU)
72#define FMA_FM_MDRL FMA(FM_MDRL)
73#define FMA_ST1L FMA(FM_ST1L)
74#define FMA_ST1U FMA(FM_ST1U)
75#define FMA_ST2L FMA(FM_ST2L)
76#define FMA_ST2U FMA(FM_ST2U)
77#ifdef SUPERNET_3
78#define FMA_ST3L FMA(FM_ST3L)
79#define FMA_ST3U FMA(FM_ST3U)
80#endif
81
82#define TMODE_RRQ RQ_RRQ
83#define TMODE_WAQ2 RQ_WA2
84#define HSRA HSR(0)
85
86
87#define FMA_FM_ST1L FMA_ST1L
88#define FMA_FM_ST1U FMA_ST1U
89#define FMA_FM_ST2L FMA_ST2L
90#define FMA_FM_ST2U FMA_ST2U
91#ifdef SUPERNET_3
92#define FMA_FM_ST3L FMA_ST3L
93#define FMA_FM_ST3U FMA_ST3U
94#endif
95
96#define FMA_FM_SWPR FMA(FM_SWPR)
97
98#define FMA_FM_RPXA0 FMA(FM_RPXA0)
99
100#define FMA_FM_RPXS FMA(FM_RPXS)
101#define FMA_FM_WPXS FMA(FM_WPXS)
102
103#define FMA_FM_IMSK1U FMA(FM_IMSK1U)
104#define FMA_FM_IMSK1L FMA(FM_IMSK1L)
105
106#define FMA_FM_EAS FMA(FM_EAS)
107#define FMA_FM_EAA0 FMA(FM_EAA0)
108
109#define TMODE_WAQ0 RQ_WA0
110#define TMODE_WSQ RQ_WSQ
111
112/* Define default for DRV_PCM_STATE_CHANGE */
113#ifndef DRV_PCM_STATE_CHANGE
114#define DRV_PCM_STATE_CHANGE(smc,plc,p_state) /* nothing */
115#endif
116
117/* Define default for DRV_RMT_INDICATION */
118#ifndef DRV_RMT_INDICATION
119#define DRV_RMT_INDICATION(smc,i) /* nothing */
120#endif
121
122#endif /* n_SKFBIINC_ */
123
diff --git a/drivers/net/skfp/h/smc.h b/drivers/net/skfp/h/smc.h
new file mode 100644
index 000000000000..94325915e0d5
--- /dev/null
+++ b/drivers/net/skfp/h/smc.h
@@ -0,0 +1,471 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * The information in this file is provided "AS IS" without warranty.
12 *
13 ******************************************************************************/
14
15#ifndef _SCMECM_
16#define _SCMECM_
17
18#if defined(PCI) && !defined(OSDEF)
19/*
20 * In the case of the PCI bus the file osdef1st.h must be present
21 */
22#define OSDEF
23#endif
24
25#ifdef PCI
26#ifndef SUPERNET_3
27#define SUPERNET_3
28#endif
29#ifndef TAG_MODE
30#define TAG_MODE
31#endif
32#endif
33
34/*
35 * include all other files in required order
36 * the following files must have been included before:
37 * types.h
38 * fddi.h
39 */
40#ifdef OSDEF
41#include "h/osdef1st.h"
42#endif /* OSDEF */
43#ifdef OEM_CONCEPT
44#include "oemdef.h"
45#endif /* OEM_CONCEPT */
46#include "h/smt.h"
47#include "h/cmtdef.h"
48#include "h/fddimib.h"
49#include "h/targethw.h" /* all target hw dependencies */
50#include "h/targetos.h" /* all target os dependencies */
51#ifdef ESS
52#include "h/sba.h"
53#endif
54
55/*
56 * Event Queue
57 * queue.c
58 * events are class/value pairs
59 * class is addressee, e.g. RMT, PCM etc.
60 * value is command, e.g. line state change, ring op change etc.
61 */
62struct event_queue {
63 u_short class ; /* event class */
64 u_short event ; /* event value */
65} ;
66
67/*
68 * define event queue as circular buffer
69 */
70#ifdef CONCENTRATOR
71#define MAX_EVENT 128
72#else /* nCONCENTRATOR */
73#define MAX_EVENT 64
74#endif /* nCONCENTRATOR */
75
76struct s_queue {
77
78 struct event_queue ev_queue[MAX_EVENT];
79 struct event_queue *ev_put ;
80 struct event_queue *ev_get ;
81} ;
82
83/*
84 * ECM - Entity Coordination Management
85 * ecm.c
86 */
87struct s_ecm {
88 u_char path_test ; /* ECM path test variable */
89 u_char sb_flag ; /* ECM stuck bypass */
90 u_char DisconnectFlag ; /* jd 05-Aug-1999 Bug #10419
91 * ECM disconnected */
92 u_char ecm_line_state ; /* flag to dispatcher : line states */
93 u_long trace_prop ; /* ECM Trace_Prop flag >= 16 bits !! */
94 /* NUMPHYS note:
95 * this variable must have enough bits to hold all entiies in
96 * the station. So NUMPHYS may not be greater than 31.
97 */
98 char ec_pad[2] ;
99 struct smt_timer ecm_timer ; /* timer */
100} ;
101
102
103/*
104 * RMT - Ring Management
105 * rmt.c
106 */
107struct s_rmt {
108 u_char dup_addr_test ; /* state of dupl. addr. test */
109 u_char da_flag ; /* flag : duplicate address det. */
110 u_char loop_avail ; /* flag : MAC available for loopback */
111 u_char sm_ma_avail ; /* flag : MAC available for SMT */
112 u_char no_flag ; /* flag : ring not operational */
113 u_char bn_flag ; /* flag : MAC reached beacon state */
114 u_char jm_flag ; /* flag : jamming in NON_OP_DUP */
115 u_char rm_join ; /* CFM flag RM_Join */
116 u_char rm_loop ; /* CFM flag RM_Loop */
117
118 long fast_rm_join ; /* bit mask of active ports */
119 /*
120 * timer and flags
121 */
122 struct smt_timer rmt_timer0 ; /* timer 0 */
123 struct smt_timer rmt_timer1 ; /* timer 1 */
124 struct smt_timer rmt_timer2 ; /* timer 2 */
125 u_char timer0_exp ; /* flag : timer 0 expired */
126 u_char timer1_exp ; /* flag : timer 1 expired */
127 u_char timer2_exp ; /* flag : timer 2 expired */
128
129 u_char rm_pad1[1] ;
130} ;
131
132/*
133 * CFM - Configuration Management
134 * cfm.c
135 * used for SAS and DAS
136 */
137struct s_cfm {
138 u_char cf_state; /* CFM state machine current state */
139 u_char cf_pad[3] ;
140} ;
141
142/*
143 * CEM - Configuration Element Management
144 * cem.c
145 * used for Concentrator
146 */
147#ifdef CONCENTRATOR
148struct s_cem {
149 int ce_state ; /* CEM state */
150 int ce_port ; /* PA PB PM PM+1 .. */
151 int ce_type ; /* TA TB TS TM */
152} ;
153
154/*
155 * linked list of CCEs in current token path
156 */
157struct s_c_ring {
158 struct s_c_ring *c_next ;
159 char c_entity ;
160} ;
161
162struct mib_path_config {
163 u_long fddimibPATHConfigSMTIndex;
164 u_long fddimibPATHConfigPATHIndex;
165 u_long fddimibPATHConfigTokenOrder;
166 u_long fddimibPATHConfigResourceType;
167#define SNMP_RES_TYPE_MAC 2 /* Resource is a MAC */
168#define SNMP_RES_TYPE_PORT 4 /* Resource is a PORT */
169 u_long fddimibPATHConfigResourceIndex;
170 u_long fddimibPATHConfigCurrentPath;
171#define SNMP_PATH_ISOLATED 1 /* Current path is isolated */
172#define SNMP_PATH_LOCAL 2 /* Current path is local */
173#define SNMP_PATH_SECONDARY 3 /* Current path is secondary */
174#define SNMP_PATH_PRIMARY 4 /* Current path is primary */
175#define SNMP_PATH_CONCATENATED 5 /* Current path is concatenated */
176#define SNMP_PATH_THRU 6 /* Current path is thru */
177};
178
179
180#endif
181
182/*
183 * PCM connect states
184 */
185#define PCM_DISABLED 0
186#define PCM_CONNECTING 1
187#define PCM_STANDBY 2
188#define PCM_ACTIVE 3
189
190struct s_pcm {
191 u_char pcm_pad[3] ;
192} ;
193
194/*
195 * PHY struct
196 * one per physical port
197 */
198struct s_phy {
199 /* Inter Module Globals */
200 struct fddi_mib_p *mib ;
201
202 u_char np ; /* index 0 .. NUMPHYS */
203 u_char cf_join ;
204 u_char cf_loop ;
205 u_char wc_flag ; /* withhold connection flag */
206 u_char pc_mode ; /* Holds the negotiated mode of the PCM */
207 u_char pc_lem_fail ; /* flag : LCT failed */
208 u_char lc_test ;
209 u_char scrub ; /* CFM flag Scrub -> PCM */
210 char phy_name ;
211 u_char pmd_type[2] ; /* SK connector/transceiver type codes */
212#define PMD_SK_CONN 0 /* pmd_type[PMD_SK_CONN] = Connector */
213#define PMD_SK_PMD 1 /* pmd_type[PMD_SK_PMD] = Xver */
214 u_char pmd_scramble ; /* scrambler on/off */
215
216 /* inner Module Globals */
217 u_char curr_ls ; /* current line state */
218 u_char ls_flag ;
219 u_char rc_flag ;
220 u_char tc_flag ;
221 u_char td_flag ;
222 u_char bitn ;
223 u_char tr_flag ; /* trace recvd while in active */
224 u_char twisted ; /* flag to indicate an A-A or B-B connection */
225 u_char t_val[NUMBITS] ; /* transmit bits for signaling */
226 u_char r_val[NUMBITS] ; /* receive bits for signaling */
227 u_long t_next[NUMBITS] ;
228 struct smt_timer pcm_timer0 ;
229 struct smt_timer pcm_timer1 ;
230 struct smt_timer pcm_timer2 ;
231 u_char timer0_exp ;
232 u_char timer1_exp ;
233 u_char timer2_exp ;
234 u_char pcm_pad1[1] ;
235 int cem_pst ; /* CEM privae state; used for dual homing */
236 struct lem_counter lem ;
237#ifdef AMDPLC
238 struct s_plc plc ;
239#endif
240} ;
241
242/*
243 * timer package
244 * smttimer.c
245 */
246struct s_timer {
247 struct smt_timer *st_queue ;
248 struct smt_timer st_fast ;
249} ;
250
251/*
252 * SRF types and data
253 */
254#define SMT_EVENT_BASE 1
255#define SMT_EVENT_MAC_PATH_CHANGE (SMT_EVENT_BASE+0)
256#define SMT_EVENT_MAC_NEIGHBOR_CHANGE (SMT_EVENT_BASE+1)
257#define SMT_EVENT_PORT_PATH_CHANGE (SMT_EVENT_BASE+2)
258#define SMT_EVENT_PORT_CONNECTION (SMT_EVENT_BASE+3)
259
260#define SMT_IS_CONDITION(x) ((x)>=SMT_COND_BASE)
261
262#define SMT_COND_BASE (SMT_EVENT_PORT_CONNECTION+1)
263#define SMT_COND_SMT_PEER_WRAP (SMT_COND_BASE+0)
264#define SMT_COND_SMT_HOLD (SMT_COND_BASE+1)
265#define SMT_COND_MAC_FRAME_ERROR (SMT_COND_BASE+2)
266#define SMT_COND_MAC_DUP_ADDR (SMT_COND_BASE+3)
267#define SMT_COND_MAC_NOT_COPIED (SMT_COND_BASE+4)
268#define SMT_COND_PORT_EB_ERROR (SMT_COND_BASE+5)
269#define SMT_COND_PORT_LER (SMT_COND_BASE+6)
270
271#define SR0_WAIT 0
272#define SR1_HOLDOFF 1
273#define SR2_DISABLED 2
274
275struct s_srf {
276 u_long SRThreshold ; /* threshold value */
277 u_char RT_Flag ; /* report transmitted flag */
278 u_char sr_state ; /* state-machine */
279 u_char any_report ; /* any report required */
280 u_long TSR ; /* timer */
281 u_short ring_status ; /* IBM ring status */
282} ;
283
284/*
285 * IBM token ring status
286 */
287#define RS_RES15 (1<<15) /* reserved */
288#define RS_HARDERROR (1<<14) /* ring down */
289#define RS_SOFTERROR (1<<13) /* sent SRF */
290#define RS_BEACON (1<<12) /* transmitted beacon */
291#define RS_PATHTEST (1<<11) /* path test failed */
292#define RS_SELFTEST (1<<10) /* selftest required */
293#define RS_RES9 (1<< 9) /* reserved */
294#define RS_DISCONNECT (1<< 8) /* remote disconnect */
295#define RS_RES7 (1<< 7) /* reserved */
296#define RS_DUPADDR (1<< 6) /* duplicate address */
297#define RS_NORINGOP (1<< 5) /* no ring op */
298#define RS_VERSION (1<< 4) /* SMT version mismatch */
299#define RS_STUCKBYPASSS (1<< 3) /* stuck bypass */
300#define RS_EVENT (1<< 2) /* FDDI event occurred */
301#define RS_RINGOPCHANGE (1<< 1) /* ring op changed */
302#define RS_RES0 (1<< 0) /* reserved */
303
304#define RS_SET(smc,bit) \
305 ring_status_indication(smc,smc->srf.ring_status |= bit)
306#define RS_CLEAR(smc,bit) \
307 ring_status_indication(smc,smc->srf.ring_status &= ~bit)
308
309#define RS_CLEAR_EVENT (0xffff & ~(RS_NORINGOP))
310
311/* Define the AIX-event-Notification as null function if it isn't defined */
312/* in the targetos.h file */
313#ifndef AIX_EVENT
314#define AIX_EVENT(smc,opt0,opt1,opt2,opt3) /* nothing */
315#endif
316
317struct s_srf_evc {
318 u_char evc_code ; /* event code type */
319 u_char evc_index ; /* index for mult. instances */
320 u_char evc_rep_required ; /* report required */
321 u_short evc_para ; /* SMT Para Number */
322 u_char *evc_cond_state ; /* condition state */
323 u_char *evc_multiple ; /* multiple occurrence */
324} ;
325
326/*
327 * Values used by frame based services
328 * smt.c
329 */
330#define SMT_MAX_TEST 5
331#define SMT_TID_NIF 0 /* pending NIF request */
332#define SMT_TID_NIF_TEST 1 /* pending NIF test */
333#define SMT_TID_ECF_UNA 2 /* pending ECF UNA test */
334#define SMT_TID_ECF_DNA 3 /* pending ECF DNA test */
335#define SMT_TID_ECF 4 /* pending ECF test */
336
337struct smt_values {
338 u_long smt_tvu ; /* timer valid una */
339 u_long smt_tvd ; /* timer valid dna */
340 u_long smt_tid ; /* transaction id */
341 u_long pend[SMT_MAX_TEST] ; /* TID of requests */
342 u_long uniq_time ; /* unique time stamp */
343 u_short uniq_ticks ; /* unique time stamp */
344 u_short please_reconnect ; /* flag : reconnect */
345 u_long smt_last_lem ;
346 u_long smt_last_notify ;
347 struct smt_timer smt_timer ; /* SMT NIF timer */
348 u_long last_tok_time[NUMMACS]; /* token cnt emulation */
349} ;
350
351/*
352 * SMT/CMT configurable parameters
353 */
354#define SMT_DAS 0 /* dual attach */
355#define SMT_SAS 1 /* single attach */
356#define SMT_NAC 2 /* null attach concentrator */
357
358struct smt_config {
359 u_char attach_s ; /* CFM attach to secondary path */
360 u_char sas ; /* SMT_DAS/SAS/NAC */
361 u_char build_ring_map ; /* build ringmap if TRUE */
362 u_char numphys ; /* number of active phys */
363 u_char sc_pad[1] ;
364
365 u_long pcm_tb_min ; /* PCM : TB_Min timer value */
366 u_long pcm_tb_max ; /* PCM : TB_Max timer value */
367 u_long pcm_c_min ; /* PCM : C_Min timer value */
368 u_long pcm_t_out ; /* PCM : T_Out timer value */
369 u_long pcm_tl_min ; /* PCM : TL_min timer value */
370 u_long pcm_lc_short ; /* PCM : LC_Short timer value */
371 u_long pcm_lc_medium ; /* PCM : LC_Medium timer value */
372 u_long pcm_lc_long ; /* PCM : LC_Long timer value */
373 u_long pcm_lc_extended ; /* PCM : LC_Extended timer value */
374 u_long pcm_t_next_9 ; /* PCM : T_Next[9] timer value */
375 u_long pcm_ns_max ; /* PCM : NS_Max timer value */
376
377 u_long ecm_i_max ; /* ECM : I_Max timer value */
378 u_long ecm_in_max ; /* ECM : IN_Max timer value */
379 u_long ecm_td_min ; /* ECM : TD_Min timer */
380 u_long ecm_test_done ; /* ECM : path test done timer */
381 u_long ecm_check_poll ; /* ECM : check bypass poller */
382
383 u_long rmt_t_non_op ; /* RMT : T_Non_OP timer value */
384 u_long rmt_t_stuck ; /* RMT : T_Stuck timer value */
385 u_long rmt_t_direct ; /* RMT : T_Direct timer value */
386 u_long rmt_t_jam ; /* RMT : T_Jam timer value */
387 u_long rmt_t_announce ; /* RMT : T_Announce timer value */
388 u_long rmt_t_poll ; /* RMT : claim/beacon poller */
389 u_long rmt_dup_mac_behavior ; /* Flag for the beavior of SMT if
390 * a Duplicate MAC Address was detected.
391 * FALSE: SMT will leave finaly the ring
392 * TRUE: SMT will reinstert into the ring
393 */
394 u_long mac_d_max ; /* MAC : D_Max timer value */
395
396 u_long lct_short ; /* LCT : error threshhold */
397 u_long lct_medium ; /* LCT : error threshhold */
398 u_long lct_long ; /* LCT : error threshhold */
399 u_long lct_extended ; /* LCT : error threshhold */
400} ;
401
402#ifdef DEBUG
403/*
404 * Debugging struct sometimes used in smc
405 */
406struct smt_debug {
407 int d_smtf ;
408 int d_smt ;
409 int d_ecm ;
410 int d_rmt ;
411 int d_cfm ;
412 int d_pcm ;
413 int d_plc ;
414#ifdef ESS
415 int d_ess ;
416#endif
417#ifdef SBA
418 int d_sba ;
419#endif
420 struct os_debug d_os; /* Include specific OS DEBUG struct */
421} ;
422
423#ifndef DEBUG_BRD
424/* all boards shall be debugged with one debug struct */
425extern struct smt_debug debug; /* Declaration of debug struct */
426#endif /* DEBUG_BRD */
427
428#endif /* DEBUG */
429
430/*
431 * the SMT Context Struct SMC
432 * this struct contains ALL global variables of SMT
433 */
434struct s_smc {
435 struct s_smt_os os ; /* os specific */
436 struct s_smt_hw hw ; /* hardware */
437
438/*
439 * NOTE: os and hw MUST BE the first two structs
440 * anything beyond hw WILL BE SET TO ZERO in smt_set_defaults()
441 */
442 struct smt_config s ; /* smt constants */
443 struct smt_values sm ; /* smt variables */
444 struct s_ecm e ; /* ecm */
445 struct s_rmt r ; /* rmt */
446 struct s_cfm cf ; /* cfm/cem */
447#ifdef CONCENTRATOR
448 struct s_cem ce[NUMPHYS] ; /* cem */
449 struct s_c_ring cr[NUMPHYS+NUMMACS] ;
450#endif
451 struct s_pcm p ; /* pcm */
452 struct s_phy y[NUMPHYS] ; /* phy */
453 struct s_queue q ; /* queue */
454 struct s_timer t ; /* timer */
455 struct s_srf srf ; /* SRF */
456 struct s_srf_evc evcs[6+NUMPHYS*4] ;
457 struct fddi_mib mib ; /* __THE_MIB__ */
458#ifdef SBA
459 struct s_sba sba ; /* SBA variables */
460#endif
461#ifdef ESS
462 struct s_ess ess ; /* Ess variables */
463#endif
464#if defined(DEBUG) && defined(DEBUG_BRD)
465 /* If you want all single board to be debugged separately */
466 struct smt_debug debug; /* Declaration of debug struct */
467#endif /* DEBUG_BRD && DEBUG */
468} ;
469
470#endif /* _SCMECM_ */
471
diff --git a/drivers/net/skfp/h/smt.h b/drivers/net/skfp/h/smt.h
new file mode 100644
index 000000000000..1ff589988d10
--- /dev/null
+++ b/drivers/net/skfp/h/smt.h
@@ -0,0 +1,882 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * The information in this file is provided "AS IS" without warranty.
12 *
13 ******************************************************************************/
14
15/*
16 * SMT 7.2 frame definitions
17 */
18
19#ifndef _SMT_
20#define _SMT_
21
22/* #define SMT5_10 */
23#define SMT6_10
24#define SMT7_20
25
26#define OPT_PMF /* if parameter management is supported */
27#define OPT_SRF /* if status report is supported */
28
29/*
30 * SMT frame version 5.1
31 */
32
33#define SMT_VID 0x0001 /* V 5.1 .. 6.1 */
34#define SMT_VID_2 0x0002 /* V 7.2 */
35
36struct smt_sid {
37 u_char sid_oem[2] ; /* implementation spec. */
38 struct fddi_addr sid_node ; /* node address */
39} ;
40
41typedef u_char t_station_id[8] ;
42
43/*
44 * note on alignment :
45 * sizeof(struct smt_header) = 32
46 * all parameters are long aligned
47 * if struct smt_header starts at offset 0, all longs are aligned correctly
48 * (FC starts at offset 3)
49 */
50_packed struct smt_header {
51 struct fddi_addr smt_dest ; /* destination address */
52 struct fddi_addr smt_source ; /* source address */
53 u_char smt_class ; /* NIF, SIF ... */
54 u_char smt_type ; /* req., response .. */
55 u_short smt_version ; /* version id */
56 u_int smt_tid ; /* transaction ID */
57 struct smt_sid smt_sid ; /* station ID */
58 u_short smt_pad ; /* pad with 0 */
59 u_short smt_len ; /* length of info field */
60} ;
61#define SWAP_SMTHEADER "662sl8ss"
62
63#if 0
64/*
65 * MAC FC values
66 */
67#define FC_SMT_INFO 0x41 /* SMT info */
68#define FC_SMT_NSA 0x4f /* SMT Next Station Addressing */
69#endif
70
71
72/*
73 * type codes
74 */
75#define SMT_ANNOUNCE 0x01 /* announcement */
76#define SMT_REQUEST 0x02 /* request */
77#define SMT_REPLY 0x03 /* reply */
78
79/*
80 * class codes
81 */
82#define SMT_NIF 0x01 /* neighbor information frames */
83#define SMT_SIF_CONFIG 0x02 /* station information configuration */
84#define SMT_SIF_OPER 0x03 /* station information operation */
85#define SMT_ECF 0x04 /* echo frames */
86#define SMT_RAF 0x05 /* resource allocation */
87#define SMT_RDF 0x06 /* request denied */
88#define SMT_SRF 0x07 /* status report */
89#define SMT_PMF_GET 0x08 /* parameter management get */
90#define SMT_PMF_SET 0x09 /* parameter management set */
91#define SMT_ESF 0xff /* extended service */
92
93#define SMT_MAX_ECHO_LEN 4458 /* max length of SMT Echo */
94#if defined(CONC) || defined(CONC_II)
95#define SMT_TEST_ECHO_LEN 50 /* test length of SMT Echo */
96#else
97#define SMT_TEST_ECHO_LEN SMT_MAX_ECHO_LEN /* test length */
98#endif
99
100#define SMT_MAX_INFO_LEN (4352-20) /* max length for SMT info */
101
102
103/*
104 * parameter types
105 */
106
107struct smt_para {
108 u_short p_type ; /* type */
109 u_short p_len ; /* length of parameter */
110} ;
111
112#define PARA_LEN (sizeof(struct smt_para))
113
114#define SMTSETPARA(p,t) (p)->para.p_type = (t),\
115 (p)->para.p_len = sizeof(*(p)) - PARA_LEN
116
117/*
118 * P01 : Upstream Neighbor Address, UNA
119 */
120#define SMT_P_UNA 0x0001 /* upstream neighbor address */
121#define SWAP_SMT_P_UNA "s6"
122
123struct smt_p_una {
124 struct smt_para para ; /* generic parameter header */
125 u_short una_pad ;
126 struct fddi_addr una_node ; /* node address, zero if unknown */
127} ;
128
129/*
130 * P02 : Station Descriptor
131 */
132#define SMT_P_SDE 0x0002 /* station descriptor */
133#define SWAP_SMT_P_SDE "1111"
134
135#define SMT_SDE_STATION 0 /* end node */
136#define SMT_SDE_CONCENTRATOR 1 /* concentrator */
137
138struct smt_p_sde {
139 struct smt_para para ; /* generic parameter header */
140 u_char sde_type ; /* station type */
141 u_char sde_mac_count ; /* number of MACs */
142 u_char sde_non_master ; /* number of A,B or S ports */
143 u_char sde_master ; /* number of S ports on conc. */
144} ;
145
146/*
147 * P03 : Station State
148 */
149#define SMT_P_STATE 0x0003 /* station state */
150#define SWAP_SMT_P_STATE "scc"
151
152struct smt_p_state {
153 struct smt_para para ; /* generic parameter header */
154 u_short st_pad ;
155 u_char st_topology ; /* topology */
156 u_char st_dupl_addr ; /* duplicate address detected */
157} ;
158#define SMT_ST_WRAPPED (1<<0) /* station wrapped */
159#define SMT_ST_UNATTACHED (1<<1) /* unattached concentrator */
160#define SMT_ST_TWISTED_A (1<<2) /* A-A connection, twisted ring */
161#define SMT_ST_TWISTED_B (1<<3) /* B-B connection, twisted ring */
162#define SMT_ST_ROOTED_S (1<<4) /* rooted station */
163#define SMT_ST_SRF (1<<5) /* SRF protocol supported */
164#define SMT_ST_SYNC_SERVICE (1<<6) /* use synchronous bandwidth */
165
166#define SMT_ST_MY_DUPA (1<<0) /* my station detected dupl. */
167#define SMT_ST_UNA_DUPA (1<<1) /* my UNA detected duplicate */
168
169/*
170 * P04 : timestamp
171 */
172#define SMT_P_TIMESTAMP 0x0004 /* time stamp */
173#define SWAP_SMT_P_TIMESTAMP "8"
174struct smt_p_timestamp {
175 struct smt_para para ; /* generic parameter header */
176 u_char ts_time[8] ; /* time, resolution 80nS, unique */
177} ;
178
179/*
180 * P05 : station policies
181 */
182#define SMT_P_POLICY 0x0005 /* station policies */
183#define SWAP_SMT_P_POLICY "ss"
184
185struct smt_p_policy {
186 struct smt_para para ; /* generic parameter header */
187 u_short pl_config ;
188 u_short pl_connect ; /* bit string POLICY_AA ... */
189} ;
190#define SMT_PL_HOLD 1 /* hold policy supported (Dual MAC) */
191
192/*
193 * P06 : latency equivalent
194 */
195#define SMT_P_LATENCY 0x0006 /* latency */
196#define SWAP_SMT_P_LATENCY "ssss"
197
198/*
199 * note: latency has two phy entries by definition
200 * for a SAS, the 2nd one is null
201 */
202struct smt_p_latency {
203 struct smt_para para ; /* generic parameter header */
204 u_short lt_phyout_idx1 ; /* index */
205 u_short lt_latency1 ; /* latency , unit : byte clock */
206 u_short lt_phyout_idx2 ; /* 0 if SAS */
207 u_short lt_latency2 ; /* 0 if SAS */
208} ;
209
210/*
211 * P07 : MAC neighbors
212 */
213#define SMT_P_NEIGHBORS 0x0007 /* MAC neighbor description */
214#define SWAP_SMT_P_NEIGHBORS "ss66"
215
216struct smt_p_neighbor {
217 struct smt_para para ; /* generic parameter header */
218 u_short nb_mib_index ; /* MIB index */
219 u_short nb_mac_index ; /* n+1 .. n+m, m = #MACs, n = #PHYs */
220 struct fddi_addr nb_una ; /* UNA , 0 for unknown */
221 struct fddi_addr nb_dna ; /* DNA , 0 for unknown */
222} ;
223
224/*
225 * PHY record
226 */
227#define SMT_PHY_A 0 /* A port */
228#define SMT_PHY_B 1 /* B port */
229#define SMT_PHY_S 2 /* slave port */
230#define SMT_PHY_M 3 /* master port */
231
232#define SMT_CS_DISABLED 0 /* connect state : disabled */
233#define SMT_CS_CONNECTING 1 /* connect state : connecting */
234#define SMT_CS_STANDBY 2 /* connect state : stand by */
235#define SMT_CS_ACTIVE 3 /* connect state : active */
236
237#define SMT_RM_NONE 0
238#define SMT_RM_MAC 1
239
240struct smt_phy_rec {
241 u_short phy_mib_index ; /* MIB index */
242 u_char phy_type ; /* A/B/S/M */
243 u_char phy_connect_state ; /* disabled/connecting/active */
244 u_char phy_remote_type ; /* A/B/S/M */
245 u_char phy_remote_mac ; /* none/remote */
246 u_short phy_resource_idx ; /* 1 .. n */
247} ;
248
249/*
250 * MAC record
251 */
252struct smt_mac_rec {
253 struct fddi_addr mac_addr ; /* MAC address */
254 u_short mac_resource_idx ; /* n+1 .. n+m */
255} ;
256
257/*
258 * P08 : path descriptors
259 * should be really an array ; however our environment has a fixed number of
260 * PHYs and MACs
261 */
262#define SMT_P_PATH 0x0008 /* path descriptor */
263#define SWAP_SMT_P_PATH "[6s]"
264
265struct smt_p_path {
266 struct smt_para para ; /* generic parameter header */
267 struct smt_phy_rec pd_phy[2] ; /* PHY A */
268 struct smt_mac_rec pd_mac ; /* MAC record */
269} ;
270
271/*
272 * P09 : MAC status
273 */
274#define SMT_P_MAC_STATUS 0x0009 /* MAC status */
275#define SWAP_SMT_P_MAC_STATUS "sslllllllll"
276
277struct smt_p_mac_status {
278 struct smt_para para ; /* generic parameter header */
279 u_short st_mib_index ; /* MIB index */
280 u_short st_mac_index ; /* n+1 .. n+m */
281 u_int st_t_req ; /* T_Req */
282 u_int st_t_neg ; /* T_Neg */
283 u_int st_t_max ; /* T_Max */
284 u_int st_tvx_value ; /* TVX_Value */
285 u_int st_t_min ; /* T_Min */
286 u_int st_sba ; /* synchr. bandwidth alloc */
287 u_int st_frame_ct ; /* frame counter */
288 u_int st_error_ct ; /* error counter */
289 u_int st_lost_ct ; /* lost frames counter */
290} ;
291
292/*
293 * P0A : PHY link error rate monitoring
294 */
295#define SMT_P_LEM 0x000a /* link error monitor */
296#define SWAP_SMT_P_LEM "ssccccll"
297/*
298 * units of lem_cutoff,lem_alarm,lem_estimate : 10**-x
299 */
300struct smt_p_lem {
301 struct smt_para para ; /* generic parameter header */
302 u_short lem_mib_index ; /* MIB index */
303 u_short lem_phy_index ; /* 1 .. n */
304 u_char lem_pad2 ; /* be nice and make it even . */
305 u_char lem_cutoff ; /* 0x4 .. 0xf, default 0x7 */
306 u_char lem_alarm ; /* 0x4 .. 0xf, default 0x8 */
307 u_char lem_estimate ; /* 0x0 .. 0xff */
308 u_int lem_reject_ct ; /* 0x00000000 .. 0xffffffff */
309 u_int lem_ct ; /* 0x00000000 .. 0xffffffff */
310} ;
311
312/*
313 * P0B : MAC frame counters
314 */
315#define SMT_P_MAC_COUNTER 0x000b /* MAC frame counters */
316#define SWAP_SMT_P_MAC_COUNTER "ssll"
317
318struct smt_p_mac_counter {
319 struct smt_para para ; /* generic parameter header */
320 u_short mc_mib_index ; /* MIB index */
321 u_short mc_index ; /* mac index */
322 u_int mc_receive_ct ; /* receive counter */
323 u_int mc_transmit_ct ; /* transmit counter */
324} ;
325
326/*
327 * P0C : MAC frame not copied counter
328 */
329#define SMT_P_MAC_FNC 0x000c /* MAC frame not copied counter */
330#define SWAP_SMT_P_MAC_FNC "ssl"
331
332struct smt_p_mac_fnc {
333 struct smt_para para ; /* generic parameter header */
334 u_short nc_mib_index ; /* MIB index */
335 u_short nc_index ; /* mac index */
336 u_int nc_counter ; /* not copied counter */
337} ;
338
339
340/*
341 * P0D : MAC priority values
342 */
343#define SMT_P_PRIORITY 0x000d /* MAC priority values */
344#define SWAP_SMT_P_PRIORITY "ssl"
345
346struct smt_p_priority {
347 struct smt_para para ; /* generic parameter header */
348 u_short pr_mib_index ; /* MIB index */
349 u_short pr_index ; /* mac index */
350 u_int pr_priority[7] ; /* priority values */
351} ;
352
353/*
354 * P0E : PHY elasticity buffer status
355 */
356#define SMT_P_EB 0x000e /* PHY EB status */
357#define SWAP_SMT_P_EB "ssl"
358
359struct smt_p_eb {
360 struct smt_para para ; /* generic parameter header */
361 u_short eb_mib_index ; /* MIB index */
362 u_short eb_index ; /* phy index */
363 u_int eb_error_ct ; /* # of eb overflows */
364} ;
365
366/*
367 * P0F : manufacturer field
368 */
369#define SMT_P_MANUFACTURER 0x000f /* manufacturer field */
370#define SWAP_SMT_P_MANUFACTURER ""
371
372struct smp_p_manufacturer {
373 struct smt_para para ; /* generic parameter header */
374 u_char mf_data[32] ; /* OUI + arbitrary data */
375} ;
376
377/*
378 * P10 : user field
379 */
380#define SMT_P_USER 0x0010 /* manufacturer field */
381#define SWAP_SMT_P_USER ""
382
383struct smp_p_user {
384 struct smt_para para ; /* generic parameter header */
385 u_char us_data[32] ; /* arbitrary data */
386} ;
387
388
389
390/*
391 * P11 : echo data
392 */
393#define SMT_P_ECHODATA 0x0011 /* echo data */
394#define SWAP_SMT_P_ECHODATA ""
395
396struct smt_p_echo {
397 struct smt_para para ; /* generic parameter header */
398 u_char ec_data[SMT_MAX_ECHO_LEN-4] ; /* echo data */
399} ;
400
401/*
402 * P12 : reason code
403 */
404#define SMT_P_REASON 0x0012 /* reason code */
405#define SWAP_SMT_P_REASON "l"
406
407struct smt_p_reason {
408 struct smt_para para ; /* generic parameter header */
409 u_int rdf_reason ; /* CLASS/VERSION */
410} ;
411#define SMT_RDF_CLASS 0x00000001 /* class not supported */
412#define SMT_RDF_VERSION 0x00000002 /* version not supported */
413#define SMT_RDF_SUCCESS 0x00000003 /* success (PMF) */
414#define SMT_RDF_BADSET 0x00000004 /* bad set count (PMF) */
415#define SMT_RDF_ILLEGAL 0x00000005 /* read only (PMF) */
416#define SMT_RDF_NOPARAM 0x6 /* paramter not supported (PMF) */
417#define SMT_RDF_RANGE 0x8 /* out of range */
418#define SMT_RDF_AUTHOR 0x9 /* not autohorized */
419#define SMT_RDF_LENGTH 0x0a /* length error */
420#define SMT_RDF_TOOLONG 0x0b /* length error */
421#define SMT_RDF_SBA 0x0d /* SBA denied */
422
423/*
424 * P13 : refused frame beginning
425 */
426#define SMT_P_REFUSED 0x0013 /* refused frame beginning */
427#define SWAP_SMT_P_REFUSED "l"
428
429struct smt_p_refused {
430 struct smt_para para ; /* generic parameter header */
431 u_int ref_fc ; /* 3 bytes 0 + FC */
432 struct smt_header ref_header ; /* refused header */
433} ;
434
435/*
436 * P14 : supported SMT versions
437 */
438#define SMT_P_VERSION 0x0014 /* SMT supported versions */
439#define SWAP_SMT_P_VERSION "sccss"
440
441struct smt_p_version {
442 struct smt_para para ; /* generic parameter header */
443 u_short v_pad ;
444 u_char v_n ; /* 1 .. 0xff, #versions */
445 u_char v_index ; /* 1 .. 0xff, index of op. v. */
446 u_short v_version[1] ; /* list of min. 1 version */
447 u_short v_pad2 ; /* pad if necessary */
448} ;
449
450/*
451 * P15 : Resource Type
452 */
453#define SWAP_SMT_P0015 "l"
454
455struct smt_p_0015 {
456 struct smt_para para ; /* generic parameter header */
457 u_int res_type ; /* recsource type */
458} ;
459
460#define SYNC_BW 0x00000001L /* Synchronous Bandwidth */
461
462/*
463 * P16 : SBA Command
464 */
465#define SWAP_SMT_P0016 "l"
466
467struct smt_p_0016 {
468 struct smt_para para ; /* generic parameter header */
469 u_int sba_cmd ; /* command for the SBA */
470} ;
471
472#define REQUEST_ALLOCATION 0x1 /* req allocation of sync bandwidth */
473#define REPORT_ALLOCATION 0x2 /* rep of sync bandwidth allocation */
474#define CHANGE_ALLOCATION 0x3 /* forces a station using sync band-*/
475 /* width to change its current allo-*/
476 /* cation */
477
478/*
479 * P17 : SBA Payload Request
480 */
481#define SWAP_SMT_P0017 "l"
482
483struct smt_p_0017 {
484 struct smt_para para ; /* generic parameter header */
485 int sba_pl_req ; /* total sync bandwidth measured in */
486} ; /* bytes per 125 us */
487
488/*
489 * P18 : SBA Overhead Request
490 */
491#define SWAP_SMT_P0018 "l"
492
493struct smt_p_0018 {
494 struct smt_para para ; /* generic parameter header */
495 int sba_ov_req ; /* total sync bandwidth req for overhead*/
496} ; /* measuered in bytes per T_Neg */
497
498/*
499 * P19 : SBA Allocation Address
500 */
501#define SWAP_SMT_P0019 "s6"
502
503struct smt_p_0019 {
504 struct smt_para para ; /* generic parameter header */
505 u_short sba_pad ;
506 struct fddi_addr alloc_addr ; /* Allocation Address */
507} ;
508
509/*
510 * P1A : SBA Category
511 */
512#define SWAP_SMT_P001A "l"
513
514struct smt_p_001a {
515 struct smt_para para ; /* generic parameter header */
516 u_int category ; /* Allocator defined classification */
517} ;
518
519/*
520 * P1B : Maximum T_Neg
521 */
522#define SWAP_SMT_P001B "l"
523
524struct smt_p_001b {
525 struct smt_para para ; /* generic parameter header */
526 u_int max_t_neg ; /* longest T_NEG for the sync service*/
527} ;
528
529/*
530 * P1C : Minimum SBA Segment Size
531 */
532#define SWAP_SMT_P001C "l"
533
534struct smt_p_001c {
535 struct smt_para para ; /* generic parameter header */
536 u_int min_seg_siz ; /* smallest number of bytes per frame*/
537} ;
538
539/*
540 * P1D : SBA Allocatable
541 */
542#define SWAP_SMT_P001D "l"
543
544struct smt_p_001d {
545 struct smt_para para ; /* generic parameter header */
546 u_int allocatable ; /* total sync bw available for alloc */
547} ;
548
549/*
550 * P20 0B : frame status capabilities
551 * NOTE: not in swap table, is used by smt.c AND PMF table
552 */
553#define SMT_P_FSC 0x200b
554/* #define SWAP_SMT_P_FSC "ssss" */
555
556struct smt_p_fsc {
557 struct smt_para para ; /* generic parameter header */
558 u_short fsc_pad0 ;
559 u_short fsc_mac_index ; /* mac index 1 .. ff */
560 u_short fsc_pad1 ;
561 u_short fsc_value ; /* FSC_TYPE[0-2] */
562} ;
563
564#define FSC_TYPE0 0 /* "normal" node (A/C handling) */
565#define FSC_TYPE1 1 /* Special A/C indicator forwarding */
566#define FSC_TYPE2 2 /* Special A/C indicator forwarding */
567
568/*
569 * P00 21 : user defined authoriziation (see pmf.c)
570 */
571#define SMT_P_AUTHOR 0x0021
572
573/*
574 * notification parameters
575 */
576#define SWAP_SMT_P1048 "ll"
577struct smt_p_1048 {
578 u_int p1048_flag ;
579 u_int p1048_cf_state ;
580} ;
581
582/*
583 * NOTE: all 2xxx 3xxx and 4xxx must include the INDEX in the swap string,
584 * even so the INDEX is NOT part of the struct.
585 * INDEX is already swapped in pmf.c, format in string is '4'
586 */
587#define SWAP_SMT_P208C "4lss66"
588struct smt_p_208c {
589 u_int p208c_flag ;
590 u_short p208c_pad ;
591 u_short p208c_dupcondition ;
592 struct fddi_addr p208c_fddilong ;
593 struct fddi_addr p208c_fddiunalong ;
594} ;
595
596#define SWAP_SMT_P208D "4lllll"
597struct smt_p_208d {
598 u_int p208d_flag ;
599 u_int p208d_frame_ct ;
600 u_int p208d_error_ct ;
601 u_int p208d_lost_ct ;
602 u_int p208d_ratio ;
603} ;
604
605#define SWAP_SMT_P208E "4llll"
606struct smt_p_208e {
607 u_int p208e_flag ;
608 u_int p208e_not_copied ;
609 u_int p208e_copied ;
610 u_int p208e_not_copied_ratio ;
611} ;
612
613#define SWAP_SMT_P208F "4ll6666s6"
614
615struct smt_p_208f {
616 u_int p208f_multiple ;
617 u_int p208f_nacondition ;
618 struct fddi_addr p208f_old_una ;
619 struct fddi_addr p208f_new_una ;
620 struct fddi_addr p208f_old_dna ;
621 struct fddi_addr p208f_new_dna ;
622 u_short p208f_curren_path ;
623 struct fddi_addr p208f_smt_address ;
624} ;
625
626#define SWAP_SMT_P2090 "4lssl"
627
628struct smt_p_2090 {
629 u_int p2090_multiple ;
630 u_short p2090_availablepaths ;
631 u_short p2090_currentpath ;
632 u_int p2090_requestedpaths ;
633} ;
634
635/*
636 * NOTE:
637 * special kludge for parameters 320b,320f,3210
638 * these parameters are part of RAF frames
639 * RAF frames are parsed in SBA.C and must be swapped
640 * PMF.C has special code to avoid double swapping
641 */
642#ifdef LITTLE_ENDIAN
643#define SBAPATHINDEX (0x01000000L)
644#else
645#define SBAPATHINDEX (0x01L)
646#endif
647
648#define SWAP_SMT_P320B "42s"
649
650struct smt_p_320b {
651 struct smt_para para ; /* generic parameter header */
652 u_int mib_index ;
653 u_short path_pad ;
654 u_short path_index ;
655} ;
656
657#define SWAP_SMT_P320F "4l"
658
659struct smt_p_320f {
660 struct smt_para para ; /* generic parameter header */
661 u_int mib_index ;
662 u_int mib_payload ;
663} ;
664
665#define SWAP_SMT_P3210 "4l"
666
667struct smt_p_3210 {
668 struct smt_para para ; /* generic parameter header */
669 u_int mib_index ;
670 u_int mib_overhead ;
671} ;
672
673#define SWAP_SMT_P4050 "4l1111ll"
674
675struct smt_p_4050 {
676 u_int p4050_flag ;
677 u_char p4050_pad ;
678 u_char p4050_cutoff ;
679 u_char p4050_alarm ;
680 u_char p4050_estimate ;
681 u_int p4050_reject_ct ;
682 u_int p4050_ct ;
683} ;
684
685#define SWAP_SMT_P4051 "4lssss"
686struct smt_p_4051 {
687 u_int p4051_multiple ;
688 u_short p4051_porttype ;
689 u_short p4051_connectstate ;
690 u_short p4051_pc_neighbor ;
691 u_short p4051_pc_withhold ;
692} ;
693
694#define SWAP_SMT_P4052 "4ll"
695struct smt_p_4052 {
696 u_int p4052_flag ;
697 u_int p4052_eberrorcount ;
698} ;
699
700#define SWAP_SMT_P4053 "4lsslss"
701
702struct smt_p_4053 {
703 u_int p4053_multiple ;
704 u_short p4053_availablepaths ;
705 u_short p4053_currentpath ;
706 u_int p4053_requestedpaths ;
707 u_short p4053_mytype ;
708 u_short p4053_neighbortype ;
709} ;
710
711
712#define SMT_P_SETCOUNT 0x1035
713#define SWAP_SMT_P_SETCOUNT "l8"
714
715struct smt_p_setcount {
716 struct smt_para para ; /* generic parameter header */
717 u_int count ;
718 u_char timestamp[8] ;
719} ;
720
721/*
722 * SMT FRAMES
723 */
724
725/*
726 * NIF : neighbor information frames
727 */
728struct smt_nif {
729 struct smt_header smt ; /* generic header */
730 struct smt_p_una una ; /* UNA */
731 struct smt_p_sde sde ; /* station descriptor */
732 struct smt_p_state state ; /* station state */
733#ifdef SMT6_10
734 struct smt_p_fsc fsc ; /* frame status cap. */
735#endif
736} ;
737
738/*
739 * SIF : station information frames
740 */
741struct smt_sif_config {
742 struct smt_header smt ; /* generic header */
743 struct smt_p_timestamp ts ; /* time stamp */
744 struct smt_p_sde sde ; /* station descriptor */
745 struct smt_p_version version ; /* supported versions */
746 struct smt_p_state state ; /* station state */
747 struct smt_p_policy policy ; /* station policy */
748 struct smt_p_latency latency ; /* path latency */
749 struct smt_p_neighbor neighbor ; /* neighbors, we have only one*/
750#ifdef OPT_PMF
751 struct smt_p_setcount setcount ; /* Set Count mandatory */
752#endif
753 /* WARNING : path MUST BE LAST FIELD !!! (see smt.c:smt_fill_path) */
754 struct smt_p_path path ; /* path descriptor */
755} ;
756#define SIZEOF_SMT_SIF_CONFIG (sizeof(struct smt_sif_config)- \
757 sizeof(struct smt_p_path))
758
759struct smt_sif_operation {
760 struct smt_header smt ; /* generic header */
761 struct smt_p_timestamp ts ; /* time stamp */
762 struct smt_p_mac_status status ; /* mac status */
763 struct smt_p_mac_counter mc ; /* MAC counter */
764 struct smt_p_mac_fnc fnc ; /* MAC frame not copied */
765 struct smp_p_manufacturer man ; /* manufacturer field */
766 struct smp_p_user user ; /* user field */
767#ifdef OPT_PMF
768 struct smt_p_setcount setcount ; /* Set Count mandatory */
769#endif
770 /* must be last */
771 struct smt_p_lem lem[1] ; /* phy lem status */
772} ;
773#define SIZEOF_SMT_SIF_OPERATION (sizeof(struct smt_sif_operation)- \
774 sizeof(struct smt_p_lem))
775
776/*
777 * ECF : echo frame
778 */
779struct smt_ecf {
780 struct smt_header smt ; /* generic header */
781 struct smt_p_echo ec_echo ; /* echo parameter */
782} ;
783#define SMT_ECF_LEN (sizeof(struct smt_header)+sizeof(struct smt_para))
784
785/*
786 * RDF : request denied frame
787 */
788struct smt_rdf {
789 struct smt_header smt ; /* generic header */
790 struct smt_p_reason reason ; /* reason code */
791 struct smt_p_version version ; /* supported versions */
792 struct smt_p_refused refused ; /* refused frame fragment */
793} ;
794
795/*
796 * SBA Request Allocation Responce Frame
797 */
798struct smt_sba_alc_res {
799 struct smt_header smt ; /* generic header */
800 struct smt_p_0015 s_type ; /* resource type */
801 struct smt_p_0016 cmd ; /* SBA command */
802 struct smt_p_reason reason ; /* reason code */
803 struct smt_p_320b path ; /* path type */
804 struct smt_p_320f payload ; /* current SBA payload */
805 struct smt_p_3210 overhead ; /* current SBA overhead */
806 struct smt_p_0019 a_addr ; /* Allocation Address */
807 struct smt_p_001a cat ; /* Category - from the request */
808 struct smt_p_001d alloc ; /* SBA Allocatable */
809} ;
810
811/*
812 * SBA Request Allocation Request Frame
813 */
814struct smt_sba_alc_req {
815 struct smt_header smt ; /* generic header */
816 struct smt_p_0015 s_type ; /* resource type */
817 struct smt_p_0016 cmd ; /* SBA command */
818 struct smt_p_320b path ; /* path type */
819 struct smt_p_0017 pl_req ; /* requested payload */
820 struct smt_p_0018 ov_req ; /* requested SBA overhead */
821 struct smt_p_320f payload ; /* current SBA payload */
822 struct smt_p_3210 overhead ; /* current SBA overhead */
823 struct smt_p_0019 a_addr ; /* Allocation Address */
824 struct smt_p_001a cat ; /* Category - from the request */
825 struct smt_p_001b tneg ; /* max T-NEG */
826 struct smt_p_001c segm ; /* minimum segment size */
827} ;
828
829/*
830 * SBA Change Allocation Request Frame
831 */
832struct smt_sba_chg {
833 struct smt_header smt ; /* generic header */
834 struct smt_p_0015 s_type ; /* resource type */
835 struct smt_p_0016 cmd ; /* SBA command */
836 struct smt_p_320b path ; /* path type */
837 struct smt_p_320f payload ; /* current SBA payload */
838 struct smt_p_3210 overhead ; /* current SBA overhead */
839 struct smt_p_001a cat ; /* Category - from the request */
840} ;
841
842/*
843 * SBA Report Allocation Request Frame
844 */
845struct smt_sba_rep_req {
846 struct smt_header smt ; /* generic header */
847 struct smt_p_0015 s_type ; /* resource type */
848 struct smt_p_0016 cmd ; /* SBA command */
849} ;
850
851/*
852 * SBA Report Allocation Response Frame
853 */
854struct smt_sba_rep_res {
855 struct smt_header smt ; /* generic header */
856 struct smt_p_0015 s_type ; /* resource type */
857 struct smt_p_0016 cmd ; /* SBA command */
858 struct smt_p_320b path ; /* path type */
859 struct smt_p_320f payload ; /* current SBA payload */
860 struct smt_p_3210 overhead ; /* current SBA overhead */
861} ;
862
863/*
864 * actions
865 */
866#define SMT_STATION_ACTION 1
867#define SMT_STATION_ACTION_CONNECT 0
868#define SMT_STATION_ACTION_DISCONNECT 1
869#define SMT_STATION_ACTION_PATHTEST 2
870#define SMT_STATION_ACTION_SELFTEST 3
871#define SMT_STATION_ACTION_DISABLE_A 4
872#define SMT_STATION_ACTION_DISABLE_B 5
873#define SMT_STATION_ACTION_DISABLE_M 6
874
875#define SMT_PORT_ACTION 2
876#define SMT_PORT_ACTION_MAINT 0
877#define SMT_PORT_ACTION_ENABLE 1
878#define SMT_PORT_ACTION_DISABLE 2
879#define SMT_PORT_ACTION_START 3
880#define SMT_PORT_ACTION_STOP 4
881
882#endif /* _SMT_ */
diff --git a/drivers/net/skfp/h/smt_p.h b/drivers/net/skfp/h/smt_p.h
new file mode 100644
index 000000000000..99f9be9552bb
--- /dev/null
+++ b/drivers/net/skfp/h/smt_p.h
@@ -0,0 +1,326 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * The information in this file is provided "AS IS" without warranty.
12 *
13 ******************************************************************************/
14
15/*
16 * defines for all SMT attributes
17 */
18
19/*
20 * this boring file was produced by perl
21 * thanks Larry !
22 */
23#define SMT_P0012 0x0012
24
25#define SMT_P0015 0x0015
26#define SMT_P0016 0x0016
27#define SMT_P0017 0x0017
28#define SMT_P0018 0x0018
29#define SMT_P0019 0x0019
30
31#define SMT_P001A 0x001a
32#define SMT_P001B 0x001b
33#define SMT_P001C 0x001c
34#define SMT_P001D 0x001d
35
36#define SMT_P100A 0x100a
37#define SMT_P100B 0x100b
38#define SMT_P100C 0x100c
39#define SMT_P100D 0x100d
40#define SMT_P100E 0x100e
41#define SMT_P100F 0x100f
42#define SMT_P1010 0x1010
43#define SMT_P1011 0x1011
44#define SMT_P1012 0x1012
45#define SMT_P1013 0x1013
46#define SMT_P1014 0x1014
47#define SMT_P1015 0x1015
48#define SMT_P1016 0x1016
49#define SMT_P1017 0x1017
50#define SMT_P1018 0x1018
51#define SMT_P1019 0x1019
52#define SMT_P101A 0x101a
53#define SMT_P101B 0x101b
54#define SMT_P101C 0x101c
55#define SMT_P101D 0x101d
56#define SMT_P101E 0x101e
57#define SMT_P101F 0x101f
58#define SMT_P1020 0x1020
59#define SMT_P1021 0x1021
60#define SMT_P1022 0x1022
61#define SMT_P1023 0x1023
62#define SMT_P1024 0x1024
63#define SMT_P1025 0x1025
64#define SMT_P1026 0x1026
65#define SMT_P1027 0x1027
66#define SMT_P1028 0x1028
67#define SMT_P1029 0x1029
68#define SMT_P102A 0x102a
69#define SMT_P102B 0x102b
70#define SMT_P102C 0x102c
71#define SMT_P102D 0x102d
72#define SMT_P102E 0x102e
73#define SMT_P102F 0x102f
74#define SMT_P1030 0x1030
75#define SMT_P1031 0x1031
76#define SMT_P1032 0x1032
77#define SMT_P1033 0x1033
78#define SMT_P1034 0x1034
79#define SMT_P1035 0x1035
80#define SMT_P1036 0x1036
81#define SMT_P1037 0x1037
82#define SMT_P1038 0x1038
83#define SMT_P1039 0x1039
84#define SMT_P103A 0x103a
85#define SMT_P103B 0x103b
86#define SMT_P103C 0x103c
87#define SMT_P103D 0x103d
88#define SMT_P103E 0x103e
89#define SMT_P103F 0x103f
90#define SMT_P1040 0x1040
91#define SMT_P1041 0x1041
92#define SMT_P1042 0x1042
93#define SMT_P1043 0x1043
94#define SMT_P1044 0x1044
95#define SMT_P1045 0x1045
96#define SMT_P1046 0x1046
97#define SMT_P1047 0x1047
98#define SMT_P1048 0x1048
99#define SMT_P1049 0x1049
100#define SMT_P104A 0x104a
101#define SMT_P104B 0x104b
102#define SMT_P104C 0x104c
103#define SMT_P104D 0x104d
104#define SMT_P104E 0x104e
105#define SMT_P104F 0x104f
106#define SMT_P1050 0x1050
107#define SMT_P1051 0x1051
108#define SMT_P1052 0x1052
109#define SMT_P1053 0x1053
110#define SMT_P1054 0x1054
111
112#define SMT_P10F0 0x10f0
113#define SMT_P10F1 0x10f1
114#ifdef ESS
115#define SMT_P10F2 0x10f2
116#define SMT_P10F3 0x10f3
117#define SMT_P10F4 0x10f4
118#define SMT_P10F5 0x10f5
119#define SMT_P10F6 0x10f6
120#define SMT_P10F7 0x10f7
121#endif
122#ifdef SBA
123#define SMT_P10F8 0x10f8
124#define SMT_P10F9 0x10f9
125#endif
126
127#define SMT_P200A 0x200a
128#define SMT_P200B 0x200b
129#define SMT_P200C 0x200c
130#define SMT_P200D 0x200d
131#define SMT_P200E 0x200e
132#define SMT_P200F 0x200f
133#define SMT_P2010 0x2010
134#define SMT_P2011 0x2011
135#define SMT_P2012 0x2012
136#define SMT_P2013 0x2013
137#define SMT_P2014 0x2014
138#define SMT_P2015 0x2015
139#define SMT_P2016 0x2016
140#define SMT_P2017 0x2017
141#define SMT_P2018 0x2018
142#define SMT_P2019 0x2019
143#define SMT_P201A 0x201a
144#define SMT_P201B 0x201b
145#define SMT_P201C 0x201c
146#define SMT_P201D 0x201d
147#define SMT_P201E 0x201e
148#define SMT_P201F 0x201f
149#define SMT_P2020 0x2020
150#define SMT_P2021 0x2021
151#define SMT_P2022 0x2022
152#define SMT_P2023 0x2023
153#define SMT_P2024 0x2024
154#define SMT_P2025 0x2025
155#define SMT_P2026 0x2026
156#define SMT_P2027 0x2027
157#define SMT_P2028 0x2028
158#define SMT_P2029 0x2029
159#define SMT_P202A 0x202a
160#define SMT_P202B 0x202b
161#define SMT_P202C 0x202c
162#define SMT_P202D 0x202d
163#define SMT_P202E 0x202e
164#define SMT_P202F 0x202f
165#define SMT_P2030 0x2030
166#define SMT_P2031 0x2031
167#define SMT_P2032 0x2032
168#define SMT_P2033 0x2033
169#define SMT_P2034 0x2034
170#define SMT_P2035 0x2035
171#define SMT_P2036 0x2036
172#define SMT_P2037 0x2037
173#define SMT_P2038 0x2038
174#define SMT_P2039 0x2039
175#define SMT_P203A 0x203a
176#define SMT_P203B 0x203b
177#define SMT_P203C 0x203c
178#define SMT_P203D 0x203d
179#define SMT_P203E 0x203e
180#define SMT_P203F 0x203f
181#define SMT_P2040 0x2040
182#define SMT_P2041 0x2041
183#define SMT_P2042 0x2042
184#define SMT_P2043 0x2043
185#define SMT_P2044 0x2044
186#define SMT_P2045 0x2045
187#define SMT_P2046 0x2046
188#define SMT_P2047 0x2047
189#define SMT_P2048 0x2048
190#define SMT_P2049 0x2049
191#define SMT_P204A 0x204a
192#define SMT_P204B 0x204b
193#define SMT_P204C 0x204c
194#define SMT_P204D 0x204d
195#define SMT_P204E 0x204e
196#define SMT_P204F 0x204f
197#define SMT_P2050 0x2050
198#define SMT_P2051 0x2051
199#define SMT_P2052 0x2052
200#define SMT_P2053 0x2053
201#define SMT_P2054 0x2054
202#define SMT_P2055 0x2055
203#define SMT_P2056 0x2056
204#define SMT_P2057 0x2057
205#define SMT_P2058 0x2058
206#define SMT_P2059 0x2059
207#define SMT_P205A 0x205a
208#define SMT_P205B 0x205b
209#define SMT_P205C 0x205c
210#define SMT_P205D 0x205d
211#define SMT_P205E 0x205e
212#define SMT_P205F 0x205f
213#define SMT_P2060 0x2060
214#define SMT_P2061 0x2061
215#define SMT_P2062 0x2062
216#define SMT_P2063 0x2063
217#define SMT_P2064 0x2064
218#define SMT_P2065 0x2065
219#define SMT_P2066 0x2066
220#define SMT_P2067 0x2067
221#define SMT_P2068 0x2068
222#define SMT_P2069 0x2069
223#define SMT_P206A 0x206a
224#define SMT_P206B 0x206b
225#define SMT_P206C 0x206c
226#define SMT_P206D 0x206d
227#define SMT_P206E 0x206e
228#define SMT_P206F 0x206f
229#define SMT_P2070 0x2070
230#define SMT_P2071 0x2071
231#define SMT_P2072 0x2072
232#define SMT_P2073 0x2073
233#define SMT_P2074 0x2074
234#define SMT_P2075 0x2075
235#define SMT_P2076 0x2076
236
237#define SMT_P208C 0x208c
238#define SMT_P208D 0x208d
239#define SMT_P208E 0x208e
240#define SMT_P208F 0x208f
241#define SMT_P2090 0x2090
242
243#define SMT_P20F0 0x20F0
244#define SMT_P20F1 0x20F1
245
246#define SMT_P320A 0x320a
247#define SMT_P320B 0x320b
248#define SMT_P320C 0x320c
249#define SMT_P320D 0x320d
250#define SMT_P320E 0x320e
251#define SMT_P320F 0x320f
252#define SMT_P3210 0x3210
253#define SMT_P3211 0x3211
254#define SMT_P3212 0x3212
255#define SMT_P3213 0x3213
256#define SMT_P3214 0x3214
257#define SMT_P3215 0x3215
258#define SMT_P3216 0x3216
259#define SMT_P3217 0x3217
260
261#define SMT_P400A 0x400a
262#define SMT_P400B 0x400b
263#define SMT_P400C 0x400c
264#define SMT_P400D 0x400d
265#define SMT_P400E 0x400e
266#define SMT_P400F 0x400f
267#define SMT_P4010 0x4010
268#define SMT_P4011 0x4011
269#define SMT_P4012 0x4012
270#define SMT_P4013 0x4013
271#define SMT_P4014 0x4014
272#define SMT_P4015 0x4015
273#define SMT_P4016 0x4016
274#define SMT_P4017 0x4017
275#define SMT_P4018 0x4018
276#define SMT_P4019 0x4019
277#define SMT_P401A 0x401a
278#define SMT_P401B 0x401b
279#define SMT_P401C 0x401c
280#define SMT_P401D 0x401d
281#define SMT_P401E 0x401e
282#define SMT_P401F 0x401f
283#define SMT_P4020 0x4020
284#define SMT_P4021 0x4021
285#define SMT_P4022 0x4022
286#define SMT_P4023 0x4023
287#define SMT_P4024 0x4024
288#define SMT_P4025 0x4025
289#define SMT_P4026 0x4026
290#define SMT_P4027 0x4027
291#define SMT_P4028 0x4028
292#define SMT_P4029 0x4029
293#define SMT_P402A 0x402a
294#define SMT_P402B 0x402b
295#define SMT_P402C 0x402c
296#define SMT_P402D 0x402d
297#define SMT_P402E 0x402e
298#define SMT_P402F 0x402f
299#define SMT_P4030 0x4030
300#define SMT_P4031 0x4031
301#define SMT_P4032 0x4032
302#define SMT_P4033 0x4033
303#define SMT_P4034 0x4034
304#define SMT_P4035 0x4035
305#define SMT_P4036 0x4036
306#define SMT_P4037 0x4037
307#define SMT_P4038 0x4038
308#define SMT_P4039 0x4039
309#define SMT_P403A 0x403a
310#define SMT_P403B 0x403b
311#define SMT_P403C 0x403c
312#define SMT_P403D 0x403d
313#define SMT_P403E 0x403e
314#define SMT_P403F 0x403f
315#define SMT_P4040 0x4040
316#define SMT_P4041 0x4041
317#define SMT_P4042 0x4042
318#define SMT_P4043 0x4043
319#define SMT_P4044 0x4044
320#define SMT_P4045 0x4045
321#define SMT_P4046 0x4046
322
323#define SMT_P4050 0x4050
324#define SMT_P4051 0x4051
325#define SMT_P4052 0x4052
326#define SMT_P4053 0x4053
diff --git a/drivers/net/skfp/h/smtstate.h b/drivers/net/skfp/h/smtstate.h
new file mode 100644
index 000000000000..62fe695077a9
--- /dev/null
+++ b/drivers/net/skfp/h/smtstate.h
@@ -0,0 +1,106 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * The information in this file is provided "AS IS" without warranty.
12 *
13 ******************************************************************************/
14
15#ifndef _SKFP_H_SMTSTATE_H_
16#define _SKFP_H_SMTSTATE_H_
17
18/*
19 * SMT state definitions
20 */
21
22#ifndef KERNEL
23/*
24 * PCM states
25 */
26#define PC0_OFF 0
27#define PC1_BREAK 1
28#define PC2_TRACE 2
29#define PC3_CONNECT 3
30#define PC4_NEXT 4
31#define PC5_SIGNAL 5
32#define PC6_JOIN 6
33#define PC7_VERIFY 7
34#define PC8_ACTIVE 8
35#define PC9_MAINT 9
36
37/*
38 * PCM modes
39 */
40#define PM_NONE 0
41#define PM_PEER 1
42#define PM_TREE 2
43
44/*
45 * PCM type
46 */
47#define TA 0
48#define TB 1
49#define TS 2
50#define TM 3
51#define TNONE 4
52
53/*
54 * CFM states
55 */
56#define SC0_ISOLATED 0 /* isolated */
57#define SC1_WRAP_A 5 /* wrap A */
58#define SC2_WRAP_B 6 /* wrap B */
59#define SC4_THRU_A 12 /* through A */
60#define SC5_THRU_B 7 /* through B (SMt 6.2) */
61#define SC7_WRAP_S 8 /* SAS */
62
63/*
64 * ECM states
65 */
66#define EC0_OUT 0
67#define EC1_IN 1
68#define EC2_TRACE 2
69#define EC3_LEAVE 3
70#define EC4_PATH_TEST 4
71#define EC5_INSERT 5
72#define EC6_CHECK 6
73#define EC7_DEINSERT 7
74
75/*
76 * RMT states
77 */
78#define RM0_ISOLATED 0
79#define RM1_NON_OP 1 /* not operational */
80#define RM2_RING_OP 2 /* ring operational */
81#define RM3_DETECT 3 /* detect dupl addresses */
82#define RM4_NON_OP_DUP 4 /* dupl. addr detected */
83#define RM5_RING_OP_DUP 5 /* ring oper. with dupl. addr */
84#define RM6_DIRECTED 6 /* sending directed beacons */
85#define RM7_TRACE 7 /* trace initiated */
86#endif
87
88struct pcm_state {
89 unsigned char pcm_type ; /* TA TB TS TM */
90 unsigned char pcm_state ; /* state PC[0-9]_* */
91 unsigned char pcm_mode ; /* PM_{NONE,PEER,TREE} */
92 unsigned char pcm_neighbor ; /* TA TB TS TM */
93 unsigned char pcm_bsf ; /* flag bs : TRUE/FALSE */
94 unsigned char pcm_lsf ; /* flag ls : TRUE/FALSE */
95 unsigned char pcm_lct_fail ; /* counter lct_fail */
96 unsigned char pcm_ls_rx ; /* rx line state */
97 short pcm_r_val ; /* signaling bits */
98 short pcm_t_val ; /* signaling bits */
99} ;
100
101struct smt_state {
102 struct pcm_state pcm_state[NUMPHYS] ; /* port A & port B */
103} ;
104
105#endif
106
diff --git a/drivers/net/skfp/h/supern_2.h b/drivers/net/skfp/h/supern_2.h
new file mode 100644
index 000000000000..5ba0b8306753
--- /dev/null
+++ b/drivers/net/skfp/h/supern_2.h
@@ -0,0 +1,1059 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * The information in this file is provided "AS IS" without warranty.
12 *
13 ******************************************************************************/
14
15/*
16 defines for AMD Supernet II chip set
17 the chips are refered to as
18 FPLUS Formac Plus
19 PLC Physical Layer
20
21 added defines for AMD Supernet III chip set
22 added comments on differences between Supernet II and Supernet III
23 added defines for the Motorola ELM (MOT_ELM)
24*/
25
26#ifndef _SUPERNET_
27#define _SUPERNET_
28
29/*
30 * Define Supernet 3 when used
31 */
32#ifdef PCI
33#ifndef SUPERNET_3
34#define SUPERNET_3
35#endif
36#define TAG
37#endif
38
39#define MB 0xff
40#define MW 0xffff
41#define MD 0xffffffff
42
43/*
44 * FORMAC frame status (rx_msext)
45 */
46#define FS_EI (1<<2)
47#define FS_AI (1<<1)
48#define FS_CI (1<<0)
49
50#define FS_MSVALID (1<<15) /* end of queue */
51#define FS_MSRABT (1<<14) /* frame was aborted during reception*/
52#define FS_SSRCRTG (1<<12) /* if SA has set MSB (source-routing)*/
53#define FS_SEAC2 (FS_EI<<9) /* error indicator */
54#define FS_SEAC1 (FS_AI<<9) /* address indicator */
55#define FS_SEAC0 (FS_CI<<9) /* copy indicator */
56#define FS_SFRMERR (1<<8) /* error detected (CRC or length) */
57#define FS_SADRRG (1<<7) /* address recognized */
58#define FS_SFRMTY2 (1<<6) /* frame-class bit */
59#define FS_SFRMTY1 (1<<5) /* frame-type bit (impementor) */
60#define FS_SFRMTY0 (1<<4) /* frame-type bit (LLC) */
61#define FS_ERFBB1 (1<<1) /* byte offset (depends on LSB bit) */
62#define FS_ERFBB0 (1<<0) /* - " - */
63
64/*
65 * status frame type
66 */
67#define FRM_SMT (0) /* asynchr. frames */
68#define FRM_LLCA (1)
69#define FRM_IMPA (2)
70#define FRM_MAC (4) /* synchr. frames */
71#define FRM_LLCS (5)
72#define FRM_IMPS (6)
73
74/*
75 * bits in rx_descr.i (receive frame status word)
76 */
77#define RX_MSVALID ((long)1<<31) /* memory status valid */
78#define RX_MSRABT ((long)1<<30) /* memory status receive abort */
79#define RX_FS_E ((long)FS_SEAC2<<16) /* error indicator */
80#define RX_FS_A ((long)FS_SEAC1<<16) /* address indicator */
81#define RX_FS_C ((long)FS_SEAC0<<16) /* copy indicator */
82#define RX_FS_CRC ((long)FS_SFRMERR<<16)/* error detected */
83#define RX_FS_ADDRESS ((long)FS_SADRRG<<16) /* address recognized */
84#define RX_FS_MAC ((long)FS_SFRMTY2<<16)/* MAC frame */
85#define RX_FS_SMT ((long)0<<16) /* SMT frame */
86#define RX_FS_IMPL ((long)FS_SFRMTY1<<16)/* implementer frame */
87#define RX_FS_LLC ((long)FS_SFRMTY0<<16)/* LLC frame */
88
89/*
90 * receive frame descriptor
91 */
92union rx_descr {
93 struct {
94#ifdef LITTLE_ENDIAN
95 unsigned rx_length :16 ; /* frame length lower/upper byte */
96 unsigned rx_erfbb :2 ; /* received frame byte boundary */
97 unsigned rx_reserv2:2 ; /* reserved */
98 unsigned rx_sfrmty :3 ; /* frame type bits */
99 unsigned rx_sadrrg :1 ; /* DA == MA or broad-/multicast */
100 unsigned rx_sfrmerr:1 ; /* received frame not valid */
101 unsigned rx_seac0 :1 ; /* frame-copied C-indicator */
102 unsigned rx_seac1 :1 ; /* address-match A-indicator */
103 unsigned rx_seac2 :1 ; /* frame-error E-indicator */
104 unsigned rx_ssrcrtg:1 ; /* == 1 SA has MSB set */
105 unsigned rx_reserv1:1 ; /* reserved */
106 unsigned rx_msrabt :1 ; /* memory status receive abort */
107 unsigned rx_msvalid:1 ; /* memory status valid */
108#else
109 unsigned rx_msvalid:1 ; /* memory status valid */
110 unsigned rx_msrabt :1 ; /* memory status receive abort */
111 unsigned rx_reserv1:1 ; /* reserved */
112 unsigned rx_ssrcrtg:1 ; /* == 1 SA has MSB set */
113 unsigned rx_seac2 :1 ; /* frame-error E-indicator */
114 unsigned rx_seac1 :1 ; /* address-match A-indicator */
115 unsigned rx_seac0 :1 ; /* frame-copied C-indicator */
116 unsigned rx_sfrmerr:1 ; /* received frame not valid */
117 unsigned rx_sadrrg :1 ; /* DA == MA or broad-/multicast */
118 unsigned rx_sfrmty :3 ; /* frame type bits */
119 unsigned rx_erfbb :2 ; /* received frame byte boundary */
120 unsigned rx_reserv2:2 ; /* reserved */
121 unsigned rx_length :16 ; /* frame length lower/upper byte */
122#endif
123 } r ;
124 long i ;
125} ;
126
127/* defines for Receive Frame Descriptor access */
128#define RD_S_ERFBB 0x00030000L /* received frame byte boundary */
129#define RD_S_RES2 0x000c0000L /* reserved */
130#define RD_S_SFRMTY 0x00700000L /* frame type bits */
131#define RD_S_SADRRG 0x00800000L /* DA == MA or broad-/multicast */
132#define RD_S_SFRMERR 0x01000000L /* received frame not valid */
133#define RD_S_SEAC 0x0e000000L /* frame status indicators */
134#define RD_S_SEAC0 0x02000000L /* frame-copied case-indicator */
135#define RD_S_SEAC1 0x04000000L /* address-match A-indicator */
136#define RD_S_SEAC2 0x08000000L /* frame-error E-indicator */
137#define RD_S_SSRCRTG 0x10000000L /* == 1 SA has MSB set */
138#define RD_S_RES1 0x20000000L /* reserved */
139#define RD_S_MSRABT 0x40000000L /* memory status receive abort */
140#define RD_S_MSVALID 0x80000000L /* memory status valid */
141
142#define RD_STATUS 0xffff0000L
143#define RD_LENGTH 0x0000ffffL
144
145/* defines for Receive Frames Status Word values */
146/*RD_S_SFRMTY*/
147#define RD_FRM_SMT (unsigned long)(0<<20) /* asynchr. frames */
148#define RD_FRM_LLCA (unsigned long)(1<<20)
149#define RD_FRM_IMPA (unsigned long)(2<<20)
150#define RD_FRM_MAC (unsigned long)(4<<20) /* synchr. frames */
151#define RD_FRM_LLCS (unsigned long)(5<<20)
152#define RD_FRM_IMPS (unsigned long)(6<<20)
153
154#define TX_DESCRIPTOR 0x40000000L
155#define TX_OFFSET_3 0x18000000L
156
157#define TXP1 2
158
159/*
160 * transmit frame descriptor
161 */
162union tx_descr {
163 struct {
164#ifdef LITTLE_ENDIAN
165 unsigned tx_length:16 ; /* frame length lower/upper byte */
166 unsigned tx_res :8 ; /* reserved (bit 16..23) */
167 unsigned tx_xmtabt:1 ; /* transmit abort */
168 unsigned tx_nfcs :1 ; /* no frame check sequence */
169 unsigned tx_xdone :1 ; /* give up token */
170 unsigned tx_rpxm :2 ; /* byte offset */
171 unsigned tx_pat1 :2 ; /* must be TXP1 */
172 unsigned tx_more :1 ; /* more frame in chain */
173#else
174 unsigned tx_more :1 ; /* more frame in chain */
175 unsigned tx_pat1 :2 ; /* must be TXP1 */
176 unsigned tx_rpxm :2 ; /* byte offset */
177 unsigned tx_xdone :1 ; /* give up token */
178 unsigned tx_nfcs :1 ; /* no frame check sequence */
179 unsigned tx_xmtabt:1 ; /* transmit abort */
180 unsigned tx_res :8 ; /* reserved (bit 16..23) */
181 unsigned tx_length:16 ; /* frame length lower/upper byte */
182#endif
183 } t ;
184 long i ;
185} ;
186
187/* defines for Transmit Descriptor access */
188#define TD_C_MORE 0x80000000L /* more frame in chain */
189#define TD_C_DESCR 0x60000000L /* must be TXP1 */
190#define TD_C_TXFBB 0x18000000L /* byte offset */
191#define TD_C_XDONE 0x04000000L /* give up token */
192#define TD_C_NFCS 0x02000000L /* no frame check sequence */
193#define TD_C_XMTABT 0x01000000L /* transmit abort */
194
195#define TD_C_LNCNU 0x0000ff00L
196#define TD_C_LNCNL 0x000000ffL
197#define TD_C_LNCN 0x0000ffffL /* frame length lower/upper byte */
198
199/*
200 * transmit pointer
201 */
202union tx_pointer {
203 struct t {
204#ifdef LITTLE_ENDIAN
205 unsigned tp_pointer:16 ; /* pointer to tx_descr (low/high) */
206 unsigned tp_res :8 ; /* reserved (bit 16..23) */
207 unsigned tp_pattern:8 ; /* fixed pattern (bit 24..31) */
208#else
209 unsigned tp_pattern:8 ; /* fixed pattern (bit 24..31) */
210 unsigned tp_res :8 ; /* reserved (bit 16..23) */
211 unsigned tp_pointer:16 ; /* pointer to tx_descr (low/high) */
212#endif
213 } t ;
214 long i ;
215} ;
216
217/* defines for Nontag Mode Pointer access */
218#define TD_P_CNTRL 0xff000000L
219#define TD_P_RPXU 0x0000ff00L
220#define TD_P_RPXL 0x000000ffL
221#define TD_P_RPX 0x0000ffffL
222
223
224#define TX_PATTERN 0xa0
225#define TX_POINTER_END 0xa0000000L
226#define TX_INT_PATTERN 0xa0000000L
227
228struct tx_queue {
229 struct tx_queue *tq_next ;
230 u_short tq_pack_offset ; /* offset buffer memory */
231 u_char tq_pad[2] ;
232} ;
233
234/*
235 defines for FORMAC Plus (Am79C830)
236*/
237
238/*
239 * FORMAC+ read/write (r/w) registers
240 */
241#define FM_CMDREG1 0x00 /* write command reg 1 instruction */
242#define FM_CMDREG2 0x01 /* write command reg 2 instruction */
243#define FM_ST1U 0x00 /* read upper 16-bit of status reg 1 */
244#define FM_ST1L 0x01 /* read lower 16-bit of status reg 1 */
245#define FM_ST2U 0x02 /* read upper 16-bit of status reg 2 */
246#define FM_ST2L 0x03 /* read lower 16-bit of status reg 2 */
247#define FM_IMSK1U 0x04 /* r/w upper 16-bit of IMSK 1 */
248#define FM_IMSK1L 0x05 /* r/w lower 16-bit of IMSK 1 */
249#define FM_IMSK2U 0x06 /* r/w upper 16-bit of IMSK 2 */
250#define FM_IMSK2L 0x07 /* r/w lower 16-bit of IMSK 2 */
251#define FM_SAID 0x08 /* r/w short addr.-individual */
252#define FM_LAIM 0x09 /* r/w long addr.-ind. (MSW of LAID) */
253#define FM_LAIC 0x0a /* r/w long addr.-ind. (middle)*/
254#define FM_LAIL 0x0b /* r/w long addr.-ind. (LSW) */
255#define FM_SAGP 0x0c /* r/w short address-group */
256#define FM_LAGM 0x0d /* r/w long addr.-gr. (MSW of LAGP) */
257#define FM_LAGC 0x0e /* r/w long addr.-gr. (middle) */
258#define FM_LAGL 0x0f /* r/w long addr.-gr. (LSW) */
259#define FM_MDREG1 0x10 /* r/w 16-bit mode reg 1 */
260#define FM_STMCHN 0x11 /* read state-machine reg */
261#define FM_MIR1 0x12 /* read upper 16-bit of MAC Info Reg */
262#define FM_MIR0 0x13 /* read lower 16-bit of MAC Info Reg */
263#define FM_TMAX 0x14 /* r/w 16-bit TMAX reg */
264#define FM_TVX 0x15 /* write 8-bit TVX reg with NP7-0
265 read TVX on NP7-0, timer on NP15-8*/
266#define FM_TRT 0x16 /* r/w upper 16-bit of TRT timer */
267#define FM_THT 0x17 /* r/w upper 16-bit of THT timer */
268#define FM_TNEG 0x18 /* read upper 16-bit of TNEG (TTRT) */
269#define FM_TMRS 0x19 /* read lower 5-bit of TNEG,TRT,THT */
270 /* F E D C B A 9 8 7 6 5 4 3 2 1 0
271 x |-TNEG4-0| |-TRT4-0-| |-THT4-0-| (x-late count) */
272#define FM_TREQ0 0x1a /* r/w 16-bit TREQ0 reg (LSW of TRT) */
273#define FM_TREQ1 0x1b /* r/w 16-bit TREQ1 reg (MSW of TRT) */
274#define FM_PRI0 0x1c /* r/w priority r. for asyn.-queue 0 */
275#define FM_PRI1 0x1d /* r/w priority r. for asyn.-queue 1 */
276#define FM_PRI2 0x1e /* r/w priority r. for asyn.-queue 2 */
277#define FM_TSYNC 0x1f /* r/w 16-bit of the TSYNC register */
278#define FM_MDREG2 0x20 /* r/w 16-bit mode reg 2 */
279#define FM_FRMTHR 0x21 /* r/w the frame threshold register */
280#define FM_EACB 0x22 /* r/w end addr of claim/beacon area */
281#define FM_EARV 0x23 /* r/w end addr of receive queue */
282/* Supernet 3 */
283#define FM_EARV1 FM_EARV
284
285#define FM_EAS 0x24 /* r/w end addr of synchr. queue */
286#define FM_EAA0 0x25 /* r/w end addr of asyn. queue 0 */
287#define FM_EAA1 0x26 /* r/w end addr of asyn. queue 1 */
288#define FM_EAA2 0x27 /* r/w end addr of asyn. queue 2 */
289#define FM_SACL 0x28 /* r/w start addr of claim frame */
290#define FM_SABC 0x29 /* r/w start addr of beacon frame */
291#define FM_WPXSF 0x2a /* r/w the write ptr. for special fr.*/
292#define FM_RPXSF 0x2b /* r/w the read ptr. for special fr. */
293#define FM_RPR 0x2d /* r/w the read ptr. for receive qu. */
294#define FM_WPR 0x2e /* r/w the write ptr. for receive qu.*/
295#define FM_SWPR 0x2f /* r/w the shadow wr.-ptr. for rec.q.*/
296/* Supernet 3 */
297#define FM_RPR1 FM_RPR
298#define FM_WPR1 FM_WPR
299#define FM_SWPR1 FM_SWPR
300
301#define FM_WPXS 0x30 /* r/w the write ptr. for synchr. qu.*/
302#define FM_WPXA0 0x31 /* r/w the write ptr. for asyn. qu.0 */
303#define FM_WPXA1 0x32 /* r/w the write ptr. for asyn. qu.1 */
304#define FM_WPXA2 0x33 /* r/w the write ptr. for asyn. qu.2 */
305#define FM_SWPXS 0x34 /* r/w the shadow wr.-ptr. for syn.q.*/
306#define FM_SWPXA0 0x35 /* r/w the shad. wr.-ptr. for asyn.q0*/
307#define FM_SWPXA1 0x36 /* r/w the shad. wr.-ptr. for asyn.q1*/
308#define FM_SWPXA2 0x37 /* r/w the shad. wr.-ptr. for asyn.q2*/
309#define FM_RPXS 0x38 /* r/w the read ptr. for synchr. qu. */
310#define FM_RPXA0 0x39 /* r/w the read ptr. for asyn. qu. 0 */
311#define FM_RPXA1 0x3a /* r/w the read ptr. for asyn. qu. 1 */
312#define FM_RPXA2 0x3b /* r/w the read ptr. for asyn. qu. 2 */
313#define FM_MARR 0x3c /* r/w the memory read addr register */
314#define FM_MARW 0x3d /* r/w the memory write addr register*/
315#define FM_MDRU 0x3e /* r/w upper 16-bit of mem. data reg */
316#define FM_MDRL 0x3f /* r/w lower 16-bit of mem. data reg */
317
318/* following instructions relate to MAC counters and timer */
319#define FM_TMSYNC 0x40 /* r/w upper 16 bits of TMSYNC timer */
320#define FM_FCNTR 0x41 /* r/w the 16-bit frame counter */
321#define FM_LCNTR 0x42 /* r/w the 16-bit lost counter */
322#define FM_ECNTR 0x43 /* r/w the 16-bit error counter */
323
324/* Supernet 3: extensions to old register block */
325#define FM_FSCNTR 0x44 /* r/? Frame Strip Counter */
326#define FM_FRSELREG 0x45 /* r/w Frame Selection Register */
327
328/* Supernet 3: extensions for 2. receive queue etc. */
329#define FM_MDREG3 0x60 /* r/w Mode Register 3 */
330#define FM_ST3U 0x61 /* read upper 16-bit of status reg 3 */
331#define FM_ST3L 0x62 /* read lower 16-bit of status reg 3 */
332#define FM_IMSK3U 0x63 /* r/w upper 16-bit of IMSK reg 3 */
333#define FM_IMSK3L 0x64 /* r/w lower 16-bit of IMSK reg 3 */
334#define FM_IVR 0x65 /* read Interrupt Vector register */
335#define FM_IMR 0x66 /* r/w Interrupt mask register */
336/* 0x67 Hidden */
337#define FM_RPR2 0x68 /* r/w the read ptr. for rec. qu. 2 */
338#define FM_WPR2 0x69 /* r/w the write ptr. for rec. qu. 2 */
339#define FM_SWPR2 0x6a /* r/w the shadow wptr. for rec. q. 2 */
340#define FM_EARV2 0x6b /* r/w end addr of rec. qu. 2 */
341#define FM_UNLCKDLY 0x6c /* r/w Auto Unlock Delay register */
342 /* Bit 15-8: RECV2 unlock threshold */
343 /* Bit 7-0: RECV1 unlock threshold */
344/* 0x6f-0x73 Hidden */
345#define FM_LTDPA1 0x79 /* r/w Last Trans desc ptr for A1 qu. */
346/* 0x80-0x9a PLCS registers of built-in PLCS (Supernet 3 only) */
347
348/* Supernet 3: Adderss Filter Registers */
349#define FM_AFCMD 0xb0 /* r/w Address Filter Command Reg */
350#define FM_AFSTAT 0xb2 /* r/w Address Filter Status Reg */
351#define FM_AFBIST 0xb4 /* r/w Address Filter BIST signature */
352#define FM_AFCOMP2 0xb6 /* r/w Address Filter Comparand 2 */
353#define FM_AFCOMP1 0xb8 /* r/w Address Filter Comparand 1 */
354#define FM_AFCOMP0 0xba /* r/w Address Filter Comparand 0 */
355#define FM_AFMASK2 0xbc /* r/w Address Filter Mask 2 */
356#define FM_AFMASK1 0xbe /* r/w Address Filter Mask 1 */
357#define FM_AFMASK0 0xc0 /* r/w Address Filter Mask 0 */
358#define FM_AFPERS 0xc2 /* r/w Address Filter Personality Reg */
359
360/* Supernet 3: Orion (PDX?) Registers */
361#define FM_ORBIST 0xd0 /* r/w Orion BIST signature */
362#define FM_ORSTAT 0xd2 /* r/w Orion Status Register */
363
364
365/*
366 * Mode Register 1 (MDREG1)
367 */
368#define FM_RES0 0x0001 /* reserved */
369 /* SN3: other definition */
370#define FM_XMTINH_HOLD 0x0002 /* transmit-inhibit/hold bit */
371 /* SN3: other definition */
372#define FM_HOFLXI 0x0003 /* SN3: Hold / Flush / Inhibit */
373#define FM_FULL_HALF 0x0004 /* full-duplex/half-duplex bit */
374#define FM_LOCKTX 0x0008 /* lock-transmit-asynchr.-queues bit */
375#define FM_EXGPA0 0x0010 /* extended-group-addressing bit 0 */
376#define FM_EXGPA1 0x0020 /* extended-group-addressing bit 1 */
377#define FM_DISCRY 0x0040 /* disable-carry bit */
378 /* SN3: reserved */
379#define FM_SELRA 0x0080 /* select input from PHY (1=RA,0=RB) */
380
381#define FM_ADDET 0x0700 /* address detection */
382#define FM_MDAMA (0<<8) /* address detection : DA = MA */
383#define FM_MDASAMA (1<<8) /* address detection : DA=MA||SA=MA */
384#define FM_MRNNSAFNMA (2<<8) /* rec. non-NSA frames DA=MA&&SA!=MA */
385#define FM_MRNNSAF (3<<8) /* rec. non-NSA frames DA = MA */
386#define FM_MDISRCV (4<<8) /* disable receive function */
387#define FM_MRES0 (5<<8) /* reserve */
388#define FM_MLIMPROM (6<<8) /* limited-promiscuous mode */
389#define FM_MPROMISCOUS (7<<8) /* address detection : promiscous */
390
391#define FM_SELSA 0x0800 /* select-short-address bit */
392
393#define FM_MMODE 0x7000 /* mode select */
394#define FM_MINIT (0<<12) /* initialize */
395#define FM_MMEMACT (1<<12) /* memory activate */
396#define FM_MONLINESP (2<<12) /* on-line special */
397#define FM_MONLINE (3<<12) /* on-line (FDDI operational mode) */
398#define FM_MILOOP (4<<12) /* internal loopback */
399#define FM_MRES1 (5<<12) /* reserved */
400#define FM_MRES2 (6<<12) /* reserved */
401#define FM_MELOOP (7<<12) /* external loopback */
402
403#define FM_SNGLFRM 0x8000 /* single-frame-receive mode */
404 /* SN3: reserved */
405
406#define MDR1INIT (FM_MINIT | FM_MDAMA)
407
408/*
409 * Mode Register 2 (MDREG2)
410 */
411#define FM_AFULL 0x000f /* 4-bit value (empty loc.in txqueue)*/
412#define FM_RCVERR 0x0010 /* rec.-errored-frames bit */
413#define FM_SYMCTL 0x0020 /* sysmbol-control bit */
414 /* SN3: reserved */
415#define FM_SYNPRQ 0x0040 /* synchron.-NP-DMA-request bit */
416#define FM_ENNPRQ 0x0080 /* enable-NP-DMA-request bit */
417#define FM_ENHSRQ 0x0100 /* enable-host-request bit */
418#define FM_RXFBB01 0x0600 /* rec. frame byte boundary bit0 & 1 */
419#define FM_LSB 0x0800 /* determ. ordering of bytes in buffer*/
420#define FM_PARITY 0x1000 /* 1 = even, 0 = odd */
421#define FM_CHKPAR 0x2000 /* 1 = parity of 32-bit buffer BD-bus*/
422#define FM_STRPFCS 0x4000 /* 1 = strips FCS field of rec.frame */
423#define FM_BMMODE 0x8000 /* Buffer-Memory-Mode (1 = tag mode) */
424 /* SN3: 1 = tag, 0 = modified tag */
425
426/*
427 * Status Register 1, Upper 16 Bits (ST1U)
428 */
429#define FM_STEFRMS 0x0001 /* transmit end of frame: synchr. qu.*/
430#define FM_STEFRMA0 0x0002 /* transmit end of frame: asyn. qu.0 */
431#define FM_STEFRMA1 0x0004 /* transmit end of frame: asyn. qu.1 */
432#define FM_STEFRMA2 0x0008 /* transmit end of frame: asyn. qu.2 */
433 /* SN3: reserved */
434#define FM_STECFRMS 0x0010 /* transmit end of chain of syn. qu. */
435 /* SN3: reserved */
436#define FM_STECFRMA0 0x0020 /* transmit end of chain of asyn. q0 */
437 /* SN3: reserved */
438#define FM_STECFRMA1 0x0040 /* transmit end of chain of asyn. q1 */
439 /* SN3: STECMDA1 */
440#define FM_STECMDA1 0x0040 /* SN3: 'no description' */
441#define FM_STECFRMA2 0x0080 /* transmit end of chain of asyn. q2 */
442 /* SN3: reserved */
443#define FM_STEXDONS 0x0100 /* transmit until XDONE in syn. qu. */
444#define FM_STBFLA 0x0200 /* asynchr.-queue trans. buffer full */
445#define FM_STBFLS 0x0400 /* synchr.-queue transm. buffer full */
446#define FM_STXABRS 0x0800 /* synchr. queue transmit-abort */
447#define FM_STXABRA0 0x1000 /* asynchr. queue 0 transmit-abort */
448#define FM_STXABRA1 0x2000 /* asynchr. queue 1 transmit-abort */
449#define FM_STXABRA2 0x4000 /* asynchr. queue 2 transmit-abort */
450 /* SN3: reserved */
451#define FM_SXMTABT 0x8000 /* transmit abort */
452
453/*
454 * Status Register 1, Lower 16 Bits (ST1L)
455 */
456#define FM_SQLCKS 0x0001 /* queue lock for synchr. queue */
457#define FM_SQLCKA0 0x0002 /* queue lock for asynchr. queue 0 */
458#define FM_SQLCKA1 0x0004 /* queue lock for asynchr. queue 1 */
459#define FM_SQLCKA2 0x0008 /* queue lock for asynchr. queue 2 */
460 /* SN3: reserved */
461#define FM_STXINFLS 0x0010 /* transmit instruction full: syn. */
462 /* SN3: reserved */
463#define FM_STXINFLA0 0x0020 /* transmit instruction full: asyn.0 */
464 /* SN3: reserved */
465#define FM_STXINFLA1 0x0040 /* transmit instruction full: asyn.1 */
466 /* SN3: reserved */
467#define FM_STXINFLA2 0x0080 /* transmit instruction full: asyn.2 */
468 /* SN3: reserved */
469#define FM_SPCEPDS 0x0100 /* parity/coding error: syn. queue */
470#define FM_SPCEPDA0 0x0200 /* parity/coding error: asyn. queue0 */
471#define FM_SPCEPDA1 0x0400 /* parity/coding error: asyn. queue1 */
472#define FM_SPCEPDA2 0x0800 /* parity/coding error: asyn. queue2 */
473 /* SN3: reserved */
474#define FM_STBURS 0x1000 /* transmit buffer underrun: syn. q. */
475#define FM_STBURA0 0x2000 /* transmit buffer underrun: asyn.0 */
476#define FM_STBURA1 0x4000 /* transmit buffer underrun: asyn.1 */
477#define FM_STBURA2 0x8000 /* transmit buffer underrun: asyn.2 */
478 /* SN3: reserved */
479
480/*
481 * Status Register 2, Upper 16 Bits (ST2U)
482 */
483#define FM_SOTRBEC 0x0001 /* other beacon received */
484#define FM_SMYBEC 0x0002 /* my beacon received */
485#define FM_SBEC 0x0004 /* beacon state entered */
486#define FM_SLOCLM 0x0008 /* low claim received */
487#define FM_SHICLM 0x0010 /* high claim received */
488#define FM_SMYCLM 0x0020 /* my claim received */
489#define FM_SCLM 0x0040 /* claim state entered */
490#define FM_SERRSF 0x0080 /* error in special frame */
491#define FM_SNFSLD 0x0100 /* NP and FORMAC+ simultaneous load */
492#define FM_SRFRCTOV 0x0200 /* receive frame counter overflow */
493 /* SN3: reserved */
494#define FM_SRCVFRM 0x0400 /* receive frame */
495 /* SN3: reserved */
496#define FM_SRCVOVR 0x0800 /* receive FIFO overflow */
497#define FM_SRBFL 0x1000 /* receive buffer full */
498#define FM_SRABT 0x2000 /* receive abort */
499#define FM_SRBMT 0x4000 /* receive buffer empty */
500#define FM_SRCOMP 0x8000 /* receive complete. Nontag mode */
501
502/*
503 * Status Register 2, Lower 16 Bits (ST2L)
504 * Attention: SN3 docu shows these bits the other way around
505 */
506#define FM_SRES0 0x0001 /* reserved */
507#define FM_SESTRIPTK 0x0001 /* SN3: 'no description' */
508#define FM_STRTEXR 0x0002 /* TRT expired in claim | beacon st. */
509#define FM_SDUPCLM 0x0004 /* duplicate claim received */
510#define FM_SSIFG 0x0008 /* short interframe gap */
511#define FM_SFRMCTR 0x0010 /* frame counter overflow */
512#define FM_SERRCTR 0x0020 /* error counter overflow */
513#define FM_SLSTCTR 0x0040 /* lost counter overflow */
514#define FM_SPHINV 0x0080 /* PHY invalid */
515#define FM_SADET 0x0100 /* address detect */
516#define FM_SMISFRM 0x0200 /* missed frame */
517#define FM_STRTEXP 0x0400 /* TRT expired and late count > 0 */
518#define FM_STVXEXP 0x0800 /* TVX expired */
519#define FM_STKISS 0x1000 /* token issued */
520#define FM_STKERR 0x2000 /* token error */
521#define FM_SMULTDA 0x4000 /* multiple destination address */
522#define FM_SRNGOP 0x8000 /* ring operational */
523
524/*
525 * Supernet 3:
526 * Status Register 3, Upper 16 Bits (ST3U)
527 */
528#define FM_SRQUNLCK1 0x0001 /* receive queue unlocked queue 1 */
529#define FM_SRQUNLCK2 0x0002 /* receive queue unlocked queue 2 */
530#define FM_SRPERRQ1 0x0004 /* receive parity error rx queue 1 */
531#define FM_SRPERRQ2 0x0008 /* receive parity error rx queue 2 */
532 /* Bit 4-10: reserved */
533#define FM_SRCVOVR2 0x0800 /* receive FIFO overfull rx queue 2 */
534#define FM_SRBFL2 0x1000 /* receive buffer full rx queue 2 */
535#define FM_SRABT2 0x2000 /* receive abort rx queue 2 */
536#define FM_SRBMT2 0x4000 /* receive buf empty rx queue 2 */
537#define FM_SRCOMP2 0x8000 /* receive comp rx queue 2 */
538
539/*
540 * Supernet 3:
541 * Status Register 3, Lower 16 Bits (ST3L)
542 */
543#define FM_AF_BIST_DONE 0x0001 /* Address Filter BIST is done */
544#define FM_PLC_BIST_DONE 0x0002 /* internal PLC Bist is done */
545#define FM_PDX_BIST_DONE 0x0004 /* PDX BIST is done */
546 /* Bit 3: reserved */
547#define FM_SICAMDAMAT 0x0010 /* Status internal CAM DA match */
548#define FM_SICAMDAXACT 0x0020 /* Status internal CAM DA exact match */
549#define FM_SICAMSAMAT 0x0040 /* Status internal CAM SA match */
550#define FM_SICAMSAXACT 0x0080 /* Status internal CAM SA exact match */
551
552/*
553 * MAC State-Machine Register FM_STMCHN
554 */
555#define FM_MDRTAG 0x0004 /* tag bit of long word read */
556#define FM_SNPPND 0x0008 /* r/w from buffer mem. is pending */
557#define FM_TXSTAT 0x0070 /* transmitter state machine state */
558#define FM_RCSTAT 0x0380 /* receiver state machine state */
559#define FM_TM01 0x0c00 /* indicate token mode */
560#define FM_SIM 0x1000 /* indicate send immediate-mode */
561#define FM_REV 0xe000 /* FORMAC Plus revision number */
562
563/*
564 * Supernet 3
565 * Mode Register 3
566 */
567#define FM_MENRS 0x0001 /* Ena enhanced rec status encoding */
568#define FM_MENXS 0x0002 /* Ena enhanced xmit status encoding */
569#define FM_MENXCT 0x0004 /* Ena EXACT/INEXACT matching */
570#define FM_MENAFULL 0x0008 /* Ena enh QCTRL encoding for AFULL */
571#define FM_MEIND 0x0030 /* Ena enh A,C indicator settings */
572#define FM_MENQCTRL 0x0040 /* Ena enh QCTRL encoding */
573#define FM_MENRQAUNLCK 0x0080 /* Ena rec q auto unlock */
574#define FM_MENDAS 0x0100 /* Ena DAS connections by cntr MUX */
575#define FM_MENPLCCST 0x0200 /* Ena Counter Segm test in PLC blck */
576#define FM_MENSGLINT 0x0400 /* Ena Vectored Interrupt reading */
577#define FM_MENDRCV 0x0800 /* Ena dual receive queue operation */
578#define FM_MENFCLOC 0x3000 /* Ena FC location within frm data */
579#define FM_MENTRCMD 0x4000 /* Ena ASYNC1 xmit only after command */
580#define FM_MENTDLPBK 0x8000 /* Ena TDAT to RDAT lkoopback */
581
582/*
583 * Supernet 3
584 * Frame Selection Register
585 */
586#define FM_RECV1 0x000f /* options for receive queue 1 */
587#define FM_RCV1_ALL (0<<0) /* receive all frames */
588#define FM_RCV1_LLC (1<<0) /* rec all LLC frames */
589#define FM_RCV1_SMT (2<<0) /* rec all SMT frames */
590#define FM_RCV1_NSMT (3<<0) /* rec non-SMT frames */
591#define FM_RCV1_IMP (4<<0) /* rec Implementor frames */
592#define FM_RCV1_MAC (5<<0) /* rec all MAC frames */
593#define FM_RCV1_SLLC (6<<0) /* rec all sync LLC frames */
594#define FM_RCV1_ALLC (7<<0) /* rec all async LLC frames */
595#define FM_RCV1_VOID (8<<0) /* rec all void frames */
596#define FM_RCV1_ALSMT (9<<0) /* rec all async LLC & SMT frames */
597#define FM_RECV2 0x00f0 /* options for receive queue 2 */
598#define FM_RCV2_ALL (0<<4) /* receive all other frames */
599#define FM_RCV2_LLC (1<<4) /* rec all LLC frames */
600#define FM_RCV2_SMT (2<<4) /* rec all SMT frames */
601#define FM_RCV2_NSMT (3<<4) /* rec non-SMT frames */
602#define FM_RCV2_IMP (4<<4) /* rec Implementor frames */
603#define FM_RCV2_MAC (5<<4) /* rec all MAC frames */
604#define FM_RCV2_SLLC (6<<4) /* rec all sync LLC frames */
605#define FM_RCV2_ALLC (7<<4) /* rec all async LLC frames */
606#define FM_RCV2_VOID (8<<4) /* rec all void frames */
607#define FM_RCV2_ALSMT (9<<4) /* rec all async LLC & SMT frames */
608#define FM_ENXMTADSWAP 0x4000 /* enh rec addr swap (phys -> can) */
609#define FM_ENRCVADSWAP 0x8000 /* enh tx addr swap (can -> phys) */
610
611/*
612 * Supernet 3:
613 * Address Filter Command Register (AFCMD)
614 */
615#define FM_INST 0x0007 /* Address Filter Operation */
616#define FM_IINV_CAM (0<<0) /* Invalidate CAM */
617#define FM_IWRITE_CAM (1<<0) /* Write CAM */
618#define FM_IREAD_CAM (2<<0) /* Read CAM */
619#define FM_IRUN_BIST (3<<0) /* Run BIST */
620#define FM_IFIND (4<<0) /* Find */
621#define FM_IINV (5<<0) /* Invalidate */
622#define FM_ISKIP (6<<0) /* Skip */
623#define FM_ICL_SKIP (7<<0) /* Clear all SKIP bits */
624
625/*
626 * Supernet 3:
627 * Address Filter Status Register (AFSTAT)
628 */
629 /* Bit 0-4: reserved */
630#define FM_REV_NO 0x00e0 /* Revision Number of Address Filter */
631#define FM_BIST_DONE 0x0100 /* BIST complete */
632#define FM_EMPTY 0x0200 /* CAM empty */
633#define FM_ERROR 0x0400 /* Error (improper operation) */
634#define FM_MULT 0x0800 /* Multiple Match */
635#define FM_EXACT 0x1000 /* Exact Match */
636#define FM_FOUND 0x2000 /* Comparand found in CAM */
637#define FM_FULL 0x4000 /* CAM full */
638#define FM_DONE 0x8000 /* DONE indicator */
639
640/*
641 * Supernet 3:
642 * BIST Signature Register (AFBIST)
643 */
644#define AF_BIST_SIGNAT 0x0553 /* Address Filter BIST Signature */
645
646/*
647 * Supernet 3:
648 * Personality Register (AFPERS)
649 */
650#define FM_VALID 0x0001 /* CAM Entry Valid */
651#define FM_DA 0x0002 /* Destination Address */
652#define FM_DAX 0x0004 /* Destination Address Exact */
653#define FM_SA 0x0008 /* Source Address */
654#define FM_SAX 0x0010 /* Source Address Exact */
655#define FM_SKIP 0x0020 /* Skip this entry */
656
657/*
658 * instruction set for command register 1 (NPADDR6-0 = 0x00)
659 */
660#define FM_IRESET 0x01 /* software reset */
661#define FM_IRMEMWI 0x02 /* load Memory Data Reg., inc MARR */
662#define FM_IRMEMWO 0x03 /* load MDR from buffer memory, n.i. */
663#define FM_IIL 0x04 /* idle/listen */
664#define FM_ICL 0x05 /* claim/listen */
665#define FM_IBL 0x06 /* beacon/listen */
666#define FM_ILTVX 0x07 /* load TVX timer from TVX reg */
667#define FM_INRTM 0x08 /* nonrestricted token mode */
668#define FM_IENTM 0x09 /* enter nonrestricted token mode */
669#define FM_IERTM 0x0a /* enter restricted token mode */
670#define FM_IRTM 0x0b /* restricted token mode */
671#define FM_ISURT 0x0c /* send unrestricted token */
672#define FM_ISRT 0x0d /* send restricted token */
673#define FM_ISIM 0x0e /* enter send-immediate mode */
674#define FM_IESIM 0x0f /* exit send-immediate mode */
675#define FM_ICLLS 0x11 /* clear synchronous queue lock */
676#define FM_ICLLA0 0x12 /* clear asynchronous queue 0 lock */
677#define FM_ICLLA1 0x14 /* clear asynchronous queue 1 lock */
678#define FM_ICLLA2 0x18 /* clear asynchronous queue 2 lock */
679 /* SN3: reserved */
680#define FM_ICLLR 0x20 /* clear receive queue (SN3:1) lock */
681#define FM_ICLLR2 0x21 /* SN3: clear receive queue 2 lock */
682#define FM_ITRXBUS 0x22 /* SN3: Tristate X-Bus (SAS only) */
683#define FM_IDRXBUS 0x23 /* SN3: drive X-Bus */
684#define FM_ICLLAL 0x3f /* clear all queue locks */
685
686/*
687 * instruction set for command register 2 (NPADDR6-0 = 0x01)
688 */
689#define FM_ITRS 0x01 /* transmit synchronous queue */
690 /* SN3: reserved */
691#define FM_ITRA0 0x02 /* transmit asynchronous queue 0 */
692 /* SN3: reserved */
693#define FM_ITRA1 0x04 /* transmit asynchronous queue 1 */
694 /* SN3: reserved */
695#define FM_ITRA2 0x08 /* transmit asynchronous queue 2 */
696 /* SN3: reserved */
697#define FM_IACTR 0x10 /* abort current transmit activity */
698#define FM_IRSTQ 0x20 /* reset transmit queues */
699#define FM_ISTTB 0x30 /* set tag bit */
700#define FM_IERSF 0x40 /* enable receive single frame */
701 /* SN3: reserved */
702#define FM_ITR 0x50 /* SN3: Transmit Command */
703
704
705/*
706 * defines for PLC (Am79C864)
707 */
708
709/*
710 * PLC read/write (r/w) registers
711 */
712#define PL_CNTRL_A 0x00 /* control register A (r/w) */
713#define PL_CNTRL_B 0x01 /* control register B (r/w) */
714#define PL_INTR_MASK 0x02 /* interrupt mask (r/w) */
715#define PL_XMIT_VECTOR 0x03 /* transmit vector register (r/w) */
716#define PL_VECTOR_LEN 0x04 /* transmit vector length (r/w) */
717#define PL_LE_THRESHOLD 0x05 /* link error event threshold (r/w) */
718#define PL_C_MIN 0x06 /* minimum connect state time (r/w) */
719#define PL_TL_MIN 0x07 /* min. line state transmit t. (r/w) */
720#define PL_TB_MIN 0x08 /* minimum break time (r/w) */
721#define PL_T_OUT 0x09 /* signal timeout (r/w) */
722#define PL_CNTRL_C 0x0a /* control register C (r/w) */
723#define PL_LC_LENGTH 0x0b /* link confidence test time (r/w) */
724#define PL_T_SCRUB 0x0c /* scrub time = MAC TVX (r/w) */
725#define PL_NS_MAX 0x0d /* max. noise time before break (r/w)*/
726#define PL_TPC_LOAD_V 0x0e /* TPC timer load value (write only) */
727#define PL_TNE_LOAD_V 0x0f /* TNE timer load value (write only) */
728#define PL_STATUS_A 0x10 /* status register A (read only) */
729#define PL_STATUS_B 0x11 /* status register B (read only) */
730#define PL_TPC 0x12 /* timer for PCM (ro) [20.48 us] */
731#define PL_TNE 0x13 /* time of noise event [0.32 us] */
732#define PL_CLK_DIV 0x14 /* TNE clock divider (read only) */
733#define PL_BIST_SIGNAT 0x15 /* built in self test signature (ro)*/
734#define PL_RCV_VECTOR 0x16 /* receive vector reg. (read only) */
735#define PL_INTR_EVENT 0x17 /* interrupt event reg. (read only) */
736#define PL_VIOL_SYM_CTR 0x18 /* violation symbol count. (read o) */
737#define PL_MIN_IDLE_CTR 0x19 /* minimum idle counter (read only) */
738#define PL_LINK_ERR_CTR 0x1a /* link error event ctr.(read only) */
739#ifdef MOT_ELM
740#define PL_T_FOT_ASS 0x1e /* FOTOFF Assert Timer */
741#define PL_T_FOT_DEASS 0x1f /* FOTOFF Deassert Timer */
742#endif /* MOT_ELM */
743
744#ifdef MOT_ELM
745/*
746 * Special Quad-Elm Registers.
747 * A Quad-ELM consists of for ELMs and these additional registers.
748 */
749#define QELM_XBAR_W 0x80 /* Crossbar Control ELM W */
750#define QELM_XBAR_X 0x81 /* Crossbar Control ELM X */
751#define QELM_XBAR_Y 0x82 /* Crossbar Control ELM Y */
752#define QELM_XBAR_Z 0x83 /* Crossbar Control ELM Z */
753#define QELM_XBAR_P 0x84 /* Crossbar Control Bus P */
754#define QELM_XBAR_S 0x85 /* Crossbar Control Bus S */
755#define QELM_XBAR_R 0x86 /* Crossbar Control Bus R */
756#define QELM_WR_XBAR 0x87 /* Write the Crossbar now (write) */
757#define QELM_CTR_W 0x88 /* Counter W */
758#define QELM_CTR_X 0x89 /* Counter X */
759#define QELM_CTR_Y 0x8a /* Counter Y */
760#define QELM_CTR_Z 0x8b /* Counter Z */
761#define QELM_INT_MASK 0x8c /* Interrupt mask register */
762#define QELM_INT_DATA 0x8d /* Interrupt data (event) register */
763#define QELM_ELMB 0x00 /* Elm base */
764#define QELM_ELM_SIZE 0x20 /* ELM size */
765#endif /* MOT_ELM */
766/*
767 * PLC control register A (PL_CNTRL_A: log. addr. 0x00)
768 * It is used for timer configuration, specification of PCM MAINT state option,
769 * counter interrupt frequency, PLC data path config. and Built In Self Test.
770 */
771#define PL_RUN_BIST 0x0001 /* begin running its Built In Self T.*/
772#define PL_RF_DISABLE 0x0002 /* disable the Repeat Filter state m.*/
773#define PL_SC_REM_LOOP 0x0004 /* remote loopback path */
774#define PL_SC_BYPASS 0x0008 /* by providing a physical bypass */
775#define PL_LM_LOC_LOOP 0x0010 /* loop path just after elastic buff.*/
776#define PL_EB_LOC_LOOP 0x0020 /* loop path just prior to PDT/PDR IF*/
777#define PL_FOT_OFF 0x0040 /* assertion of /FOTOFF pin of PLC */
778#define PL_LOOPBACK 0x0080 /* it cause the /LPBCK pin ass. low */
779#define PL_MINI_CTR_INT 0x0100 /* partially contr. when bit is ass. */
780#define PL_VSYM_CTR_INT 0x0200 /* controls when int bit is asserted */
781#define PL_ENA_PAR_CHK 0x0400 /* enable parity check */
782#define PL_REQ_SCRUB 0x0800 /* limited access to scrub capability*/
783#define PL_TPC_16BIT 0x1000 /* causes the TPC as a 16 bit timer */
784#define PL_TNE_16BIT 0x2000 /* causes the TNE as a 16 bit timer */
785#define PL_NOISE_TIMER 0x4000 /* allows the noise timing function */
786
787/*
788 * PLC control register B (PL_CNTRL_B: log. addr. 0x01)
789 * It contains signals and requeste to direct the process of PCM and it is also
790 * used to control the Line State Match interrupt.
791 */
792#define PL_PCM_CNTRL 0x0003 /* control PCM state machine */
793#define PL_PCM_NAF (0) /* state is not affected */
794#define PL_PCM_START (1) /* goes to the BREAK state */
795#define PL_PCM_TRACE (2) /* goes to the TRACE state */
796#define PL_PCM_STOP (3) /* goes to the OFF state */
797
798#define PL_MAINT 0x0004 /* if OFF state --> MAINT state */
799#define PL_LONG 0x0008 /* perf. a long Link Confid.Test(LCT)*/
800#define PL_PC_JOIN 0x0010 /* if NEXT state --> JOIN state */
801
802#define PL_PC_LOOP 0x0060 /* loopback used in the LCT */
803#define PL_NOLCT (0<<5) /* no LCT is performed */
804#define PL_TPDR (1<<5) /* PCM asserts transmit PDR */
805#define PL_TIDLE (2<<5) /* PCM asserts transmit idle */
806#define PL_RLBP (3<<5) /* trans. PDR & remote loopb. path */
807
808#define PL_CLASS_S 0x0080 /* signif. that single att. station */
809
810#define PL_MAINT_LS 0x0700 /* line state while in the MAINT st. */
811#define PL_M_QUI0 (0<<8) /* transmit QUIET line state */
812#define PL_M_IDLE (1<<8) /* transmit IDLE line state */
813#define PL_M_HALT (2<<8) /* transmit HALT line state */
814#define PL_M_MASTR (3<<8) /* transmit MASTER line state */
815#define PL_M_QUI1 (4<<8) /* transmit QUIET line state */
816#define PL_M_QUI2 (5<<8) /* transmit QUIET line state */
817#define PL_M_TPDR (6<<8) /* tr. PHY_DATA requ.-symbol is tr.ed*/
818#define PL_M_QUI3 (7<<8) /* transmit QUIET line state */
819
820#define PL_MATCH_LS 0x7800 /* line state to be comp. with curr.*/
821#define PL_I_ANY (0<<11) /* Int. on any change in *_LINE_ST */
822#define PL_I_IDLE (1<<11) /* Interrupt on IDLE line state */
823#define PL_I_HALT (2<<11) /* Interrupt on HALT line state */
824#define PL_I_MASTR (4<<11) /* Interrupt on MASTER line state */
825#define PL_I_QUIET (8<<11) /* Interrupt on QUIET line state */
826
827#define PL_CONFIG_CNTRL 0x8000 /* control over scrub, byp. & loopb.*/
828
829/*
830 * PLC control register C (PL_CNTRL_C: log. addr. 0x0a)
831 * It contains the scrambling control registers (PLC-S only)
832 */
833#define PL_C_CIPHER_ENABLE (1<<0) /* enable scrambler */
834#define PL_C_CIPHER_LPBCK (1<<1) /* loopback scrambler */
835#define PL_C_SDOFF_ENABLE (1<<6) /* enable SDOFF timer */
836#define PL_C_SDON_ENABLE (1<<7) /* enable SDON timer */
837#ifdef MOT_ELM
838#define PL_C_FOTOFF_CTRL (3<<2) /* FOTOFF timer control */
839#define PL_C_FOTOFF_TIM (0<<2) /* FOTOFF use timer for (de)-assert */
840#define PL_C_FOTOFF_INA (2<<2) /* FOTOFF forced inactive */
841#define PL_C_FOTOFF_ACT (3<<2) /* FOTOFF forced active */
842#define PL_C_FOTOFF_SRCE (1<<4) /* FOTOFF source is PCM state != OFF */
843#define PL_C_RXDATA_EN (1<<5) /* Rec scr data forced to 0 */
844#define PL_C_SDNRZEN (1<<8) /* Monitor rec descr. data for act */
845#else /* nMOT_ELM */
846#define PL_C_FOTOFF_CTRL (3<<8) /* FOTOFF timer control */
847#define PL_C_FOTOFF_0 (0<<8) /* timer off */
848#define PL_C_FOTOFF_30 (1<<8) /* 30uS */
849#define PL_C_FOTOFF_50 (2<<8) /* 50uS */
850#define PL_C_FOTOFF_NEVER (3<<8) /* never */
851#define PL_C_SDON_TIMER (3<<10) /* SDON timer control */
852#define PL_C_SDON_084 (0<<10) /* 0.84 uS */
853#define PL_C_SDON_132 (1<<10) /* 1.32 uS */
854#define PL_C_SDON_252 (2<<10) /* 2.52 uS */
855#define PL_C_SDON_512 (3<<10) /* 5.12 uS */
856#define PL_C_SOFF_TIMER (3<<12) /* SDOFF timer control */
857#define PL_C_SOFF_076 (0<<12) /* 0.76 uS */
858#define PL_C_SOFF_132 (1<<12) /* 1.32 uS */
859#define PL_C_SOFF_252 (2<<12) /* 2.52 uS */
860#define PL_C_SOFF_512 (3<<12) /* 5.12 uS */
861#define PL_C_TSEL (3<<14) /* scrambler path select */
862#endif /* nMOT_ELM */
863
864/*
865 * PLC status register A (PL_STATUS_A: log. addr. 0x10)
866 * It is used to report status information to the Node Processor about the
867 * Line State Machine (LSM).
868 */
869#ifdef MOT_ELM
870#define PLC_INT_MASK 0xc000 /* ELM integration bits in status A */
871#define PLC_INT_C 0x0000 /* ELM Revision Band C */
872#define PLC_INT_CAMEL 0x4000 /* ELM integrated into CAMEL */
873#define PLC_INT_QE 0x8000 /* ELM integrated into Quad ELM */
874#define PLC_REV_MASK 0x3800 /* revision bits in status A */
875#define PLC_REVISION_B 0x0000 /* rev bits for ELM Rev B */
876#define PLC_REVISION_QA 0x0800 /* rev bits for ELM core in QELM-A */
877#else /* nMOT_ELM */
878#define PLC_REV_MASK 0xf800 /* revision bits in status A */
879#define PLC_REVISION_A 0x0000 /* revision bits for PLC */
880#define PLC_REVISION_S 0xf800 /* revision bits for PLC-S */
881#define PLC_REV_SN3 0x7800 /* revision bits for PLC-S in IFCP */
882#endif /* nMOT_ELM */
883#define PL_SYM_PR_CTR 0x0007 /* contains the LSM symbol pair Ctr. */
884#define PL_UNKN_LINE_ST 0x0008 /* unknown line state bit from LSM */
885#define PL_LSM_STATE 0x0010 /* state bit of LSM */
886
887#define PL_LINE_ST 0x00e0 /* contains recogn. line state of LSM*/
888#define PL_L_NLS (0<<5) /* noise line state */
889#define PL_L_ALS (1<<5) /* activ line state */
890#define PL_L_UND (2<<5) /* undefined */
891#define PL_L_ILS4 (3<<5) /* idle l. s. (after 4 idle symbols) */
892#define PL_L_QLS (4<<5) /* quiet line state */
893#define PL_L_MLS (5<<5) /* master line state */
894#define PL_L_HLS (6<<5) /* halt line state */
895#define PL_L_ILS16 (7<<5) /* idle line state (after 16 idle s.)*/
896
897#define PL_PREV_LINE_ST 0x0300 /* value of previous line state */
898#define PL_P_QLS (0<<8) /* quiet line state */
899#define PL_P_MLS (1<<8) /* master line state */
900#define PL_P_HLS (2<<8) /* halt line state */
901#define PL_P_ILS16 (3<<8) /* idle line state (after 16 idle s.)*/
902
903#define PL_SIGNAL_DET 0x0400 /* 1=that signal detect is deasserted*/
904
905
906/*
907 * PLC status register B (PL_STATUS_B: log. addr. 0x11)
908 * It contains signals and status from the repeat filter and PCM state machine.
909 */
910#define PL_BREAK_REASON 0x0007 /* reason for PCM state mach.s to br.*/
911#define PL_B_NOT (0) /* PCM SM has not gone to BREAK state*/
912#define PL_B_PCS (1) /* PC_Start issued */
913#define PL_B_TPC (2) /* TPC timer expired after T_OUT */
914#define PL_B_TNE (3) /* TNE timer expired after NS_MAX */
915#define PL_B_QLS (4) /* quit line state detected */
916#define PL_B_ILS (5) /* idle line state detected */
917#define PL_B_HLS (6) /* halt line state detected */
918
919#define PL_TCF 0x0008 /* transmit code flag (start exec.) */
920#define PL_RCF 0x0010 /* receive code flag (start exec.) */
921#define PL_LSF 0x0020 /* line state flag (l.s. has been r.)*/
922#define PL_PCM_SIGNAL 0x0040 /* indic. that XMIT_VECTOR hb.written*/
923
924#define PL_PCM_STATE 0x0780 /* state bits of PCM state machine */
925#define PL_PC0 (0<<7) /* OFF - when /RST or PCM_CNTRL */
926#define PL_PC1 (1<<7) /* BREAK - entry point in start PCM*/
927#define PL_PC2 (2<<7) /* TRACE - to localize stuck Beacon*/
928#define PL_PC3 (3<<7) /* CONNECT - synchronize ends of conn*/
929#define PL_PC4 (4<<7) /* NEXT - to separate the signalng*/
930#define PL_PC5 (5<<7) /* SIGNAL - PCM trans/rec. bit infos*/
931#define PL_PC6 (6<<7) /* JOIN - 1. state to activ conn. */
932#define PL_PC7 (7<<7) /* VERIFY - 2. - " - (3. ACTIVE) */
933#define PL_PC8 (8<<7) /* ACTIVE - PHY has been incorporated*/
934#define PL_PC9 (9<<7) /* MAINT - for test purposes or so
935 that PCM op. completely in softw. */
936
937#define PL_PCI_SCRUB 0x0800 /* scrubbing function is being exec. */
938
939#define PL_PCI_STATE 0x3000 /* Physical Connect. Insertion SM */
940#define PL_CI_REMV (0<<12) /* REMOVED */
941#define PL_CI_ISCR (1<<12) /* INSERT_SCRUB */
942#define PL_CI_RSCR (2<<12) /* REMOVE_SCRUB */
943#define PL_CI_INS (3<<12) /* INSERTED */
944
945#define PL_RF_STATE 0xc000 /* state bit of repeate filter SM */
946#define PL_RF_REPT (0<<14) /* REPEAT */
947#define PL_RF_IDLE (1<<14) /* IDLE */
948#define PL_RF_HALT1 (2<<14) /* HALT1 */
949#define PL_RF_HALT2 (3<<14) /* HALT2 */
950
951
952/*
953 * PLC interrupt event register (PL_INTR_EVENT: log. addr. 0x17)
954 * It is read only and is clearde whenever it is read!
955 * It is used by the PLC to report events to the node processor.
956 */
957#define PL_PARITY_ERR 0x0001 /* p. error h.b.detected on TX9-0 inp*/
958#define PL_LS_MATCH 0x0002 /* l.s.== l.s. PLC_CNTRL_B's MATCH_LS*/
959#define PL_PCM_CODE 0x0004 /* transmit&receive | LCT complete */
960#define PL_TRACE_PROP 0x0008 /* master l.s. while PCM ACTIV|TRACE */
961#define PL_SELF_TEST 0x0010 /* QUIET|HALT while PCM in TRACE st. */
962#define PL_PCM_BREAK 0x0020 /* PCM has entered the BREAK state */
963#define PL_PCM_ENABLED 0x0040 /* asserted SC_JOIN, scrub. & ACTIV */
964#define PL_TPC_EXPIRED 0x0080 /* TPC timer reached zero */
965#define PL_TNE_EXPIRED 0x0100 /* TNE timer reached zero */
966#define PL_EBUF_ERR 0x0200 /* elastic buff. det. over-|underflow*/
967#define PL_PHYINV 0x0400 /* physical layer invalid signal */
968#define PL_VSYM_CTR 0x0800 /* violation symbol counter has incr.*/
969#define PL_MINI_CTR 0x1000 /* dep. on PLC_CNTRL_A's MINI_CTR_INT*/
970#define PL_LE_CTR 0x2000 /* link error event counter */
971#define PL_LSDO 0x4000 /* SDO input pin changed to a 1 */
972#define PL_NP_ERR 0x8000 /* NP has requested to r/w an inv. r.*/
973
974/*
975 * The PLC interrupt mask register (PL_INTR_MASK: log. addr. 0x02) constr. is
976 * equal PL_INTR_EVENT register.
977 * For each set bit, the setting of corresponding bit generate an int to NP.
978 */
979
980#ifdef MOT_ELM
981/*
982 * Quad ELM Crosbar Control register values (QELM_XBAR_?)
983 */
984#define QELM_XOUT_IDLE 0x0000 /* Idles/Passthrough */
985#define QELM_XOUT_P 0x0001 /* Output to: Bus P */
986#define QELM_XOUT_S 0x0002 /* Output to: Bus S */
987#define QELM_XOUT_R 0x0003 /* Output to: Bus R */
988#define QELM_XOUT_W 0x0004 /* Output to: ELM W */
989#define QELM_XOUT_X 0x0005 /* Output to: ELM X */
990#define QELM_XOUT_Y 0x0006 /* Output to: ELM Y */
991#define QELM_XOUT_Z 0x0007 /* Output to: ELM Z */
992
993/*
994 * Quad ELM Interrupt data and event registers.
995 */
996#define QELM_NP_ERR (1<<15) /* Node Processor Error */
997#define QELM_COUNT_Z (1<<7) /* Counter Z Interrupt */
998#define QELM_COUNT_Y (1<<6) /* Counter Y Interrupt */
999#define QELM_COUNT_X (1<<5) /* Counter X Interrupt */
1000#define QELM_COUNT_W (1<<4) /* Counter W Interrupt */
1001#define QELM_ELM_Z (1<<3) /* ELM Z Interrupt */
1002#define QELM_ELM_Y (1<<2) /* ELM Y Interrupt */
1003#define QELM_ELM_X (1<<1) /* ELM X Interrupt */
1004#define QELM_ELM_W (1<<0) /* ELM W Interrupt */
1005#endif /* MOT_ELM */
1006/*
1007 * PLC Timing Parameters
1008 */
1009#define TP_C_MIN 0xff9c /* 2 ms */
1010#define TP_TL_MIN 0xfff0 /* 0.3 ms */
1011#define TP_TB_MIN 0xff10 /* 5 ms */
1012#define TP_T_OUT 0xd9db /* 200 ms */
1013#define TP_LC_LENGTH 0xf676 /* 50 ms */
1014#define TP_LC_LONGLN 0xa0a2 /* 500 ms */
1015#define TP_T_SCRUB 0xff6d /* 3.5 ms */
1016#define TP_NS_MAX 0xf021 /* 1.3 ms */
1017
1018/*
1019 * BIST values
1020 */
1021#define PLC_BIST 0x6ecd /* BIST signature for PLC */
1022#define PLCS_BIST 0x5b6b /* BIST signature for PLC-S */
1023#define PLC_ELM_B_BIST 0x6ecd /* BIST signature of ELM Rev. B */
1024#define PLC_ELM_D_BIST 0x5b6b /* BIST signature of ELM Rev. D */
1025#define PLC_CAM_A_BIST 0x9e75 /* BIST signature of CAMEL Rev. A */
1026#define PLC_CAM_B_BIST 0x5b6b /* BIST signature of CAMEL Rev. B */
1027#define PLC_IFD_A_BIST 0x9e75 /* BIST signature of IFDDI Rev. A */
1028#define PLC_IFD_B_BIST 0x5b6b /* BIST signature of IFDDI Rev. B */
1029#define PLC_QELM_A_BIST 0x5b6b /* BIST signature of QELM Rev. A */
1030
1031/*
1032 FDDI board recources
1033 */
1034
1035/*
1036 * request register array (log. addr: RQA_A + a<<1 {a=0..7}) write only.
1037 * It specifies to FORMAC+ the type of buffer memory access the host requires.
1038 */
1039#define RQ_NOT 0 /* not request */
1040#define RQ_RES 1 /* reserved */
1041#define RQ_SFW 2 /* special frame write */
1042#define RQ_RRQ 3 /* read request: receive queue */
1043#define RQ_WSQ 4 /* write request: synchronous queue */
1044#define RQ_WA0 5 /* write requ.: asynchronous queue 0 */
1045#define RQ_WA1 6 /* write requ.: asynchronous queue 1 */
1046#define RQ_WA2 7 /* write requ.: asynchronous queue 2 */
1047
1048#define SZ_LONG (sizeof(long))
1049
1050/*
1051 * FDDI defaults
1052 * NOTE : In the ANSI docs, times are specified in units of "symbol time".
1053 * AMD chips use BCLK as unit. 1 BCKL == 2 symbols
1054 */
1055#define COMPLREF ((u_long)32*256*256) /* two's complement 21 bit */
1056#define MSTOBCLK(x) ((u_long)(x)*12500L)
1057#define MSTOTVX(x) (((u_long)(x)*1000L)/80/255)
1058
1059#endif /* _SUPERNET_ */
diff --git a/drivers/net/skfp/h/targethw.h b/drivers/net/skfp/h/targethw.h
new file mode 100644
index 000000000000..22c4923241d3
--- /dev/null
+++ b/drivers/net/skfp/h/targethw.h
@@ -0,0 +1,169 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * The information in this file is provided "AS IS" without warranty.
12 *
13 ******************************************************************************/
14
15#ifndef _TARGETHW_
16#define _TARGETHW_
17
18 /*
19 * PCI Watermark definition
20 */
21#ifdef PCI
22#define RX_WATERMARK 24
23#define TX_WATERMARK 24
24#define SK_ML_ID_1 0x20
25#define SK_ML_ID_2 0x30
26#endif
27
28#include "h/skfbi.h"
29#ifndef TAG_MODE
30#include "h/fplus.h"
31#else
32#include "h/fplustm.h"
33#endif
34
35#ifndef HW_PTR
36#define HW_PTR void __iomem *
37#endif
38
39#ifdef MULT_OEM
40#define OI_STAT_LAST 0 /* end of OEM data base */
41#define OI_STAT_PRESENT 1 /* entry present but not empty */
42#define OI_STAT_VALID 2 /* holds valid ID, but is not active */
43#define OI_STAT_ACTIVE 3 /* holds valid ID, entry is active */
44 /* active = adapter is supported */
45
46/* Memory representation of IDs must match representation in adapter. */
47struct s_oem_ids {
48 u_char oi_status ; /* Stat: last, present, valid, active */
49 u_char oi_mark[5] ; /* "PID00" .. "PID07" .. */
50 u_char oi_id[4] ; /* id bytes, representation as */
51 /* defined by hardware, */
52#ifdef PCI
53 u_char oi_sub_id[4] ; /* sub id bytes, representation as */
54 /* defined by hardware, */
55#endif
56#ifdef ISA
57 u_char oi_logo_len ; /* the length of the adapter logo */
58 u_char oi_logo[6] ; /* the adapter logo */
59 u_char oi_reserved1 ;
60#endif /* ISA */
61} ;
62#endif /* MULT_OEM */
63
64
65struct s_smt_hw {
66 /*
67 * global
68 */
69 HW_PTR iop ; /* IO base address */
70 short dma ; /* DMA channel */
71 short irq ; /* IRQ level */
72 short eprom ; /* FLASH prom */
73#ifndef PCI
74 short DmaWriteExtraBytes ; /* add bytes for DMA write */
75#endif
76
77#ifndef SYNC
78 u_short n_a_send ; /* pending send requests */
79#endif
80
81#if (defined(EISA) || defined(MCA) || defined(PCI))
82 short slot ; /* slot number */
83 short max_slots ; /* maximum number of slots */
84#endif
85
86#if (defined(PCI) || defined(MCA))
87 short wdog_used ; /* TRUE if the watch dog is used */
88#endif
89
90#ifdef MCA
91 short slot_32 ; /* 32bit slot (1) or 16bit slot (0) */
92 short rev ; /* Board revision (FMx_REV). */
93 short VFullRead ; /* V_full value for DMA read */
94 short VFullWrite ; /* V_full value for DMA write */
95#endif
96
97#ifdef EISA
98 short led ; /* LED for FE card */
99
100 short dma_rmode ; /* read mode */
101 short dma_wmode ; /* write mode */
102 short dma_emode ; /* extend mode */
103
104 /* DMA controller channel dependent io addresses */
105 u_short dma_base_word_count ;
106 u_short dma_base_address ;
107 u_short dma_base_address_page ;
108#endif
109
110#ifdef PCI
111 u_short pci_handle ; /* handle to access the BIOS func */
112 u_long is_imask ; /* int maske for the int source reg */
113 u_long phys_mem_addr ; /* physical memory address */
114 u_short mc_dummy ; /* work around for MC compiler bug */
115 /*
116 * state of the hardware
117 */
118 u_short hw_state ; /* started or stopped */
119
120#define STARTED 1
121#define STOPPED 0
122
123 int hw_is_64bit ; /* does we have a 64 bit adapter */
124#endif
125
126#ifdef TAG_MODE
127 u_long pci_fix_value ; /* value parsed by PCIFIX */
128#endif
129
130 /*
131 * hwt.c
132 */
133 u_long t_start ; /* HWT start */
134 u_long t_stop ; /* HWT stop */
135 u_short timer_activ ; /* HWT timer active */
136
137 /*
138 * PIC
139 */
140 u_char pic_a1 ;
141 u_char pic_21 ;
142
143 /*
144 * GENERIC ; do not modify beyond this line
145 */
146
147 /*
148 * physical and canonical address
149 */
150 struct fddi_addr fddi_home_addr ;
151 struct fddi_addr fddi_canon_addr ;
152 struct fddi_addr fddi_phys_addr ;
153
154 /*
155 * mac variables
156 */
157 struct mac_parameter mac_pa ; /* tmin, tmax, tvx, treq .. */
158 struct mac_counter mac_ct ; /* recv., lost, error */
159 u_short mac_ring_is_up ; /* ring is up flag */
160
161 struct s_smt_fp fp ; /* formac+ */
162
163#ifdef MULT_OEM
164 struct s_oem_ids *oem_id ; /* pointer to selected id */
165 int oem_min_status ; /* IDs to take care of */
166#endif /* MULT_OEM */
167
168} ;
169#endif
diff --git a/drivers/net/skfp/h/targetos.h b/drivers/net/skfp/h/targetos.h
new file mode 100644
index 000000000000..5d940e7b8ea0
--- /dev/null
+++ b/drivers/net/skfp/h/targetos.h
@@ -0,0 +1,165 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * The information in this file is provided "AS IS" without warranty.
12 *
13 ******************************************************************************/
14
15/*
16 * Operating system specific definitions for driver and
17 * hardware module.
18 */
19
20#ifndef TARGETOS_H
21#define TARGETOS_H
22
23
24//-------- those should go into include/linux/pci.h
25#define PCI_VENDOR_ID_SK 0x1148
26#define PCI_DEVICE_ID_SK_FP 0x4000
27//--------
28
29
30
31//-------- those should go into include/linux/if_fddi.h
32#define FDDI_MAC_HDR_LEN 13
33
34#define FDDI_RII 0x01 /* routing information bit */
35#define FDDI_RCF_DIR_BIT 0x80
36#define FDDI_RCF_LEN_MASK 0x1f
37#define FDDI_RCF_BROADCAST 0x8000
38#define FDDI_RCF_LIMITED_BROADCAST 0xA000
39#define FDDI_RCF_FRAME2K 0x20
40#define FDDI_RCF_FRAME4K 0x30
41//--------
42
43
44#undef ADDR
45
46#include <asm/io.h>
47#include <linux/netdevice.h>
48#include <linux/fddidevice.h>
49#include <linux/skbuff.h>
50#include <linux/pci.h>
51#include <linux/init.h>
52
53// is redefined by linux, but we need our definition
54#undef ADDR
55#ifdef MEM_MAPPED_IO
56#define ADDR(a) (smc->hw.iop+(a))
57#else
58#define ADDR(a) (((a)>>7) ? (outp(smc->hw.iop+B0_RAP,(a)>>7), (smc->hw.iop+( ((a)&0x7F) | ((a)>>7 ? 0x80:0)) )) : (smc->hw.iop+(((a)&0x7F)|((a)>>7 ? 0x80:0))))
59#endif
60
61#include "h/hwmtm.h"
62
63#define TRUE 1
64#define FALSE 0
65
66// HWM Definitions
67// -----------------------
68#define FDDI_TRACE(string, arg1, arg2, arg3) // Performance analysis.
69#ifdef PCI
70#define NDD_TRACE(string, arg1, arg2, arg3) // Performance analysis.
71#endif // PCI
72#define SMT_PAGESIZE PAGE_SIZE // Size of a memory page (power of 2).
73// -----------------------
74
75
76// SMT Definitions
77// -----------------------
78#define TICKS_PER_SECOND HZ
79#define SMC_VERSION 1
80// -----------------------
81
82
83// OS-Driver Definitions
84// -----------------------
85#define NO_ADDRESS 0xffe0 /* No Device (I/O) Address */
86#define SKFP_MAX_NUM_BOARDS 8 /* maximum number of PCI boards */
87
88#define SK_BUS_TYPE_PCI 0
89#define SK_BUS_TYPE_EISA 1
90
91#define FP_IO_LEN 256 /* length of IO area used */
92
93#define u8 unsigned char
94#define u16 unsigned short
95#define u32 unsigned int
96
97#define MAX_TX_QUEUE_LEN 20 // number of packets queued by driver
98#define MAX_FRAME_SIZE 4550
99
100#define RX_LOW_WATERMARK NUM_RECEIVE_BUFFERS / 2
101#define TX_LOW_WATERMARK NUM_TRANSMIT_BUFFERS - 2
102
103/*
104** Include the IOCTL stuff
105*/
106#include <linux/sockios.h>
107
108#define SKFPIOCTL SIOCDEVPRIVATE
109
110struct s_skfp_ioctl {
111 unsigned short cmd; /* Command to run */
112 unsigned short len; /* Length of the data buffer */
113 unsigned char __user *data; /* Pointer to the data buffer */
114};
115
116/*
117** Recognised ioctl commands for the driver
118*/
119#define SKFP_GET_STATS 0x05 /* Get the driver statistics */
120#define SKFP_CLR_STATS 0x06 /* Zero out the driver statistics */
121
122// The per-adapter driver structure
123struct s_smt_os {
124 struct net_device *dev;
125 struct net_device *next_module;
126 u32 bus_type; /* bus type (0 == PCI, 1 == EISA) */
127 struct pci_dev pdev; /* PCI device structure */
128
129 unsigned long base_addr;
130 unsigned char factory_mac_addr[8];
131 ulong SharedMemSize;
132 ulong SharedMemHeap;
133 void* SharedMemAddr;
134 dma_addr_t SharedMemDMA;
135
136 ulong QueueSkb;
137 struct sk_buff_head SendSkbQueue;
138
139 ulong MaxFrameSize;
140 u8 ResetRequested;
141
142 // MAC statistics structure
143 struct fddi_statistics MacStat;
144
145 // receive into this local buffer if no skb available
146 // data will be not valid, because multiple RxDs can
147 // point here at the same time, it must be at least
148 // MAX_FRAME_SIZE bytes in size
149 unsigned char *LocalRxBuffer;
150 dma_addr_t LocalRxBufferDMA;
151
152 // Version (required by SMT module).
153 u_long smc_version ;
154
155 // Required by Hardware Module (HWM).
156 struct hw_modul hwm ;
157
158 // For SMP-savety
159 spinlock_t DriverLock;
160
161};
162
163typedef struct s_smt_os skfddi_priv;
164
165#endif // _TARGETOS_
diff --git a/drivers/net/skfp/h/types.h b/drivers/net/skfp/h/types.h
new file mode 100644
index 000000000000..5a3bf8378f9e
--- /dev/null
+++ b/drivers/net/skfp/h/types.h
@@ -0,0 +1,39 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * The information in this file is provided "AS IS" without warranty.
12 *
13 ******************************************************************************/
14
15#include <linux/types.h>
16/*
17 ----------------------
18 Basic SMT system types
19 ----------------------
20*/
21#ifndef _TYPES_
22#define _TYPES_
23
24#define _packed
25#ifndef far
26#define far
27#endif
28#ifndef _far
29#define _far
30#endif
31
32#define inp(p) ioread8(p)
33#define inpw(p) ioread16(p)
34#define inpd(p) ioread32(p)
35#define outp(p,c) iowrite8(c,p)
36#define outpw(p,s) iowrite16(s,p)
37#define outpd(p,l) iowrite32(l,p)
38
39#endif /* _TYPES_ */
diff --git a/drivers/net/skfp/hwmtm.c b/drivers/net/skfp/hwmtm.c
new file mode 100644
index 000000000000..18d429021edb
--- /dev/null
+++ b/drivers/net/skfp/hwmtm.c
@@ -0,0 +1,2219 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * See the file "skfddi.c" for further information.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * The information in this file is provided "AS IS" without warranty.
14 *
15 ******************************************************************************/
16
17#ifndef lint
18static char const ID_sccs[] = "@(#)hwmtm.c 1.40 99/05/31 (C) SK" ;
19#endif
20
21#define HWMTM
22
23#ifndef FDDI
24#define FDDI
25#endif
26
27#include "h/types.h"
28#include "h/fddi.h"
29#include "h/smc.h"
30#include "h/supern_2.h"
31#include "h/skfbiinc.h"
32
33/*
34 -------------------------------------------------------------
35 DOCUMENTATION
36 -------------------------------------------------------------
37 BEGIN_MANUAL_ENTRY(DOCUMENTATION)
38
39 T B D
40
41 END_MANUAL_ENTRY
42*/
43/*
44 -------------------------------------------------------------
45 LOCAL VARIABLES:
46 -------------------------------------------------------------
47*/
48#ifdef COMMON_MB_POOL
49static SMbuf *mb_start = 0 ;
50static SMbuf *mb_free = 0 ;
51static int mb_init = FALSE ;
52static int call_count = 0 ;
53#endif
54
55/*
56 -------------------------------------------------------------
57 EXTERNE VARIABLES:
58 -------------------------------------------------------------
59*/
60
61#ifdef DEBUG
62#ifndef DEBUG_BRD
63extern struct smt_debug debug ;
64#endif
65#endif
66
67#ifdef NDIS_OS2
68extern u_char offDepth ;
69extern u_char force_irq_pending ;
70#endif
71
72/*
73 -------------------------------------------------------------
74 LOCAL FUNCTIONS:
75 -------------------------------------------------------------
76*/
77
78static void queue_llc_rx(struct s_smc *smc, SMbuf *mb);
79static void smt_to_llc(struct s_smc *smc, SMbuf *mb);
80static void init_txd_ring(struct s_smc *smc);
81static void init_rxd_ring(struct s_smc *smc);
82static void queue_txd_mb(struct s_smc *smc, SMbuf *mb);
83static u_long init_descr_ring(struct s_smc *smc, union s_fp_descr volatile *start,
84 int count);
85static u_long repair_txd_ring(struct s_smc *smc, struct s_smt_tx_queue *queue);
86static u_long repair_rxd_ring(struct s_smc *smc, struct s_smt_rx_queue *queue);
87static SMbuf* get_llc_rx(struct s_smc *smc);
88static SMbuf* get_txd_mb(struct s_smc *smc);
89
90/*
91 -------------------------------------------------------------
92 EXTERNAL FUNCTIONS:
93 -------------------------------------------------------------
94*/
95/* The external SMT functions are listed in cmtdef.h */
96
97extern void* mac_drv_get_space(struct s_smc *smc, unsigned int size);
98extern void* mac_drv_get_desc_mem(struct s_smc *smc, unsigned int size);
99extern void init_board(struct s_smc *smc, u_char *mac_addr);
100extern void mac_drv_fill_rxd(struct s_smc *smc);
101extern void plc1_irq(struct s_smc *smc);
102extern void mac_drv_tx_complete(struct s_smc *smc,
103 volatile struct s_smt_fp_txd *txd);
104extern void plc2_irq(struct s_smc *smc);
105extern void mac1_irq(struct s_smc *smc, u_short stu, u_short stl);
106extern void mac2_irq(struct s_smc *smc, u_short code_s2u, u_short code_s2l);
107extern void mac3_irq(struct s_smc *smc, u_short code_s3u, u_short code_s3l);
108extern void timer_irq(struct s_smc *smc);
109extern void mac_drv_rx_complete(struct s_smc *smc,
110 volatile struct s_smt_fp_rxd *rxd,
111 int frag_count, int len);
112extern void mac_drv_requeue_rxd(struct s_smc *smc,
113 volatile struct s_smt_fp_rxd *rxd,
114 int frag_count);
115extern void init_plc(struct s_smc *smc);
116extern void mac_drv_clear_rxd(struct s_smc *smc,
117 volatile struct s_smt_fp_rxd *rxd, int frag_count);
118
119#ifdef USE_OS_CPY
120extern void hwm_cpy_rxd2mb(void);
121extern void hwm_cpy_txd2mb(void);
122#endif
123
124#ifdef ALL_RX_COMPLETE
125extern void mac_drv_all_receives_complete(void);
126#endif
127
128extern u_long mac_drv_virt2phys(struct s_smc *smc, void *virt);
129extern u_long dma_master(struct s_smc *smc, void *virt, int len, int flag);
130
131#ifdef NDIS_OS2
132extern void post_proc(void);
133#else
134extern void dma_complete(struct s_smc *smc, volatile union s_fp_descr *descr,
135 int flag);
136#endif
137
138extern int init_fplus(struct s_smc *smc);
139extern int mac_drv_rx_init(struct s_smc *smc, int len, int fc, char *look_ahead,
140 int la_len);
141
142/*
143 -------------------------------------------------------------
144 PUBLIC FUNCTIONS:
145 -------------------------------------------------------------
146*/
147void process_receive(struct s_smc *smc);
148void fddi_isr(struct s_smc *smc);
149void mac_drv_clear_txd(struct s_smc *smc);
150void smt_free_mbuf(struct s_smc *smc, SMbuf *mb);
151void init_driver_fplus(struct s_smc *smc);
152void mac_drv_rx_mode(struct s_smc *smc, int mode);
153void init_fddi_driver(struct s_smc *smc, u_char *mac_addr);
154void mac_drv_clear_tx_queue(struct s_smc *smc);
155void mac_drv_clear_rx_queue(struct s_smc *smc);
156void hwm_tx_frag(struct s_smc *smc, char far *virt, u_long phys, int len,
157 int frame_status);
158void hwm_rx_frag(struct s_smc *smc, char far *virt, u_long phys, int len,
159 int frame_status);
160
161int mac_drv_rx_frag(struct s_smc *smc, void far *virt, int len);
162int mac_drv_init(struct s_smc *smc);
163int hwm_tx_init(struct s_smc *smc, u_char fc, int frag_count, int frame_len,
164 int frame_status);
165
166u_int mac_drv_check_space(void);
167
168SMbuf* smt_get_mbuf(struct s_smc *smc);
169
170#ifdef DEBUG
171 void mac_drv_debug_lev(void);
172#endif
173
174/*
175 -------------------------------------------------------------
176 MACROS:
177 -------------------------------------------------------------
178*/
179#ifndef UNUSED
180#ifdef lint
181#define UNUSED(x) (x) = (x)
182#else
183#define UNUSED(x)
184#endif
185#endif
186
187#ifdef USE_CAN_ADDR
188#define MA smc->hw.fddi_canon_addr.a
189#define GROUP_ADDR_BIT 0x01
190#else
191#define MA smc->hw.fddi_home_addr.a
192#define GROUP_ADDR_BIT 0x80
193#endif
194
195#define RXD_TXD_COUNT (HWM_ASYNC_TXD_COUNT+HWM_SYNC_TXD_COUNT+\
196 SMT_R1_RXD_COUNT+SMT_R2_RXD_COUNT)
197
198#ifdef MB_OUTSIDE_SMC
199#define EXT_VIRT_MEM ((RXD_TXD_COUNT+1)*sizeof(struct s_smt_fp_txd) +\
200 MAX_MBUF*sizeof(SMbuf))
201#define EXT_VIRT_MEM_2 ((RXD_TXD_COUNT+1)*sizeof(struct s_smt_fp_txd))
202#else
203#define EXT_VIRT_MEM ((RXD_TXD_COUNT+1)*sizeof(struct s_smt_fp_txd))
204#endif
205
206 /*
207 * define critical read for 16 Bit drivers
208 */
209#if defined(NDIS_OS2) || defined(ODI2)
210#define CR_READ(var) ((var) & 0xffff0000 | ((var) & 0xffff))
211#else
212#define CR_READ(var) (u_long)(var)
213#endif
214
215#define IMASK_SLOW (IS_PLINT1 | IS_PLINT2 | IS_TIMINT | IS_TOKEN | \
216 IS_MINTR1 | IS_MINTR2 | IS_MINTR3 | IS_R1_P | \
217 IS_R1_C | IS_XA_C | IS_XS_C)
218
219/*
220 -------------------------------------------------------------
221 INIT- AND SMT FUNCTIONS:
222 -------------------------------------------------------------
223*/
224
225
226/*
227 * BEGIN_MANUAL_ENTRY(mac_drv_check_space)
228 * u_int mac_drv_check_space()
229 *
230 * function DOWNCALL (drvsr.c)
231 * This function calculates the needed non virtual
232 * memory for MBufs, RxD and TxD descriptors etc.
233 * needed by the driver.
234 *
235 * return u_int memory in bytes
236 *
237 * END_MANUAL_ENTRY
238 */
239u_int mac_drv_check_space(void)
240{
241#ifdef MB_OUTSIDE_SMC
242#ifdef COMMON_MB_POOL
243 call_count++ ;
244 if (call_count == 1) {
245 return(EXT_VIRT_MEM) ;
246 }
247 else {
248 return(EXT_VIRT_MEM_2) ;
249 }
250#else
251 return (EXT_VIRT_MEM) ;
252#endif
253#else
254 return (0) ;
255#endif
256}
257
258/*
259 * BEGIN_MANUAL_ENTRY(mac_drv_init)
260 * void mac_drv_init(smc)
261 *
262 * function DOWNCALL (drvsr.c)
263 * In this function the hardware module allocates it's
264 * memory.
265 * The operating system dependent module should call
266 * mac_drv_init once, after the adatper is detected.
267 * END_MANUAL_ENTRY
268 */
269int mac_drv_init(struct s_smc *smc)
270{
271 if (sizeof(struct s_smt_fp_rxd) % 16) {
272 SMT_PANIC(smc,HWM_E0001,HWM_E0001_MSG) ;
273 }
274 if (sizeof(struct s_smt_fp_txd) % 16) {
275 SMT_PANIC(smc,HWM_E0002,HWM_E0002_MSG) ;
276 }
277
278 /*
279 * get the required memory for the RxDs and TxDs
280 */
281 if (!(smc->os.hwm.descr_p = (union s_fp_descr volatile *)
282 mac_drv_get_desc_mem(smc,(u_int)
283 (RXD_TXD_COUNT+1)*sizeof(struct s_smt_fp_txd)))) {
284 return(1) ; /* no space the hwm modul can't work */
285 }
286
287 /*
288 * get the memory for the SMT MBufs
289 */
290#ifndef MB_OUTSIDE_SMC
291 smc->os.hwm.mbuf_pool.mb_start=(SMbuf *)(&smc->os.hwm.mbuf_pool.mb[0]) ;
292#else
293#ifndef COMMON_MB_POOL
294 if (!(smc->os.hwm.mbuf_pool.mb_start = (SMbuf *) mac_drv_get_space(smc,
295 MAX_MBUF*sizeof(SMbuf)))) {
296 return(1) ; /* no space the hwm modul can't work */
297 }
298#else
299 if (!mb_start) {
300 if (!(mb_start = (SMbuf *) mac_drv_get_space(smc,
301 MAX_MBUF*sizeof(SMbuf)))) {
302 return(1) ; /* no space the hwm modul can't work */
303 }
304 }
305#endif
306#endif
307 return (0) ;
308}
309
310/*
311 * BEGIN_MANUAL_ENTRY(init_driver_fplus)
312 * init_driver_fplus(smc)
313 *
314 * Sets hardware modul specific values for the mode register 2
315 * (e.g. the byte alignment for the received frames, the position of the
316 * least significant byte etc.)
317 * END_MANUAL_ENTRY
318 */
319void init_driver_fplus(struct s_smc *smc)
320{
321 smc->hw.fp.mdr2init = FM_LSB | FM_BMMODE | FM_ENNPRQ | FM_ENHSRQ | 3 ;
322
323#ifdef PCI
324 smc->hw.fp.mdr2init |= FM_CHKPAR | FM_PARITY ;
325#endif
326 smc->hw.fp.mdr3init = FM_MENRQAUNLCK | FM_MENRS ;
327
328#ifdef USE_CAN_ADDR
329 /* enable address bit swapping */
330 smc->hw.fp.frselreg_init = FM_ENXMTADSWAP | FM_ENRCVADSWAP ;
331#endif
332}
333
334static u_long init_descr_ring(struct s_smc *smc,
335 union s_fp_descr volatile *start,
336 int count)
337{
338 int i ;
339 union s_fp_descr volatile *d1 ;
340 union s_fp_descr volatile *d2 ;
341 u_long phys ;
342
343 DB_GEN("descr ring starts at = %x ",(void *)start,0,3) ;
344 for (i=count-1, d1=start; i ; i--) {
345 d2 = d1 ;
346 d1++ ; /* descr is owned by the host */
347 d2->r.rxd_rbctrl = AIX_REVERSE(BMU_CHECK) ;
348 d2->r.rxd_next = &d1->r ;
349 phys = mac_drv_virt2phys(smc,(void *)d1) ;
350 d2->r.rxd_nrdadr = AIX_REVERSE(phys) ;
351 }
352 DB_GEN("descr ring ends at = %x ",(void *)d1,0,3) ;
353 d1->r.rxd_rbctrl = AIX_REVERSE(BMU_CHECK) ;
354 d1->r.rxd_next = &start->r ;
355 phys = mac_drv_virt2phys(smc,(void *)start) ;
356 d1->r.rxd_nrdadr = AIX_REVERSE(phys) ;
357
358 for (i=count, d1=start; i ; i--) {
359 DRV_BUF_FLUSH(&d1->r,DDI_DMA_SYNC_FORDEV) ;
360 d1++;
361 }
362 return(phys) ;
363}
364
365static void init_txd_ring(struct s_smc *smc)
366{
367 struct s_smt_fp_txd volatile *ds ;
368 struct s_smt_tx_queue *queue ;
369 u_long phys ;
370
371 /*
372 * initialize the transmit descriptors
373 */
374 ds = (struct s_smt_fp_txd volatile *) ((char *)smc->os.hwm.descr_p +
375 SMT_R1_RXD_COUNT*sizeof(struct s_smt_fp_rxd)) ;
376 queue = smc->hw.fp.tx[QUEUE_A0] ;
377 DB_GEN("Init async TxD ring, %d TxDs ",HWM_ASYNC_TXD_COUNT,0,3) ;
378 (void)init_descr_ring(smc,(union s_fp_descr volatile *)ds,
379 HWM_ASYNC_TXD_COUNT) ;
380 phys = AIX_REVERSE(ds->txd_ntdadr) ;
381 ds++ ;
382 queue->tx_curr_put = queue->tx_curr_get = ds ;
383 ds-- ;
384 queue->tx_free = HWM_ASYNC_TXD_COUNT ;
385 queue->tx_used = 0 ;
386 outpd(ADDR(B5_XA_DA),phys) ;
387
388 ds = (struct s_smt_fp_txd volatile *) ((char *)ds +
389 HWM_ASYNC_TXD_COUNT*sizeof(struct s_smt_fp_txd)) ;
390 queue = smc->hw.fp.tx[QUEUE_S] ;
391 DB_GEN("Init sync TxD ring, %d TxDs ",HWM_SYNC_TXD_COUNT,0,3) ;
392 (void)init_descr_ring(smc,(union s_fp_descr volatile *)ds,
393 HWM_SYNC_TXD_COUNT) ;
394 phys = AIX_REVERSE(ds->txd_ntdadr) ;
395 ds++ ;
396 queue->tx_curr_put = queue->tx_curr_get = ds ;
397 queue->tx_free = HWM_SYNC_TXD_COUNT ;
398 queue->tx_used = 0 ;
399 outpd(ADDR(B5_XS_DA),phys) ;
400}
401
402static void init_rxd_ring(struct s_smc *smc)
403{
404 struct s_smt_fp_rxd volatile *ds ;
405 struct s_smt_rx_queue *queue ;
406 u_long phys ;
407
408 /*
409 * initialize the receive descriptors
410 */
411 ds = (struct s_smt_fp_rxd volatile *) smc->os.hwm.descr_p ;
412 queue = smc->hw.fp.rx[QUEUE_R1] ;
413 DB_GEN("Init RxD ring, %d RxDs ",SMT_R1_RXD_COUNT,0,3) ;
414 (void)init_descr_ring(smc,(union s_fp_descr volatile *)ds,
415 SMT_R1_RXD_COUNT) ;
416 phys = AIX_REVERSE(ds->rxd_nrdadr) ;
417 ds++ ;
418 queue->rx_curr_put = queue->rx_curr_get = ds ;
419 queue->rx_free = SMT_R1_RXD_COUNT ;
420 queue->rx_used = 0 ;
421 outpd(ADDR(B4_R1_DA),phys) ;
422}
423
424/*
425 * BEGIN_MANUAL_ENTRY(init_fddi_driver)
426 * void init_fddi_driver(smc,mac_addr)
427 *
428 * initializes the driver and it's variables
429 *
430 * END_MANUAL_ENTRY
431 */
432void init_fddi_driver(struct s_smc *smc, u_char *mac_addr)
433{
434 SMbuf *mb ;
435 int i ;
436
437 init_board(smc,mac_addr) ;
438 (void)init_fplus(smc) ;
439
440 /*
441 * initialize the SMbufs for the SMT
442 */
443#ifndef COMMON_MB_POOL
444 mb = smc->os.hwm.mbuf_pool.mb_start ;
445 smc->os.hwm.mbuf_pool.mb_free = (SMbuf *)NULL ;
446 for (i = 0; i < MAX_MBUF; i++) {
447 mb->sm_use_count = 1 ;
448 smt_free_mbuf(smc,mb) ;
449 mb++ ;
450 }
451#else
452 mb = mb_start ;
453 if (!mb_init) {
454 mb_free = 0 ;
455 for (i = 0; i < MAX_MBUF; i++) {
456 mb->sm_use_count = 1 ;
457 smt_free_mbuf(smc,mb) ;
458 mb++ ;
459 }
460 mb_init = TRUE ;
461 }
462#endif
463
464 /*
465 * initialize the other variables
466 */
467 smc->os.hwm.llc_rx_pipe = smc->os.hwm.llc_rx_tail = (SMbuf *)NULL ;
468 smc->os.hwm.txd_tx_pipe = smc->os.hwm.txd_tx_tail = NULL ;
469 smc->os.hwm.pass_SMT = smc->os.hwm.pass_NSA = smc->os.hwm.pass_DB = 0 ;
470 smc->os.hwm.pass_llc_promisc = TRUE ;
471 smc->os.hwm.queued_rx_frames = smc->os.hwm.queued_txd_mb = 0 ;
472 smc->os.hwm.detec_count = 0 ;
473 smc->os.hwm.rx_break = 0 ;
474 smc->os.hwm.rx_len_error = 0 ;
475 smc->os.hwm.isr_flag = FALSE ;
476
477 /*
478 * make sure that the start pointer is 16 byte aligned
479 */
480 i = 16 - ((long)smc->os.hwm.descr_p & 0xf) ;
481 if (i != 16) {
482 DB_GEN("i = %d",i,0,3) ;
483 smc->os.hwm.descr_p = (union s_fp_descr volatile *)
484 ((char *)smc->os.hwm.descr_p+i) ;
485 }
486 DB_GEN("pt to descr area = %x",(void *)smc->os.hwm.descr_p,0,3) ;
487
488 init_txd_ring(smc) ;
489 init_rxd_ring(smc) ;
490 mac_drv_fill_rxd(smc) ;
491
492 init_plc(smc) ;
493}
494
495
496SMbuf *smt_get_mbuf(struct s_smc *smc)
497{
498 register SMbuf *mb ;
499
500#ifndef COMMON_MB_POOL
501 mb = smc->os.hwm.mbuf_pool.mb_free ;
502#else
503 mb = mb_free ;
504#endif
505 if (mb) {
506#ifndef COMMON_MB_POOL
507 smc->os.hwm.mbuf_pool.mb_free = mb->sm_next ;
508#else
509 mb_free = mb->sm_next ;
510#endif
511 mb->sm_off = 8 ;
512 mb->sm_use_count = 1 ;
513 }
514 DB_GEN("get SMbuf: mb = %x",(void *)mb,0,3) ;
515 return (mb) ; /* May be NULL */
516}
517
518void smt_free_mbuf(struct s_smc *smc, SMbuf *mb)
519{
520
521 if (mb) {
522 mb->sm_use_count-- ;
523 DB_GEN("free_mbuf: sm_use_count = %d",mb->sm_use_count,0,3) ;
524 /*
525 * If the use_count is != zero the MBuf is queued
526 * more than once and must not queued into the
527 * free MBuf queue
528 */
529 if (!mb->sm_use_count) {
530 DB_GEN("free SMbuf: mb = %x",(void *)mb,0,3) ;
531#ifndef COMMON_MB_POOL
532 mb->sm_next = smc->os.hwm.mbuf_pool.mb_free ;
533 smc->os.hwm.mbuf_pool.mb_free = mb ;
534#else
535 mb->sm_next = mb_free ;
536 mb_free = mb ;
537#endif
538 }
539 }
540 else
541 SMT_PANIC(smc,HWM_E0003,HWM_E0003_MSG) ;
542}
543
544
545/*
546 * BEGIN_MANUAL_ENTRY(mac_drv_repair_descr)
547 * void mac_drv_repair_descr(smc)
548 *
549 * function called from SMT (HWM / hwmtm.c)
550 * The BMU is idle when this function is called.
551 * Mac_drv_repair_descr sets up the physical address
552 * for all receive and transmit queues where the BMU
553 * should continue.
554 * It may be that the BMU was reseted during a fragmented
555 * transfer. In this case there are some fragments which will
556 * never completed by the BMU. The OWN bit of this fragments
557 * must be switched to be owned by the host.
558 *
559 * Give a start command to the receive BMU.
560 * Start the transmit BMUs if transmit frames pending.
561 *
562 * END_MANUAL_ENTRY
563 */
564void mac_drv_repair_descr(struct s_smc *smc)
565{
566 u_long phys ;
567
568 if (smc->hw.hw_state != STOPPED) {
569 SK_BREAK() ;
570 SMT_PANIC(smc,HWM_E0013,HWM_E0013_MSG) ;
571 return ;
572 }
573
574 /*
575 * repair tx queues: don't start
576 */
577 phys = repair_txd_ring(smc,smc->hw.fp.tx[QUEUE_A0]) ;
578 outpd(ADDR(B5_XA_DA),phys) ;
579 if (smc->hw.fp.tx_q[QUEUE_A0].tx_used) {
580 outpd(ADDR(B0_XA_CSR),CSR_START) ;
581 }
582 phys = repair_txd_ring(smc,smc->hw.fp.tx[QUEUE_S]) ;
583 outpd(ADDR(B5_XS_DA),phys) ;
584 if (smc->hw.fp.tx_q[QUEUE_S].tx_used) {
585 outpd(ADDR(B0_XS_CSR),CSR_START) ;
586 }
587
588 /*
589 * repair rx queues
590 */
591 phys = repair_rxd_ring(smc,smc->hw.fp.rx[QUEUE_R1]) ;
592 outpd(ADDR(B4_R1_DA),phys) ;
593 outpd(ADDR(B0_R1_CSR),CSR_START) ;
594}
595
596static u_long repair_txd_ring(struct s_smc *smc, struct s_smt_tx_queue *queue)
597{
598 int i ;
599 int tx_used ;
600 u_long phys ;
601 u_long tbctrl ;
602 struct s_smt_fp_txd volatile *t ;
603
604 SK_UNUSED(smc) ;
605
606 t = queue->tx_curr_get ;
607 tx_used = queue->tx_used ;
608 for (i = tx_used+queue->tx_free-1 ; i ; i-- ) {
609 t = t->txd_next ;
610 }
611 phys = AIX_REVERSE(t->txd_ntdadr) ;
612
613 t = queue->tx_curr_get ;
614 while (tx_used) {
615 DRV_BUF_FLUSH(t,DDI_DMA_SYNC_FORCPU) ;
616 tbctrl = AIX_REVERSE(t->txd_tbctrl) ;
617
618 if (tbctrl & BMU_OWN) {
619 if (tbctrl & BMU_STF) {
620 break ; /* exit the loop */
621 }
622 else {
623 /*
624 * repair the descriptor
625 */
626 t->txd_tbctrl &= AIX_REVERSE(~BMU_OWN) ;
627 }
628 }
629 phys = AIX_REVERSE(t->txd_ntdadr) ;
630 DRV_BUF_FLUSH(t,DDI_DMA_SYNC_FORDEV) ;
631 t = t->txd_next ;
632 tx_used-- ;
633 }
634 return(phys) ;
635}
636
637/*
638 * Repairs the receive descriptor ring and returns the physical address
639 * where the BMU should continue working.
640 *
641 * o The physical address where the BMU was stopped has to be
642 * determined. This is the next RxD after rx_curr_get with an OWN
643 * bit set.
644 * o The BMU should start working at beginning of the next frame.
645 * RxDs with an OWN bit set but with a reset STF bit should be
646 * skipped and owned by the driver (OWN = 0).
647 */
648static u_long repair_rxd_ring(struct s_smc *smc, struct s_smt_rx_queue *queue)
649{
650 int i ;
651 int rx_used ;
652 u_long phys ;
653 u_long rbctrl ;
654 struct s_smt_fp_rxd volatile *r ;
655
656 SK_UNUSED(smc) ;
657
658 r = queue->rx_curr_get ;
659 rx_used = queue->rx_used ;
660 for (i = SMT_R1_RXD_COUNT-1 ; i ; i-- ) {
661 r = r->rxd_next ;
662 }
663 phys = AIX_REVERSE(r->rxd_nrdadr) ;
664
665 r = queue->rx_curr_get ;
666 while (rx_used) {
667 DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORCPU) ;
668 rbctrl = AIX_REVERSE(r->rxd_rbctrl) ;
669
670 if (rbctrl & BMU_OWN) {
671 if (rbctrl & BMU_STF) {
672 break ; /* exit the loop */
673 }
674 else {
675 /*
676 * repair the descriptor
677 */
678 r->rxd_rbctrl &= AIX_REVERSE(~BMU_OWN) ;
679 }
680 }
681 phys = AIX_REVERSE(r->rxd_nrdadr) ;
682 DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORDEV) ;
683 r = r->rxd_next ;
684 rx_used-- ;
685 }
686 return(phys) ;
687}
688
689
690/*
691 -------------------------------------------------------------
692 INTERRUPT SERVICE ROUTINE:
693 -------------------------------------------------------------
694*/
695
696/*
697 * BEGIN_MANUAL_ENTRY(fddi_isr)
698 * void fddi_isr(smc)
699 *
700 * function DOWNCALL (drvsr.c)
701 * interrupt service routine, handles the interrupt requests
702 * generated by the FDDI adapter.
703 *
704 * NOTE: The operating system dependent module must garantee that the
705 * interrupts of the adapter are disabled when it calls fddi_isr.
706 *
707 * About the USE_BREAK_ISR mechanismn:
708 *
709 * The main requirement of this mechanismn is to force an timer IRQ when
710 * leaving process_receive() with leave_isr set. process_receive() may
711 * be called at any time from anywhere!
712 * To be sure we don't miss such event we set 'force_irq' per default.
713 * We have to force and Timer IRQ if 'smc->os.hwm.leave_isr' AND
714 * 'force_irq' are set. 'force_irq' may be reset if a receive complete
715 * IRQ is pending.
716 *
717 * END_MANUAL_ENTRY
718 */
719void fddi_isr(struct s_smc *smc)
720{
721 u_long is ; /* ISR source */
722 u_short stu, stl ;
723 SMbuf *mb ;
724
725#ifdef USE_BREAK_ISR
726 int force_irq ;
727#endif
728
729#ifdef ODI2
730 if (smc->os.hwm.rx_break) {
731 mac_drv_fill_rxd(smc) ;
732 if (smc->hw.fp.rx_q[QUEUE_R1].rx_used > 0) {
733 smc->os.hwm.rx_break = 0 ;
734 process_receive(smc) ;
735 }
736 else {
737 smc->os.hwm.detec_count = 0 ;
738 smt_force_irq(smc) ;
739 }
740 }
741#endif
742 smc->os.hwm.isr_flag = TRUE ;
743
744#ifdef USE_BREAK_ISR
745 force_irq = TRUE ;
746 if (smc->os.hwm.leave_isr) {
747 smc->os.hwm.leave_isr = FALSE ;
748 process_receive(smc) ;
749 }
750#endif
751
752 while ((is = GET_ISR() & ISR_MASK)) {
753 NDD_TRACE("CH0B",is,0,0) ;
754 DB_GEN("ISA = 0x%x",is,0,7) ;
755
756 if (is & IMASK_SLOW) {
757 NDD_TRACE("CH1b",is,0,0) ;
758 if (is & IS_PLINT1) { /* PLC1 */
759 plc1_irq(smc) ;
760 }
761 if (is & IS_PLINT2) { /* PLC2 */
762 plc2_irq(smc) ;
763 }
764 if (is & IS_MINTR1) { /* FORMAC+ STU1(U/L) */
765 stu = inpw(FM_A(FM_ST1U)) ;
766 stl = inpw(FM_A(FM_ST1L)) ;
767 DB_GEN("Slow transmit complete",0,0,6) ;
768 mac1_irq(smc,stu,stl) ;
769 }
770 if (is & IS_MINTR2) { /* FORMAC+ STU2(U/L) */
771 stu= inpw(FM_A(FM_ST2U)) ;
772 stl= inpw(FM_A(FM_ST2L)) ;
773 DB_GEN("Slow receive complete",0,0,6) ;
774 DB_GEN("stl = %x : stu = %x",stl,stu,7) ;
775 mac2_irq(smc,stu,stl) ;
776 }
777 if (is & IS_MINTR3) { /* FORMAC+ STU3(U/L) */
778 stu= inpw(FM_A(FM_ST3U)) ;
779 stl= inpw(FM_A(FM_ST3L)) ;
780 DB_GEN("FORMAC Mode Register 3",0,0,6) ;
781 mac3_irq(smc,stu,stl) ;
782 }
783 if (is & IS_TIMINT) { /* Timer 82C54-2 */
784 timer_irq(smc) ;
785#ifdef NDIS_OS2
786 force_irq_pending = 0 ;
787#endif
788 /*
789 * out of RxD detection
790 */
791 if (++smc->os.hwm.detec_count > 4) {
792 /*
793 * check out of RxD condition
794 */
795 process_receive(smc) ;
796 }
797 }
798 if (is & IS_TOKEN) { /* Restricted Token Monitor */
799 rtm_irq(smc) ;
800 }
801 if (is & IS_R1_P) { /* Parity error rx queue 1 */
802 /* clear IRQ */
803 outpd(ADDR(B4_R1_CSR),CSR_IRQ_CL_P) ;
804 SMT_PANIC(smc,HWM_E0004,HWM_E0004_MSG) ;
805 }
806 if (is & IS_R1_C) { /* Encoding error rx queue 1 */
807 /* clear IRQ */
808 outpd(ADDR(B4_R1_CSR),CSR_IRQ_CL_C) ;
809 SMT_PANIC(smc,HWM_E0005,HWM_E0005_MSG) ;
810 }
811 if (is & IS_XA_C) { /* Encoding error async tx q */
812 /* clear IRQ */
813 outpd(ADDR(B5_XA_CSR),CSR_IRQ_CL_C) ;
814 SMT_PANIC(smc,HWM_E0006,HWM_E0006_MSG) ;
815 }
816 if (is & IS_XS_C) { /* Encoding error sync tx q */
817 /* clear IRQ */
818 outpd(ADDR(B5_XS_CSR),CSR_IRQ_CL_C) ;
819 SMT_PANIC(smc,HWM_E0007,HWM_E0007_MSG) ;
820 }
821 }
822
823 /*
824 * Fast Tx complete Async/Sync Queue (BMU service)
825 */
826 if (is & (IS_XS_F|IS_XA_F)) {
827 DB_GEN("Fast tx complete queue",0,0,6) ;
828 /*
829 * clear IRQ, Note: no IRQ is lost, because
830 * we always service both queues
831 */
832 outpd(ADDR(B5_XS_CSR),CSR_IRQ_CL_F) ;
833 outpd(ADDR(B5_XA_CSR),CSR_IRQ_CL_F) ;
834 mac_drv_clear_txd(smc) ;
835 llc_restart_tx(smc) ;
836 }
837
838 /*
839 * Fast Rx Complete (BMU service)
840 */
841 if (is & IS_R1_F) {
842 DB_GEN("Fast receive complete",0,0,6) ;
843 /* clear IRQ */
844#ifndef USE_BREAK_ISR
845 outpd(ADDR(B4_R1_CSR),CSR_IRQ_CL_F) ;
846 process_receive(smc) ;
847#else
848 process_receive(smc) ;
849 if (smc->os.hwm.leave_isr) {
850 force_irq = FALSE ;
851 } else {
852 outpd(ADDR(B4_R1_CSR),CSR_IRQ_CL_F) ;
853 process_receive(smc) ;
854 }
855#endif
856 }
857
858#ifndef NDIS_OS2
859 while ((mb = get_llc_rx(smc))) {
860 smt_to_llc(smc,mb) ;
861 }
862#else
863 if (offDepth)
864 post_proc() ;
865
866 while (!offDepth && (mb = get_llc_rx(smc))) {
867 smt_to_llc(smc,mb) ;
868 }
869
870 if (!offDepth && smc->os.hwm.rx_break) {
871 process_receive(smc) ;
872 }
873#endif
874 if (smc->q.ev_get != smc->q.ev_put) {
875 NDD_TRACE("CH2a",0,0,0) ;
876 ev_dispatcher(smc) ;
877 }
878#ifdef NDIS_OS2
879 post_proc() ;
880 if (offDepth) { /* leave fddi_isr because */
881 break ; /* indications not allowed */
882 }
883#endif
884#ifdef USE_BREAK_ISR
885 if (smc->os.hwm.leave_isr) {
886 break ; /* leave fddi_isr */
887 }
888#endif
889
890 /* NOTE: when the isr is left, no rx is pending */
891 } /* end of interrupt source polling loop */
892
893#ifdef USE_BREAK_ISR
894 if (smc->os.hwm.leave_isr && force_irq) {
895 smt_force_irq(smc) ;
896 }
897#endif
898 smc->os.hwm.isr_flag = FALSE ;
899 NDD_TRACE("CH0E",0,0,0) ;
900}
901
902
903/*
904 -------------------------------------------------------------
905 RECEIVE FUNCTIONS:
906 -------------------------------------------------------------
907*/
908
909#ifndef NDIS_OS2
910/*
911 * BEGIN_MANUAL_ENTRY(mac_drv_rx_mode)
912 * void mac_drv_rx_mode(smc,mode)
913 *
914 * function DOWNCALL (fplus.c)
915 * Corresponding to the parameter mode, the operating system
916 * dependent module can activate several receive modes.
917 *
918 * para mode = 1: RX_ENABLE_ALLMULTI enable all multicasts
919 * = 2: RX_DISABLE_ALLMULTI disable "enable all multicasts"
920 * = 3: RX_ENABLE_PROMISC enable promiscuous
921 * = 4: RX_DISABLE_PROMISC disable promiscuous
922 * = 5: RX_ENABLE_NSA enable rec. of all NSA frames
923 * (disabled after 'driver reset' & 'set station address')
924 * = 6: RX_DISABLE_NSA disable rec. of all NSA frames
925 *
926 * = 21: RX_ENABLE_PASS_SMT ( see description )
927 * = 22: RX_DISABLE_PASS_SMT ( " " )
928 * = 23: RX_ENABLE_PASS_NSA ( " " )
929 * = 24: RX_DISABLE_PASS_NSA ( " " )
930 * = 25: RX_ENABLE_PASS_DB ( " " )
931 * = 26: RX_DISABLE_PASS_DB ( " " )
932 * = 27: RX_DISABLE_PASS_ALL ( " " )
933 * = 28: RX_DISABLE_LLC_PROMISC ( " " )
934 * = 29: RX_ENABLE_LLC_PROMISC ( " " )
935 *
936 *
937 * RX_ENABLE_PASS_SMT / RX_DISABLE_PASS_SMT
938 *
939 * If the operating system dependent module activates the
940 * mode RX_ENABLE_PASS_SMT, the hardware module
941 * duplicates all SMT frames with the frame control
942 * FC_SMT_INFO and passes them to the LLC receive channel
943 * by calling mac_drv_rx_init.
944 * The SMT Frames which are sent by the local SMT and the NSA
945 * frames whose A- and C-Indicator is not set are also duplicated
946 * and passed.
947 * The receive mode RX_DISABLE_PASS_SMT disables the passing
948 * of SMT frames.
949 *
950 * RX_ENABLE_PASS_NSA / RX_DISABLE_PASS_NSA
951 *
952 * If the operating system dependent module activates the
953 * mode RX_ENABLE_PASS_NSA, the hardware module
954 * duplicates all NSA frames with frame control FC_SMT_NSA
955 * and a set A-Indicator and passed them to the LLC
956 * receive channel by calling mac_drv_rx_init.
957 * All NSA Frames which are sent by the local SMT
958 * are also duplicated and passed.
959 * The receive mode RX_DISABLE_PASS_NSA disables the passing
960 * of NSA frames with the A- or C-Indicator set.
961 *
962 * NOTE: For fear that the hardware module receives NSA frames with
963 * a reset A-Indicator, the operating system dependent module
964 * has to call mac_drv_rx_mode with the mode RX_ENABLE_NSA
965 * before activate the RX_ENABLE_PASS_NSA mode and after every
966 * 'driver reset' and 'set station address'.
967 *
968 * RX_ENABLE_PASS_DB / RX_DISABLE_PASS_DB
969 *
970 * If the operating system dependent module activates the
971 * mode RX_ENABLE_PASS_DB, direct BEACON frames
972 * (FC_BEACON frame control) are passed to the LLC receive
973 * channel by mac_drv_rx_init.
974 * The receive mode RX_DISABLE_PASS_DB disables the passing
975 * of direct BEACON frames.
976 *
977 * RX_DISABLE_PASS_ALL
978 *
979 * Disables all special receives modes. It is equal to
980 * call mac_drv_set_rx_mode successively with the
981 * parameters RX_DISABLE_NSA, RX_DISABLE_PASS_SMT,
982 * RX_DISABLE_PASS_NSA and RX_DISABLE_PASS_DB.
983 *
984 * RX_ENABLE_LLC_PROMISC
985 *
986 * (default) all received LLC frames and all SMT/NSA/DBEACON
987 * frames depending on the attitude of the flags
988 * PASS_SMT/PASS_NSA/PASS_DBEACON will be delivered to the
989 * LLC layer
990 *
991 * RX_DISABLE_LLC_PROMISC
992 *
993 * all received SMT/NSA/DBEACON frames depending on the
994 * attitude of the flags PASS_SMT/PASS_NSA/PASS_DBEACON
995 * will be delivered to the LLC layer.
996 * all received LLC frames with a directed address, Multicast
997 * or Broadcast address will be delivered to the LLC
998 * layer too.
999 *
1000 * END_MANUAL_ENTRY
1001 */
1002void mac_drv_rx_mode(struct s_smc *smc, int mode)
1003{
1004 switch(mode) {
1005 case RX_ENABLE_PASS_SMT:
1006 smc->os.hwm.pass_SMT = TRUE ;
1007 break ;
1008 case RX_DISABLE_PASS_SMT:
1009 smc->os.hwm.pass_SMT = FALSE ;
1010 break ;
1011 case RX_ENABLE_PASS_NSA:
1012 smc->os.hwm.pass_NSA = TRUE ;
1013 break ;
1014 case RX_DISABLE_PASS_NSA:
1015 smc->os.hwm.pass_NSA = FALSE ;
1016 break ;
1017 case RX_ENABLE_PASS_DB:
1018 smc->os.hwm.pass_DB = TRUE ;
1019 break ;
1020 case RX_DISABLE_PASS_DB:
1021 smc->os.hwm.pass_DB = FALSE ;
1022 break ;
1023 case RX_DISABLE_PASS_ALL:
1024 smc->os.hwm.pass_SMT = smc->os.hwm.pass_NSA = FALSE ;
1025 smc->os.hwm.pass_DB = FALSE ;
1026 smc->os.hwm.pass_llc_promisc = TRUE ;
1027 mac_set_rx_mode(smc,RX_DISABLE_NSA) ;
1028 break ;
1029 case RX_DISABLE_LLC_PROMISC:
1030 smc->os.hwm.pass_llc_promisc = FALSE ;
1031 break ;
1032 case RX_ENABLE_LLC_PROMISC:
1033 smc->os.hwm.pass_llc_promisc = TRUE ;
1034 break ;
1035 case RX_ENABLE_ALLMULTI:
1036 case RX_DISABLE_ALLMULTI:
1037 case RX_ENABLE_PROMISC:
1038 case RX_DISABLE_PROMISC:
1039 case RX_ENABLE_NSA:
1040 case RX_DISABLE_NSA:
1041 default:
1042 mac_set_rx_mode(smc,mode) ;
1043 break ;
1044 }
1045}
1046#endif /* ifndef NDIS_OS2 */
1047
1048/*
1049 * process receive queue
1050 */
1051void process_receive(struct s_smc *smc)
1052{
1053 int i ;
1054 int n ;
1055 int frag_count ; /* number of RxDs of the curr rx buf */
1056 int used_frags ; /* number of RxDs of the curr frame */
1057 struct s_smt_rx_queue *queue ; /* points to the queue ctl struct */
1058 struct s_smt_fp_rxd volatile *r ; /* rxd pointer */
1059 struct s_smt_fp_rxd volatile *rxd ; /* first rxd of rx frame */
1060 u_long rbctrl ; /* receive buffer control word */
1061 u_long rfsw ; /* receive frame status word */
1062 u_short rx_used ;
1063 u_char far *virt ;
1064 char far *data ;
1065 SMbuf *mb ;
1066 u_char fc ; /* Frame control */
1067 int len ; /* Frame length */
1068
1069 smc->os.hwm.detec_count = 0 ;
1070 queue = smc->hw.fp.rx[QUEUE_R1] ;
1071 NDD_TRACE("RHxB",0,0,0) ;
1072 for ( ; ; ) {
1073 r = queue->rx_curr_get ;
1074 rx_used = queue->rx_used ;
1075 frag_count = 0 ;
1076
1077#ifdef USE_BREAK_ISR
1078 if (smc->os.hwm.leave_isr) {
1079 goto rx_end ;
1080 }
1081#endif
1082#ifdef NDIS_OS2
1083 if (offDepth) {
1084 smc->os.hwm.rx_break = 1 ;
1085 goto rx_end ;
1086 }
1087 smc->os.hwm.rx_break = 0 ;
1088#endif
1089#ifdef ODI2
1090 if (smc->os.hwm.rx_break) {
1091 goto rx_end ;
1092 }
1093#endif
1094 n = 0 ;
1095 do {
1096 DB_RX("Check RxD %x for OWN and EOF",(void *)r,0,5) ;
1097 DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORCPU) ;
1098 rbctrl = CR_READ(r->rxd_rbctrl) ;
1099 rbctrl = AIX_REVERSE(rbctrl) ;
1100
1101 if (rbctrl & BMU_OWN) {
1102 NDD_TRACE("RHxE",r,rfsw,rbctrl) ;
1103 DB_RX("End of RxDs",0,0,4) ;
1104 goto rx_end ;
1105 }
1106 /*
1107 * out of RxD detection
1108 */
1109 if (!rx_used) {
1110 SK_BREAK() ;
1111 SMT_PANIC(smc,HWM_E0009,HWM_E0009_MSG) ;
1112 /* Either we don't have an RxD or all
1113 * RxDs are filled. Therefore it's allowed
1114 * for to set the STOPPED flag */
1115 smc->hw.hw_state = STOPPED ;
1116 mac_drv_clear_rx_queue(smc) ;
1117 smc->hw.hw_state = STARTED ;
1118 mac_drv_fill_rxd(smc) ;
1119 smc->os.hwm.detec_count = 0 ;
1120 goto rx_end ;
1121 }
1122 rfsw = AIX_REVERSE(r->rxd_rfsw) ;
1123 if ((rbctrl & BMU_STF) != ((rbctrl & BMU_ST_BUF) <<5)) {
1124 /*
1125 * The BMU_STF bit is deleted, 1 frame is
1126 * placed into more than 1 rx buffer
1127 *
1128 * skip frame by setting the rx len to 0
1129 *
1130 * if fragment count == 0
1131 * The missing STF bit belongs to the
1132 * current frame, search for the
1133 * EOF bit to complete the frame
1134 * else
1135 * the fragment belongs to the next frame,
1136 * exit the loop and process the frame
1137 */
1138 SK_BREAK() ;
1139 rfsw = 0 ;
1140 if (frag_count) {
1141 break ;
1142 }
1143 }
1144 n += rbctrl & 0xffff ;
1145 r = r->rxd_next ;
1146 frag_count++ ;
1147 rx_used-- ;
1148 } while (!(rbctrl & BMU_EOF)) ;
1149 used_frags = frag_count ;
1150 DB_RX("EOF set in RxD, used_frags = %d ",used_frags,0,5) ;
1151
1152 /* may be next 2 DRV_BUF_FLUSH() can be skipped, because */
1153 /* BMU_ST_BUF will not be changed by the ASIC */
1154 DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORCPU) ;
1155 while (rx_used && !(r->rxd_rbctrl & AIX_REVERSE(BMU_ST_BUF))) {
1156 DB_RX("Check STF bit in %x",(void *)r,0,5) ;
1157 r = r->rxd_next ;
1158 DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORCPU) ;
1159 frag_count++ ;
1160 rx_used-- ;
1161 }
1162 DB_RX("STF bit found",0,0,5) ;
1163
1164 /*
1165 * The received frame is finished for the process receive
1166 */
1167 rxd = queue->rx_curr_get ;
1168 queue->rx_curr_get = r ;
1169 queue->rx_free += frag_count ;
1170 queue->rx_used = rx_used ;
1171
1172 /*
1173 * ASIC Errata no. 7 (STF - Bit Bug)
1174 */
1175 rxd->rxd_rbctrl &= AIX_REVERSE(~BMU_STF) ;
1176
1177 for (r=rxd, i=frag_count ; i ; r=r->rxd_next, i--){
1178 DB_RX("dma_complete for RxD %x",(void *)r,0,5) ;
1179 dma_complete(smc,(union s_fp_descr volatile *)r,DMA_WR);
1180 }
1181 smc->hw.fp.err_stats.err_valid++ ;
1182 smc->mib.m[MAC0].fddiMACCopied_Ct++ ;
1183
1184 /* the length of the data including the FC */
1185 len = (rfsw & RD_LENGTH) - 4 ;
1186
1187 DB_RX("frame length = %d",len,0,4) ;
1188 /*
1189 * check the frame_lenght and all error flags
1190 */
1191 if (rfsw & (RX_MSRABT|RX_FS_E|RX_FS_CRC|RX_FS_IMPL)){
1192 if (rfsw & RD_S_MSRABT) {
1193 DB_RX("Frame aborted by the FORMAC",0,0,2) ;
1194 smc->hw.fp.err_stats.err_abort++ ;
1195 }
1196 /*
1197 * check frame status
1198 */
1199 if (rfsw & RD_S_SEAC2) {
1200 DB_RX("E-Indicator set",0,0,2) ;
1201 smc->hw.fp.err_stats.err_e_indicator++ ;
1202 }
1203 if (rfsw & RD_S_SFRMERR) {
1204 DB_RX("CRC error",0,0,2) ;
1205 smc->hw.fp.err_stats.err_crc++ ;
1206 }
1207 if (rfsw & RX_FS_IMPL) {
1208 DB_RX("Implementer frame",0,0,2) ;
1209 smc->hw.fp.err_stats.err_imp_frame++ ;
1210 }
1211 goto abort_frame ;
1212 }
1213 if (len > FDDI_RAW_MTU-4) {
1214 DB_RX("Frame too long error",0,0,2) ;
1215 smc->hw.fp.err_stats.err_too_long++ ;
1216 goto abort_frame ;
1217 }
1218 /*
1219 * SUPERNET 3 Bug: FORMAC delivers status words
1220 * of aborded frames to the BMU
1221 */
1222 if (len <= 4) {
1223 DB_RX("Frame length = 0",0,0,2) ;
1224 goto abort_frame ;
1225 }
1226
1227 if (len != (n-4)) {
1228 DB_RX("BMU: rx len differs: [%d:%d]",len,n,4);
1229 smc->os.hwm.rx_len_error++ ;
1230 goto abort_frame ;
1231 }
1232
1233 /*
1234 * Check SA == MA
1235 */
1236 virt = (u_char far *) rxd->rxd_virt ;
1237 DB_RX("FC = %x",*virt,0,2) ;
1238 if (virt[12] == MA[5] &&
1239 virt[11] == MA[4] &&
1240 virt[10] == MA[3] &&
1241 virt[9] == MA[2] &&
1242 virt[8] == MA[1] &&
1243 (virt[7] & ~GROUP_ADDR_BIT) == MA[0]) {
1244 goto abort_frame ;
1245 }
1246
1247 /*
1248 * test if LLC frame
1249 */
1250 if (rfsw & RX_FS_LLC) {
1251 /*
1252 * if pass_llc_promisc is disable
1253 * if DA != Multicast or Broadcast or DA!=MA
1254 * abort the frame
1255 */
1256 if (!smc->os.hwm.pass_llc_promisc) {
1257 if(!(virt[1] & GROUP_ADDR_BIT)) {
1258 if (virt[6] != MA[5] ||
1259 virt[5] != MA[4] ||
1260 virt[4] != MA[3] ||
1261 virt[3] != MA[2] ||
1262 virt[2] != MA[1] ||
1263 virt[1] != MA[0]) {
1264 DB_RX("DA != MA and not multi- or broadcast",0,0,2) ;
1265 goto abort_frame ;
1266 }
1267 }
1268 }
1269
1270 /*
1271 * LLC frame received
1272 */
1273 DB_RX("LLC - receive",0,0,4) ;
1274 mac_drv_rx_complete(smc,rxd,frag_count,len) ;
1275 }
1276 else {
1277 if (!(mb = smt_get_mbuf(smc))) {
1278 smc->hw.fp.err_stats.err_no_buf++ ;
1279 DB_RX("No SMbuf; receive terminated",0,0,4) ;
1280 goto abort_frame ;
1281 }
1282 data = smtod(mb,char *) - 1 ;
1283
1284 /*
1285 * copy the frame into a SMT_MBuf
1286 */
1287#ifdef USE_OS_CPY
1288 hwm_cpy_rxd2mb(rxd,data,len) ;
1289#else
1290 for (r=rxd, i=used_frags ; i ; r=r->rxd_next, i--){
1291 n = AIX_REVERSE(r->rxd_rbctrl) & RD_LENGTH ;
1292 DB_RX("cp SMT frame to mb: len = %d",n,0,6) ;
1293 memcpy(data,r->rxd_virt,n) ;
1294 data += n ;
1295 }
1296 data = smtod(mb,char *) - 1 ;
1297#endif
1298 fc = *(char *)mb->sm_data = *data ;
1299 mb->sm_len = len - 1 ; /* len - fc */
1300 data++ ;
1301
1302 /*
1303 * SMT frame received
1304 */
1305 switch(fc) {
1306 case FC_SMT_INFO :
1307 smc->hw.fp.err_stats.err_smt_frame++ ;
1308 DB_RX("SMT frame received ",0,0,5) ;
1309
1310 if (smc->os.hwm.pass_SMT) {
1311 DB_RX("pass SMT frame ",0,0,5) ;
1312 mac_drv_rx_complete(smc, rxd,
1313 frag_count,len) ;
1314 }
1315 else {
1316 DB_RX("requeue RxD",0,0,5) ;
1317 mac_drv_requeue_rxd(smc,rxd,frag_count);
1318 }
1319
1320 smt_received_pack(smc,mb,(int)(rfsw>>25)) ;
1321 break ;
1322 case FC_SMT_NSA :
1323 smc->hw.fp.err_stats.err_smt_frame++ ;
1324 DB_RX("SMT frame received ",0,0,5) ;
1325
1326 /* if pass_NSA set pass the NSA frame or */
1327 /* pass_SMT set and the A-Indicator */
1328 /* is not set, pass the NSA frame */
1329 if (smc->os.hwm.pass_NSA ||
1330 (smc->os.hwm.pass_SMT &&
1331 !(rfsw & A_INDIC))) {
1332 DB_RX("pass SMT frame ",0,0,5) ;
1333 mac_drv_rx_complete(smc, rxd,
1334 frag_count,len) ;
1335 }
1336 else {
1337 DB_RX("requeue RxD",0,0,5) ;
1338 mac_drv_requeue_rxd(smc,rxd,frag_count);
1339 }
1340
1341 smt_received_pack(smc,mb,(int)(rfsw>>25)) ;
1342 break ;
1343 case FC_BEACON :
1344 if (smc->os.hwm.pass_DB) {
1345 DB_RX("pass DB frame ",0,0,5) ;
1346 mac_drv_rx_complete(smc, rxd,
1347 frag_count,len) ;
1348 }
1349 else {
1350 DB_RX("requeue RxD",0,0,5) ;
1351 mac_drv_requeue_rxd(smc,rxd,frag_count);
1352 }
1353 smt_free_mbuf(smc,mb) ;
1354 break ;
1355 default :
1356 /*
1357 * unknown FC abord the frame
1358 */
1359 DB_RX("unknown FC error",0,0,2) ;
1360 smt_free_mbuf(smc,mb) ;
1361 DB_RX("requeue RxD",0,0,5) ;
1362 mac_drv_requeue_rxd(smc,rxd,frag_count) ;
1363 if ((fc & 0xf0) == FC_MAC)
1364 smc->hw.fp.err_stats.err_mac_frame++ ;
1365 else
1366 smc->hw.fp.err_stats.err_imp_frame++ ;
1367
1368 break ;
1369 }
1370 }
1371
1372 DB_RX("next RxD is %x ",queue->rx_curr_get,0,3) ;
1373 NDD_TRACE("RHx1",queue->rx_curr_get,0,0) ;
1374
1375 continue ;
1376 /*--------------------------------------------------------------------*/
1377abort_frame:
1378 DB_RX("requeue RxD",0,0,5) ;
1379 mac_drv_requeue_rxd(smc,rxd,frag_count) ;
1380
1381 DB_RX("next RxD is %x ",queue->rx_curr_get,0,3) ;
1382 NDD_TRACE("RHx2",queue->rx_curr_get,0,0) ;
1383 }
1384rx_end:
1385#ifdef ALL_RX_COMPLETE
1386 mac_drv_all_receives_complete(smc) ;
1387#endif
1388 return ; /* lint bug: needs return detect end of function */
1389}
1390
1391static void smt_to_llc(struct s_smc *smc, SMbuf *mb)
1392{
1393 u_char fc ;
1394
1395 DB_RX("send a queued frame to the llc layer",0,0,4) ;
1396 smc->os.hwm.r.len = mb->sm_len ;
1397 smc->os.hwm.r.mb_pos = smtod(mb,char *) ;
1398 fc = *smc->os.hwm.r.mb_pos ;
1399 (void)mac_drv_rx_init(smc,(int)mb->sm_len,(int)fc,
1400 smc->os.hwm.r.mb_pos,(int)mb->sm_len) ;
1401 smt_free_mbuf(smc,mb) ;
1402}
1403
1404/*
1405 * BEGIN_MANUAL_ENTRY(hwm_rx_frag)
1406 * void hwm_rx_frag(smc,virt,phys,len,frame_status)
1407 *
1408 * function MACRO (hardware module, hwmtm.h)
1409 * This function calls dma_master for preparing the
1410 * system hardware for the DMA transfer and initializes
1411 * the current RxD with the length and the physical and
1412 * virtual address of the fragment. Furthermore, it sets the
1413 * STF and EOF bits depending on the frame status byte,
1414 * switches the OWN flag of the RxD, so that it is owned by the
1415 * adapter and issues an rx_start.
1416 *
1417 * para virt virtual pointer to the fragment
1418 * len the length of the fragment
1419 * frame_status status of the frame, see design description
1420 *
1421 * NOTE: It is possible to call this function with a fragment length
1422 * of zero.
1423 *
1424 * END_MANUAL_ENTRY
1425 */
1426void hwm_rx_frag(struct s_smc *smc, char far *virt, u_long phys, int len,
1427 int frame_status)
1428{
1429 struct s_smt_fp_rxd volatile *r ;
1430 u_int rbctrl ;
1431
1432 NDD_TRACE("RHfB",virt,len,frame_status) ;
1433 DB_RX("hwm_rx_frag: len = %d, frame_status = %x\n",len,frame_status,2) ;
1434 r = smc->hw.fp.rx_q[QUEUE_R1].rx_curr_put ;
1435 r->rxd_virt = virt ;
1436 r->rxd_rbadr = AIX_REVERSE(phys) ;
1437 rbctrl = AIX_REVERSE( (((u_long)frame_status &
1438 (FIRST_FRAG|LAST_FRAG))<<26) |
1439 (((u_long) frame_status & FIRST_FRAG) << 21) |
1440 BMU_OWN | BMU_CHECK | BMU_EN_IRQ_EOF | len) ;
1441 r->rxd_rbctrl = rbctrl ;
1442
1443 DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORDEV) ;
1444 outpd(ADDR(B0_R1_CSR),CSR_START) ;
1445 smc->hw.fp.rx_q[QUEUE_R1].rx_free-- ;
1446 smc->hw.fp.rx_q[QUEUE_R1].rx_used++ ;
1447 smc->hw.fp.rx_q[QUEUE_R1].rx_curr_put = r->rxd_next ;
1448 NDD_TRACE("RHfE",r,AIX_REVERSE(r->rxd_rbadr),0) ;
1449}
1450
1451#ifndef NDIS_OS2
1452/*
1453 * BEGIN_MANUAL_ENTRY(mac_drv_rx_frag)
1454 * int mac_drv_rx_frag(smc,virt,len)
1455 *
1456 * function DOWNCALL (hwmtm.c)
1457 * mac_drv_rx_frag fills the fragment with a part of the frame.
1458 *
1459 * para virt the virtual address of the fragment
1460 * len the length in bytes of the fragment
1461 *
1462 * return 0: success code, no errors possible
1463 *
1464 * END_MANUAL_ENTRY
1465 */
1466int mac_drv_rx_frag(struct s_smc *smc, void far *virt, int len)
1467{
1468 NDD_TRACE("RHSB",virt,len,smc->os.hwm.r.mb_pos) ;
1469
1470 DB_RX("receive from queue: len/virt: = %d/%x",len,virt,4) ;
1471 memcpy((char far *)virt,smc->os.hwm.r.mb_pos,len) ;
1472 smc->os.hwm.r.mb_pos += len ;
1473
1474 NDD_TRACE("RHSE",smc->os.hwm.r.mb_pos,0,0) ;
1475 return(0) ;
1476}
1477#endif
1478
1479
1480/*
1481 * BEGINN_MANUAL_ENTRY(mac_drv_clear_rx_queue)
1482 *
1483 * void mac_drv_clear_rx_queue(smc)
1484 * struct s_smc *smc ;
1485 *
1486 * function DOWNCALL (hardware module, hwmtm.c)
1487 * mac_drv_clear_rx_queue is called by the OS-specific module
1488 * after it has issued a card_stop.
1489 * In this case, the frames in the receive queue are obsolete and
1490 * should be removed. For removing mac_drv_clear_rx_queue
1491 * calls dma_master for each RxD and mac_drv_clear_rxd for each
1492 * receive buffer.
1493 *
1494 * NOTE: calling sequence card_stop:
1495 * CLI_FBI(), card_stop(),
1496 * mac_drv_clear_tx_queue(), mac_drv_clear_rx_queue(),
1497 *
1498 * NOTE: The caller is responsible that the BMUs are idle
1499 * when this function is called.
1500 *
1501 * END_MANUAL_ENTRY
1502 */
1503void mac_drv_clear_rx_queue(struct s_smc *smc)
1504{
1505 struct s_smt_fp_rxd volatile *r ;
1506 struct s_smt_fp_rxd volatile *next_rxd ;
1507 struct s_smt_rx_queue *queue ;
1508 int frag_count ;
1509 int i ;
1510
1511 if (smc->hw.hw_state != STOPPED) {
1512 SK_BREAK() ;
1513 SMT_PANIC(smc,HWM_E0012,HWM_E0012_MSG) ;
1514 return ;
1515 }
1516
1517 queue = smc->hw.fp.rx[QUEUE_R1] ;
1518 DB_RX("clear_rx_queue",0,0,5) ;
1519
1520 /*
1521 * dma_complete and mac_drv_clear_rxd for all RxDs / receive buffers
1522 */
1523 r = queue->rx_curr_get ;
1524 while (queue->rx_used) {
1525 DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORCPU) ;
1526 DB_RX("switch OWN bit of RxD 0x%x ",r,0,5) ;
1527 r->rxd_rbctrl &= AIX_REVERSE(~BMU_OWN) ;
1528 frag_count = 1 ;
1529 DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORDEV) ;
1530 r = r->rxd_next ;
1531 DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORCPU) ;
1532 while (r != queue->rx_curr_put &&
1533 !(r->rxd_rbctrl & AIX_REVERSE(BMU_ST_BUF))) {
1534 DB_RX("Check STF bit in %x",(void *)r,0,5) ;
1535 r->rxd_rbctrl &= AIX_REVERSE(~BMU_OWN) ;
1536 DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORDEV) ;
1537 r = r->rxd_next ;
1538 DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORCPU) ;
1539 frag_count++ ;
1540 }
1541 DB_RX("STF bit found",0,0,5) ;
1542 next_rxd = r ;
1543
1544 for (r=queue->rx_curr_get,i=frag_count; i ; r=r->rxd_next,i--){
1545 DB_RX("dma_complete for RxD %x",(void *)r,0,5) ;
1546 dma_complete(smc,(union s_fp_descr volatile *)r,DMA_WR);
1547 }
1548
1549 DB_RX("mac_drv_clear_rxd: RxD %x frag_count %d ",
1550 (void *)queue->rx_curr_get,frag_count,5) ;
1551 mac_drv_clear_rxd(smc,queue->rx_curr_get,frag_count) ;
1552
1553 queue->rx_curr_get = next_rxd ;
1554 queue->rx_used -= frag_count ;
1555 queue->rx_free += frag_count ;
1556 }
1557}
1558
1559
1560/*
1561 -------------------------------------------------------------
1562 SEND FUNCTIONS:
1563 -------------------------------------------------------------
1564*/
1565
1566/*
1567 * BEGIN_MANUAL_ENTRY(hwm_tx_init)
1568 * int hwm_tx_init(smc,fc,frag_count,frame_len,frame_status)
1569 *
1570 * function DOWN_CALL (hardware module, hwmtm.c)
1571 * hwm_tx_init checks if the frame can be sent through the
1572 * corresponding send queue.
1573 *
1574 * para fc the frame control. To determine through which
1575 * send queue the frame should be transmitted.
1576 * 0x50 - 0x57: asynchronous LLC frame
1577 * 0xD0 - 0xD7: synchronous LLC frame
1578 * 0x41, 0x4F: SMT frame to the network
1579 * 0x42: SMT frame to the network and to the local SMT
1580 * 0x43: SMT frame to the local SMT
1581 * frag_count count of the fragments for this frame
1582 * frame_len length of the frame
1583 * frame_status status of the frame, the send queue bit is already
1584 * specified
1585 *
1586 * return frame_status
1587 *
1588 * END_MANUAL_ENTRY
1589 */
1590int hwm_tx_init(struct s_smc *smc, u_char fc, int frag_count, int frame_len,
1591 int frame_status)
1592{
1593 NDD_TRACE("THiB",fc,frag_count,frame_len) ;
1594 smc->os.hwm.tx_p = smc->hw.fp.tx[frame_status & QUEUE_A0] ;
1595 smc->os.hwm.tx_descr = TX_DESCRIPTOR | (((u_long)(frame_len-1)&3)<<27) ;
1596 smc->os.hwm.tx_len = frame_len ;
1597 DB_TX("hwm_tx_init: fc = %x, len = %d",fc,frame_len,3) ;
1598 if ((fc & ~(FC_SYNC_BIT|FC_LLC_PRIOR)) == FC_ASYNC_LLC) {
1599 frame_status |= LAN_TX ;
1600 }
1601 else {
1602 switch (fc) {
1603 case FC_SMT_INFO :
1604 case FC_SMT_NSA :
1605 frame_status |= LAN_TX ;
1606 break ;
1607 case FC_SMT_LOC :
1608 frame_status |= LOC_TX ;
1609 break ;
1610 case FC_SMT_LAN_LOC :
1611 frame_status |= LAN_TX | LOC_TX ;
1612 break ;
1613 default :
1614 SMT_PANIC(smc,HWM_E0010,HWM_E0010_MSG) ;
1615 }
1616 }
1617 if (!smc->hw.mac_ring_is_up) {
1618 frame_status &= ~LAN_TX ;
1619 frame_status |= RING_DOWN ;
1620 DB_TX("Ring is down: terminate LAN_TX",0,0,2) ;
1621 }
1622 if (frag_count > smc->os.hwm.tx_p->tx_free) {
1623#ifndef NDIS_OS2
1624 mac_drv_clear_txd(smc) ;
1625 if (frag_count > smc->os.hwm.tx_p->tx_free) {
1626 DB_TX("Out of TxDs, terminate LAN_TX",0,0,2) ;
1627 frame_status &= ~LAN_TX ;
1628 frame_status |= OUT_OF_TXD ;
1629 }
1630#else
1631 DB_TX("Out of TxDs, terminate LAN_TX",0,0,2) ;
1632 frame_status &= ~LAN_TX ;
1633 frame_status |= OUT_OF_TXD ;
1634#endif
1635 }
1636 DB_TX("frame_status = %x",frame_status,0,3) ;
1637 NDD_TRACE("THiE",frame_status,smc->os.hwm.tx_p->tx_free,0) ;
1638 return(frame_status) ;
1639}
1640
1641/*
1642 * BEGIN_MANUAL_ENTRY(hwm_tx_frag)
1643 * void hwm_tx_frag(smc,virt,phys,len,frame_status)
1644 *
1645 * function DOWNCALL (hardware module, hwmtm.c)
1646 * If the frame should be sent to the LAN, this function calls
1647 * dma_master, fills the current TxD with the virtual and the
1648 * physical address, sets the STF and EOF bits dependent on
1649 * the frame status, and requests the BMU to start the
1650 * transmit.
1651 * If the frame should be sent to the local SMT, an SMT_MBuf
1652 * is allocated if the FIRST_FRAG bit is set in the frame_status.
1653 * The fragment of the frame is copied into the SMT MBuf.
1654 * The function smt_received_pack is called if the LAST_FRAG
1655 * bit is set in the frame_status word.
1656 *
1657 * para virt virtual pointer to the fragment
1658 * len the length of the fragment
1659 * frame_status status of the frame, see design description
1660 *
1661 * return nothing returned, no parameter is modified
1662 *
1663 * NOTE: It is possible to invoke this macro with a fragment length
1664 * of zero.
1665 *
1666 * END_MANUAL_ENTRY
1667 */
1668void hwm_tx_frag(struct s_smc *smc, char far *virt, u_long phys, int len,
1669 int frame_status)
1670{
1671 struct s_smt_fp_txd volatile *t ;
1672 struct s_smt_tx_queue *queue ;
1673 u_int tbctrl ;
1674
1675 queue = smc->os.hwm.tx_p ;
1676
1677 NDD_TRACE("THfB",virt,len,frame_status) ;
1678 /* Bug fix: AF / May 31 1999 (#missing)
1679 * snmpinfo problem reported by IBM is caused by invalid
1680 * t-pointer (txd) if LAN_TX is not set but LOC_TX only.
1681 * Set: t = queue->tx_curr_put here !
1682 */
1683 t = queue->tx_curr_put ;
1684
1685 DB_TX("hwm_tx_frag: len = %d, frame_status = %x ",len,frame_status,2) ;
1686 if (frame_status & LAN_TX) {
1687 /* '*t' is already defined */
1688 DB_TX("LAN_TX: TxD = %x, virt = %x ",t,virt,3) ;
1689 t->txd_virt = virt ;
1690 t->txd_txdscr = AIX_REVERSE(smc->os.hwm.tx_descr) ;
1691 t->txd_tbadr = AIX_REVERSE(phys) ;
1692 tbctrl = AIX_REVERSE((((u_long)frame_status &
1693 (FIRST_FRAG|LAST_FRAG|EN_IRQ_EOF))<< 26) |
1694 BMU_OWN|BMU_CHECK |len) ;
1695 t->txd_tbctrl = tbctrl ;
1696
1697#ifndef AIX
1698 DRV_BUF_FLUSH(t,DDI_DMA_SYNC_FORDEV) ;
1699 outpd(queue->tx_bmu_ctl,CSR_START) ;
1700#else /* ifndef AIX */
1701 DRV_BUF_FLUSH(t,DDI_DMA_SYNC_FORDEV) ;
1702 if (frame_status & QUEUE_A0) {
1703 outpd(ADDR(B0_XA_CSR),CSR_START) ;
1704 }
1705 else {
1706 outpd(ADDR(B0_XS_CSR),CSR_START) ;
1707 }
1708#endif
1709 queue->tx_free-- ;
1710 queue->tx_used++ ;
1711 queue->tx_curr_put = t->txd_next ;
1712 if (frame_status & LAST_FRAG) {
1713 smc->mib.m[MAC0].fddiMACTransmit_Ct++ ;
1714 }
1715 }
1716 if (frame_status & LOC_TX) {
1717 DB_TX("LOC_TX: ",0,0,3) ;
1718 if (frame_status & FIRST_FRAG) {
1719 if(!(smc->os.hwm.tx_mb = smt_get_mbuf(smc))) {
1720 smc->hw.fp.err_stats.err_no_buf++ ;
1721 DB_TX("No SMbuf; transmit terminated",0,0,4) ;
1722 }
1723 else {
1724 smc->os.hwm.tx_data =
1725 smtod(smc->os.hwm.tx_mb,char *) - 1 ;
1726#ifdef USE_OS_CPY
1727#ifdef PASS_1ST_TXD_2_TX_COMP
1728 hwm_cpy_txd2mb(t,smc->os.hwm.tx_data,
1729 smc->os.hwm.tx_len) ;
1730#endif
1731#endif
1732 }
1733 }
1734 if (smc->os.hwm.tx_mb) {
1735#ifndef USE_OS_CPY
1736 DB_TX("copy fragment into MBuf ",0,0,3) ;
1737 memcpy(smc->os.hwm.tx_data,virt,len) ;
1738 smc->os.hwm.tx_data += len ;
1739#endif
1740 if (frame_status & LAST_FRAG) {
1741#ifdef USE_OS_CPY
1742#ifndef PASS_1ST_TXD_2_TX_COMP
1743 /*
1744 * hwm_cpy_txd2mb(txd,data,len) copies 'len'
1745 * bytes from the virtual pointer in 'rxd'
1746 * to 'data'. The virtual pointer of the
1747 * os-specific tx-buffer should be written
1748 * in the LAST txd.
1749 */
1750 hwm_cpy_txd2mb(t,smc->os.hwm.tx_data,
1751 smc->os.hwm.tx_len) ;
1752#endif /* nPASS_1ST_TXD_2_TX_COMP */
1753#endif /* USE_OS_CPY */
1754 smc->os.hwm.tx_data =
1755 smtod(smc->os.hwm.tx_mb,char *) - 1 ;
1756 *(char *)smc->os.hwm.tx_mb->sm_data =
1757 *smc->os.hwm.tx_data ;
1758 smc->os.hwm.tx_data++ ;
1759 smc->os.hwm.tx_mb->sm_len =
1760 smc->os.hwm.tx_len - 1 ;
1761 DB_TX("pass LLC frame to SMT ",0,0,3) ;
1762 smt_received_pack(smc,smc->os.hwm.tx_mb,
1763 RD_FS_LOCAL) ;
1764 }
1765 }
1766 }
1767 NDD_TRACE("THfE",t,queue->tx_free,0) ;
1768}
1769
1770
1771/*
1772 * queues a receive for later send
1773 */
1774static void queue_llc_rx(struct s_smc *smc, SMbuf *mb)
1775{
1776 DB_GEN("queue_llc_rx: mb = %x",(void *)mb,0,4) ;
1777 smc->os.hwm.queued_rx_frames++ ;
1778 mb->sm_next = (SMbuf *)NULL ;
1779 if (smc->os.hwm.llc_rx_pipe == 0) {
1780 smc->os.hwm.llc_rx_pipe = mb ;
1781 }
1782 else {
1783 smc->os.hwm.llc_rx_tail->sm_next = mb ;
1784 }
1785 smc->os.hwm.llc_rx_tail = mb ;
1786
1787 /*
1788 * force an timer IRQ to receive the data
1789 */
1790 if (!smc->os.hwm.isr_flag) {
1791 smt_force_irq(smc) ;
1792 }
1793}
1794
1795/*
1796 * get a SMbuf from the llc_rx_queue
1797 */
1798static SMbuf *get_llc_rx(struct s_smc *smc)
1799{
1800 SMbuf *mb ;
1801
1802 if ((mb = smc->os.hwm.llc_rx_pipe)) {
1803 smc->os.hwm.queued_rx_frames-- ;
1804 smc->os.hwm.llc_rx_pipe = mb->sm_next ;
1805 }
1806 DB_GEN("get_llc_rx: mb = 0x%x",(void *)mb,0,4) ;
1807 return(mb) ;
1808}
1809
1810/*
1811 * queues a transmit SMT MBuf during the time were the MBuf is
1812 * queued the TxD ring
1813 */
1814static void queue_txd_mb(struct s_smc *smc, SMbuf *mb)
1815{
1816 DB_GEN("_rx: queue_txd_mb = %x",(void *)mb,0,4) ;
1817 smc->os.hwm.queued_txd_mb++ ;
1818 mb->sm_next = (SMbuf *)NULL ;
1819 if (smc->os.hwm.txd_tx_pipe == 0) {
1820 smc->os.hwm.txd_tx_pipe = mb ;
1821 }
1822 else {
1823 smc->os.hwm.txd_tx_tail->sm_next = mb ;
1824 }
1825 smc->os.hwm.txd_tx_tail = mb ;
1826}
1827
1828/*
1829 * get a SMbuf from the txd_tx_queue
1830 */
1831static SMbuf *get_txd_mb(struct s_smc *smc)
1832{
1833 SMbuf *mb ;
1834
1835 if ((mb = smc->os.hwm.txd_tx_pipe)) {
1836 smc->os.hwm.queued_txd_mb-- ;
1837 smc->os.hwm.txd_tx_pipe = mb->sm_next ;
1838 }
1839 DB_GEN("get_txd_mb: mb = 0x%x",(void *)mb,0,4) ;
1840 return(mb) ;
1841}
1842
1843/*
1844 * SMT Send function
1845 */
1846void smt_send_mbuf(struct s_smc *smc, SMbuf *mb, int fc)
1847{
1848 char far *data ;
1849 int len ;
1850 int n ;
1851 int i ;
1852 int frag_count ;
1853 int frame_status ;
1854 SK_LOC_DECL(char far,*virt[3]) ;
1855 int frag_len[3] ;
1856 struct s_smt_tx_queue *queue ;
1857 struct s_smt_fp_txd volatile *t ;
1858 u_long phys ;
1859 u_int tbctrl ;
1860
1861 NDD_TRACE("THSB",mb,fc,0) ;
1862 DB_TX("smt_send_mbuf: mb = 0x%x, fc = 0x%x",mb,fc,4) ;
1863
1864 mb->sm_off-- ; /* set to fc */
1865 mb->sm_len++ ; /* + fc */
1866 data = smtod(mb,char *) ;
1867 *data = fc ;
1868 if (fc == FC_SMT_LOC)
1869 *data = FC_SMT_INFO ;
1870
1871 /*
1872 * determine the frag count and the virt addresses of the frags
1873 */
1874 frag_count = 0 ;
1875 len = mb->sm_len ;
1876 while (len) {
1877 n = SMT_PAGESIZE - ((long)data & (SMT_PAGESIZE-1)) ;
1878 if (n >= len) {
1879 n = len ;
1880 }
1881 DB_TX("frag: virt/len = 0x%x/%d ",(void *)data,n,5) ;
1882 virt[frag_count] = data ;
1883 frag_len[frag_count] = n ;
1884 frag_count++ ;
1885 len -= n ;
1886 data += n ;
1887 }
1888
1889 /*
1890 * determine the frame status
1891 */
1892 queue = smc->hw.fp.tx[QUEUE_A0] ;
1893 if (fc == FC_BEACON || fc == FC_SMT_LOC) {
1894 frame_status = LOC_TX ;
1895 }
1896 else {
1897 frame_status = LAN_TX ;
1898 if ((smc->os.hwm.pass_NSA &&(fc == FC_SMT_NSA)) ||
1899 (smc->os.hwm.pass_SMT &&(fc == FC_SMT_INFO)))
1900 frame_status |= LOC_TX ;
1901 }
1902
1903 if (!smc->hw.mac_ring_is_up || frag_count > queue->tx_free) {
1904 frame_status &= ~LAN_TX;
1905 if (frame_status) {
1906 DB_TX("Ring is down: terminate LAN_TX",0,0,2) ;
1907 }
1908 else {
1909 DB_TX("Ring is down: terminate transmission",0,0,2) ;
1910 smt_free_mbuf(smc,mb) ;
1911 return ;
1912 }
1913 }
1914 DB_TX("frame_status = 0x%x ",frame_status,0,5) ;
1915
1916 if ((frame_status & LAN_TX) && (frame_status & LOC_TX)) {
1917 mb->sm_use_count = 2 ;
1918 }
1919
1920 if (frame_status & LAN_TX) {
1921 t = queue->tx_curr_put ;
1922 frame_status |= FIRST_FRAG ;
1923 for (i = 0; i < frag_count; i++) {
1924 DB_TX("init TxD = 0x%x",(void *)t,0,5) ;
1925 if (i == frag_count-1) {
1926 frame_status |= LAST_FRAG ;
1927 t->txd_txdscr = AIX_REVERSE(TX_DESCRIPTOR |
1928 (((u_long)(mb->sm_len-1)&3) << 27)) ;
1929 }
1930 t->txd_virt = virt[i] ;
1931 phys = dma_master(smc, (void far *)virt[i],
1932 frag_len[i], DMA_RD|SMT_BUF) ;
1933 t->txd_tbadr = AIX_REVERSE(phys) ;
1934 tbctrl = AIX_REVERSE((((u_long) frame_status &
1935 (FIRST_FRAG|LAST_FRAG)) << 26) |
1936 BMU_OWN | BMU_CHECK | BMU_SMT_TX |frag_len[i]) ;
1937 t->txd_tbctrl = tbctrl ;
1938#ifndef AIX
1939 DRV_BUF_FLUSH(t,DDI_DMA_SYNC_FORDEV) ;
1940 outpd(queue->tx_bmu_ctl,CSR_START) ;
1941#else
1942 DRV_BUF_FLUSH(t,DDI_DMA_SYNC_FORDEV) ;
1943 outpd(ADDR(B0_XA_CSR),CSR_START) ;
1944#endif
1945 frame_status &= ~FIRST_FRAG ;
1946 queue->tx_curr_put = t = t->txd_next ;
1947 queue->tx_free-- ;
1948 queue->tx_used++ ;
1949 }
1950 smc->mib.m[MAC0].fddiMACTransmit_Ct++ ;
1951 queue_txd_mb(smc,mb) ;
1952 }
1953
1954 if (frame_status & LOC_TX) {
1955 DB_TX("pass Mbuf to LLC queue",0,0,5) ;
1956 queue_llc_rx(smc,mb) ;
1957 }
1958
1959 /*
1960 * We need to unqueue the free SMT_MBUFs here, because it may
1961 * be that the SMT want's to send more than 1 frame for one down call
1962 */
1963 mac_drv_clear_txd(smc) ;
1964 NDD_TRACE("THSE",t,queue->tx_free,frag_count) ;
1965}
1966
1967/* BEGIN_MANUAL_ENTRY(mac_drv_clear_txd)
1968 * void mac_drv_clear_txd(smc)
1969 *
1970 * function DOWNCALL (hardware module, hwmtm.c)
1971 * mac_drv_clear_txd searches in both send queues for TxD's
1972 * which were finished by the adapter. It calls dma_complete
1973 * for each TxD. If the last fragment of an LLC frame is
1974 * reached, it calls mac_drv_tx_complete to release the
1975 * send buffer.
1976 *
1977 * return nothing
1978 *
1979 * END_MANUAL_ENTRY
1980 */
1981void mac_drv_clear_txd(struct s_smc *smc)
1982{
1983 struct s_smt_tx_queue *queue ;
1984 struct s_smt_fp_txd volatile *t1 ;
1985 struct s_smt_fp_txd volatile *t2 = NULL ;
1986 SMbuf *mb ;
1987 u_long tbctrl ;
1988 int i ;
1989 int frag_count ;
1990 int n ;
1991
1992 NDD_TRACE("THcB",0,0,0) ;
1993 for (i = QUEUE_S; i <= QUEUE_A0; i++) {
1994 queue = smc->hw.fp.tx[i] ;
1995 t1 = queue->tx_curr_get ;
1996 DB_TX("clear_txd: QUEUE = %d (0=sync/1=async)",i,0,5) ;
1997
1998 for ( ; ; ) {
1999 frag_count = 0 ;
2000
2001 do {
2002 DRV_BUF_FLUSH(t1,DDI_DMA_SYNC_FORCPU) ;
2003 DB_TX("check OWN/EOF bit of TxD 0x%x",t1,0,5) ;
2004 tbctrl = CR_READ(t1->txd_tbctrl) ;
2005 tbctrl = AIX_REVERSE(tbctrl) ;
2006
2007 if (tbctrl & BMU_OWN || !queue->tx_used){
2008 DB_TX("End of TxDs queue %d",i,0,4) ;
2009 goto free_next_queue ; /* next queue */
2010 }
2011 t1 = t1->txd_next ;
2012 frag_count++ ;
2013 } while (!(tbctrl & BMU_EOF)) ;
2014
2015 t1 = queue->tx_curr_get ;
2016 for (n = frag_count; n; n--) {
2017 tbctrl = AIX_REVERSE(t1->txd_tbctrl) ;
2018 dma_complete(smc,
2019 (union s_fp_descr volatile *) t1,
2020 (int) (DMA_RD |
2021 ((tbctrl & BMU_SMT_TX) >> 18))) ;
2022 t2 = t1 ;
2023 t1 = t1->txd_next ;
2024 }
2025
2026 if (tbctrl & BMU_SMT_TX) {
2027 mb = get_txd_mb(smc) ;
2028 smt_free_mbuf(smc,mb) ;
2029 }
2030 else {
2031#ifndef PASS_1ST_TXD_2_TX_COMP
2032 DB_TX("mac_drv_tx_comp for TxD 0x%x",t2,0,4) ;
2033 mac_drv_tx_complete(smc,t2) ;
2034#else
2035 DB_TX("mac_drv_tx_comp for TxD 0x%x",
2036 queue->tx_curr_get,0,4) ;
2037 mac_drv_tx_complete(smc,queue->tx_curr_get) ;
2038#endif
2039 }
2040 queue->tx_curr_get = t1 ;
2041 queue->tx_free += frag_count ;
2042 queue->tx_used -= frag_count ;
2043 }
2044free_next_queue: ;
2045 }
2046 NDD_TRACE("THcE",0,0,0) ;
2047}
2048
2049/*
2050 * BEGINN_MANUAL_ENTRY(mac_drv_clear_tx_queue)
2051 *
2052 * void mac_drv_clear_tx_queue(smc)
2053 * struct s_smc *smc ;
2054 *
2055 * function DOWNCALL (hardware module, hwmtm.c)
2056 * mac_drv_clear_tx_queue is called from the SMT when
2057 * the RMT state machine has entered the ISOLATE state.
2058 * This function is also called by the os-specific module
2059 * after it has called the function card_stop().
2060 * In this case, the frames in the send queues are obsolete and
2061 * should be removed.
2062 *
2063 * note calling sequence:
2064 * CLI_FBI(), card_stop(),
2065 * mac_drv_clear_tx_queue(), mac_drv_clear_rx_queue(),
2066 *
2067 * NOTE: The caller is responsible that the BMUs are idle
2068 * when this function is called.
2069 *
2070 * END_MANUAL_ENTRY
2071 */
2072void mac_drv_clear_tx_queue(struct s_smc *smc)
2073{
2074 struct s_smt_fp_txd volatile *t ;
2075 struct s_smt_tx_queue *queue ;
2076 int tx_used ;
2077 int i ;
2078
2079 if (smc->hw.hw_state != STOPPED) {
2080 SK_BREAK() ;
2081 SMT_PANIC(smc,HWM_E0011,HWM_E0011_MSG) ;
2082 return ;
2083 }
2084
2085 for (i = QUEUE_S; i <= QUEUE_A0; i++) {
2086 queue = smc->hw.fp.tx[i] ;
2087 DB_TX("clear_tx_queue: QUEUE = %d (0=sync/1=async)",i,0,5) ;
2088
2089 /*
2090 * switch the OWN bit of all pending frames to the host
2091 */
2092 t = queue->tx_curr_get ;
2093 tx_used = queue->tx_used ;
2094 while (tx_used) {
2095 DRV_BUF_FLUSH(t,DDI_DMA_SYNC_FORCPU) ;
2096 DB_TX("switch OWN bit of TxD 0x%x ",t,0,5) ;
2097 t->txd_tbctrl &= AIX_REVERSE(~BMU_OWN) ;
2098 DRV_BUF_FLUSH(t,DDI_DMA_SYNC_FORDEV) ;
2099 t = t->txd_next ;
2100 tx_used-- ;
2101 }
2102 }
2103
2104 /*
2105 * release all TxD's for both send queues
2106 */
2107 mac_drv_clear_txd(smc) ;
2108
2109 for (i = QUEUE_S; i <= QUEUE_A0; i++) {
2110 queue = smc->hw.fp.tx[i] ;
2111 t = queue->tx_curr_get ;
2112
2113 /*
2114 * write the phys pointer of the NEXT descriptor into the
2115 * BMU's current address descriptor pointer and set
2116 * tx_curr_get and tx_curr_put to this position
2117 */
2118 if (i == QUEUE_S) {
2119 outpd(ADDR(B5_XS_DA),AIX_REVERSE(t->txd_ntdadr)) ;
2120 }
2121 else {
2122 outpd(ADDR(B5_XA_DA),AIX_REVERSE(t->txd_ntdadr)) ;
2123 }
2124
2125 queue->tx_curr_put = queue->tx_curr_get->txd_next ;
2126 queue->tx_curr_get = queue->tx_curr_put ;
2127 }
2128}
2129
2130
2131/*
2132 -------------------------------------------------------------
2133 TEST FUNCTIONS:
2134 -------------------------------------------------------------
2135*/
2136
2137#ifdef DEBUG
2138/*
2139 * BEGIN_MANUAL_ENTRY(mac_drv_debug_lev)
2140 * void mac_drv_debug_lev(smc,flag,lev)
2141 *
2142 * function DOWNCALL (drvsr.c)
2143 * To get a special debug info the user can assign a debug level
2144 * to any debug flag.
2145 *
2146 * para flag debug flag, possible values are:
2147 * = 0: reset all debug flags (the defined level is
2148 * ignored)
2149 * = 1: debug.d_smtf
2150 * = 2: debug.d_smt
2151 * = 3: debug.d_ecm
2152 * = 4: debug.d_rmt
2153 * = 5: debug.d_cfm
2154 * = 6: debug.d_pcm
2155 *
2156 * = 10: debug.d_os.hwm_rx (hardware module receive path)
2157 * = 11: debug.d_os.hwm_tx(hardware module transmit path)
2158 * = 12: debug.d_os.hwm_gen(hardware module general flag)
2159 *
2160 * lev debug level
2161 *
2162 * END_MANUAL_ENTRY
2163 */
2164void mac_drv_debug_lev(struct s_smc *smc, int flag, int lev)
2165{
2166 switch(flag) {
2167 case (int)NULL:
2168 DB_P.d_smtf = DB_P.d_smt = DB_P.d_ecm = DB_P.d_rmt = 0 ;
2169 DB_P.d_cfm = 0 ;
2170 DB_P.d_os.hwm_rx = DB_P.d_os.hwm_tx = DB_P.d_os.hwm_gen = 0 ;
2171#ifdef SBA
2172 DB_P.d_sba = 0 ;
2173#endif
2174#ifdef ESS
2175 DB_P.d_ess = 0 ;
2176#endif
2177 break ;
2178 case DEBUG_SMTF:
2179 DB_P.d_smtf = lev ;
2180 break ;
2181 case DEBUG_SMT:
2182 DB_P.d_smt = lev ;
2183 break ;
2184 case DEBUG_ECM:
2185 DB_P.d_ecm = lev ;
2186 break ;
2187 case DEBUG_RMT:
2188 DB_P.d_rmt = lev ;
2189 break ;
2190 case DEBUG_CFM:
2191 DB_P.d_cfm = lev ;
2192 break ;
2193 case DEBUG_PCM:
2194 DB_P.d_pcm = lev ;
2195 break ;
2196 case DEBUG_SBA:
2197#ifdef SBA
2198 DB_P.d_sba = lev ;
2199#endif
2200 break ;
2201 case DEBUG_ESS:
2202#ifdef ESS
2203 DB_P.d_ess = lev ;
2204#endif
2205 break ;
2206 case DB_HWM_RX:
2207 DB_P.d_os.hwm_rx = lev ;
2208 break ;
2209 case DB_HWM_TX:
2210 DB_P.d_os.hwm_tx = lev ;
2211 break ;
2212 case DB_HWM_GEN:
2213 DB_P.d_os.hwm_gen = lev ;
2214 break ;
2215 default:
2216 break ;
2217 }
2218}
2219#endif
diff --git a/drivers/net/skfp/hwt.c b/drivers/net/skfp/hwt.c
new file mode 100644
index 000000000000..e01f8a0f35c6
--- /dev/null
+++ b/drivers/net/skfp/hwt.c
@@ -0,0 +1,305 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * See the file "skfddi.c" for further information.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * The information in this file is provided "AS IS" without warranty.
14 *
15 ******************************************************************************/
16
17/*
18 * Timer Driver for FBI board (timer chip 82C54)
19 */
20
21/*
22 * Modifications:
23 *
24 * 28-Jun-1994 sw Edit v1.6.
25 * MCA: Added support for the SK-NET FDDI-FM2 adapter. The
26 * following functions have been added(+) or modified(*):
27 * hwt_start(*), hwt_stop(*), hwt_restart(*), hwt_read(*)
28 */
29
30#include "h/types.h"
31#include "h/fddi.h"
32#include "h/smc.h"
33
34#ifndef lint
35static const char ID_sccs[] = "@(#)hwt.c 1.13 97/04/23 (C) SK " ;
36#endif
37
38/*
39 * Prototypes of local functions.
40 */
41/* 28-Jun-1994 sw - Note: hwt_restart() is also used in module 'drvfbi.c'. */
42/*static void hwt_restart() ; */
43
44/************************
45 *
46 * hwt_start
47 *
48 * Start hardware timer (clock ticks are 16us).
49 *
50 * void hwt_start(
51 * struct s_smc *smc,
52 * u_long time) ;
53 * In
54 * smc - A pointer to the SMT Context structure.
55 *
56 * time - The time in units of 16us to load the timer with.
57 * Out
58 * Nothing.
59 *
60 ************************/
61#define HWT_MAX (65000)
62
63void hwt_start(struct s_smc *smc, u_long time)
64{
65 u_short cnt ;
66
67 if (time > HWT_MAX)
68 time = HWT_MAX ;
69
70 smc->hw.t_start = time ;
71 smc->hw.t_stop = 0L ;
72
73 cnt = (u_short)time ;
74 /*
75 * if time < 16 us
76 * time = 16 us
77 */
78 if (!cnt)
79 cnt++ ;
80#ifndef PCI
81 /*
82 * 6.25MHz -> CLK0 : T0 (cnt0 = 16us) -> OUT0
83 * OUT0 -> CLK1 : T1 (cnt1) OUT1 -> ISRA(IS_TIMINT)
84 */
85 OUT_82c54_TIMER(3,1<<6 | 3<<4 | 0<<1) ; /* counter 1, mode 0 */
86 OUT_82c54_TIMER(1,cnt & 0xff) ; /* LSB */
87 OUT_82c54_TIMER(1,(cnt>>8) & 0xff) ; /* MSB */
88 /*
89 * start timer by switching counter 0 to mode 3
90 * T0 resolution 16 us (CLK0=0.16us)
91 */
92 OUT_82c54_TIMER(3,0<<6 | 3<<4 | 3<<1) ; /* counter 0, mode 3 */
93 OUT_82c54_TIMER(0,100) ; /* LSB */
94 OUT_82c54_TIMER(0,0) ; /* MSB */
95#else /* PCI */
96 outpd(ADDR(B2_TI_INI), (u_long) cnt * 200) ; /* Load timer value. */
97 outpw(ADDR(B2_TI_CRTL), TIM_START) ; /* Start timer. */
98#endif /* PCI */
99 smc->hw.timer_activ = TRUE ;
100}
101
102/************************
103 *
104 * hwt_stop
105 *
106 * Stop hardware timer.
107 *
108 * void hwt_stop(
109 * struct s_smc *smc) ;
110 * In
111 * smc - A pointer to the SMT Context structure.
112 * Out
113 * Nothing.
114 *
115 ************************/
116void hwt_stop(struct s_smc *smc)
117{
118#ifndef PCI
119 /* stop counter 0 by switching to mode 0 */
120 OUT_82c54_TIMER(3,0<<6 | 3<<4 | 0<<1) ; /* counter 0, mode 0 */
121 OUT_82c54_TIMER(0,0) ; /* LSB */
122 OUT_82c54_TIMER(0,0) ; /* MSB */
123#else /* PCI */
124 outpw(ADDR(B2_TI_CRTL), TIM_STOP) ;
125 outpw(ADDR(B2_TI_CRTL), TIM_CL_IRQ) ;
126#endif /* PCI */
127
128 smc->hw.timer_activ = FALSE ;
129}
130
131/************************
132 *
133 * hwt_init
134 *
135 * Initialize hardware timer.
136 *
137 * void hwt_init(
138 * struct s_smc *smc) ;
139 * In
140 * smc - A pointer to the SMT Context structure.
141 * Out
142 * Nothing.
143 *
144 ************************/
145void hwt_init(struct s_smc *smc)
146{
147 smc->hw.t_start = 0 ;
148 smc->hw.t_stop = 0 ;
149 smc->hw.timer_activ = FALSE ;
150
151 hwt_restart(smc) ;
152}
153
154/************************
155 *
156 * hwt_restart
157 *
158 * Clear timer interrupt.
159 *
160 * void hwt_restart(
161 * struct s_smc *smc) ;
162 * In
163 * smc - A pointer to the SMT Context structure.
164 * Out
165 * Nothing.
166 *
167 ************************/
168void hwt_restart(struct s_smc *smc)
169{
170 hwt_stop(smc) ;
171#ifndef PCI
172 OUT_82c54_TIMER(3,1<<6 | 3<<4 | 0<<1) ; /* counter 1, mode 0 */
173 OUT_82c54_TIMER(1,1 ) ; /* LSB */
174 OUT_82c54_TIMER(1,0 ) ; /* MSB */
175#endif
176}
177
178/************************
179 *
180 * hwt_read
181 *
182 * Stop hardware timer and read time elapsed since last start.
183 *
184 * u_long hwt_read(smc) ;
185 * In
186 * smc - A pointer to the SMT Context structure.
187 * Out
188 * The elapsed time since last start in units of 16us.
189 *
190 ************************/
191u_long hwt_read(struct s_smc *smc)
192{
193 u_short tr ;
194#ifndef PCI
195 u_short is ;
196#else
197 u_long is ;
198#endif
199
200 if (smc->hw.timer_activ) {
201 hwt_stop(smc) ;
202#ifndef PCI
203 OUT_82c54_TIMER(3,1<<6) ; /* latch command */
204 tr = IN_82c54_TIMER(1) & 0xff ;
205 tr += (IN_82c54_TIMER(1) & 0xff)<<8 ;
206#else /* PCI */
207 tr = (u_short)((inpd(ADDR(B2_TI_VAL))/200) & 0xffff) ;
208#endif /* PCI */
209 is = GET_ISR() ;
210 /* Check if timer expired (or wraparound). */
211 if ((tr > smc->hw.t_start) || (is & IS_TIMINT)) {
212 hwt_restart(smc) ;
213 smc->hw.t_stop = smc->hw.t_start ;
214 }
215 else
216 smc->hw.t_stop = smc->hw.t_start - tr ;
217 }
218 return (smc->hw.t_stop) ;
219}
220
221#ifdef PCI
222/************************
223 *
224 * hwt_quick_read
225 *
226 * Stop hardware timer and read timer value and start the timer again.
227 *
228 * u_long hwt_read(smc) ;
229 * In
230 * smc - A pointer to the SMT Context structure.
231 * Out
232 * current timer value in units of 80ns.
233 *
234 ************************/
235u_long hwt_quick_read(struct s_smc *smc)
236{
237 u_long interval ;
238 u_long time ;
239
240 interval = inpd(ADDR(B2_TI_INI)) ;
241 outpw(ADDR(B2_TI_CRTL), TIM_STOP) ;
242 time = inpd(ADDR(B2_TI_VAL)) ;
243 outpd(ADDR(B2_TI_INI),time) ;
244 outpw(ADDR(B2_TI_CRTL), TIM_START) ;
245 outpd(ADDR(B2_TI_INI),interval) ;
246
247 return(time) ;
248}
249
250/************************
251 *
252 * hwt_wait_time(smc,start,duration)
253 *
254 * This function returnes after the amount of time is elapsed
255 * since the start time.
256 *
257 * para start start time
258 * duration time to wait
259 *
260 * NOTE: The fuction will return immediately, if the timer is not
261 * started
262 ************************/
263void hwt_wait_time(struct s_smc *smc, u_long start, long int duration)
264{
265 long diff ;
266 long interval ;
267 int wrapped ;
268
269 /*
270 * check if timer is running
271 */
272 if (smc->hw.timer_activ == FALSE ||
273 hwt_quick_read(smc) == hwt_quick_read(smc)) {
274 return ;
275 }
276
277 interval = inpd(ADDR(B2_TI_INI)) ;
278 if (interval > duration) {
279 do {
280 diff = (long)(start - hwt_quick_read(smc)) ;
281 if (diff < 0) {
282 diff += interval ;
283 }
284 } while (diff <= duration) ;
285 }
286 else {
287 diff = interval ;
288 wrapped = 0 ;
289 do {
290 if (!wrapped) {
291 if (hwt_quick_read(smc) >= start) {
292 diff += interval ;
293 wrapped = 1 ;
294 }
295 }
296 else {
297 if (hwt_quick_read(smc) < start) {
298 wrapped = 0 ;
299 }
300 }
301 } while (diff <= duration) ;
302 }
303}
304#endif
305
diff --git a/drivers/net/skfp/lnkstat.c b/drivers/net/skfp/lnkstat.c
new file mode 100644
index 000000000000..00a248044f86
--- /dev/null
+++ b/drivers/net/skfp/lnkstat.c
@@ -0,0 +1,204 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * See the file "skfddi.c" for further information.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * The information in this file is provided "AS IS" without warranty.
14 *
15 ******************************************************************************/
16
17/*
18 IBM FDDI read error log function
19*/
20
21#include "h/types.h"
22#include "h/fddi.h"
23#include "h/smc.h"
24#include "h/lnkstat.h"
25
26#ifndef lint
27static const char ID_sccs[] = "@(#)lnkstat.c 1.8 97/04/11 (C) SK " ;
28#endif
29
30#ifdef sun
31#define _far
32#endif
33
34#define EL_IS_OK(x,l) ((((int)&(((struct s_error_log *)0)->x)) + \
35 sizeof(er->x)) <= l)
36
37/*
38 BEGIN_MANUAL_ENTRY(if,func;others;11)
39
40 u_long smt_get_error_word(smc)
41 struct s_smc *smc ;
42
43Function DOWNCALL (SMT, lnkstat.c)
44 This functions returns the SMT error work for AIX events.
45
46Return smt_error_word These bits are supported:
47
48 SMT_ERL_ALC == [PS/PA].fddiPORTLerFlag
49 SMT_ERL_BLC == [PB].fddiPORTLerFlag
50 SMT_ERL_NCC == fddiMACNotCopiedFlag
51 SMT_ERL_FEC == fddiMACFrameErrorFlag
52
53 END_MANUAL_ENTRY()
54 */
55u_long smt_get_error_word(struct s_smc *smc)
56{
57 u_long st;
58
59 /*
60 * smt error word low
61 */
62 st = 0 ;
63 if (smc->s.sas == SMT_SAS) {
64 if (smc->mib.p[PS].fddiPORTLerFlag)
65 st |= SMT_ERL_ALC ;
66 }
67 else {
68 if (smc->mib.p[PA].fddiPORTLerFlag)
69 st |= SMT_ERL_ALC ;
70 if (smc->mib.p[PB].fddiPORTLerFlag)
71 st |= SMT_ERL_BLC ;
72 }
73 if (smc->mib.m[MAC0].fddiMACNotCopiedFlag)
74 st |= SMT_ERL_NCC ; /* not copied condition */
75 if (smc->mib.m[MAC0].fddiMACFrameErrorFlag)
76 st |= SMT_ERL_FEC ; /* frame error condition */
77
78 return st;
79}
80
81/*
82 BEGIN_MANUAL_ENTRY(if,func;others;11)
83
84 u_long smt_get_event_word(smc)
85 struct s_smc *smc ;
86
87Function DOWNCALL (SMT, lnkstat.c)
88 This functions returns the SMT event work for AIX events.
89
90Return smt_event_word always 0
91
92 END_MANUAL_ENTRY()
93 */
94u_long smt_get_event_word(struct s_smc *smc)
95{
96 return (u_long) 0;
97}
98
99/*
100 BEGIN_MANUAL_ENTRY(if,func;others;11)
101
102 u_long smt_get_port_event_word(smc)
103 struct s_smc *smc ;
104
105Function DOWNCALL (SMT, lnkstat.c)
106 This functions returns the SMT port event work for AIX events.
107
108Return smt_port_event_word always 0
109
110 END_MANUAL_ENTRY()
111 */
112u_long smt_get_port_event_word(struct s_smc *smc)
113{
114 return (u_long) 0;
115}
116
117/*
118 BEGIN_MANUAL_ENTRY(if,func;others;11)
119
120 u_long smt_read_errorlog(smc,p,len)
121 struct s_smc *smc ;
122 char _far *p ;
123 int len ;
124
125Function DOWNCALL (SMT, lnkstat.c)
126 This functions returns the SMT error log field for AIX events.
127
128Para p pointer to the error log field
129 len len of the error log field
130
131Return len used len of the error log field
132
133 END_MANUAL_ENTRY()
134 */
135int smt_read_errorlog(struct s_smc *smc, char _far *p, int len)
136{
137 int i ;
138 int st ;
139 struct s_error_log _far *er ;
140
141 er = (struct s_error_log _far *) p ;
142 if (len > sizeof(struct s_error_log))
143 len = sizeof(struct s_error_log) ;
144 for (i = 0 ; i < len ; i++)
145 *p++ = 0 ;
146 /*
147 * set count
148 */
149 if (EL_IS_OK(set_count_high,len)) {
150 er->set_count_low = (u_short)smc->mib.fddiSMTSetCount.count ;
151 er->set_count_high =
152 (u_short)(smc->mib.fddiSMTSetCount.count >> 16L) ;
153 }
154 /*
155 * aci
156 */
157 if (EL_IS_OK(aci_id_code,len)) {
158 er->aci_id_code = 0 ;
159 }
160 /*
161 * purge counter is missed frames; 16 bits only
162 */
163 if (EL_IS_OK(purge_frame_counter,len)) {
164 if (smc->mib.m[MAC0].fddiMACCopied_Ct > 0xffff)
165 er->purge_frame_counter = 0xffff ;
166 else
167 er->purge_frame_counter =
168 (u_short)smc->mib.m[MAC0].fddiMACCopied_Ct ;
169 }
170 /*
171 * CMT and RMT state machines
172 */
173 if (EL_IS_OK(ecm_state,len))
174 er->ecm_state = smc->mib.fddiSMTECMState ;
175
176 if (EL_IS_OK(pcm_b_state,len)) {
177 if (smc->s.sas == SMT_SAS) {
178 er->pcm_a_state = smc->y[PS].mib->fddiPORTPCMState ;
179 er->pcm_b_state = 0 ;
180 }
181 else {
182 er->pcm_a_state = smc->y[PA].mib->fddiPORTPCMState ;
183 er->pcm_b_state = smc->y[PB].mib->fddiPORTPCMState ;
184 }
185 }
186 if (EL_IS_OK(cfm_state,len))
187 er->cfm_state = smc->mib.fddiSMTCF_State ;
188 if (EL_IS_OK(rmt_state,len))
189 er->rmt_state = smc->mib.m[MAC0].fddiMACRMTState ;
190
191 /*
192 * smt error word low (we only need the low order 16 bits.)
193 */
194
195 st = smt_get_error_word(smc) & 0xffff ;
196
197 if (EL_IS_OK(smt_error_low,len))
198 er->smt_error_low = st ;
199
200 if (EL_IS_OK(ucode_version_level,len))
201 er->ucode_version_level = 0x0101 ;
202 return(len) ;
203}
204
diff --git a/drivers/net/skfp/pcmplc.c b/drivers/net/skfp/pcmplc.c
new file mode 100644
index 000000000000..571f055c096b
--- /dev/null
+++ b/drivers/net/skfp/pcmplc.c
@@ -0,0 +1,2024 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * See the file "skfddi.c" for further information.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * The information in this file is provided "AS IS" without warranty.
14 *
15 ******************************************************************************/
16
17/*
18 PCM
19 Physical Connection Management
20*/
21
22/*
23 * Hardware independent state machine implemantation
24 * The following external SMT functions are referenced :
25 *
26 * queue_event()
27 * smt_timer_start()
28 * smt_timer_stop()
29 *
30 * The following external HW dependent functions are referenced :
31 * sm_pm_control()
32 * sm_ph_linestate()
33 * sm_pm_ls_latch()
34 *
35 * The following HW dependent events are required :
36 * PC_QLS
37 * PC_ILS
38 * PC_HLS
39 * PC_MLS
40 * PC_NSE
41 * PC_LEM
42 *
43 */
44
45
46#include "h/types.h"
47#include "h/fddi.h"
48#include "h/smc.h"
49#include "h/supern_2.h"
50#define KERNEL
51#include "h/smtstate.h"
52
53#ifndef lint
54static const char ID_sccs[] = "@(#)pcmplc.c 2.55 99/08/05 (C) SK " ;
55#endif
56
57#ifdef FDDI_MIB
58extern int snmp_fddi_trap(
59#ifdef ANSIC
60struct s_smc * smc, int type, int index
61#endif
62);
63#endif
64#ifdef CONCENTRATOR
65extern int plc_is_installed(
66#ifdef ANSIC
67struct s_smc *smc ,
68int p
69#endif
70) ;
71#endif
72/*
73 * FSM Macros
74 */
75#define AFLAG (0x20)
76#define GO_STATE(x) (mib->fddiPORTPCMState = (x)|AFLAG)
77#define ACTIONS_DONE() (mib->fddiPORTPCMState &= ~AFLAG)
78#define ACTIONS(x) (x|AFLAG)
79
80/*
81 * PCM states
82 */
83#define PC0_OFF 0
84#define PC1_BREAK 1
85#define PC2_TRACE 2
86#define PC3_CONNECT 3
87#define PC4_NEXT 4
88#define PC5_SIGNAL 5
89#define PC6_JOIN 6
90#define PC7_VERIFY 7
91#define PC8_ACTIVE 8
92#define PC9_MAINT 9
93
94#ifdef DEBUG
95/*
96 * symbolic state names
97 */
98static const char * const pcm_states[] = {
99 "PC0_OFF","PC1_BREAK","PC2_TRACE","PC3_CONNECT","PC4_NEXT",
100 "PC5_SIGNAL","PC6_JOIN","PC7_VERIFY","PC8_ACTIVE","PC9_MAINT"
101} ;
102
103/*
104 * symbolic event names
105 */
106static const char * const pcm_events[] = {
107 "NONE","PC_START","PC_STOP","PC_LOOP","PC_JOIN","PC_SIGNAL",
108 "PC_REJECT","PC_MAINT","PC_TRACE","PC_PDR",
109 "PC_ENABLE","PC_DISABLE",
110 "PC_QLS","PC_ILS","PC_MLS","PC_HLS","PC_LS_PDR","PC_LS_NONE",
111 "PC_TIMEOUT_TB_MAX","PC_TIMEOUT_TB_MIN",
112 "PC_TIMEOUT_C_MIN","PC_TIMEOUT_T_OUT",
113 "PC_TIMEOUT_TL_MIN","PC_TIMEOUT_T_NEXT","PC_TIMEOUT_LCT",
114 "PC_NSE","PC_LEM"
115} ;
116#endif
117
118#ifdef MOT_ELM
119/*
120 * PCL-S control register
121 * this register in the PLC-S controls the scrambling parameters
122 */
123#define PLCS_CONTROL_C_U 0
124#define PLCS_CONTROL_C_S (PL_C_SDOFF_ENABLE | PL_C_SDON_ENABLE | \
125 PL_C_CIPHER_ENABLE)
126#define PLCS_FASSERT_U 0
127#define PLCS_FASSERT_S 0xFd76 /* 52.0 us */
128#define PLCS_FDEASSERT_U 0
129#define PLCS_FDEASSERT_S 0
130#else /* nMOT_ELM */
131/*
132 * PCL-S control register
133 * this register in the PLC-S controls the scrambling parameters
134 * can be patched for ANSI compliance if standard changes
135 */
136static const u_char plcs_control_c_u[17] = "PLC_CNTRL_C_U=\0\0" ;
137static const u_char plcs_control_c_s[17] = "PLC_CNTRL_C_S=\01\02" ;
138
139#define PLCS_CONTROL_C_U (plcs_control_c_u[14] | (plcs_control_c_u[15]<<8))
140#define PLCS_CONTROL_C_S (plcs_control_c_s[14] | (plcs_control_c_s[15]<<8))
141#endif /* nMOT_ELM */
142
143/*
144 * external vars
145 */
146/* struct definition see 'cmtdef.h' (also used by CFM) */
147
148#define PS_OFF 0
149#define PS_BIT3 1
150#define PS_BIT4 2
151#define PS_BIT7 3
152#define PS_LCT 4
153#define PS_BIT8 5
154#define PS_JOIN 6
155#define PS_ACTIVE 7
156
157#define LCT_LEM_MAX 255
158
159/*
160 * PLC timing parameter
161 */
162
163#define PLC_MS(m) ((int)((0x10000L-(m*100000L/2048))))
164#define SLOW_TL_MIN PLC_MS(6)
165#define SLOW_C_MIN PLC_MS(10)
166
167static const struct plt {
168 int timer ; /* relative plc timer address */
169 int para ; /* default timing parameters */
170} pltm[] = {
171 { PL_C_MIN, SLOW_C_MIN }, /* min t. to remain Connect State */
172 { PL_TL_MIN, SLOW_TL_MIN }, /* min t. to transmit a Line State */
173 { PL_TB_MIN, TP_TB_MIN }, /* min break time */
174 { PL_T_OUT, TP_T_OUT }, /* Signaling timeout */
175 { PL_LC_LENGTH, TP_LC_LENGTH }, /* Link Confidence Test Time */
176 { PL_T_SCRUB, TP_T_SCRUB }, /* Scrub Time == MAC TVX time ! */
177 { PL_NS_MAX, TP_NS_MAX }, /* max t. that noise is tolerated */
178 { 0,0 }
179} ;
180
181/*
182 * interrupt mask
183 */
184#ifdef SUPERNET_3
185/*
186 * Do we need the EBUF error during signaling, too, to detect SUPERNET_3
187 * PLL bug?
188 */
189static int plc_imsk_na = PL_PCM_CODE | PL_TRACE_PROP | PL_PCM_BREAK |
190 PL_PCM_ENABLED | PL_SELF_TEST | PL_EBUF_ERR;
191#else /* SUPERNET_3 */
192/*
193 * We do NOT need the elasticity buffer error during signaling.
194 */
195static int plc_imsk_na = PL_PCM_CODE | PL_TRACE_PROP | PL_PCM_BREAK |
196 PL_PCM_ENABLED | PL_SELF_TEST ;
197#endif /* SUPERNET_3 */
198static int plc_imsk_act = PL_PCM_CODE | PL_TRACE_PROP | PL_PCM_BREAK |
199 PL_PCM_ENABLED | PL_SELF_TEST | PL_EBUF_ERR;
200
201/* external functions */
202void all_selection_criteria(struct s_smc *smc);
203
204/* internal functions */
205static void pcm_fsm(struct s_smc *smc, struct s_phy *phy, int cmd);
206static void pc_rcode_actions(struct s_smc *smc, int bit, struct s_phy *phy);
207static void pc_tcode_actions(struct s_smc *smc, const int bit, struct s_phy *phy);
208static void reset_lem_struct(struct s_phy *phy);
209static void plc_init(struct s_smc *smc, int p);
210static void sm_ph_lem_start(struct s_smc *smc, int np, int threshold);
211static void sm_ph_lem_stop(struct s_smc *smc, int np);
212static void sm_ph_linestate(struct s_smc *smc, int phy, int ls);
213static void real_init_plc(struct s_smc *smc);
214
215/*
216 * SMT timer interface
217 * start PCM timer 0
218 */
219static void start_pcm_timer0(struct s_smc *smc, u_long value, int event,
220 struct s_phy *phy)
221{
222 phy->timer0_exp = FALSE ; /* clear timer event flag */
223 smt_timer_start(smc,&phy->pcm_timer0,value,
224 EV_TOKEN(EVENT_PCM+phy->np,event)) ;
225}
226/*
227 * SMT timer interface
228 * stop PCM timer 0
229 */
230static void stop_pcm_timer0(struct s_smc *smc, struct s_phy *phy)
231{
232 if (phy->pcm_timer0.tm_active)
233 smt_timer_stop(smc,&phy->pcm_timer0) ;
234}
235
236/*
237 init PCM state machine (called by driver)
238 clear all PCM vars and flags
239*/
240void pcm_init(struct s_smc *smc)
241{
242 int i ;
243 int np ;
244 struct s_phy *phy ;
245 struct fddi_mib_p *mib ;
246
247 for (np = 0,phy = smc->y ; np < NUMPHYS ; np++,phy++) {
248 /* Indicates the type of PHY being used */
249 mib = phy->mib ;
250 mib->fddiPORTPCMState = ACTIONS(PC0_OFF) ;
251 phy->np = np ;
252 switch (smc->s.sas) {
253#ifdef CONCENTRATOR
254 case SMT_SAS :
255 mib->fddiPORTMy_Type = (np == PS) ? TS : TM ;
256 break ;
257 case SMT_DAS :
258 mib->fddiPORTMy_Type = (np == PA) ? TA :
259 (np == PB) ? TB : TM ;
260 break ;
261 case SMT_NAC :
262 mib->fddiPORTMy_Type = TM ;
263 break;
264#else
265 case SMT_SAS :
266 mib->fddiPORTMy_Type = (np == PS) ? TS : TNONE ;
267 mib->fddiPORTHardwarePresent = (np == PS) ? TRUE :
268 FALSE ;
269#ifndef SUPERNET_3
270 smc->y[PA].mib->fddiPORTPCMState = PC0_OFF ;
271#else
272 smc->y[PB].mib->fddiPORTPCMState = PC0_OFF ;
273#endif
274 break ;
275 case SMT_DAS :
276 mib->fddiPORTMy_Type = (np == PB) ? TB : TA ;
277 break ;
278#endif
279 }
280 /*
281 * set PMD-type
282 */
283 phy->pmd_scramble = 0 ;
284 switch (phy->pmd_type[PMD_SK_PMD]) {
285 case 'P' :
286 mib->fddiPORTPMDClass = MIB_PMDCLASS_MULTI ;
287 break ;
288 case 'L' :
289 mib->fddiPORTPMDClass = MIB_PMDCLASS_LCF ;
290 break ;
291 case 'D' :
292 mib->fddiPORTPMDClass = MIB_PMDCLASS_TP ;
293 break ;
294 case 'S' :
295 mib->fddiPORTPMDClass = MIB_PMDCLASS_TP ;
296 phy->pmd_scramble = TRUE ;
297 break ;
298 case 'U' :
299 mib->fddiPORTPMDClass = MIB_PMDCLASS_TP ;
300 phy->pmd_scramble = TRUE ;
301 break ;
302 case '1' :
303 mib->fddiPORTPMDClass = MIB_PMDCLASS_SINGLE1 ;
304 break ;
305 case '2' :
306 mib->fddiPORTPMDClass = MIB_PMDCLASS_SINGLE2 ;
307 break ;
308 case '3' :
309 mib->fddiPORTPMDClass = MIB_PMDCLASS_SINGLE2 ;
310 break ;
311 case '4' :
312 mib->fddiPORTPMDClass = MIB_PMDCLASS_SINGLE1 ;
313 break ;
314 case 'H' :
315 mib->fddiPORTPMDClass = MIB_PMDCLASS_UNKNOWN ;
316 break ;
317 case 'I' :
318 mib->fddiPORTPMDClass = MIB_PMDCLASS_TP ;
319 break ;
320 case 'G' :
321 mib->fddiPORTPMDClass = MIB_PMDCLASS_TP ;
322 break ;
323 default:
324 mib->fddiPORTPMDClass = MIB_PMDCLASS_UNKNOWN ;
325 break ;
326 }
327 /*
328 * A and B port can be on primary and secondary path
329 */
330 switch (mib->fddiPORTMy_Type) {
331 case TA :
332 mib->fddiPORTAvailablePaths |= MIB_PATH_S ;
333 mib->fddiPORTRequestedPaths[1] = MIB_P_PATH_LOCAL ;
334 mib->fddiPORTRequestedPaths[2] =
335 MIB_P_PATH_LOCAL |
336 MIB_P_PATH_CON_ALTER |
337 MIB_P_PATH_SEC_PREFER ;
338 mib->fddiPORTRequestedPaths[3] =
339 MIB_P_PATH_LOCAL |
340 MIB_P_PATH_CON_ALTER |
341 MIB_P_PATH_SEC_PREFER |
342 MIB_P_PATH_THRU ;
343 break ;
344 case TB :
345 mib->fddiPORTAvailablePaths |= MIB_PATH_S ;
346 mib->fddiPORTRequestedPaths[1] = MIB_P_PATH_LOCAL ;
347 mib->fddiPORTRequestedPaths[2] =
348 MIB_P_PATH_LOCAL |
349 MIB_P_PATH_PRIM_PREFER ;
350 mib->fddiPORTRequestedPaths[3] =
351 MIB_P_PATH_LOCAL |
352 MIB_P_PATH_PRIM_PREFER |
353 MIB_P_PATH_CON_PREFER |
354 MIB_P_PATH_THRU ;
355 break ;
356 case TS :
357 mib->fddiPORTAvailablePaths |= MIB_PATH_S ;
358 mib->fddiPORTRequestedPaths[1] = MIB_P_PATH_LOCAL ;
359 mib->fddiPORTRequestedPaths[2] =
360 MIB_P_PATH_LOCAL |
361 MIB_P_PATH_CON_ALTER |
362 MIB_P_PATH_PRIM_PREFER ;
363 mib->fddiPORTRequestedPaths[3] =
364 MIB_P_PATH_LOCAL |
365 MIB_P_PATH_CON_ALTER |
366 MIB_P_PATH_PRIM_PREFER ;
367 break ;
368 case TM :
369 mib->fddiPORTRequestedPaths[1] = MIB_P_PATH_LOCAL ;
370 mib->fddiPORTRequestedPaths[2] =
371 MIB_P_PATH_LOCAL |
372 MIB_P_PATH_SEC_ALTER |
373 MIB_P_PATH_PRIM_ALTER ;
374 mib->fddiPORTRequestedPaths[3] = 0 ;
375 break ;
376 }
377
378 phy->pc_lem_fail = FALSE ;
379 mib->fddiPORTPCMStateX = mib->fddiPORTPCMState ;
380 mib->fddiPORTLCTFail_Ct = 0 ;
381 mib->fddiPORTBS_Flag = 0 ;
382 mib->fddiPORTCurrentPath = MIB_PATH_ISOLATED ;
383 mib->fddiPORTNeighborType = TNONE ;
384 phy->ls_flag = 0 ;
385 phy->rc_flag = 0 ;
386 phy->tc_flag = 0 ;
387 phy->td_flag = 0 ;
388 if (np >= PM)
389 phy->phy_name = '0' + np - PM ;
390 else
391 phy->phy_name = 'A' + np ;
392 phy->wc_flag = FALSE ; /* set by SMT */
393 memset((char *)&phy->lem,0,sizeof(struct lem_counter)) ;
394 reset_lem_struct(phy) ;
395 memset((char *)&phy->plc,0,sizeof(struct s_plc)) ;
396 phy->plc.p_state = PS_OFF ;
397 for (i = 0 ; i < NUMBITS ; i++) {
398 phy->t_next[i] = 0 ;
399 }
400 }
401 real_init_plc(smc) ;
402}
403
404void init_plc(struct s_smc *smc)
405{
406 SK_UNUSED(smc) ;
407
408 /*
409 * dummy
410 * this is an obsolete public entry point that has to remain
411 * for compat. It is used by various drivers.
412 * the work is now done in real_init_plc()
413 * which is called from pcm_init() ;
414 */
415}
416
417static void real_init_plc(struct s_smc *smc)
418{
419 int p ;
420
421 for (p = 0 ; p < NUMPHYS ; p++)
422 plc_init(smc,p) ;
423}
424
425static void plc_init(struct s_smc *smc, int p)
426{
427 int i ;
428#ifndef MOT_ELM
429 int rev ; /* Revision of PLC-x */
430#endif /* MOT_ELM */
431
432 /* transit PCM state machine to MAINT state */
433 outpw(PLC(p,PL_CNTRL_B),0) ;
434 outpw(PLC(p,PL_CNTRL_B),PL_PCM_STOP) ;
435 outpw(PLC(p,PL_CNTRL_A),0) ;
436
437 /*
438 * if PLC-S then set control register C
439 */
440#ifndef MOT_ELM
441 rev = inpw(PLC(p,PL_STATUS_A)) & PLC_REV_MASK ;
442 if (rev != PLC_REVISION_A)
443#endif /* MOT_ELM */
444 {
445 if (smc->y[p].pmd_scramble) {
446 outpw(PLC(p,PL_CNTRL_C),PLCS_CONTROL_C_S) ;
447#ifdef MOT_ELM
448 outpw(PLC(p,PL_T_FOT_ASS),PLCS_FASSERT_S) ;
449 outpw(PLC(p,PL_T_FOT_DEASS),PLCS_FDEASSERT_S) ;
450#endif /* MOT_ELM */
451 }
452 else {
453 outpw(PLC(p,PL_CNTRL_C),PLCS_CONTROL_C_U) ;
454#ifdef MOT_ELM
455 outpw(PLC(p,PL_T_FOT_ASS),PLCS_FASSERT_U) ;
456 outpw(PLC(p,PL_T_FOT_DEASS),PLCS_FDEASSERT_U) ;
457#endif /* MOT_ELM */
458 }
459 }
460
461 /*
462 * set timer register
463 */
464 for ( i = 0 ; pltm[i].timer; i++) /* set timer parameter reg */
465 outpw(PLC(p,pltm[i].timer),pltm[i].para) ;
466
467 (void)inpw(PLC(p,PL_INTR_EVENT)) ; /* clear interrupt event reg */
468 plc_clear_irq(smc,p) ;
469 outpw(PLC(p,PL_INTR_MASK),plc_imsk_na); /* enable non active irq's */
470
471 /*
472 * if PCM is configured for class s, it will NOT go to the
473 * REMOVE state if offline (page 3-36;)
474 * in the concentrator, all inactive PHYS always must be in
475 * the remove state
476 * there's no real need to use this feature at all ..
477 */
478#ifndef CONCENTRATOR
479 if ((smc->s.sas == SMT_SAS) && (p == PS)) {
480 outpw(PLC(p,PL_CNTRL_B),PL_CLASS_S) ;
481 }
482#endif
483}
484
485/*
486 * control PCM state machine
487 */
488static void plc_go_state(struct s_smc *smc, int p, int state)
489{
490 HW_PTR port ;
491 int val ;
492
493 SK_UNUSED(smc) ;
494
495 port = (HW_PTR) (PLC(p,PL_CNTRL_B)) ;
496 val = inpw(port) & ~(PL_PCM_CNTRL | PL_MAINT) ;
497 outpw(port,val) ;
498 outpw(port,val | state) ;
499}
500
501/*
502 * read current line state (called by ECM & PCM)
503 */
504int sm_pm_get_ls(struct s_smc *smc, int phy)
505{
506 int state ;
507
508#ifdef CONCENTRATOR
509 if (!plc_is_installed(smc,phy))
510 return(PC_QLS) ;
511#endif
512
513 state = inpw(PLC(phy,PL_STATUS_A)) & PL_LINE_ST ;
514 switch(state) {
515 case PL_L_QLS:
516 state = PC_QLS ;
517 break ;
518 case PL_L_MLS:
519 state = PC_MLS ;
520 break ;
521 case PL_L_HLS:
522 state = PC_HLS ;
523 break ;
524 case PL_L_ILS4:
525 case PL_L_ILS16:
526 state = PC_ILS ;
527 break ;
528 case PL_L_ALS:
529 state = PC_LS_PDR ;
530 break ;
531 default :
532 state = PC_LS_NONE ;
533 }
534 return(state) ;
535}
536
537static int plc_send_bits(struct s_smc *smc, struct s_phy *phy, int len)
538{
539 int np = phy->np ; /* PHY index */
540 int n ;
541 int i ;
542
543 SK_UNUSED(smc) ;
544
545 /* create bit vector */
546 for (i = len-1,n = 0 ; i >= 0 ; i--) {
547 n = (n<<1) | phy->t_val[phy->bitn+i] ;
548 }
549 if (inpw(PLC(np,PL_STATUS_B)) & PL_PCM_SIGNAL) {
550#if 0
551 printf("PL_PCM_SIGNAL is set\n") ;
552#endif
553 return(1) ;
554 }
555 /* write bit[n] & length = 1 to regs */
556 outpw(PLC(np,PL_VECTOR_LEN),len-1) ; /* len=nr-1 */
557 outpw(PLC(np,PL_XMIT_VECTOR),n) ;
558#ifdef DEBUG
559#if 1
560#ifdef DEBUG_BRD
561 if (smc->debug.d_plc & 0x80)
562#else
563 if (debug.d_plc & 0x80)
564#endif
565 printf("SIGNALING bit %d .. %d\n",phy->bitn,phy->bitn+len-1) ;
566#endif
567#endif
568 return(0) ;
569}
570
571/*
572 * config plc muxes
573 */
574void plc_config_mux(struct s_smc *smc, int mux)
575{
576 if (smc->s.sas != SMT_DAS)
577 return ;
578 if (mux == MUX_WRAPB) {
579 SETMASK(PLC(PA,PL_CNTRL_B),PL_CONFIG_CNTRL,PL_CONFIG_CNTRL) ;
580 SETMASK(PLC(PA,PL_CNTRL_A),PL_SC_REM_LOOP,PL_SC_REM_LOOP) ;
581 }
582 else {
583 CLEAR(PLC(PA,PL_CNTRL_B),PL_CONFIG_CNTRL) ;
584 CLEAR(PLC(PA,PL_CNTRL_A),PL_SC_REM_LOOP) ;
585 }
586 CLEAR(PLC(PB,PL_CNTRL_B),PL_CONFIG_CNTRL) ;
587 CLEAR(PLC(PB,PL_CNTRL_A),PL_SC_REM_LOOP) ;
588}
589
590/*
591 PCM state machine
592 called by dispatcher & fddi_init() (driver)
593 do
594 display state change
595 process event
596 until SM is stable
597*/
598void pcm(struct s_smc *smc, const int np, int event)
599{
600 int state ;
601 int oldstate ;
602 struct s_phy *phy ;
603 struct fddi_mib_p *mib ;
604
605#ifndef CONCENTRATOR
606 /*
607 * ignore 2nd PHY if SAS
608 */
609 if ((np != PS) && (smc->s.sas == SMT_SAS))
610 return ;
611#endif
612 phy = &smc->y[np] ;
613 mib = phy->mib ;
614 oldstate = mib->fddiPORTPCMState ;
615 do {
616 DB_PCM("PCM %c: state %s",
617 phy->phy_name,
618 (mib->fddiPORTPCMState & AFLAG) ? "ACTIONS " : "") ;
619 DB_PCM("%s, event %s\n",
620 pcm_states[mib->fddiPORTPCMState & ~AFLAG],
621 pcm_events[event]) ;
622 state = mib->fddiPORTPCMState ;
623 pcm_fsm(smc,phy,event) ;
624 event = 0 ;
625 } while (state != mib->fddiPORTPCMState) ;
626 /*
627 * because the PLC does the bit signaling for us,
628 * we're always in SIGNAL state
629 * the MIB want's to see CONNECT
630 * we therefore fake an entry in the MIB
631 */
632 if (state == PC5_SIGNAL)
633 mib->fddiPORTPCMStateX = PC3_CONNECT ;
634 else
635 mib->fddiPORTPCMStateX = state ;
636
637#ifndef SLIM_SMT
638 /*
639 * path change
640 */
641 if ( mib->fddiPORTPCMState != oldstate &&
642 ((oldstate == PC8_ACTIVE) || (mib->fddiPORTPCMState == PC8_ACTIVE))) {
643 smt_srf_event(smc,SMT_EVENT_PORT_PATH_CHANGE,
644 (int) (INDEX_PORT+ phy->np),0) ;
645 }
646#endif
647
648#ifdef FDDI_MIB
649 /* check whether a snmp-trap has to be sent */
650
651 if ( mib->fddiPORTPCMState != oldstate ) {
652 /* a real state change took place */
653 DB_SNMP ("PCM from %d to %d\n", oldstate, mib->fddiPORTPCMState);
654 if ( mib->fddiPORTPCMState == PC0_OFF ) {
655 /* send first trap */
656 snmp_fddi_trap (smc, 1, (int) mib->fddiPORTIndex );
657 } else if ( oldstate == PC0_OFF ) {
658 /* send second trap */
659 snmp_fddi_trap (smc, 2, (int) mib->fddiPORTIndex );
660 } else if ( mib->fddiPORTPCMState != PC2_TRACE &&
661 oldstate == PC8_ACTIVE ) {
662 /* send third trap */
663 snmp_fddi_trap (smc, 3, (int) mib->fddiPORTIndex );
664 } else if ( mib->fddiPORTPCMState == PC8_ACTIVE ) {
665 /* send fourth trap */
666 snmp_fddi_trap (smc, 4, (int) mib->fddiPORTIndex );
667 }
668 }
669#endif
670
671 pcm_state_change(smc,np,state) ;
672}
673
674/*
675 * PCM state machine
676 */
677static void pcm_fsm(struct s_smc *smc, struct s_phy *phy, int cmd)
678{
679 int i ;
680 int np = phy->np ; /* PHY index */
681 struct s_plc *plc ;
682 struct fddi_mib_p *mib ;
683#ifndef MOT_ELM
684 u_short plc_rev ; /* Revision of the plc */
685#endif /* nMOT_ELM */
686
687 plc = &phy->plc ;
688 mib = phy->mib ;
689
690 /*
691 * general transitions independent of state
692 */
693 switch (cmd) {
694 case PC_STOP :
695 /*PC00-PC80*/
696 if (mib->fddiPORTPCMState != PC9_MAINT) {
697 GO_STATE(PC0_OFF) ;
698 AIX_EVENT(smc, (u_long) FDDI_RING_STATUS, (u_long)
699 FDDI_PORT_EVENT, (u_long) FDDI_PORT_STOP,
700 smt_get_port_event_word(smc));
701 }
702 return ;
703 case PC_START :
704 /*PC01-PC81*/
705 if (mib->fddiPORTPCMState != PC9_MAINT)
706 GO_STATE(PC1_BREAK) ;
707 return ;
708 case PC_DISABLE :
709 /* PC09-PC99 */
710 GO_STATE(PC9_MAINT) ;
711 AIX_EVENT(smc, (u_long) FDDI_RING_STATUS, (u_long)
712 FDDI_PORT_EVENT, (u_long) FDDI_PORT_DISABLED,
713 smt_get_port_event_word(smc));
714 return ;
715 case PC_TIMEOUT_LCT :
716 /* if long or extended LCT */
717 stop_pcm_timer0(smc,phy) ;
718 CLEAR(PLC(np,PL_CNTRL_B),PL_LONG) ;
719 /* end of LCT is indicate by PCM_CODE (initiate PCM event) */
720 return ;
721 }
722
723 switch(mib->fddiPORTPCMState) {
724 case ACTIONS(PC0_OFF) :
725 stop_pcm_timer0(smc,phy) ;
726 outpw(PLC(np,PL_CNTRL_A),0) ;
727 CLEAR(PLC(np,PL_CNTRL_B),PL_PC_JOIN) ;
728 CLEAR(PLC(np,PL_CNTRL_B),PL_LONG) ;
729 sm_ph_lem_stop(smc,np) ; /* disable LEM */
730 phy->cf_loop = FALSE ;
731 phy->cf_join = FALSE ;
732 queue_event(smc,EVENT_CFM,CF_JOIN+np) ;
733 plc_go_state(smc,np,PL_PCM_STOP) ;
734 mib->fddiPORTConnectState = PCM_DISABLED ;
735 ACTIONS_DONE() ;
736 break ;
737 case PC0_OFF:
738 /*PC09*/
739 if (cmd == PC_MAINT) {
740 GO_STATE(PC9_MAINT) ;
741 break ;
742 }
743 break ;
744 case ACTIONS(PC1_BREAK) :
745 /* Stop the LCT timer if we came from Signal state */
746 stop_pcm_timer0(smc,phy) ;
747 ACTIONS_DONE() ;
748 plc_go_state(smc,np,0) ;
749 CLEAR(PLC(np,PL_CNTRL_B),PL_PC_JOIN) ;
750 CLEAR(PLC(np,PL_CNTRL_B),PL_LONG) ;
751 sm_ph_lem_stop(smc,np) ; /* disable LEM */
752 /*
753 * if vector is already loaded, go to OFF to clear PCM_SIGNAL
754 */
755#if 0
756 if (inpw(PLC(np,PL_STATUS_B)) & PL_PCM_SIGNAL) {
757 plc_go_state(smc,np,PL_PCM_STOP) ;
758 /* TB_MIN ? */
759 }
760#endif
761 /*
762 * Go to OFF state in any case.
763 */
764 plc_go_state(smc,np,PL_PCM_STOP) ;
765
766 if (mib->fddiPORTPC_Withhold == PC_WH_NONE)
767 mib->fddiPORTConnectState = PCM_CONNECTING ;
768 phy->cf_loop = FALSE ;
769 phy->cf_join = FALSE ;
770 queue_event(smc,EVENT_CFM,CF_JOIN+np) ;
771 phy->ls_flag = FALSE ;
772 phy->pc_mode = PM_NONE ; /* needed by CFM */
773 phy->bitn = 0 ; /* bit signaling start bit */
774 for (i = 0 ; i < 3 ; i++)
775 pc_tcode_actions(smc,i,phy) ;
776
777 /* Set the non-active interrupt mask register */
778 outpw(PLC(np,PL_INTR_MASK),plc_imsk_na) ;
779
780 /*
781 * If the LCT was stopped. There might be a
782 * PCM_CODE interrupt event present.
783 * This must be cleared.
784 */
785 (void)inpw(PLC(np,PL_INTR_EVENT)) ;
786#ifndef MOT_ELM
787 /* Get the plc revision for revision dependent code */
788 plc_rev = inpw(PLC(np,PL_STATUS_A)) & PLC_REV_MASK ;
789
790 if (plc_rev != PLC_REV_SN3)
791#endif /* MOT_ELM */
792 {
793 /*
794 * No supernet III PLC, so set Xmit verctor and
795 * length BEFORE starting the state machine.
796 */
797 if (plc_send_bits(smc,phy,3)) {
798 return ;
799 }
800 }
801
802 /*
803 * Now give the Start command.
804 * - The start command shall be done before setting the bits
805 * to be signaled. (In PLC-S description and PLCS in SN3.
806 * - The start command shall be issued AFTER setting the
807 * XMIT vector and the XMIT length register.
808 *
809 * We do it exactly according this specs for the old PLC and
810 * the new PLCS inside the SN3.
811 * For the usual PLCS we try it the way it is done for the
812 * old PLC and set the XMIT registers again, if the PLC is
813 * not in SIGNAL state. This is done according to an PLCS
814 * errata workaround.
815 */
816
817 plc_go_state(smc,np,PL_PCM_START) ;
818
819 /*
820 * workaround for PLC-S eng. sample errata
821 */
822#ifdef MOT_ELM
823 if (!(inpw(PLC(np,PL_STATUS_B)) & PL_PCM_SIGNAL))
824#else /* nMOT_ELM */
825 if (((inpw(PLC(np,PL_STATUS_A)) & PLC_REV_MASK) !=
826 PLC_REVISION_A) &&
827 !(inpw(PLC(np,PL_STATUS_B)) & PL_PCM_SIGNAL))
828#endif /* nMOT_ELM */
829 {
830 /*
831 * Set register again (PLCS errata) or the first time
832 * (new SN3 PLCS).
833 */
834 (void) plc_send_bits(smc,phy,3) ;
835 }
836 /*
837 * end of workaround
838 */
839
840 GO_STATE(PC5_SIGNAL) ;
841 plc->p_state = PS_BIT3 ;
842 plc->p_bits = 3 ;
843 plc->p_start = 0 ;
844
845 break ;
846 case PC1_BREAK :
847 break ;
848 case ACTIONS(PC2_TRACE) :
849 plc_go_state(smc,np,PL_PCM_TRACE) ;
850 ACTIONS_DONE() ;
851 break ;
852 case PC2_TRACE :
853 break ;
854
855 case PC3_CONNECT : /* these states are done by hardware */
856 case PC4_NEXT :
857 break ;
858
859 case ACTIONS(PC5_SIGNAL) :
860 ACTIONS_DONE() ;
861 case PC5_SIGNAL :
862 if ((cmd != PC_SIGNAL) && (cmd != PC_TIMEOUT_LCT))
863 break ;
864 switch (plc->p_state) {
865 case PS_BIT3 :
866 for (i = 0 ; i <= 2 ; i++)
867 pc_rcode_actions(smc,i,phy) ;
868 pc_tcode_actions(smc,3,phy) ;
869 plc->p_state = PS_BIT4 ;
870 plc->p_bits = 1 ;
871 plc->p_start = 3 ;
872 phy->bitn = 3 ;
873 if (plc_send_bits(smc,phy,1)) {
874 return ;
875 }
876 break ;
877 case PS_BIT4 :
878 pc_rcode_actions(smc,3,phy) ;
879 for (i = 4 ; i <= 6 ; i++)
880 pc_tcode_actions(smc,i,phy) ;
881 plc->p_state = PS_BIT7 ;
882 plc->p_bits = 3 ;
883 plc->p_start = 4 ;
884 phy->bitn = 4 ;
885 if (plc_send_bits(smc,phy,3)) {
886 return ;
887 }
888 break ;
889 case PS_BIT7 :
890 for (i = 3 ; i <= 6 ; i++)
891 pc_rcode_actions(smc,i,phy) ;
892 plc->p_state = PS_LCT ;
893 plc->p_bits = 0 ;
894 plc->p_start = 7 ;
895 phy->bitn = 7 ;
896 sm_ph_lem_start(smc,np,(int)smc->s.lct_short) ; /* enable LEM */
897 /* start LCT */
898 i = inpw(PLC(np,PL_CNTRL_B)) & ~PL_PC_LOOP ;
899 outpw(PLC(np,PL_CNTRL_B),i) ; /* must be cleared */
900 outpw(PLC(np,PL_CNTRL_B),i | PL_RLBP) ;
901 break ;
902 case PS_LCT :
903 /* check for local LCT failure */
904 pc_tcode_actions(smc,7,phy) ;
905 /*
906 * set tval[7]
907 */
908 plc->p_state = PS_BIT8 ;
909 plc->p_bits = 1 ;
910 plc->p_start = 7 ;
911 phy->bitn = 7 ;
912 if (plc_send_bits(smc,phy,1)) {
913 return ;
914 }
915 break ;
916 case PS_BIT8 :
917 /* check for remote LCT failure */
918 pc_rcode_actions(smc,7,phy) ;
919 if (phy->t_val[7] || phy->r_val[7]) {
920 plc_go_state(smc,np,PL_PCM_STOP) ;
921 GO_STATE(PC1_BREAK) ;
922 break ;
923 }
924 for (i = 8 ; i <= 9 ; i++)
925 pc_tcode_actions(smc,i,phy) ;
926 plc->p_state = PS_JOIN ;
927 plc->p_bits = 2 ;
928 plc->p_start = 8 ;
929 phy->bitn = 8 ;
930 if (plc_send_bits(smc,phy,2)) {
931 return ;
932 }
933 break ;
934 case PS_JOIN :
935 for (i = 8 ; i <= 9 ; i++)
936 pc_rcode_actions(smc,i,phy) ;
937 plc->p_state = PS_ACTIVE ;
938 GO_STATE(PC6_JOIN) ;
939 break ;
940 }
941 break ;
942
943 case ACTIONS(PC6_JOIN) :
944 /*
945 * prevent mux error when going from WRAP_A to WRAP_B
946 */
947 if (smc->s.sas == SMT_DAS && np == PB &&
948 (smc->y[PA].pc_mode == PM_TREE ||
949 smc->y[PB].pc_mode == PM_TREE)) {
950 SETMASK(PLC(np,PL_CNTRL_A),
951 PL_SC_REM_LOOP,PL_SC_REM_LOOP) ;
952 SETMASK(PLC(np,PL_CNTRL_B),
953 PL_CONFIG_CNTRL,PL_CONFIG_CNTRL) ;
954 }
955 SETMASK(PLC(np,PL_CNTRL_B),PL_PC_JOIN,PL_PC_JOIN) ;
956 SETMASK(PLC(np,PL_CNTRL_B),PL_PC_JOIN,PL_PC_JOIN) ;
957 ACTIONS_DONE() ;
958 cmd = 0 ;
959 /* fall thru */
960 case PC6_JOIN :
961 switch (plc->p_state) {
962 case PS_ACTIVE:
963 /*PC88b*/
964 if (!phy->cf_join) {
965 phy->cf_join = TRUE ;
966 queue_event(smc,EVENT_CFM,CF_JOIN+np) ; ;
967 }
968 if (cmd == PC_JOIN)
969 GO_STATE(PC8_ACTIVE) ;
970 /*PC82*/
971 if (cmd == PC_TRACE) {
972 GO_STATE(PC2_TRACE) ;
973 break ;
974 }
975 break ;
976 }
977 break ;
978
979 case PC7_VERIFY :
980 break ;
981
982 case ACTIONS(PC8_ACTIVE) :
983 /*
984 * start LEM for SMT
985 */
986 sm_ph_lem_start(smc,(int)phy->np,LCT_LEM_MAX) ;
987
988 phy->tr_flag = FALSE ;
989 mib->fddiPORTConnectState = PCM_ACTIVE ;
990
991 /* Set the active interrupt mask register */
992 outpw(PLC(np,PL_INTR_MASK),plc_imsk_act) ;
993
994 ACTIONS_DONE() ;
995 break ;
996 case PC8_ACTIVE :
997 /*PC81 is done by PL_TNE_EXPIRED irq */
998 /*PC82*/
999 if (cmd == PC_TRACE) {
1000 GO_STATE(PC2_TRACE) ;
1001 break ;
1002 }
1003 /*PC88c: is done by TRACE_PROP irq */
1004
1005 break ;
1006 case ACTIONS(PC9_MAINT) :
1007 stop_pcm_timer0(smc,phy) ;
1008 CLEAR(PLC(np,PL_CNTRL_B),PL_PC_JOIN) ;
1009 CLEAR(PLC(np,PL_CNTRL_B),PL_LONG) ;
1010 CLEAR(PLC(np,PL_INTR_MASK),PL_LE_CTR) ; /* disable LEM int. */
1011 sm_ph_lem_stop(smc,np) ; /* disable LEM */
1012 phy->cf_loop = FALSE ;
1013 phy->cf_join = FALSE ;
1014 queue_event(smc,EVENT_CFM,CF_JOIN+np) ;
1015 plc_go_state(smc,np,PL_PCM_STOP) ;
1016 mib->fddiPORTConnectState = PCM_DISABLED ;
1017 SETMASK(PLC(np,PL_CNTRL_B),PL_MAINT,PL_MAINT) ;
1018 sm_ph_linestate(smc,np,(int) MIB2LS(mib->fddiPORTMaint_LS)) ;
1019 outpw(PLC(np,PL_CNTRL_A),PL_SC_BYPASS) ;
1020 ACTIONS_DONE() ;
1021 break ;
1022 case PC9_MAINT :
1023 DB_PCMN(1,"PCM %c : MAINT\n",phy->phy_name,0) ;
1024 /*PC90*/
1025 if (cmd == PC_ENABLE) {
1026 GO_STATE(PC0_OFF) ;
1027 break ;
1028 }
1029 break ;
1030
1031 default:
1032 SMT_PANIC(smc,SMT_E0118, SMT_E0118_MSG) ;
1033 break ;
1034 }
1035}
1036
1037/*
1038 * force line state on a PHY output (only in MAINT state)
1039 */
1040static void sm_ph_linestate(struct s_smc *smc, int phy, int ls)
1041{
1042 int cntrl ;
1043
1044 SK_UNUSED(smc) ;
1045
1046 cntrl = (inpw(PLC(phy,PL_CNTRL_B)) & ~PL_MAINT_LS) |
1047 PL_PCM_STOP | PL_MAINT ;
1048 switch(ls) {
1049 case PC_QLS: /* Force Quiet */
1050 cntrl |= PL_M_QUI0 ;
1051 break ;
1052 case PC_MLS: /* Force Master */
1053 cntrl |= PL_M_MASTR ;
1054 break ;
1055 case PC_HLS: /* Force Halt */
1056 cntrl |= PL_M_HALT ;
1057 break ;
1058 default :
1059 case PC_ILS: /* Force Idle */
1060 cntrl |= PL_M_IDLE ;
1061 break ;
1062 case PC_LS_PDR: /* Enable repeat filter */
1063 cntrl |= PL_M_TPDR ;
1064 break ;
1065 }
1066 outpw(PLC(phy,PL_CNTRL_B),cntrl) ;
1067}
1068
1069static void reset_lem_struct(struct s_phy *phy)
1070{
1071 struct lem_counter *lem = &phy->lem ;
1072
1073 phy->mib->fddiPORTLer_Estimate = 15 ;
1074 lem->lem_float_ber = 15 * 100 ;
1075}
1076
1077/*
1078 * link error monitor
1079 */
1080static void lem_evaluate(struct s_smc *smc, struct s_phy *phy)
1081{
1082 int ber ;
1083 u_long errors ;
1084 struct lem_counter *lem = &phy->lem ;
1085 struct fddi_mib_p *mib ;
1086 int cond ;
1087
1088 mib = phy->mib ;
1089
1090 if (!lem->lem_on)
1091 return ;
1092
1093 errors = inpw(PLC(((int) phy->np),PL_LINK_ERR_CTR)) ;
1094 lem->lem_errors += errors ;
1095 mib->fddiPORTLem_Ct += errors ;
1096
1097 errors = lem->lem_errors ;
1098 /*
1099 * calculation is called on a intervall of 8 seconds
1100 * -> this means, that one error in 8 sec. is one of 8*125*10E6
1101 * the same as BER = 10E-9
1102 * Please note:
1103 * -> 9 errors in 8 seconds mean:
1104 * BER = 9 * 10E-9 and this is
1105 * < 10E-8, so the limit of 10E-8 is not reached!
1106 */
1107
1108 if (!errors) ber = 15 ;
1109 else if (errors <= 9) ber = 9 ;
1110 else if (errors <= 99) ber = 8 ;
1111 else if (errors <= 999) ber = 7 ;
1112 else if (errors <= 9999) ber = 6 ;
1113 else if (errors <= 99999) ber = 5 ;
1114 else if (errors <= 999999) ber = 4 ;
1115 else if (errors <= 9999999) ber = 3 ;
1116 else if (errors <= 99999999) ber = 2 ;
1117 else if (errors <= 999999999) ber = 1 ;
1118 else ber = 0 ;
1119
1120 /*
1121 * weighted average
1122 */
1123 ber *= 100 ;
1124 lem->lem_float_ber = lem->lem_float_ber * 7 + ber * 3 ;
1125 lem->lem_float_ber /= 10 ;
1126 mib->fddiPORTLer_Estimate = lem->lem_float_ber / 100 ;
1127 if (mib->fddiPORTLer_Estimate < 4) {
1128 mib->fddiPORTLer_Estimate = 4 ;
1129 }
1130
1131 if (lem->lem_errors) {
1132 DB_PCMN(1,"LEM %c :\n",phy->np == PB? 'B' : 'A',0) ;
1133 DB_PCMN(1,"errors : %ld\n",lem->lem_errors,0) ;
1134 DB_PCMN(1,"sum_errors : %ld\n",mib->fddiPORTLem_Ct,0) ;
1135 DB_PCMN(1,"current BER : 10E-%d\n",ber/100,0) ;
1136 DB_PCMN(1,"float BER : 10E-(%d/100)\n",lem->lem_float_ber,0) ;
1137 DB_PCMN(1,"avg. BER : 10E-%d\n",
1138 mib->fddiPORTLer_Estimate,0) ;
1139 }
1140
1141 lem->lem_errors = 0L ;
1142
1143#ifndef SLIM_SMT
1144 cond = (mib->fddiPORTLer_Estimate <= mib->fddiPORTLer_Alarm) ?
1145 TRUE : FALSE ;
1146#ifdef SMT_EXT_CUTOFF
1147 smt_ler_alarm_check(smc,phy,cond) ;
1148#endif /* nSMT_EXT_CUTOFF */
1149 if (cond != mib->fddiPORTLerFlag) {
1150 smt_srf_event(smc,SMT_COND_PORT_LER,
1151 (int) (INDEX_PORT+ phy->np) ,cond) ;
1152 }
1153#endif
1154
1155 if ( mib->fddiPORTLer_Estimate <= mib->fddiPORTLer_Cutoff) {
1156 phy->pc_lem_fail = TRUE ; /* flag */
1157 mib->fddiPORTLem_Reject_Ct++ ;
1158 /*
1159 * "forgive 10e-2" if we cutoff so we can come
1160 * up again ..
1161 */
1162 lem->lem_float_ber += 2*100 ;
1163
1164 /*PC81b*/
1165#ifdef CONCENTRATOR
1166 DB_PCMN(1,"PCM: LER cutoff on port %d cutoff %d\n",
1167 phy->np, mib->fddiPORTLer_Cutoff) ;
1168#endif
1169#ifdef SMT_EXT_CUTOFF
1170 smt_port_off_event(smc,phy->np);
1171#else /* nSMT_EXT_CUTOFF */
1172 queue_event(smc,(int)(EVENT_PCM+phy->np),PC_START) ;
1173#endif /* nSMT_EXT_CUTOFF */
1174 }
1175}
1176
1177/*
1178 * called by SMT to calculate LEM bit error rate
1179 */
1180void sm_lem_evaluate(struct s_smc *smc)
1181{
1182 int np ;
1183
1184 for (np = 0 ; np < NUMPHYS ; np++)
1185 lem_evaluate(smc,&smc->y[np]) ;
1186}
1187
1188static void lem_check_lct(struct s_smc *smc, struct s_phy *phy)
1189{
1190 struct lem_counter *lem = &phy->lem ;
1191 struct fddi_mib_p *mib ;
1192 int errors ;
1193
1194 mib = phy->mib ;
1195
1196 phy->pc_lem_fail = FALSE ; /* flag */
1197 errors = inpw(PLC(((int)phy->np),PL_LINK_ERR_CTR)) ;
1198 lem->lem_errors += errors ;
1199 mib->fddiPORTLem_Ct += errors ;
1200 if (lem->lem_errors) {
1201 switch(phy->lc_test) {
1202 case LC_SHORT:
1203 if (lem->lem_errors >= smc->s.lct_short)
1204 phy->pc_lem_fail = TRUE ;
1205 break ;
1206 case LC_MEDIUM:
1207 if (lem->lem_errors >= smc->s.lct_medium)
1208 phy->pc_lem_fail = TRUE ;
1209 break ;
1210 case LC_LONG:
1211 if (lem->lem_errors >= smc->s.lct_long)
1212 phy->pc_lem_fail = TRUE ;
1213 break ;
1214 case LC_EXTENDED:
1215 if (lem->lem_errors >= smc->s.lct_extended)
1216 phy->pc_lem_fail = TRUE ;
1217 break ;
1218 }
1219 DB_PCMN(1," >>errors : %d\n",lem->lem_errors,0) ;
1220 }
1221 if (phy->pc_lem_fail) {
1222 mib->fddiPORTLCTFail_Ct++ ;
1223 mib->fddiPORTLem_Reject_Ct++ ;
1224 }
1225 else
1226 mib->fddiPORTLCTFail_Ct = 0 ;
1227}
1228
1229/*
1230 * LEM functions
1231 */
1232static void sm_ph_lem_start(struct s_smc *smc, int np, int threshold)
1233{
1234 struct lem_counter *lem = &smc->y[np].lem ;
1235
1236 lem->lem_on = 1 ;
1237 lem->lem_errors = 0L ;
1238
1239 /* Do NOT reset mib->fddiPORTLer_Estimate here. It is called too
1240 * often.
1241 */
1242
1243 outpw(PLC(np,PL_LE_THRESHOLD),threshold) ;
1244 (void)inpw(PLC(np,PL_LINK_ERR_CTR)) ; /* clear error counter */
1245
1246 /* enable LE INT */
1247 SETMASK(PLC(np,PL_INTR_MASK),PL_LE_CTR,PL_LE_CTR) ;
1248}
1249
1250static void sm_ph_lem_stop(struct s_smc *smc, int np)
1251{
1252 struct lem_counter *lem = &smc->y[np].lem ;
1253
1254 lem->lem_on = 0 ;
1255 CLEAR(PLC(np,PL_INTR_MASK),PL_LE_CTR) ;
1256}
1257
1258/* ARGSUSED */
1259void sm_pm_ls_latch(struct s_smc *smc, int phy, int on_off)
1260/* int on_off; en- or disable ident. ls */
1261{
1262 SK_UNUSED(smc) ;
1263
1264 phy = phy ; on_off = on_off ;
1265}
1266
1267
1268/*
1269 * PCM pseudo code
1270 * receive actions are called AFTER the bit n is received,
1271 * i.e. if pc_rcode_actions(5) is called, bit 6 is the next bit to be received
1272 */
1273
1274/*
1275 * PCM pseudo code 5.1 .. 6.1
1276 */
1277static void pc_rcode_actions(struct s_smc *smc, int bit, struct s_phy *phy)
1278{
1279 struct fddi_mib_p *mib ;
1280
1281 mib = phy->mib ;
1282
1283 DB_PCMN(1,"SIG rec %x %x: \n", bit,phy->r_val[bit] ) ;
1284 bit++ ;
1285
1286 switch(bit) {
1287 case 0:
1288 case 1:
1289 case 2:
1290 break ;
1291 case 3 :
1292 if (phy->r_val[1] == 0 && phy->r_val[2] == 0)
1293 mib->fddiPORTNeighborType = TA ;
1294 else if (phy->r_val[1] == 0 && phy->r_val[2] == 1)
1295 mib->fddiPORTNeighborType = TB ;
1296 else if (phy->r_val[1] == 1 && phy->r_val[2] == 0)
1297 mib->fddiPORTNeighborType = TS ;
1298 else if (phy->r_val[1] == 1 && phy->r_val[2] == 1)
1299 mib->fddiPORTNeighborType = TM ;
1300 break ;
1301 case 4:
1302 if (mib->fddiPORTMy_Type == TM &&
1303 mib->fddiPORTNeighborType == TM) {
1304 DB_PCMN(1,"PCM %c : E100 withhold M-M\n",
1305 phy->phy_name,0) ;
1306 mib->fddiPORTPC_Withhold = PC_WH_M_M ;
1307 RS_SET(smc,RS_EVENT) ;
1308 }
1309 else if (phy->t_val[3] || phy->r_val[3]) {
1310 mib->fddiPORTPC_Withhold = PC_WH_NONE ;
1311 if (mib->fddiPORTMy_Type == TM ||
1312 mib->fddiPORTNeighborType == TM)
1313 phy->pc_mode = PM_TREE ;
1314 else
1315 phy->pc_mode = PM_PEER ;
1316
1317 /* reevaluate the selection criteria (wc_flag) */
1318 all_selection_criteria (smc);
1319
1320 if (phy->wc_flag) {
1321 mib->fddiPORTPC_Withhold = PC_WH_PATH ;
1322 }
1323 }
1324 else {
1325 mib->fddiPORTPC_Withhold = PC_WH_OTHER ;
1326 RS_SET(smc,RS_EVENT) ;
1327 DB_PCMN(1,"PCM %c : E101 withhold other\n",
1328 phy->phy_name,0) ;
1329 }
1330 phy->twisted = ((mib->fddiPORTMy_Type != TS) &&
1331 (mib->fddiPORTMy_Type != TM) &&
1332 (mib->fddiPORTNeighborType ==
1333 mib->fddiPORTMy_Type)) ;
1334 if (phy->twisted) {
1335 DB_PCMN(1,"PCM %c : E102 !!! TWISTED !!!\n",
1336 phy->phy_name,0) ;
1337 }
1338 break ;
1339 case 5 :
1340 break ;
1341 case 6:
1342 if (phy->t_val[4] || phy->r_val[4]) {
1343 if ((phy->t_val[4] && phy->t_val[5]) ||
1344 (phy->r_val[4] && phy->r_val[5]) )
1345 phy->lc_test = LC_EXTENDED ;
1346 else
1347 phy->lc_test = LC_LONG ;
1348 }
1349 else if (phy->t_val[5] || phy->r_val[5])
1350 phy->lc_test = LC_MEDIUM ;
1351 else
1352 phy->lc_test = LC_SHORT ;
1353 switch (phy->lc_test) {
1354 case LC_SHORT : /* 50ms */
1355 outpw(PLC((int)phy->np,PL_LC_LENGTH), TP_LC_LENGTH ) ;
1356 phy->t_next[7] = smc->s.pcm_lc_short ;
1357 break ;
1358 case LC_MEDIUM : /* 500ms */
1359 outpw(PLC((int)phy->np,PL_LC_LENGTH), TP_LC_LONGLN ) ;
1360 phy->t_next[7] = smc->s.pcm_lc_medium ;
1361 break ;
1362 case LC_LONG :
1363 SETMASK(PLC((int)phy->np,PL_CNTRL_B),PL_LONG,PL_LONG) ;
1364 phy->t_next[7] = smc->s.pcm_lc_long ;
1365 break ;
1366 case LC_EXTENDED :
1367 SETMASK(PLC((int)phy->np,PL_CNTRL_B),PL_LONG,PL_LONG) ;
1368 phy->t_next[7] = smc->s.pcm_lc_extended ;
1369 break ;
1370 }
1371 if (phy->t_next[7] > smc->s.pcm_lc_medium) {
1372 start_pcm_timer0(smc,phy->t_next[7],PC_TIMEOUT_LCT,phy);
1373 }
1374 DB_PCMN(1,"LCT timer = %ld us\n", phy->t_next[7], 0) ;
1375 phy->t_next[9] = smc->s.pcm_t_next_9 ;
1376 break ;
1377 case 7:
1378 if (phy->t_val[6]) {
1379 phy->cf_loop = TRUE ;
1380 }
1381 phy->td_flag = TRUE ;
1382 break ;
1383 case 8:
1384 if (phy->t_val[7] || phy->r_val[7]) {
1385 DB_PCMN(1,"PCM %c : E103 LCT fail %s\n",
1386 phy->phy_name,phy->t_val[7]? "local":"remote") ;
1387 queue_event(smc,(int)(EVENT_PCM+phy->np),PC_START) ;
1388 }
1389 break ;
1390 case 9:
1391 if (phy->t_val[8] || phy->r_val[8]) {
1392 if (phy->t_val[8])
1393 phy->cf_loop = TRUE ;
1394 phy->td_flag = TRUE ;
1395 }
1396 break ;
1397 case 10:
1398 if (phy->r_val[9]) {
1399 /* neighbor intends to have MAC on output */ ;
1400 mib->fddiPORTMacIndicated.R_val = TRUE ;
1401 }
1402 else {
1403 /* neighbor does not intend to have MAC on output */ ;
1404 mib->fddiPORTMacIndicated.R_val = FALSE ;
1405 }
1406 break ;
1407 }
1408}
1409
1410/*
1411 * PCM pseudo code 5.1 .. 6.1
1412 */
1413static void pc_tcode_actions(struct s_smc *smc, const int bit, struct s_phy *phy)
1414{
1415 int np = phy->np ;
1416 struct fddi_mib_p *mib ;
1417
1418 mib = phy->mib ;
1419
1420 switch(bit) {
1421 case 0:
1422 phy->t_val[0] = 0 ; /* no escape used */
1423 break ;
1424 case 1:
1425 if (mib->fddiPORTMy_Type == TS || mib->fddiPORTMy_Type == TM)
1426 phy->t_val[1] = 1 ;
1427 else
1428 phy->t_val[1] = 0 ;
1429 break ;
1430 case 2 :
1431 if (mib->fddiPORTMy_Type == TB || mib->fddiPORTMy_Type == TM)
1432 phy->t_val[2] = 1 ;
1433 else
1434 phy->t_val[2] = 0 ;
1435 break ;
1436 case 3:
1437 {
1438 int type,ne ;
1439 int policy ;
1440
1441 type = mib->fddiPORTMy_Type ;
1442 ne = mib->fddiPORTNeighborType ;
1443 policy = smc->mib.fddiSMTConnectionPolicy ;
1444
1445 phy->t_val[3] = 1 ; /* Accept connection */
1446 switch (type) {
1447 case TA :
1448 if (
1449 ((policy & POLICY_AA) && ne == TA) ||
1450 ((policy & POLICY_AB) && ne == TB) ||
1451 ((policy & POLICY_AS) && ne == TS) ||
1452 ((policy & POLICY_AM) && ne == TM) )
1453 phy->t_val[3] = 0 ; /* Reject */
1454 break ;
1455 case TB :
1456 if (
1457 ((policy & POLICY_BA) && ne == TA) ||
1458 ((policy & POLICY_BB) && ne == TB) ||
1459 ((policy & POLICY_BS) && ne == TS) ||
1460 ((policy & POLICY_BM) && ne == TM) )
1461 phy->t_val[3] = 0 ; /* Reject */
1462 break ;
1463 case TS :
1464 if (
1465 ((policy & POLICY_SA) && ne == TA) ||
1466 ((policy & POLICY_SB) && ne == TB) ||
1467 ((policy & POLICY_SS) && ne == TS) ||
1468 ((policy & POLICY_SM) && ne == TM) )
1469 phy->t_val[3] = 0 ; /* Reject */
1470 break ;
1471 case TM :
1472 if ( ne == TM ||
1473 ((policy & POLICY_MA) && ne == TA) ||
1474 ((policy & POLICY_MB) && ne == TB) ||
1475 ((policy & POLICY_MS) && ne == TS) ||
1476 ((policy & POLICY_MM) && ne == TM) )
1477 phy->t_val[3] = 0 ; /* Reject */
1478 break ;
1479 }
1480#ifndef SLIM_SMT
1481 /*
1482 * detect undesirable connection attempt event
1483 */
1484 if ( (type == TA && ne == TA ) ||
1485 (type == TA && ne == TS ) ||
1486 (type == TB && ne == TB ) ||
1487 (type == TB && ne == TS ) ||
1488 (type == TS && ne == TA ) ||
1489 (type == TS && ne == TB ) ) {
1490 smt_srf_event(smc,SMT_EVENT_PORT_CONNECTION,
1491 (int) (INDEX_PORT+ phy->np) ,0) ;
1492 }
1493#endif
1494 }
1495 break ;
1496 case 4:
1497 if (mib->fddiPORTPC_Withhold == PC_WH_NONE) {
1498 if (phy->pc_lem_fail) {
1499 phy->t_val[4] = 1 ; /* long */
1500 phy->t_val[5] = 0 ;
1501 }
1502 else {
1503 phy->t_val[4] = 0 ;
1504 if (mib->fddiPORTLCTFail_Ct > 0)
1505 phy->t_val[5] = 1 ; /* medium */
1506 else
1507 phy->t_val[5] = 0 ; /* short */
1508
1509 /*
1510 * Implementers choice: use medium
1511 * instead of short when undesired
1512 * connection attempt is made.
1513 */
1514 if (phy->wc_flag)
1515 phy->t_val[5] = 1 ; /* medium */
1516 }
1517 mib->fddiPORTConnectState = PCM_CONNECTING ;
1518 }
1519 else {
1520 mib->fddiPORTConnectState = PCM_STANDBY ;
1521 phy->t_val[4] = 1 ; /* extended */
1522 phy->t_val[5] = 1 ;
1523 }
1524 break ;
1525 case 5:
1526 break ;
1527 case 6:
1528 /* we do NOT have a MAC for LCT */
1529 phy->t_val[6] = 0 ;
1530 break ;
1531 case 7:
1532 phy->cf_loop = FALSE ;
1533 lem_check_lct(smc,phy) ;
1534 if (phy->pc_lem_fail) {
1535 DB_PCMN(1,"PCM %c : E104 LCT failed\n",
1536 phy->phy_name,0) ;
1537 phy->t_val[7] = 1 ;
1538 }
1539 else
1540 phy->t_val[7] = 0 ;
1541 break ;
1542 case 8:
1543 phy->t_val[8] = 0 ; /* Don't request MAC loopback */
1544 break ;
1545 case 9:
1546 phy->cf_loop = 0 ;
1547 if ((mib->fddiPORTPC_Withhold != PC_WH_NONE) ||
1548 ((smc->s.sas == SMT_DAS) && (phy->wc_flag))) {
1549 queue_event(smc,EVENT_PCM+np,PC_START) ;
1550 break ;
1551 }
1552 phy->t_val[9] = FALSE ;
1553 switch (smc->s.sas) {
1554 case SMT_DAS :
1555 /*
1556 * MAC intended on output
1557 */
1558 if (phy->pc_mode == PM_TREE) {
1559 if ((np == PB) || ((np == PA) &&
1560 (smc->y[PB].mib->fddiPORTConnectState !=
1561 PCM_ACTIVE)))
1562 phy->t_val[9] = TRUE ;
1563 }
1564 else {
1565 if (np == PB)
1566 phy->t_val[9] = TRUE ;
1567 }
1568 break ;
1569 case SMT_SAS :
1570 if (np == PS)
1571 phy->t_val[9] = TRUE ;
1572 break ;
1573#ifdef CONCENTRATOR
1574 case SMT_NAC :
1575 /*
1576 * MAC intended on output
1577 */
1578 if (np == PB)
1579 phy->t_val[9] = TRUE ;
1580 break ;
1581#endif
1582 }
1583 mib->fddiPORTMacIndicated.T_val = phy->t_val[9] ;
1584 break ;
1585 }
1586 DB_PCMN(1,"SIG snd %x %x: \n", bit,phy->t_val[bit] ) ;
1587}
1588
1589/*
1590 * return status twisted (called by SMT)
1591 */
1592int pcm_status_twisted(struct s_smc *smc)
1593{
1594 int twist = 0 ;
1595 if (smc->s.sas != SMT_DAS)
1596 return(0) ;
1597 if (smc->y[PA].twisted && (smc->y[PA].mib->fddiPORTPCMState == PC8_ACTIVE))
1598 twist |= 1 ;
1599 if (smc->y[PB].twisted && (smc->y[PB].mib->fddiPORTPCMState == PC8_ACTIVE))
1600 twist |= 2 ;
1601 return(twist) ;
1602}
1603
1604/*
1605 * return status (called by SMT)
1606 * type
1607 * state
1608 * remote phy type
1609 * remote mac yes/no
1610 */
1611void pcm_status_state(struct s_smc *smc, int np, int *type, int *state,
1612 int *remote, int *mac)
1613{
1614 struct s_phy *phy = &smc->y[np] ;
1615 struct fddi_mib_p *mib ;
1616
1617 mib = phy->mib ;
1618
1619 /* remote PHY type and MAC - set only if active */
1620 *mac = 0 ;
1621 *type = mib->fddiPORTMy_Type ; /* our PHY type */
1622 *state = mib->fddiPORTConnectState ;
1623 *remote = mib->fddiPORTNeighborType ;
1624
1625 switch(mib->fddiPORTPCMState) {
1626 case PC8_ACTIVE :
1627 *mac = mib->fddiPORTMacIndicated.R_val ;
1628 break ;
1629 }
1630}
1631
1632/*
1633 * return rooted station status (called by SMT)
1634 */
1635int pcm_rooted_station(struct s_smc *smc)
1636{
1637 int n ;
1638
1639 for (n = 0 ; n < NUMPHYS ; n++) {
1640 if (smc->y[n].mib->fddiPORTPCMState == PC8_ACTIVE &&
1641 smc->y[n].mib->fddiPORTNeighborType == TM)
1642 return(0) ;
1643 }
1644 return(1) ;
1645}
1646
1647/*
1648 * Interrupt actions for PLC & PCM events
1649 */
1650void plc_irq(struct s_smc *smc, int np, unsigned int cmd)
1651/* int np; PHY index */
1652{
1653 struct s_phy *phy = &smc->y[np] ;
1654 struct s_plc *plc = &phy->plc ;
1655 int n ;
1656#ifdef SUPERNET_3
1657 int corr_mask ;
1658#endif /* SUPERNET_3 */
1659 int i ;
1660
1661 if (np >= smc->s.numphys) {
1662 plc->soft_err++ ;
1663 return ;
1664 }
1665 if (cmd & PL_EBUF_ERR) { /* elastic buff. det. over-|underflow*/
1666 /*
1667 * Check whether the SRF Condition occurred.
1668 */
1669 if (!plc->ebuf_cont && phy->mib->fddiPORTPCMState == PC8_ACTIVE){
1670 /*
1671 * This is the real Elasticity Error.
1672 * More than one in a row are treated as a
1673 * single one.
1674 * Only count this in the active state.
1675 */
1676 phy->mib->fddiPORTEBError_Ct ++ ;
1677
1678 }
1679
1680 plc->ebuf_err++ ;
1681 if (plc->ebuf_cont <= 1000) {
1682 /*
1683 * Prevent counter from being wrapped after
1684 * hanging years in that interrupt.
1685 */
1686 plc->ebuf_cont++ ; /* Ebuf continous error */
1687 }
1688
1689#ifdef SUPERNET_3
1690 if (plc->ebuf_cont == 1000 &&
1691 ((inpw(PLC(np,PL_STATUS_A)) & PLC_REV_MASK) ==
1692 PLC_REV_SN3)) {
1693 /*
1694 * This interrupt remeained high for at least
1695 * 1000 consecutive interrupt calls.
1696 *
1697 * This is caused by a hardware error of the
1698 * ORION part of the Supernet III chipset.
1699 *
1700 * Disable this bit from the mask.
1701 */
1702 corr_mask = (plc_imsk_na & ~PL_EBUF_ERR) ;
1703 outpw(PLC(np,PL_INTR_MASK),corr_mask);
1704
1705 /*
1706 * Disconnect from the ring.
1707 * Call the driver with the reset indication.
1708 */
1709 queue_event(smc,EVENT_ECM,EC_DISCONNECT) ;
1710
1711 /*
1712 * Make an error log entry.
1713 */
1714 SMT_ERR_LOG(smc,SMT_E0136, SMT_E0136_MSG) ;
1715
1716 /*
1717 * Indicate the Reset.
1718 */
1719 drv_reset_indication(smc) ;
1720 }
1721#endif /* SUPERNET_3 */
1722 } else {
1723 /* Reset the continous error variable */
1724 plc->ebuf_cont = 0 ; /* reset Ebuf continous error */
1725 }
1726 if (cmd & PL_PHYINV) { /* physical layer invalid signal */
1727 plc->phyinv++ ;
1728 }
1729 if (cmd & PL_VSYM_CTR) { /* violation symbol counter has incr.*/
1730 plc->vsym_ctr++ ;
1731 }
1732 if (cmd & PL_MINI_CTR) { /* dep. on PLC_CNTRL_A's MINI_CTR_INT*/
1733 plc->mini_ctr++ ;
1734 }
1735 if (cmd & PL_LE_CTR) { /* link error event counter */
1736 int j ;
1737
1738 /*
1739 * note: PL_LINK_ERR_CTR MUST be read to clear it
1740 */
1741 j = inpw(PLC(np,PL_LE_THRESHOLD)) ;
1742 i = inpw(PLC(np,PL_LINK_ERR_CTR)) ;
1743
1744 if (i < j) {
1745 /* wrapped around */
1746 i += 256 ;
1747 }
1748
1749 if (phy->lem.lem_on) {
1750 /* Note: Lem errors shall only be counted when
1751 * link is ACTIVE or LCT is active.
1752 */
1753 phy->lem.lem_errors += i ;
1754 phy->mib->fddiPORTLem_Ct += i ;
1755 }
1756 }
1757 if (cmd & PL_TPC_EXPIRED) { /* TPC timer reached zero */
1758 if (plc->p_state == PS_LCT) {
1759 /*
1760 * end of LCT
1761 */
1762 ;
1763 }
1764 plc->tpc_exp++ ;
1765 }
1766 if (cmd & PL_LS_MATCH) { /* LS == LS in PLC_CNTRL_B's MATCH_LS*/
1767 switch (inpw(PLC(np,PL_CNTRL_B)) & PL_MATCH_LS) {
1768 case PL_I_IDLE : phy->curr_ls = PC_ILS ; break ;
1769 case PL_I_HALT : phy->curr_ls = PC_HLS ; break ;
1770 case PL_I_MASTR : phy->curr_ls = PC_MLS ; break ;
1771 case PL_I_QUIET : phy->curr_ls = PC_QLS ; break ;
1772 }
1773 }
1774 if (cmd & PL_PCM_BREAK) { /* PCM has entered the BREAK state */
1775 int reason;
1776
1777 reason = inpw(PLC(np,PL_STATUS_B)) & PL_BREAK_REASON ;
1778
1779 switch (reason) {
1780 case PL_B_PCS : plc->b_pcs++ ; break ;
1781 case PL_B_TPC : plc->b_tpc++ ; break ;
1782 case PL_B_TNE : plc->b_tne++ ; break ;
1783 case PL_B_QLS : plc->b_qls++ ; break ;
1784 case PL_B_ILS : plc->b_ils++ ; break ;
1785 case PL_B_HLS : plc->b_hls++ ; break ;
1786 }
1787
1788 /*jd 05-Aug-1999 changed: Bug #10419 */
1789 DB_PCMN(1,"PLC %d: MDcF = %x\n", np, smc->e.DisconnectFlag);
1790 if (smc->e.DisconnectFlag == FALSE) {
1791 DB_PCMN(1,"PLC %d: restart (reason %x)\n", np, reason);
1792 queue_event(smc,EVENT_PCM+np,PC_START) ;
1793 }
1794 else {
1795 DB_PCMN(1,"PLC %d: NO!! restart (reason %x)\n", np, reason);
1796 }
1797 return ;
1798 }
1799 /*
1800 * If both CODE & ENABLE are set ignore enable
1801 */
1802 if (cmd & PL_PCM_CODE) { /* receive last sign.-bit | LCT complete */
1803 queue_event(smc,EVENT_PCM+np,PC_SIGNAL) ;
1804 n = inpw(PLC(np,PL_RCV_VECTOR)) ;
1805 for (i = 0 ; i < plc->p_bits ; i++) {
1806 phy->r_val[plc->p_start+i] = n & 1 ;
1807 n >>= 1 ;
1808 }
1809 }
1810 else if (cmd & PL_PCM_ENABLED) { /* asserted SC_JOIN, scrub.completed*/
1811 queue_event(smc,EVENT_PCM+np,PC_JOIN) ;
1812 }
1813 if (cmd & PL_TRACE_PROP) { /* MLS while PC8_ACTIV || PC2_TRACE */
1814 /*PC22b*/
1815 if (!phy->tr_flag) {
1816 DB_PCMN(1,"PCM : irq TRACE_PROP %d %d\n",
1817 np,smc->mib.fddiSMTECMState) ;
1818 phy->tr_flag = TRUE ;
1819 smc->e.trace_prop |= ENTITY_BIT(ENTITY_PHY(np)) ;
1820 queue_event(smc,EVENT_ECM,EC_TRACE_PROP) ;
1821 }
1822 }
1823 /*
1824 * filter PLC glitch ???
1825 * QLS || HLS only while in PC2_TRACE state
1826 */
1827 if ((cmd & PL_SELF_TEST) && (phy->mib->fddiPORTPCMState == PC2_TRACE)) {
1828 /*PC22a*/
1829 if (smc->e.path_test == PT_PASSED) {
1830 DB_PCMN(1,"PCM : state = %s %d\n", get_pcmstate(smc,np),
1831 phy->mib->fddiPORTPCMState) ;
1832
1833 smc->e.path_test = PT_PENDING ;
1834 queue_event(smc,EVENT_ECM,EC_PATH_TEST) ;
1835 }
1836 }
1837 if (cmd & PL_TNE_EXPIRED) { /* TNE: length of noise events */
1838 /* break_required (TNE > NS_Max) */
1839 if (phy->mib->fddiPORTPCMState == PC8_ACTIVE) {
1840 if (!phy->tr_flag) {
1841 DB_PCMN(1,"PCM %c : PC81 %s\n",phy->phy_name,"NSE");
1842 queue_event(smc,EVENT_PCM+np,PC_START) ;
1843 return ;
1844 }
1845 }
1846 }
1847#if 0
1848 if (cmd & PL_NP_ERR) { /* NP has requested to r/w an inv reg*/
1849 /*
1850 * It's a bug by AMD
1851 */
1852 plc->np_err++ ;
1853 }
1854 /* pin inactiv (GND) */
1855 if (cmd & PL_PARITY_ERR) { /* p. error dedected on TX9-0 inp */
1856 plc->parity_err++ ;
1857 }
1858 if (cmd & PL_LSDO) { /* carrier detected */
1859 ;
1860 }
1861#endif
1862}
1863
1864void pcm_set_lct_short(struct s_smc *smc, int n)
1865{
1866 if (n <= 0 || n > 1000)
1867 return ;
1868 smc->s.lct_short = n ;
1869}
1870
1871#ifdef DEBUG
1872/*
1873 * fill state struct
1874 */
1875void pcm_get_state(struct s_smc *smc, struct smt_state *state)
1876{
1877 struct s_phy *phy ;
1878 struct pcm_state *pcs ;
1879 int i ;
1880 int ii ;
1881 short rbits ;
1882 short tbits ;
1883 struct fddi_mib_p *mib ;
1884
1885 for (i = 0, phy = smc->y, pcs = state->pcm_state ; i < NUMPHYS ;
1886 i++ , phy++, pcs++ ) {
1887 mib = phy->mib ;
1888 pcs->pcm_type = (u_char) mib->fddiPORTMy_Type ;
1889 pcs->pcm_state = (u_char) mib->fddiPORTPCMState ;
1890 pcs->pcm_mode = phy->pc_mode ;
1891 pcs->pcm_neighbor = (u_char) mib->fddiPORTNeighborType ;
1892 pcs->pcm_bsf = mib->fddiPORTBS_Flag ;
1893 pcs->pcm_lsf = phy->ls_flag ;
1894 pcs->pcm_lct_fail = (u_char) mib->fddiPORTLCTFail_Ct ;
1895 pcs->pcm_ls_rx = LS2MIB(sm_pm_get_ls(smc,i)) ;
1896 for (ii = 0, rbits = tbits = 0 ; ii < NUMBITS ; ii++) {
1897 rbits <<= 1 ;
1898 tbits <<= 1 ;
1899 if (phy->r_val[NUMBITS-1-ii])
1900 rbits |= 1 ;
1901 if (phy->t_val[NUMBITS-1-ii])
1902 tbits |= 1 ;
1903 }
1904 pcs->pcm_r_val = rbits ;
1905 pcs->pcm_t_val = tbits ;
1906 }
1907}
1908
1909int get_pcm_state(struct s_smc *smc, int np)
1910{
1911 int pcs ;
1912
1913 SK_UNUSED(smc) ;
1914
1915 switch (inpw(PLC(np,PL_STATUS_B)) & PL_PCM_STATE) {
1916 case PL_PC0 : pcs = PC_STOP ; break ;
1917 case PL_PC1 : pcs = PC_START ; break ;
1918 case PL_PC2 : pcs = PC_TRACE ; break ;
1919 case PL_PC3 : pcs = PC_SIGNAL ; break ;
1920 case PL_PC4 : pcs = PC_SIGNAL ; break ;
1921 case PL_PC5 : pcs = PC_SIGNAL ; break ;
1922 case PL_PC6 : pcs = PC_JOIN ; break ;
1923 case PL_PC7 : pcs = PC_JOIN ; break ;
1924 case PL_PC8 : pcs = PC_ENABLE ; break ;
1925 case PL_PC9 : pcs = PC_MAINT ; break ;
1926 default : pcs = PC_DISABLE ; break ;
1927 }
1928 return(pcs) ;
1929}
1930
1931char *get_linestate(struct s_smc *smc, int np)
1932{
1933 char *ls = "" ;
1934
1935 SK_UNUSED(smc) ;
1936
1937 switch (inpw(PLC(np,PL_STATUS_A)) & PL_LINE_ST) {
1938 case PL_L_NLS : ls = "NOISE" ; break ;
1939 case PL_L_ALS : ls = "ACTIV" ; break ;
1940 case PL_L_UND : ls = "UNDEF" ; break ;
1941 case PL_L_ILS4: ls = "ILS 4" ; break ;
1942 case PL_L_QLS : ls = "QLS" ; break ;
1943 case PL_L_MLS : ls = "MLS" ; break ;
1944 case PL_L_HLS : ls = "HLS" ; break ;
1945 case PL_L_ILS16:ls = "ILS16" ; break ;
1946#ifdef lint
1947 default: ls = "unknown" ; break ;
1948#endif
1949 }
1950 return(ls) ;
1951}
1952
1953char *get_pcmstate(struct s_smc *smc, int np)
1954{
1955 char *pcs ;
1956
1957 SK_UNUSED(smc) ;
1958
1959 switch (inpw(PLC(np,PL_STATUS_B)) & PL_PCM_STATE) {
1960 case PL_PC0 : pcs = "OFF" ; break ;
1961 case PL_PC1 : pcs = "BREAK" ; break ;
1962 case PL_PC2 : pcs = "TRACE" ; break ;
1963 case PL_PC3 : pcs = "CONNECT"; break ;
1964 case PL_PC4 : pcs = "NEXT" ; break ;
1965 case PL_PC5 : pcs = "SIGNAL" ; break ;
1966 case PL_PC6 : pcs = "JOIN" ; break ;
1967 case PL_PC7 : pcs = "VERIFY" ; break ;
1968 case PL_PC8 : pcs = "ACTIV" ; break ;
1969 case PL_PC9 : pcs = "MAINT" ; break ;
1970 default : pcs = "UNKNOWN" ; break ;
1971 }
1972 return(pcs) ;
1973}
1974
1975void list_phy(struct s_smc *smc)
1976{
1977 struct s_plc *plc ;
1978 int np ;
1979
1980 for (np = 0 ; np < NUMPHYS ; np++) {
1981 plc = &smc->y[np].plc ;
1982 printf("PHY %d:\tERRORS\t\t\tBREAK_REASONS\t\tSTATES:\n",np) ;
1983 printf("\tsoft_error: %ld \t\tPC_Start : %ld\n",
1984 plc->soft_err,plc->b_pcs);
1985 printf("\tparity_err: %ld \t\tTPC exp. : %ld\t\tLine: %s\n",
1986 plc->parity_err,plc->b_tpc,get_linestate(smc,np)) ;
1987 printf("\tebuf_error: %ld \t\tTNE exp. : %ld\n",
1988 plc->ebuf_err,plc->b_tne) ;
1989 printf("\tphyinvalid: %ld \t\tQLS det. : %ld\t\tPCM : %s\n",
1990 plc->phyinv,plc->b_qls,get_pcmstate(smc,np)) ;
1991 printf("\tviosym_ctr: %ld \t\tILS det. : %ld\n",
1992 plc->vsym_ctr,plc->b_ils) ;
1993 printf("\tmingap_ctr: %ld \t\tHLS det. : %ld\n",
1994 plc->mini_ctr,plc->b_hls) ;
1995 printf("\tnodepr_err: %ld\n",plc->np_err) ;
1996 printf("\tTPC_exp : %ld\n",plc->tpc_exp) ;
1997 printf("\tLEM_err : %ld\n",smc->y[np].lem.lem_errors) ;
1998 }
1999}
2000
2001
2002#ifdef CONCENTRATOR
2003void pcm_lem_dump(struct s_smc *smc)
2004{
2005 int i ;
2006 struct s_phy *phy ;
2007 struct fddi_mib_p *mib ;
2008
2009 char *entostring() ;
2010
2011 printf("PHY errors BER\n") ;
2012 printf("----------------------\n") ;
2013 for (i = 0,phy = smc->y ; i < NUMPHYS ; i++,phy++) {
2014 if (!plc_is_installed(smc,i))
2015 continue ;
2016 mib = phy->mib ;
2017 printf("%s\t%ld\t10E-%d\n",
2018 entostring(smc,ENTITY_PHY(i)),
2019 mib->fddiPORTLem_Ct,
2020 mib->fddiPORTLer_Estimate) ;
2021 }
2022}
2023#endif
2024#endif
diff --git a/drivers/net/skfp/pmf.c b/drivers/net/skfp/pmf.c
new file mode 100644
index 000000000000..f2b446d8b0bf
--- /dev/null
+++ b/drivers/net/skfp/pmf.c
@@ -0,0 +1,1671 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * See the file "skfddi.c" for further information.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * The information in this file is provided "AS IS" without warranty.
14 *
15 ******************************************************************************/
16
17/*
18 Parameter Management Frame processing for SMT 7.2
19*/
20
21#include "h/types.h"
22#include "h/fddi.h"
23#include "h/smc.h"
24#include "h/smt_p.h"
25
26#define KERNEL
27#include "h/smtstate.h"
28
29#ifndef SLIM_SMT
30
31#ifndef lint
32static const char ID_sccs[] = "@(#)pmf.c 1.37 97/08/04 (C) SK " ;
33#endif
34
35static int smt_authorize(struct s_smc *smc, struct smt_header *sm);
36static int smt_check_set_count(struct s_smc *smc, struct smt_header *sm);
37static const struct s_p_tab* smt_get_ptab(u_short para);
38static int smt_mib_phys(struct s_smc *smc);
39int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index, int local,
40 int set);
41void smt_add_para(struct s_smc *smc, struct s_pcon *pcon, u_short para,
42 int index, int local);
43static SMbuf *smt_build_pmf_response(struct s_smc *smc, struct smt_header *req,
44 int set, int local);
45
46#define MOFFSS(e) ((int)&(((struct fddi_mib *)0)->e))
47#define MOFFSA(e) ((int) (((struct fddi_mib *)0)->e))
48
49#define MOFFMS(e) ((int)&(((struct fddi_mib_m *)0)->e))
50#define MOFFMA(e) ((int) (((struct fddi_mib_m *)0)->e))
51
52#define MOFFAS(e) ((int)&(((struct fddi_mib_a *)0)->e))
53#define MOFFAA(e) ((int) (((struct fddi_mib_a *)0)->e))
54
55#define MOFFPS(e) ((int)&(((struct fddi_mib_p *)0)->e))
56#define MOFFPA(e) ((int) (((struct fddi_mib_p *)0)->e))
57
58
59#define AC_G 0x01 /* Get */
60#define AC_GR 0x02 /* Get/Set */
61#define AC_S 0x04 /* Set */
62#define AC_NA 0x08
63#define AC_GROUP 0x10 /* Group */
64#define MS2BCLK(x) ((x)*12500L)
65/*
66 F LFag (byte)
67 B byte
68 S u_short 16 bit
69 C Counter 32 bit
70 L Long 32 bit
71 T Timer_2 32 bit
72 P TimeStamp ;
73 A LongAddress (6 byte)
74 E Enum 16 bit
75 R ResId 16 Bit
76*/
77static const struct s_p_tab {
78 u_short p_num ; /* parameter code */
79 u_char p_access ; /* access rights */
80 u_short p_offset ; /* offset in mib */
81 char p_swap[3] ; /* format string */
82} p_tab[] = {
83 /* StationIdGrp */
84 { SMT_P100A,AC_GROUP } ,
85 { SMT_P100B,AC_G, MOFFSS(fddiSMTStationId), "8" } ,
86 { SMT_P100D,AC_G, MOFFSS(fddiSMTOpVersionId), "S" } ,
87 { SMT_P100E,AC_G, MOFFSS(fddiSMTHiVersionId), "S" } ,
88 { SMT_P100F,AC_G, MOFFSS(fddiSMTLoVersionId), "S" } ,
89 { SMT_P1010,AC_G, MOFFSA(fddiSMTManufacturerData), "D" } ,
90 { SMT_P1011,AC_GR, MOFFSA(fddiSMTUserData), "D" } ,
91 { SMT_P1012,AC_G, MOFFSS(fddiSMTMIBVersionId), "S" } ,
92
93 /* StationConfigGrp */
94 { SMT_P1014,AC_GROUP } ,
95 { SMT_P1015,AC_G, MOFFSS(fddiSMTMac_Ct), "B" } ,
96 { SMT_P1016,AC_G, MOFFSS(fddiSMTNonMaster_Ct), "B" } ,
97 { SMT_P1017,AC_G, MOFFSS(fddiSMTMaster_Ct), "B" } ,
98 { SMT_P1018,AC_G, MOFFSS(fddiSMTAvailablePaths), "B" } ,
99 { SMT_P1019,AC_G, MOFFSS(fddiSMTConfigCapabilities),"S" } ,
100 { SMT_P101A,AC_GR, MOFFSS(fddiSMTConfigPolicy), "wS" } ,
101 { SMT_P101B,AC_GR, MOFFSS(fddiSMTConnectionPolicy),"wS" } ,
102 { SMT_P101D,AC_GR, MOFFSS(fddiSMTTT_Notify), "wS" } ,
103 { SMT_P101E,AC_GR, MOFFSS(fddiSMTStatRptPolicy), "bB" } ,
104 { SMT_P101F,AC_GR, MOFFSS(fddiSMTTrace_MaxExpiration),"lL" } ,
105 { SMT_P1020,AC_G, MOFFSA(fddiSMTPORTIndexes), "II" } ,
106 { SMT_P1021,AC_G, MOFFSS(fddiSMTMACIndexes), "I" } ,
107 { SMT_P1022,AC_G, MOFFSS(fddiSMTBypassPresent), "F" } ,
108
109 /* StatusGrp */
110 { SMT_P1028,AC_GROUP } ,
111 { SMT_P1029,AC_G, MOFFSS(fddiSMTECMState), "E" } ,
112 { SMT_P102A,AC_G, MOFFSS(fddiSMTCF_State), "E" } ,
113 { SMT_P102C,AC_G, MOFFSS(fddiSMTRemoteDisconnectFlag),"F" } ,
114 { SMT_P102D,AC_G, MOFFSS(fddiSMTStationStatus), "E" } ,
115 { SMT_P102E,AC_G, MOFFSS(fddiSMTPeerWrapFlag), "F" } ,
116
117 /* MIBOperationGrp */
118 { SMT_P1032,AC_GROUP } ,
119 { SMT_P1033,AC_G, MOFFSA(fddiSMTTimeStamp),"P" } ,
120 { SMT_P1034,AC_G, MOFFSA(fddiSMTTransitionTimeStamp),"P" } ,
121 /* NOTE : SMT_P1035 is already swapped ! SMT_P_SETCOUNT */
122 { SMT_P1035,AC_G, MOFFSS(fddiSMTSetCount),"4P" } ,
123 { SMT_P1036,AC_G, MOFFSS(fddiSMTLastSetStationId),"8" } ,
124
125 { SMT_P103C,AC_S, 0, "wS" } ,
126
127 /*
128 * PRIVATE EXTENSIONS
129 * only accessible locally to get/set passwd
130 */
131 { SMT_P10F0,AC_GR, MOFFSA(fddiPRPMFPasswd), "8" } ,
132 { SMT_P10F1,AC_GR, MOFFSS(fddiPRPMFStation), "8" } ,
133#ifdef ESS
134 { SMT_P10F2,AC_GR, MOFFSS(fddiESSPayload), "lL" } ,
135 { SMT_P10F3,AC_GR, MOFFSS(fddiESSOverhead), "lL" } ,
136 { SMT_P10F4,AC_GR, MOFFSS(fddiESSMaxTNeg), "lL" } ,
137 { SMT_P10F5,AC_GR, MOFFSS(fddiESSMinSegmentSize), "lL" } ,
138 { SMT_P10F6,AC_GR, MOFFSS(fddiESSCategory), "lL" } ,
139 { SMT_P10F7,AC_GR, MOFFSS(fddiESSSynchTxMode), "wS" } ,
140#endif
141#ifdef SBA
142 { SMT_P10F8,AC_GR, MOFFSS(fddiSBACommand), "bF" } ,
143 { SMT_P10F9,AC_GR, MOFFSS(fddiSBAAvailable), "bF" } ,
144#endif
145 /* MAC Attributes */
146 { SMT_P200A,AC_GROUP } ,
147 { SMT_P200B,AC_G, MOFFMS(fddiMACFrameStatusFunctions),"S" } ,
148 { SMT_P200D,AC_G, MOFFMS(fddiMACT_MaxCapabilitiy),"T" } ,
149 { SMT_P200E,AC_G, MOFFMS(fddiMACTVXCapabilitiy),"T" } ,
150
151 /* ConfigGrp */
152 { SMT_P2014,AC_GROUP } ,
153 { SMT_P2016,AC_G, MOFFMS(fddiMACAvailablePaths), "B" } ,
154 { SMT_P2017,AC_G, MOFFMS(fddiMACCurrentPath), "S" } ,
155 { SMT_P2018,AC_G, MOFFMS(fddiMACUpstreamNbr), "A" } ,
156 { SMT_P2019,AC_G, MOFFMS(fddiMACDownstreamNbr), "A" } ,
157 { SMT_P201A,AC_G, MOFFMS(fddiMACOldUpstreamNbr), "A" } ,
158 { SMT_P201B,AC_G, MOFFMS(fddiMACOldDownstreamNbr),"A" } ,
159 { SMT_P201D,AC_G, MOFFMS(fddiMACDupAddressTest), "E" } ,
160 { SMT_P2020,AC_GR, MOFFMS(fddiMACRequestedPaths), "wS" } ,
161 { SMT_P2021,AC_G, MOFFMS(fddiMACDownstreamPORTType),"E" } ,
162 { SMT_P2022,AC_G, MOFFMS(fddiMACIndex), "S" } ,
163
164 /* AddressGrp */
165 { SMT_P2028,AC_GROUP } ,
166 { SMT_P2029,AC_G, MOFFMS(fddiMACSMTAddress), "A" } ,
167
168 /* OperationGrp */
169 { SMT_P2032,AC_GROUP } ,
170 { SMT_P2033,AC_G, MOFFMS(fddiMACT_Req), "T" } ,
171 { SMT_P2034,AC_G, MOFFMS(fddiMACT_Neg), "T" } ,
172 { SMT_P2035,AC_G, MOFFMS(fddiMACT_Max), "T" } ,
173 { SMT_P2036,AC_G, MOFFMS(fddiMACTvxValue), "T" } ,
174 { SMT_P2038,AC_G, MOFFMS(fddiMACT_Pri0), "T" } ,
175 { SMT_P2039,AC_G, MOFFMS(fddiMACT_Pri1), "T" } ,
176 { SMT_P203A,AC_G, MOFFMS(fddiMACT_Pri2), "T" } ,
177 { SMT_P203B,AC_G, MOFFMS(fddiMACT_Pri3), "T" } ,
178 { SMT_P203C,AC_G, MOFFMS(fddiMACT_Pri4), "T" } ,
179 { SMT_P203D,AC_G, MOFFMS(fddiMACT_Pri5), "T" } ,
180 { SMT_P203E,AC_G, MOFFMS(fddiMACT_Pri6), "T" } ,
181
182
183 /* CountersGrp */
184 { SMT_P2046,AC_GROUP } ,
185 { SMT_P2047,AC_G, MOFFMS(fddiMACFrame_Ct), "C" } ,
186 { SMT_P2048,AC_G, MOFFMS(fddiMACCopied_Ct), "C" } ,
187 { SMT_P2049,AC_G, MOFFMS(fddiMACTransmit_Ct), "C" } ,
188 { SMT_P204A,AC_G, MOFFMS(fddiMACToken_Ct), "C" } ,
189 { SMT_P2051,AC_G, MOFFMS(fddiMACError_Ct), "C" } ,
190 { SMT_P2052,AC_G, MOFFMS(fddiMACLost_Ct), "C" } ,
191 { SMT_P2053,AC_G, MOFFMS(fddiMACTvxExpired_Ct), "C" } ,
192 { SMT_P2054,AC_G, MOFFMS(fddiMACNotCopied_Ct), "C" } ,
193 { SMT_P2056,AC_G, MOFFMS(fddiMACRingOp_Ct), "C" } ,
194
195 /* FrameErrorConditionGrp */
196 { SMT_P205A,AC_GROUP } ,
197 { SMT_P205F,AC_GR, MOFFMS(fddiMACFrameErrorThreshold),"wS" } ,
198 { SMT_P2060,AC_G, MOFFMS(fddiMACFrameErrorRatio), "S" } ,
199
200 /* NotCopiedConditionGrp */
201 { SMT_P2064,AC_GROUP } ,
202 { SMT_P2067,AC_GR, MOFFMS(fddiMACNotCopiedThreshold),"wS" } ,
203 { SMT_P2069,AC_G, MOFFMS(fddiMACNotCopiedRatio), "S" } ,
204
205 /* StatusGrp */
206 { SMT_P206E,AC_GROUP } ,
207 { SMT_P206F,AC_G, MOFFMS(fddiMACRMTState), "S" } ,
208 { SMT_P2070,AC_G, MOFFMS(fddiMACDA_Flag), "F" } ,
209 { SMT_P2071,AC_G, MOFFMS(fddiMACUNDA_Flag), "F" } ,
210 { SMT_P2072,AC_G, MOFFMS(fddiMACFrameErrorFlag), "F" } ,
211 { SMT_P2073,AC_G, MOFFMS(fddiMACNotCopiedFlag), "F" } ,
212 { SMT_P2074,AC_G, MOFFMS(fddiMACMA_UnitdataAvailable),"F" } ,
213 { SMT_P2075,AC_G, MOFFMS(fddiMACHardwarePresent), "F" } ,
214 { SMT_P2076,AC_GR, MOFFMS(fddiMACMA_UnitdataEnable),"bF" } ,
215
216 /*
217 * PRIVATE EXTENSIONS
218 * only accessible locally to get/set TMIN
219 */
220 { SMT_P20F0,AC_NA } ,
221 { SMT_P20F1,AC_GR, MOFFMS(fddiMACT_Min), "lT" } ,
222
223 /* Path Attributes */
224 /*
225 * DON't swap 320B,320F,3210: they are already swapped in swap_para()
226 */
227 { SMT_P320A,AC_GROUP } ,
228 { SMT_P320B,AC_G, MOFFAS(fddiPATHIndex), "r" } ,
229 { SMT_P320F,AC_GR, MOFFAS(fddiPATHSbaPayload), "l4" } ,
230 { SMT_P3210,AC_GR, MOFFAS(fddiPATHSbaOverhead), "l4" } ,
231 /* fddiPATHConfiguration */
232 { SMT_P3212,AC_G, 0, "" } ,
233 { SMT_P3213,AC_GR, MOFFAS(fddiPATHT_Rmode), "lT" } ,
234 { SMT_P3214,AC_GR, MOFFAS(fddiPATHSbaAvailable), "lL" } ,
235 { SMT_P3215,AC_GR, MOFFAS(fddiPATHTVXLowerBound), "lT" } ,
236 { SMT_P3216,AC_GR, MOFFAS(fddiPATHT_MaxLowerBound),"lT" } ,
237 { SMT_P3217,AC_GR, MOFFAS(fddiPATHMaxT_Req), "lT" } ,
238
239 /* Port Attributes */
240 /* ConfigGrp */
241 { SMT_P400A,AC_GROUP } ,
242 { SMT_P400C,AC_G, MOFFPS(fddiPORTMy_Type), "E" } ,
243 { SMT_P400D,AC_G, MOFFPS(fddiPORTNeighborType), "E" } ,
244 { SMT_P400E,AC_GR, MOFFPS(fddiPORTConnectionPolicies),"bB" } ,
245 { SMT_P400F,AC_G, MOFFPS(fddiPORTMacIndicated), "2" } ,
246 { SMT_P4010,AC_G, MOFFPS(fddiPORTCurrentPath), "E" } ,
247 { SMT_P4011,AC_GR, MOFFPA(fddiPORTRequestedPaths), "l4" } ,
248 { SMT_P4012,AC_G, MOFFPS(fddiPORTMACPlacement), "S" } ,
249 { SMT_P4013,AC_G, MOFFPS(fddiPORTAvailablePaths), "B" } ,
250 { SMT_P4016,AC_G, MOFFPS(fddiPORTPMDClass), "E" } ,
251 { SMT_P4017,AC_G, MOFFPS(fddiPORTConnectionCapabilities), "B"} ,
252 { SMT_P401D,AC_G, MOFFPS(fddiPORTIndex), "R" } ,
253
254 /* OperationGrp */
255 { SMT_P401E,AC_GROUP } ,
256 { SMT_P401F,AC_GR, MOFFPS(fddiPORTMaint_LS), "wE" } ,
257 { SMT_P4021,AC_G, MOFFPS(fddiPORTBS_Flag), "F" } ,
258 { SMT_P4022,AC_G, MOFFPS(fddiPORTPC_LS), "E" } ,
259
260 /* ErrorCtrsGrp */
261 { SMT_P4028,AC_GROUP } ,
262 { SMT_P4029,AC_G, MOFFPS(fddiPORTEBError_Ct), "C" } ,
263 { SMT_P402A,AC_G, MOFFPS(fddiPORTLCTFail_Ct), "C" } ,
264
265 /* LerGrp */
266 { SMT_P4032,AC_GROUP } ,
267 { SMT_P4033,AC_G, MOFFPS(fddiPORTLer_Estimate), "F" } ,
268 { SMT_P4034,AC_G, MOFFPS(fddiPORTLem_Reject_Ct), "C" } ,
269 { SMT_P4035,AC_G, MOFFPS(fddiPORTLem_Ct), "C" } ,
270 { SMT_P403A,AC_GR, MOFFPS(fddiPORTLer_Cutoff), "bB" } ,
271 { SMT_P403B,AC_GR, MOFFPS(fddiPORTLer_Alarm), "bB" } ,
272
273 /* StatusGrp */
274 { SMT_P403C,AC_GROUP } ,
275 { SMT_P403D,AC_G, MOFFPS(fddiPORTConnectState), "E" } ,
276 { SMT_P403E,AC_G, MOFFPS(fddiPORTPCMStateX), "E" } ,
277 { SMT_P403F,AC_G, MOFFPS(fddiPORTPC_Withhold), "E" } ,
278 { SMT_P4040,AC_G, MOFFPS(fddiPORTLerFlag), "F" } ,
279 { SMT_P4041,AC_G, MOFFPS(fddiPORTHardwarePresent),"F" } ,
280
281 { SMT_P4046,AC_S, 0, "wS" } ,
282
283 { 0, AC_GROUP } ,
284 { 0 }
285} ;
286
287void smt_pmf_received_pack(struct s_smc *smc, SMbuf *mb, int local)
288{
289 struct smt_header *sm ;
290 SMbuf *reply ;
291
292 sm = smtod(mb,struct smt_header *) ;
293 DB_SMT("SMT: processing PMF frame at %x len %d\n",sm,mb->sm_len) ;
294#ifdef DEBUG
295 dump_smt(smc,sm,"PMF Received") ;
296#endif
297 /*
298 * Start the watchdog: It may be a long, long packet and
299 * maybe the watchdog occurs ...
300 */
301 smt_start_watchdog(smc) ;
302
303 if (sm->smt_class == SMT_PMF_GET ||
304 sm->smt_class == SMT_PMF_SET) {
305 reply = smt_build_pmf_response(smc,sm,
306 sm->smt_class == SMT_PMF_SET,local) ;
307 if (reply) {
308 sm = smtod(reply,struct smt_header *) ;
309#ifdef DEBUG
310 dump_smt(smc,sm,"PMF Reply") ;
311#endif
312 smt_send_frame(smc,reply,FC_SMT_INFO,local) ;
313 }
314 }
315}
316
317static SMbuf *smt_build_pmf_response(struct s_smc *smc, struct smt_header *req,
318 int set, int local)
319{
320 SMbuf *mb ;
321 struct smt_header *smt ;
322 struct smt_para *pa ;
323 struct smt_p_reason *res ;
324 const struct s_p_tab *pt ;
325 int len ;
326 int index ;
327 int idx_end ;
328 int error ;
329 int range ;
330 SK_LOC_DECL(struct s_pcon,pcon) ;
331 SK_LOC_DECL(struct s_pcon,set_pcon) ;
332
333 /*
334 * build SMT header
335 */
336 if (!(mb = smt_get_mbuf(smc)))
337 return(mb) ;
338
339 smt = smtod(mb, struct smt_header *) ;
340 smt->smt_dest = req->smt_source ; /* DA == source of request */
341 smt->smt_class = req->smt_class ; /* same class (GET/SET) */
342 smt->smt_type = SMT_REPLY ;
343 smt->smt_version = SMT_VID_2 ;
344 smt->smt_tid = req->smt_tid ; /* same TID */
345 smt->smt_pad = 0 ;
346 smt->smt_len = 0 ;
347
348 /*
349 * setup parameter status
350 */
351 pcon.pc_len = SMT_MAX_INFO_LEN ; /* max para length */
352 pcon.pc_err = 0 ; /* no error */
353 pcon.pc_badset = 0 ; /* no bad set count */
354 pcon.pc_p = (void *) (smt + 1) ; /* paras start here */
355
356 /*
357 * check authoriziation and set count
358 */
359 error = 0 ;
360 if (set) {
361 if (!local && smt_authorize(smc,req))
362 error = SMT_RDF_AUTHOR ;
363 else if (smt_check_set_count(smc,req))
364 pcon.pc_badset = SMT_RDF_BADSET ;
365 }
366 /*
367 * add reason code and all mandatory parameters
368 */
369 res = (struct smt_p_reason *) pcon.pc_p ;
370 smt_add_para(smc,&pcon,(u_short) SMT_P_REASON,0,0) ;
371 smt_add_para(smc,&pcon,(u_short) SMT_P1033,0,0) ;
372 /* update 1035 and 1036 later if set */
373 set_pcon = pcon ;
374 smt_add_para(smc,&pcon,(u_short) SMT_P1035,0,0) ;
375 smt_add_para(smc,&pcon,(u_short) SMT_P1036,0,0) ;
376
377 pcon.pc_err = error ;
378 len = req->smt_len ;
379 pa = (struct smt_para *) (req + 1) ;
380 /*
381 * process list of paras
382 */
383 while (!pcon.pc_err && len > 0 ) {
384 if (((u_short)len < pa->p_len + PARA_LEN) || (pa->p_len & 3)) {
385 pcon.pc_err = SMT_RDF_LENGTH ;
386 break ;
387 }
388
389 if (((range = (pa->p_type & 0xf000)) == 0x2000) ||
390 range == 0x3000 || range == 0x4000) {
391 /*
392 * get index for PART,MAC ad PATH group
393 */
394 index = *((u_char *)pa + PARA_LEN + 3) ;/* index */
395 idx_end = index ;
396 if (!set && (pa->p_len != 4)) {
397 pcon.pc_err = SMT_RDF_LENGTH ;
398 break ;
399 }
400 if (!index && !set) {
401 switch (range) {
402 case 0x2000 :
403 index = INDEX_MAC ;
404 idx_end = index - 1 + NUMMACS ;
405 break ;
406 case 0x3000 :
407 index = INDEX_PATH ;
408 idx_end = index - 1 + NUMPATHS ;
409 break ;
410 case 0x4000 :
411 index = INDEX_PORT ;
412 idx_end = index - 1 + NUMPHYS ;
413#ifndef CONCENTRATOR
414 if (smc->s.sas == SMT_SAS)
415 idx_end = INDEX_PORT ;
416#endif
417 break ;
418 }
419 }
420 }
421 else {
422 /*
423 * smt group has no index
424 */
425 if (!set && (pa->p_len != 0)) {
426 pcon.pc_err = SMT_RDF_LENGTH ;
427 break ;
428 }
429 index = 0 ;
430 idx_end = 0 ;
431 }
432 while (index <= idx_end) {
433 /*
434 * if group
435 * add all paras of group
436 */
437 pt = smt_get_ptab(pa->p_type) ;
438 if (pt && pt->p_access == AC_GROUP && !set) {
439 pt++ ;
440 while (pt->p_access == AC_G ||
441 pt->p_access == AC_GR) {
442 smt_add_para(smc,&pcon,pt->p_num,
443 index,local);
444 pt++ ;
445 }
446 }
447 /*
448 * ignore
449 * AUTHORIZATION in get/set
450 * SET COUNT in set
451 */
452 else if (pa->p_type != SMT_P_AUTHOR &&
453 (!set || (pa->p_type != SMT_P1035))) {
454 int st ;
455 if (pcon.pc_badset) {
456 smt_add_para(smc,&pcon,pa->p_type,
457 index,local) ;
458 }
459 else if (set) {
460 st = smt_set_para(smc,pa,index,local,1);
461 /*
462 * return para even if error
463 */
464 smt_add_para(smc,&pcon,pa->p_type,
465 index,local) ;
466 pcon.pc_err = st ;
467 }
468 else {
469 if (pt && pt->p_access == AC_S) {
470 pcon.pc_err =
471 SMT_RDF_ILLEGAL ;
472 }
473 smt_add_para(smc,&pcon,pa->p_type,
474 index,local) ;
475 }
476 }
477 if (pcon.pc_err)
478 break ;
479 index++ ;
480 }
481 len -= pa->p_len + PARA_LEN ;
482 pa = (struct smt_para *) ((char *)pa + pa->p_len + PARA_LEN) ;
483 }
484 smt->smt_len = SMT_MAX_INFO_LEN - pcon.pc_len ;
485 mb->sm_len = smt->smt_len + sizeof(struct smt_header) ;
486
487 /* update reason code */
488 res->rdf_reason = pcon.pc_badset ? pcon.pc_badset :
489 pcon.pc_err ? pcon.pc_err : SMT_RDF_SUCCESS ;
490 if (set && (res->rdf_reason == SMT_RDF_SUCCESS)) {
491 /*
492 * increment set count
493 * set time stamp
494 * store station id of last set
495 */
496 smc->mib.fddiSMTSetCount.count++ ;
497 smt_set_timestamp(smc,smc->mib.fddiSMTSetCount.timestamp) ;
498 smc->mib.fddiSMTLastSetStationId = req->smt_sid ;
499 smt_add_para(smc,&set_pcon,(u_short) SMT_P1035,0,0) ;
500 smt_add_para(smc,&set_pcon,(u_short) SMT_P1036,0,0) ;
501 }
502 return(mb) ;
503}
504
505static int smt_authorize(struct s_smc *smc, struct smt_header *sm)
506{
507 struct smt_para *pa ;
508 int i ;
509 char *p ;
510
511 /*
512 * check source station id if not zero
513 */
514 p = (char *) &smc->mib.fddiPRPMFStation ;
515 for (i = 0 ; i < 8 && !p[i] ; i++)
516 ;
517 if (i != 8) {
518 if (memcmp((char *) &sm->smt_sid,
519 (char *) &smc->mib.fddiPRPMFStation,8))
520 return(1) ;
521 }
522 /*
523 * check authoriziation parameter if passwd not zero
524 */
525 p = (char *) smc->mib.fddiPRPMFPasswd ;
526 for (i = 0 ; i < 8 && !p[i] ; i++)
527 ;
528 if (i != 8) {
529 pa = (struct smt_para *) sm_to_para(smc,sm,SMT_P_AUTHOR) ;
530 if (!pa)
531 return(1) ;
532 if (pa->p_len != 8)
533 return(1) ;
534 if (memcmp((char *)(pa+1),(char *)smc->mib.fddiPRPMFPasswd,8))
535 return(1) ;
536 }
537 return(0) ;
538}
539
540static int smt_check_set_count(struct s_smc *smc, struct smt_header *sm)
541{
542 struct smt_para *pa ;
543 struct smt_p_setcount *sc ;
544
545 pa = (struct smt_para *) sm_to_para(smc,sm,SMT_P1035) ;
546 if (pa) {
547 sc = (struct smt_p_setcount *) pa ;
548 if ((smc->mib.fddiSMTSetCount.count != sc->count) ||
549 memcmp((char *) smc->mib.fddiSMTSetCount.timestamp,
550 (char *)sc->timestamp,8))
551 return(1) ;
552 }
553 return(0) ;
554}
555
556void smt_add_para(struct s_smc *smc, struct s_pcon *pcon, u_short para,
557 int index, int local)
558{
559 struct smt_para *pa ;
560 const struct s_p_tab *pt ;
561 struct fddi_mib_m *mib_m = NULL;
562 struct fddi_mib_p *mib_p = NULL;
563 int len ;
564 int plen ;
565 char *from ;
566 char *to ;
567 const char *swap ;
568 char c ;
569 int range ;
570 char *mib_addr ;
571 int mac ;
572 int path ;
573 int port ;
574 int sp_len ;
575
576 /*
577 * skip if errror
578 */
579 if (pcon->pc_err)
580 return ;
581
582 /*
583 * actions don't have a value
584 */
585 pt = smt_get_ptab(para) ;
586 if (pt && pt->p_access == AC_S)
587 return ;
588
589 to = (char *) (pcon->pc_p) ; /* destination pointer */
590 len = pcon->pc_len ; /* free space */
591 plen = len ; /* remember start length */
592 pa = (struct smt_para *) to ; /* type/length pointer */
593 to += PARA_LEN ; /* skip smt_para */
594 len -= PARA_LEN ;
595 /*
596 * set index if required
597 */
598 if (((range = (para & 0xf000)) == 0x2000) ||
599 range == 0x3000 || range == 0x4000) {
600 if (len < 4)
601 goto wrong_error ;
602 to[0] = 0 ;
603 to[1] = 0 ;
604 to[2] = 0 ;
605 to[3] = index ;
606 len -= 4 ;
607 to += 4 ;
608 }
609 mac = index - INDEX_MAC ;
610 path = index - INDEX_PATH ;
611 port = index - INDEX_PORT ;
612 /*
613 * get pointer to mib
614 */
615 switch (range) {
616 case 0x1000 :
617 default :
618 mib_addr = (char *) (&smc->mib) ;
619 break ;
620 case 0x2000 :
621 if (mac < 0 || mac >= NUMMACS) {
622 pcon->pc_err = SMT_RDF_NOPARAM ;
623 return ;
624 }
625 mib_addr = (char *) (&smc->mib.m[mac]) ;
626 mib_m = (struct fddi_mib_m *) mib_addr ;
627 break ;
628 case 0x3000 :
629 if (path < 0 || path >= NUMPATHS) {
630 pcon->pc_err = SMT_RDF_NOPARAM ;
631 return ;
632 }
633 mib_addr = (char *) (&smc->mib.a[path]) ;
634 break ;
635 case 0x4000 :
636 if (port < 0 || port >= smt_mib_phys(smc)) {
637 pcon->pc_err = SMT_RDF_NOPARAM ;
638 return ;
639 }
640 mib_addr = (char *) (&smc->mib.p[port_to_mib(smc,port)]) ;
641 mib_p = (struct fddi_mib_p *) mib_addr ;
642 break ;
643 }
644 /*
645 * check special paras
646 */
647 swap = NULL;
648 switch (para) {
649 case SMT_P10F0 :
650 case SMT_P10F1 :
651#ifdef ESS
652 case SMT_P10F2 :
653 case SMT_P10F3 :
654 case SMT_P10F4 :
655 case SMT_P10F5 :
656 case SMT_P10F6 :
657 case SMT_P10F7 :
658#endif
659#ifdef SBA
660 case SMT_P10F8 :
661 case SMT_P10F9 :
662#endif
663 case SMT_P20F1 :
664 if (!local) {
665 pcon->pc_err = SMT_RDF_NOPARAM ;
666 return ;
667 }
668 break ;
669 case SMT_P2034 :
670 case SMT_P2046 :
671 case SMT_P2047 :
672 case SMT_P204A :
673 case SMT_P2051 :
674 case SMT_P2052 :
675 mac_update_counter(smc) ;
676 break ;
677 case SMT_P4022:
678 mib_p->fddiPORTPC_LS = LS2MIB(
679 sm_pm_get_ls(smc,port_to_mib(smc,port))) ;
680 break ;
681 case SMT_P_REASON :
682 * (u_long *) to = 0 ;
683 sp_len = 4 ;
684 goto sp_done ;
685 case SMT_P1033 : /* time stamp */
686 smt_set_timestamp(smc,smc->mib.fddiSMTTimeStamp) ;
687 break ;
688
689 case SMT_P1020: /* port indexes */
690#if NUMPHYS == 12
691 swap = "IIIIIIIIIIII" ;
692#else
693#if NUMPHYS == 2
694 if (smc->s.sas == SMT_SAS)
695 swap = "I" ;
696 else
697 swap = "II" ;
698#else
699#if NUMPHYS == 24
700 swap = "IIIIIIIIIIIIIIIIIIIIIIII" ;
701#else
702 ????
703#endif
704#endif
705#endif
706 break ;
707 case SMT_P3212 :
708 {
709 sp_len = cem_build_path(smc,to,path) ;
710 goto sp_done ;
711 }
712 case SMT_P1048 : /* peer wrap condition */
713 {
714 struct smt_p_1048 *sp ;
715 sp = (struct smt_p_1048 *) to ;
716 sp->p1048_flag = smc->mib.fddiSMTPeerWrapFlag ;
717 sp->p1048_cf_state = smc->mib.fddiSMTCF_State ;
718 sp_len = sizeof(struct smt_p_1048) ;
719 goto sp_done ;
720 }
721 case SMT_P208C :
722 {
723 struct smt_p_208c *sp ;
724 sp = (struct smt_p_208c *) to ;
725 sp->p208c_flag =
726 smc->mib.m[MAC0].fddiMACDuplicateAddressCond ;
727 sp->p208c_dupcondition =
728 (mib_m->fddiMACDA_Flag ? SMT_ST_MY_DUPA : 0) |
729 (mib_m->fddiMACUNDA_Flag ? SMT_ST_UNA_DUPA : 0);
730 sp->p208c_fddilong =
731 mib_m->fddiMACSMTAddress ;
732 sp->p208c_fddiunalong =
733 mib_m->fddiMACUpstreamNbr ;
734 sp->p208c_pad = 0 ;
735 sp_len = sizeof(struct smt_p_208c) ;
736 goto sp_done ;
737 }
738 case SMT_P208D : /* frame error condition */
739 {
740 struct smt_p_208d *sp ;
741 sp = (struct smt_p_208d *) to ;
742 sp->p208d_flag =
743 mib_m->fddiMACFrameErrorFlag ;
744 sp->p208d_frame_ct =
745 mib_m->fddiMACFrame_Ct ;
746 sp->p208d_error_ct =
747 mib_m->fddiMACError_Ct ;
748 sp->p208d_lost_ct =
749 mib_m->fddiMACLost_Ct ;
750 sp->p208d_ratio =
751 mib_m->fddiMACFrameErrorRatio ;
752 sp_len = sizeof(struct smt_p_208d) ;
753 goto sp_done ;
754 }
755 case SMT_P208E : /* not copied condition */
756 {
757 struct smt_p_208e *sp ;
758 sp = (struct smt_p_208e *) to ;
759 sp->p208e_flag =
760 mib_m->fddiMACNotCopiedFlag ;
761 sp->p208e_not_copied =
762 mib_m->fddiMACNotCopied_Ct ;
763 sp->p208e_copied =
764 mib_m->fddiMACCopied_Ct ;
765 sp->p208e_not_copied_ratio =
766 mib_m->fddiMACNotCopiedRatio ;
767 sp_len = sizeof(struct smt_p_208e) ;
768 goto sp_done ;
769 }
770 case SMT_P208F : /* neighbor change event */
771 {
772 struct smt_p_208f *sp ;
773 sp = (struct smt_p_208f *) to ;
774 sp->p208f_multiple =
775 mib_m->fddiMACMultiple_N ;
776 sp->p208f_nacondition =
777 mib_m->fddiMACDuplicateAddressCond ;
778 sp->p208f_old_una =
779 mib_m->fddiMACOldUpstreamNbr ;
780 sp->p208f_new_una =
781 mib_m->fddiMACUpstreamNbr ;
782 sp->p208f_old_dna =
783 mib_m->fddiMACOldDownstreamNbr ;
784 sp->p208f_new_dna =
785 mib_m->fddiMACDownstreamNbr ;
786 sp->p208f_curren_path =
787 mib_m->fddiMACCurrentPath ;
788 sp->p208f_smt_address =
789 mib_m->fddiMACSMTAddress ;
790 sp_len = sizeof(struct smt_p_208f) ;
791 goto sp_done ;
792 }
793 case SMT_P2090 :
794 {
795 struct smt_p_2090 *sp ;
796 sp = (struct smt_p_2090 *) to ;
797 sp->p2090_multiple =
798 mib_m->fddiMACMultiple_P ;
799 sp->p2090_availablepaths =
800 mib_m->fddiMACAvailablePaths ;
801 sp->p2090_currentpath =
802 mib_m->fddiMACCurrentPath ;
803 sp->p2090_requestedpaths =
804 mib_m->fddiMACRequestedPaths ;
805 sp_len = sizeof(struct smt_p_2090) ;
806 goto sp_done ;
807 }
808 case SMT_P4050 :
809 {
810 struct smt_p_4050 *sp ;
811 sp = (struct smt_p_4050 *) to ;
812 sp->p4050_flag =
813 mib_p->fddiPORTLerFlag ;
814 sp->p4050_pad = 0 ;
815 sp->p4050_cutoff =
816 mib_p->fddiPORTLer_Cutoff ; ;
817 sp->p4050_alarm =
818 mib_p->fddiPORTLer_Alarm ; ;
819 sp->p4050_estimate =
820 mib_p->fddiPORTLer_Estimate ;
821 sp->p4050_reject_ct =
822 mib_p->fddiPORTLem_Reject_Ct ;
823 sp->p4050_ct =
824 mib_p->fddiPORTLem_Ct ;
825 sp_len = sizeof(struct smt_p_4050) ;
826 goto sp_done ;
827 }
828
829 case SMT_P4051 :
830 {
831 struct smt_p_4051 *sp ;
832 sp = (struct smt_p_4051 *) to ;
833 sp->p4051_multiple =
834 mib_p->fddiPORTMultiple_U ;
835 sp->p4051_porttype =
836 mib_p->fddiPORTMy_Type ;
837 sp->p4051_connectstate =
838 mib_p->fddiPORTConnectState ; ;
839 sp->p4051_pc_neighbor =
840 mib_p->fddiPORTNeighborType ;
841 sp->p4051_pc_withhold =
842 mib_p->fddiPORTPC_Withhold ;
843 sp_len = sizeof(struct smt_p_4051) ;
844 goto sp_done ;
845 }
846 case SMT_P4052 :
847 {
848 struct smt_p_4052 *sp ;
849 sp = (struct smt_p_4052 *) to ;
850 sp->p4052_flag =
851 mib_p->fddiPORTEB_Condition ;
852 sp->p4052_eberrorcount =
853 mib_p->fddiPORTEBError_Ct ;
854 sp_len = sizeof(struct smt_p_4052) ;
855 goto sp_done ;
856 }
857 case SMT_P4053 :
858 {
859 struct smt_p_4053 *sp ;
860 sp = (struct smt_p_4053 *) to ;
861 sp->p4053_multiple =
862 mib_p->fddiPORTMultiple_P ; ;
863 sp->p4053_availablepaths =
864 mib_p->fddiPORTAvailablePaths ;
865 sp->p4053_currentpath =
866 mib_p->fddiPORTCurrentPath ;
867 memcpy( (char *) &sp->p4053_requestedpaths,
868 (char *) mib_p->fddiPORTRequestedPaths,4) ;
869 sp->p4053_mytype =
870 mib_p->fddiPORTMy_Type ;
871 sp->p4053_neighbortype =
872 mib_p->fddiPORTNeighborType ;
873 sp_len = sizeof(struct smt_p_4053) ;
874 goto sp_done ;
875 }
876 default :
877 break ;
878 }
879 /*
880 * in table ?
881 */
882 if (!pt) {
883 pcon->pc_err = (para & 0xff00) ? SMT_RDF_NOPARAM :
884 SMT_RDF_ILLEGAL ;
885 return ;
886 }
887 /*
888 * check access rights
889 */
890 switch (pt->p_access) {
891 case AC_G :
892 case AC_GR :
893 break ;
894 default :
895 pcon->pc_err = SMT_RDF_ILLEGAL ;
896 return ;
897 }
898 from = mib_addr + pt->p_offset ;
899 if (!swap)
900 swap = pt->p_swap ; /* pointer to swap string */
901
902 /*
903 * copy values
904 */
905 while ((c = *swap++)) {
906 switch(c) {
907 case 'b' :
908 case 'w' :
909 case 'l' :
910 break ;
911 case 'S' :
912 case 'E' :
913 case 'R' :
914 case 'r' :
915 if (len < 4)
916 goto len_error ;
917 to[0] = 0 ;
918 to[1] = 0 ;
919#ifdef LITTLE_ENDIAN
920 if (c == 'r') {
921 to[2] = *from++ ;
922 to[3] = *from++ ;
923 }
924 else {
925 to[3] = *from++ ;
926 to[2] = *from++ ;
927 }
928#else
929 to[2] = *from++ ;
930 to[3] = *from++ ;
931#endif
932 to += 4 ;
933 len -= 4 ;
934 break ;
935 case 'I' : /* for SET of port indexes */
936 if (len < 2)
937 goto len_error ;
938#ifdef LITTLE_ENDIAN
939 to[1] = *from++ ;
940 to[0] = *from++ ;
941#else
942 to[0] = *from++ ;
943 to[1] = *from++ ;
944#endif
945 to += 2 ;
946 len -= 2 ;
947 break ;
948 case 'F' :
949 case 'B' :
950 if (len < 4)
951 goto len_error ;
952 len -= 4 ;
953 to[0] = 0 ;
954 to[1] = 0 ;
955 to[2] = 0 ;
956 to[3] = *from++ ;
957 to += 4 ;
958 break ;
959 case 'C' :
960 case 'T' :
961 case 'L' :
962 if (len < 4)
963 goto len_error ;
964#ifdef LITTLE_ENDIAN
965 to[3] = *from++ ;
966 to[2] = *from++ ;
967 to[1] = *from++ ;
968 to[0] = *from++ ;
969#else
970 to[0] = *from++ ;
971 to[1] = *from++ ;
972 to[2] = *from++ ;
973 to[3] = *from++ ;
974#endif
975 len -= 4 ;
976 to += 4 ;
977 break ;
978 case '2' : /* PortMacIndicated */
979 if (len < 4)
980 goto len_error ;
981 to[0] = 0 ;
982 to[1] = 0 ;
983 to[2] = *from++ ;
984 to[3] = *from++ ;
985 len -= 4 ;
986 to += 4 ;
987 break ;
988 case '4' :
989 if (len < 4)
990 goto len_error ;
991 to[0] = *from++ ;
992 to[1] = *from++ ;
993 to[2] = *from++ ;
994 to[3] = *from++ ;
995 len -= 4 ;
996 to += 4 ;
997 break ;
998 case 'A' :
999 if (len < 8)
1000 goto len_error ;
1001 to[0] = 0 ;
1002 to[1] = 0 ;
1003 memcpy((char *) to+2,(char *) from,6) ;
1004 to += 8 ;
1005 from += 8 ;
1006 len -= 8 ;
1007 break ;
1008 case '8' :
1009 if (len < 8)
1010 goto len_error ;
1011 memcpy((char *) to,(char *) from,8) ;
1012 to += 8 ;
1013 from += 8 ;
1014 len -= 8 ;
1015 break ;
1016 case 'D' :
1017 if (len < 32)
1018 goto len_error ;
1019 memcpy((char *) to,(char *) from,32) ;
1020 to += 32 ;
1021 from += 32 ;
1022 len -= 32 ;
1023 break ;
1024 case 'P' : /* timestamp is NOT swapped */
1025 if (len < 8)
1026 goto len_error ;
1027 to[0] = *from++ ;
1028 to[1] = *from++ ;
1029 to[2] = *from++ ;
1030 to[3] = *from++ ;
1031 to[4] = *from++ ;
1032 to[5] = *from++ ;
1033 to[6] = *from++ ;
1034 to[7] = *from++ ;
1035 to += 8 ;
1036 len -= 8 ;
1037 break ;
1038 default :
1039 SMT_PANIC(smc,SMT_E0119, SMT_E0119_MSG) ;
1040 break ;
1041 }
1042 }
1043
1044done:
1045 /*
1046 * make it even (in case of 'I' encoding)
1047 * note: len is DECREMENTED
1048 */
1049 if (len & 3) {
1050 to[0] = 0 ;
1051 to[1] = 0 ;
1052 to += 4 - (len & 3 ) ;
1053 len = len & ~ 3 ;
1054 }
1055
1056 /* set type and length */
1057 pa->p_type = para ;
1058 pa->p_len = plen - len - PARA_LEN ;
1059 /* return values */
1060 pcon->pc_p = (void *) to ;
1061 pcon->pc_len = len ;
1062 return ;
1063
1064sp_done:
1065 len -= sp_len ;
1066 to += sp_len ;
1067 goto done ;
1068
1069len_error:
1070 /* parameter does not fit in frame */
1071 pcon->pc_err = SMT_RDF_TOOLONG ;
1072 return ;
1073
1074wrong_error:
1075 pcon->pc_err = SMT_RDF_LENGTH ;
1076}
1077
1078/*
1079 * set parameter
1080 */
1081int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index, int local,
1082 int set)
1083{
1084#define IFSET(x) if (set) (x)
1085
1086 const struct s_p_tab *pt ;
1087 int len ;
1088 char *from ;
1089 char *to ;
1090 const char *swap ;
1091 char c ;
1092 char *mib_addr ;
1093 struct fddi_mib *mib ;
1094 struct fddi_mib_m *mib_m = NULL;
1095 struct fddi_mib_a *mib_a = NULL;
1096 struct fddi_mib_p *mib_p = NULL;
1097 int mac ;
1098 int path ;
1099 int port ;
1100 SK_LOC_DECL(u_char,byte_val) ;
1101 SK_LOC_DECL(u_short,word_val) ;
1102 SK_LOC_DECL(u_long,long_val) ;
1103
1104 mac = index - INDEX_MAC ;
1105 path = index - INDEX_PATH ;
1106 port = index - INDEX_PORT ;
1107 len = pa->p_len ;
1108 from = (char *) (pa + 1 ) ;
1109
1110 mib = &smc->mib ;
1111 switch (pa->p_type & 0xf000) {
1112 case 0x1000 :
1113 default :
1114 mib_addr = (char *) mib ;
1115 break ;
1116 case 0x2000 :
1117 if (mac < 0 || mac >= NUMMACS) {
1118 return(SMT_RDF_NOPARAM) ;
1119 }
1120 mib_m = &smc->mib.m[mac] ;
1121 mib_addr = (char *) mib_m ;
1122 from += 4 ; /* skip index */
1123 len -= 4 ;
1124 break ;
1125 case 0x3000 :
1126 if (path < 0 || path >= NUMPATHS) {
1127 return(SMT_RDF_NOPARAM) ;
1128 }
1129 mib_a = &smc->mib.a[path] ;
1130 mib_addr = (char *) mib_a ;
1131 from += 4 ; /* skip index */
1132 len -= 4 ;
1133 break ;
1134 case 0x4000 :
1135 if (port < 0 || port >= smt_mib_phys(smc)) {
1136 return(SMT_RDF_NOPARAM) ;
1137 }
1138 mib_p = &smc->mib.p[port_to_mib(smc,port)] ;
1139 mib_addr = (char *) mib_p ;
1140 from += 4 ; /* skip index */
1141 len -= 4 ;
1142 break ;
1143 }
1144 switch (pa->p_type) {
1145 case SMT_P10F0 :
1146 case SMT_P10F1 :
1147#ifdef ESS
1148 case SMT_P10F2 :
1149 case SMT_P10F3 :
1150 case SMT_P10F4 :
1151 case SMT_P10F5 :
1152 case SMT_P10F6 :
1153 case SMT_P10F7 :
1154#endif
1155#ifdef SBA
1156 case SMT_P10F8 :
1157 case SMT_P10F9 :
1158#endif
1159 case SMT_P20F1 :
1160 if (!local) {
1161 return(SMT_RDF_NOPARAM) ;
1162 }
1163 break ;
1164 }
1165 pt = smt_get_ptab(pa->p_type) ;
1166 if (!pt) {
1167 return( (pa->p_type & 0xff00) ? SMT_RDF_NOPARAM :
1168 SMT_RDF_ILLEGAL ) ;
1169 }
1170 switch (pt->p_access) {
1171 case AC_GR :
1172 case AC_S :
1173 break ;
1174 default :
1175 return(SMT_RDF_ILLEGAL) ;
1176 }
1177 to = mib_addr + pt->p_offset ;
1178 swap = pt->p_swap ; /* pointer to swap string */
1179
1180 while (swap && (c = *swap++)) {
1181 switch(c) {
1182 case 'b' :
1183 to = (char *) &byte_val ;
1184 break ;
1185 case 'w' :
1186 to = (char *) &word_val ;
1187 break ;
1188 case 'l' :
1189 to = (char *) &long_val ;
1190 break ;
1191 case 'S' :
1192 case 'E' :
1193 case 'R' :
1194 case 'r' :
1195 if (len < 4) {
1196 goto len_error ;
1197 }
1198 if (from[0] | from[1])
1199 goto val_error ;
1200#ifdef LITTLE_ENDIAN
1201 if (c == 'r') {
1202 to[0] = from[2] ;
1203 to[1] = from[3] ;
1204 }
1205 else {
1206 to[1] = from[2] ;
1207 to[0] = from[3] ;
1208 }
1209#else
1210 to[0] = from[2] ;
1211 to[1] = from[3] ;
1212#endif
1213 from += 4 ;
1214 to += 2 ;
1215 len -= 4 ;
1216 break ;
1217 case 'F' :
1218 case 'B' :
1219 if (len < 4) {
1220 goto len_error ;
1221 }
1222 if (from[0] | from[1] | from[2])
1223 goto val_error ;
1224 to[0] = from[3] ;
1225 len -= 4 ;
1226 from += 4 ;
1227 to += 4 ;
1228 break ;
1229 case 'C' :
1230 case 'T' :
1231 case 'L' :
1232 if (len < 4) {
1233 goto len_error ;
1234 }
1235#ifdef LITTLE_ENDIAN
1236 to[3] = *from++ ;
1237 to[2] = *from++ ;
1238 to[1] = *from++ ;
1239 to[0] = *from++ ;
1240#else
1241 to[0] = *from++ ;
1242 to[1] = *from++ ;
1243 to[2] = *from++ ;
1244 to[3] = *from++ ;
1245#endif
1246 len -= 4 ;
1247 to += 4 ;
1248 break ;
1249 case 'A' :
1250 if (len < 8)
1251 goto len_error ;
1252 if (set)
1253 memcpy((char *) to,(char *) from+2,6) ;
1254 to += 8 ;
1255 from += 8 ;
1256 len -= 8 ;
1257 break ;
1258 case '4' :
1259 if (len < 4)
1260 goto len_error ;
1261 if (set)
1262 memcpy((char *) to,(char *) from,4) ;
1263 to += 4 ;
1264 from += 4 ;
1265 len -= 4 ;
1266 break ;
1267 case '8' :
1268 if (len < 8)
1269 goto len_error ;
1270 if (set)
1271 memcpy((char *) to,(char *) from,8) ;
1272 to += 8 ;
1273 from += 8 ;
1274 len -= 8 ;
1275 break ;
1276 case 'D' :
1277 if (len < 32)
1278 goto len_error ;
1279 if (set)
1280 memcpy((char *) to,(char *) from,32) ;
1281 to += 32 ;
1282 from += 32 ;
1283 len -= 32 ;
1284 break ;
1285 case 'P' : /* timestamp is NOT swapped */
1286 if (set) {
1287 to[0] = *from++ ;
1288 to[1] = *from++ ;
1289 to[2] = *from++ ;
1290 to[3] = *from++ ;
1291 to[4] = *from++ ;
1292 to[5] = *from++ ;
1293 to[6] = *from++ ;
1294 to[7] = *from++ ;
1295 }
1296 to += 8 ;
1297 len -= 8 ;
1298 break ;
1299 default :
1300 SMT_PANIC(smc,SMT_E0120, SMT_E0120_MSG) ;
1301 return(SMT_RDF_ILLEGAL) ;
1302 }
1303 }
1304 /*
1305 * actions and internal updates
1306 */
1307 switch (pa->p_type) {
1308 case SMT_P101A: /* fddiSMTConfigPolicy */
1309 if (word_val & ~1)
1310 goto val_error ;
1311 IFSET(mib->fddiSMTConfigPolicy = word_val) ;
1312 break ;
1313 case SMT_P101B : /* fddiSMTConnectionPolicy */
1314 if (!(word_val & POLICY_MM))
1315 goto val_error ;
1316 IFSET(mib->fddiSMTConnectionPolicy = word_val) ;
1317 break ;
1318 case SMT_P101D : /* fddiSMTTT_Notify */
1319 if (word_val < 2 || word_val > 30)
1320 goto val_error ;
1321 IFSET(mib->fddiSMTTT_Notify = word_val) ;
1322 break ;
1323 case SMT_P101E : /* fddiSMTStatRptPolicy */
1324 if (byte_val & ~1)
1325 goto val_error ;
1326 IFSET(mib->fddiSMTStatRptPolicy = byte_val) ;
1327 break ;
1328 case SMT_P101F : /* fddiSMTTrace_MaxExpiration */
1329 /*
1330 * note: lower limit trace_max = 6.001773... s
1331 * NO upper limit
1332 */
1333 if (long_val < (long)0x478bf51L)
1334 goto val_error ;
1335 IFSET(mib->fddiSMTTrace_MaxExpiration = long_val) ;
1336 break ;
1337#ifdef ESS
1338 case SMT_P10F2 : /* fddiESSPayload */
1339 if (long_val > 1562)
1340 goto val_error ;
1341 if (set && smc->mib.fddiESSPayload != long_val) {
1342 smc->ess.raf_act_timer_poll = TRUE ;
1343 smc->mib.fddiESSPayload = long_val ;
1344 }
1345 break ;
1346 case SMT_P10F3 : /* fddiESSOverhead */
1347 if (long_val < 50 || long_val > 5000)
1348 goto val_error ;
1349 if (set && smc->mib.fddiESSPayload &&
1350 smc->mib.fddiESSOverhead != long_val) {
1351 smc->ess.raf_act_timer_poll = TRUE ;
1352 smc->mib.fddiESSOverhead = long_val ;
1353 }
1354 break ;
1355 case SMT_P10F4 : /* fddiESSMaxTNeg */
1356 if (long_val > -MS2BCLK(5) || long_val < -MS2BCLK(165))
1357 goto val_error ;
1358 IFSET(mib->fddiESSMaxTNeg = long_val) ;
1359 break ;
1360 case SMT_P10F5 : /* fddiESSMinSegmentSize */
1361 if (long_val < 1 || long_val > 4478)
1362 goto val_error ;
1363 IFSET(mib->fddiESSMinSegmentSize = long_val) ;
1364 break ;
1365 case SMT_P10F6 : /* fddiESSCategory */
1366 if ((long_val & 0xffff) != 1)
1367 goto val_error ;
1368 IFSET(mib->fddiESSCategory = long_val) ;
1369 break ;
1370 case SMT_P10F7 : /* fddiESSSyncTxMode */
1371 if (word_val > 1)
1372 goto val_error ;
1373 IFSET(mib->fddiESSSynchTxMode = word_val) ;
1374 break ;
1375#endif
1376#ifdef SBA
1377 case SMT_P10F8 : /* fddiSBACommand */
1378 if (byte_val != SB_STOP && byte_val != SB_START)
1379 goto val_error ;
1380 IFSET(mib->fddiSBACommand = byte_val) ;
1381 break ;
1382 case SMT_P10F9 : /* fddiSBAAvailable */
1383 if (byte_val > 100)
1384 goto val_error ;
1385 IFSET(mib->fddiSBAAvailable = byte_val) ;
1386 break ;
1387#endif
1388 case SMT_P2020 : /* fddiMACRequestedPaths */
1389 if ((word_val & (MIB_P_PATH_PRIM_PREFER |
1390 MIB_P_PATH_PRIM_ALTER)) == 0 )
1391 goto val_error ;
1392 IFSET(mib_m->fddiMACRequestedPaths = word_val) ;
1393 break ;
1394 case SMT_P205F : /* fddiMACFrameErrorThreshold */
1395 /* 0 .. ffff acceptable */
1396 IFSET(mib_m->fddiMACFrameErrorThreshold = word_val) ;
1397 break ;
1398 case SMT_P2067 : /* fddiMACNotCopiedThreshold */
1399 /* 0 .. ffff acceptable */
1400 IFSET(mib_m->fddiMACNotCopiedThreshold = word_val) ;
1401 break ;
1402 case SMT_P2076: /* fddiMACMA_UnitdataEnable */
1403 if (byte_val & ~1)
1404 goto val_error ;
1405 if (set) {
1406 mib_m->fddiMACMA_UnitdataEnable = byte_val ;
1407 queue_event(smc,EVENT_RMT,RM_ENABLE_FLAG) ;
1408 }
1409 break ;
1410 case SMT_P20F1 : /* fddiMACT_Min */
1411 IFSET(mib_m->fddiMACT_Min = long_val) ;
1412 break ;
1413 case SMT_P320F :
1414 if (long_val > 1562)
1415 goto val_error ;
1416 IFSET(mib_a->fddiPATHSbaPayload = long_val) ;
1417#ifdef ESS
1418 if (set)
1419 ess_para_change(smc) ;
1420#endif
1421 break ;
1422 case SMT_P3210 :
1423 if (long_val > 5000)
1424 goto val_error ;
1425
1426 if (long_val != 0 && mib_a->fddiPATHSbaPayload == 0)
1427 goto val_error ;
1428
1429 IFSET(mib_a->fddiPATHSbaOverhead = long_val) ;
1430#ifdef ESS
1431 if (set)
1432 ess_para_change(smc) ;
1433#endif
1434 break ;
1435 case SMT_P3213: /* fddiPATHT_Rmode */
1436 /* no limit :
1437 * 0 .. 343.597 => 0 .. 2e32 * 80nS
1438 */
1439 if (set) {
1440 mib_a->fddiPATHT_Rmode = long_val ;
1441 rtm_set_timer(smc) ;
1442 }
1443 break ;
1444 case SMT_P3214 : /* fddiPATHSbaAvailable */
1445 if (long_val > 0x00BEBC20L)
1446 goto val_error ;
1447#ifdef SBA
1448 if (set && mib->fddiSBACommand == SB_STOP)
1449 goto val_error ;
1450#endif
1451 IFSET(mib_a->fddiPATHSbaAvailable = long_val) ;
1452 break ;
1453 case SMT_P3215 : /* fddiPATHTVXLowerBound */
1454 IFSET(mib_a->fddiPATHTVXLowerBound = long_val) ;
1455 goto change_mac_para ;
1456 case SMT_P3216 : /* fddiPATHT_MaxLowerBound */
1457 IFSET(mib_a->fddiPATHT_MaxLowerBound = long_val) ;
1458 goto change_mac_para ;
1459 case SMT_P3217 : /* fddiPATHMaxT_Req */
1460 IFSET(mib_a->fddiPATHMaxT_Req = long_val) ;
1461
1462change_mac_para:
1463 if (set && smt_set_mac_opvalues(smc)) {
1464 RS_SET(smc,RS_EVENT) ;
1465 smc->sm.please_reconnect = 1 ;
1466 queue_event(smc,EVENT_ECM,EC_DISCONNECT) ;
1467 }
1468 break ;
1469 case SMT_P400E : /* fddiPORTConnectionPolicies */
1470 if (byte_val > 1)
1471 goto val_error ;
1472 IFSET(mib_p->fddiPORTConnectionPolicies = byte_val) ;
1473 break ;
1474 case SMT_P4011 : /* fddiPORTRequestedPaths */
1475 /* all 3*8 bits allowed */
1476 IFSET(memcpy((char *)mib_p->fddiPORTRequestedPaths,
1477 (char *)&long_val,4)) ;
1478 break ;
1479 case SMT_P401F: /* fddiPORTMaint_LS */
1480 if (word_val > 4)
1481 goto val_error ;
1482 IFSET(mib_p->fddiPORTMaint_LS = word_val) ;
1483 break ;
1484 case SMT_P403A : /* fddiPORTLer_Cutoff */
1485 if (byte_val < 4 || byte_val > 15)
1486 goto val_error ;
1487 IFSET(mib_p->fddiPORTLer_Cutoff = byte_val) ;
1488 break ;
1489 case SMT_P403B : /* fddiPORTLer_Alarm */
1490 if (byte_val < 4 || byte_val > 15)
1491 goto val_error ;
1492 IFSET(mib_p->fddiPORTLer_Alarm = byte_val) ;
1493 break ;
1494
1495 /*
1496 * Actions
1497 */
1498 case SMT_P103C : /* fddiSMTStationAction */
1499 if (smt_action(smc,SMT_STATION_ACTION, (int) word_val, 0))
1500 goto val_error ;
1501 break ;
1502 case SMT_P4046: /* fddiPORTAction */
1503 if (smt_action(smc,SMT_PORT_ACTION, (int) word_val,
1504 port_to_mib(smc,port)))
1505 goto val_error ;
1506 break ;
1507 default :
1508 break ;
1509 }
1510 return(0) ;
1511
1512val_error:
1513 /* parameter value in frame is out of range */
1514 return(SMT_RDF_RANGE) ;
1515
1516len_error:
1517 /* parameter value in frame is too short */
1518 return(SMT_RDF_LENGTH) ;
1519
1520#if 0
1521no_author_error:
1522 /* parameter not setable, because the SBA is not active
1523 * Please note: we give the return code 'not authorizeed
1524 * because SBA denied is not a valid return code in the
1525 * PMF protocol.
1526 */
1527 return(SMT_RDF_AUTHOR) ;
1528#endif
1529}
1530
1531static const struct s_p_tab *smt_get_ptab(u_short para)
1532{
1533 const struct s_p_tab *pt ;
1534 for (pt = p_tab ; pt->p_num && pt->p_num != para ; pt++)
1535 ;
1536 return(pt->p_num ? pt : NULL) ;
1537}
1538
1539static int smt_mib_phys(struct s_smc *smc)
1540{
1541#ifdef CONCENTRATOR
1542 SK_UNUSED(smc) ;
1543
1544 return(NUMPHYS) ;
1545#else
1546 if (smc->s.sas == SMT_SAS)
1547 return(1) ;
1548 return(NUMPHYS) ;
1549#endif
1550}
1551
1552int port_to_mib(struct s_smc *smc, int p)
1553{
1554#ifdef CONCENTRATOR
1555 SK_UNUSED(smc) ;
1556
1557 return(p) ;
1558#else
1559 if (smc->s.sas == SMT_SAS)
1560 return(PS) ;
1561 return(p) ;
1562#endif
1563}
1564
1565
1566#ifdef DEBUG
1567#ifndef BOOT
1568void dump_smt(struct s_smc *smc, struct smt_header *sm, char *text)
1569{
1570 int len ;
1571 struct smt_para *pa ;
1572 char *c ;
1573 int n ;
1574 int nn ;
1575#ifdef LITTLE_ENDIAN
1576 int smtlen ;
1577#endif
1578
1579 SK_UNUSED(smc) ;
1580
1581#ifdef DEBUG_BRD
1582 if (smc->debug.d_smtf < 2)
1583#else
1584 if (debug.d_smtf < 2)
1585#endif
1586 return ;
1587#ifdef LITTLE_ENDIAN
1588 smtlen = sm->smt_len + sizeof(struct smt_header) ;
1589#endif
1590 printf("SMT Frame [%s]:\nDA ",text) ;
1591 dump_hex((char *) &sm->smt_dest,6) ;
1592 printf("\tSA ") ;
1593 dump_hex((char *) &sm->smt_source,6) ;
1594 printf(" Class %x Type %x Version %x\n",
1595 sm->smt_class,sm->smt_type,sm->smt_version) ;
1596 printf("TID %lx\t\tSID ",sm->smt_tid) ;
1597 dump_hex((char *) &sm->smt_sid,8) ;
1598 printf(" LEN %x\n",sm->smt_len) ;
1599
1600 len = sm->smt_len ;
1601 pa = (struct smt_para *) (sm + 1) ;
1602 while (len > 0 ) {
1603 int plen ;
1604#ifdef UNIX
1605 printf("TYPE %x LEN %x VALUE\t",pa->p_type,pa->p_len) ;
1606#else
1607 printf("TYPE %04x LEN %2x VALUE\t",pa->p_type,pa->p_len) ;
1608#endif
1609 n = pa->p_len ;
1610 if ( (n < 0 ) || (n > (int)(len - PARA_LEN))) {
1611 n = len - PARA_LEN ;
1612 printf(" BAD LENGTH\n") ;
1613 break ;
1614 }
1615#ifdef LITTLE_ENDIAN
1616 smt_swap_para(sm,smtlen,0) ;
1617#endif
1618 if (n < 24) {
1619 dump_hex((char *)(pa+1),(int) n) ;
1620 printf("\n") ;
1621 }
1622 else {
1623 int first = 0 ;
1624 c = (char *)(pa+1) ;
1625 dump_hex(c,16) ;
1626 printf("\n") ;
1627 n -= 16 ;
1628 c += 16 ;
1629 while (n > 0) {
1630 nn = (n > 16) ? 16 : n ;
1631 if (n > 64) {
1632 if (first == 0)
1633 printf("\t\t\t...\n") ;
1634 first = 1 ;
1635 }
1636 else {
1637 printf("\t\t\t") ;
1638 dump_hex(c,nn) ;
1639 printf("\n") ;
1640 }
1641 n -= nn ;
1642 c += 16 ;
1643 }
1644 }
1645#ifdef LITTLE_ENDIAN
1646 smt_swap_para(sm,smtlen,1) ;
1647#endif
1648 plen = (pa->p_len + PARA_LEN + 3) & ~3 ;
1649 len -= plen ;
1650 pa = (struct smt_para *)((char *)pa + plen) ;
1651 }
1652 printf("-------------------------------------------------\n\n") ;
1653}
1654
1655void dump_hex(char *p, int len)
1656{
1657 int n = 0 ;
1658 while (len--) {
1659 n++ ;
1660#ifdef UNIX
1661 printf("%x%s",*p++ & 0xff,len ? ( (n & 7) ? " " : "-") : "") ;
1662#else
1663 printf("%02x%s",*p++ & 0xff,len ? ( (n & 7) ? " " : "-") : "") ;
1664#endif
1665 }
1666}
1667#endif /* no BOOT */
1668#endif /* DEBUG */
1669
1670
1671#endif /* no SLIM_SMT */
diff --git a/drivers/net/skfp/queue.c b/drivers/net/skfp/queue.c
new file mode 100644
index 000000000000..09adb3d68b7c
--- /dev/null
+++ b/drivers/net/skfp/queue.c
@@ -0,0 +1,173 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * See the file "skfddi.c" for further information.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * The information in this file is provided "AS IS" without warranty.
14 *
15 ******************************************************************************/
16
17/*
18 SMT Event Queue Management
19*/
20
21#include "h/types.h"
22#include "h/fddi.h"
23#include "h/smc.h"
24
25#ifndef lint
26static const char ID_sccs[] = "@(#)queue.c 2.9 97/08/04 (C) SK " ;
27#endif
28
29#define PRINTF(a,b,c)
30
31/*
32 * init event queue management
33 */
34void ev_init(struct s_smc *smc)
35{
36 smc->q.ev_put = smc->q.ev_get = smc->q.ev_queue ;
37}
38
39/*
40 * add event to queue
41 */
42void queue_event(struct s_smc *smc, int class, int event)
43{
44 PRINTF("queue class %d event %d\n",class,event) ;
45 smc->q.ev_put->class = class ;
46 smc->q.ev_put->event = event ;
47 if (++smc->q.ev_put == &smc->q.ev_queue[MAX_EVENT])
48 smc->q.ev_put = smc->q.ev_queue ;
49
50 if (smc->q.ev_put == smc->q.ev_get) {
51 SMT_ERR_LOG(smc,SMT_E0137, SMT_E0137_MSG) ;
52 }
53}
54
55/*
56 * timer_event is called from HW timer package.
57 */
58void timer_event(struct s_smc *smc, u_long token)
59{
60 PRINTF("timer event class %d token %d\n",
61 EV_T_CLASS(token),
62 EV_T_EVENT(token)) ;
63 queue_event(smc,EV_T_CLASS(token),EV_T_EVENT(token));
64}
65
66/*
67 * event dispatcher
68 * while event queue is not empty
69 * get event from queue
70 * send command to state machine
71 * end
72 */
73void ev_dispatcher(struct s_smc *smc)
74{
75 struct event_queue *ev ; /* pointer into queue */
76 int class ;
77
78 ev = smc->q.ev_get ;
79 PRINTF("dispatch get %x put %x\n",ev,smc->q.ev_put) ;
80 while (ev != smc->q.ev_put) {
81 PRINTF("dispatch class %d event %d\n",ev->class,ev->event) ;
82 switch(class = ev->class) {
83 case EVENT_ECM : /* Entity Corordination Man. */
84 ecm(smc,(int)ev->event) ;
85 break ;
86 case EVENT_CFM : /* Configuration Man. */
87 cfm(smc,(int)ev->event) ;
88 break ;
89 case EVENT_RMT : /* Ring Man. */
90 rmt(smc,(int)ev->event) ;
91 break ;
92 case EVENT_SMT :
93 smt_event(smc,(int)ev->event) ;
94 break ;
95#ifdef CONCENTRATOR
96 case 99 :
97 timer_test_event(smc,(int)ev->event) ;
98 break ;
99#endif
100 case EVENT_PCMA : /* PHY A */
101 case EVENT_PCMB : /* PHY B */
102 default :
103 if (class >= EVENT_PCMA &&
104 class < EVENT_PCMA + NUMPHYS) {
105 pcm(smc,class - EVENT_PCMA,(int)ev->event) ;
106 break ;
107 }
108 SMT_PANIC(smc,SMT_E0121, SMT_E0121_MSG) ;
109 return ;
110 }
111
112 if (++ev == &smc->q.ev_queue[MAX_EVENT])
113 ev = smc->q.ev_queue ;
114
115 /* Renew get: it is used in queue_events to detect overruns */
116 smc->q.ev_get = ev;
117 }
118}
119
120/*
121 * smt_online connects to or disconnects from the ring
122 * MUST be called to initiate connection establishment
123 *
124 * on 0 disconnect
125 * on 1 connect
126 */
127u_short smt_online(struct s_smc *smc, int on)
128{
129 queue_event(smc,EVENT_ECM,on ? EC_CONNECT : EC_DISCONNECT) ;
130 ev_dispatcher(smc) ;
131 return(smc->mib.fddiSMTCF_State) ;
132}
133
134/*
135 * set SMT flag to value
136 * flag flag name
137 * value flag value
138 * dump current flag setting
139 */
140#ifdef CONCENTRATOR
141void do_smt_flag(struct s_smc *smc, char *flag, int value)
142{
143#ifdef DEBUG
144 struct smt_debug *deb;
145
146 SK_UNUSED(smc) ;
147
148#ifdef DEBUG_BRD
149 deb = &smc->debug;
150#else
151 deb = &debug;
152#endif
153 if (!strcmp(flag,"smt"))
154 deb->d_smt = value ;
155 else if (!strcmp(flag,"smtf"))
156 deb->d_smtf = value ;
157 else if (!strcmp(flag,"pcm"))
158 deb->d_pcm = value ;
159 else if (!strcmp(flag,"rmt"))
160 deb->d_rmt = value ;
161 else if (!strcmp(flag,"cfm"))
162 deb->d_cfm = value ;
163 else if (!strcmp(flag,"ecm"))
164 deb->d_ecm = value ;
165 printf("smt %d\n",deb->d_smt) ;
166 printf("smtf %d\n",deb->d_smtf) ;
167 printf("pcm %d\n",deb->d_pcm) ;
168 printf("rmt %d\n",deb->d_rmt) ;
169 printf("cfm %d\n",deb->d_cfm) ;
170 printf("ecm %d\n",deb->d_ecm) ;
171#endif /* DEBUG */
172}
173#endif
diff --git a/drivers/net/skfp/rmt.c b/drivers/net/skfp/rmt.c
new file mode 100644
index 000000000000..ef8d5672d9e8
--- /dev/null
+++ b/drivers/net/skfp/rmt.c
@@ -0,0 +1,654 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * See the file "skfddi.c" for further information.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * The information in this file is provided "AS IS" without warranty.
14 *
15 ******************************************************************************/
16
17/*
18 SMT RMT
19 Ring Management
20*/
21
22/*
23 * Hardware independent state machine implemantation
24 * The following external SMT functions are referenced :
25 *
26 * queue_event()
27 * smt_timer_start()
28 * smt_timer_stop()
29 *
30 * The following external HW dependent functions are referenced :
31 * sm_ma_control()
32 * sm_mac_check_beacon_claim()
33 *
34 * The following HW dependent events are required :
35 * RM_RING_OP
36 * RM_RING_NON_OP
37 * RM_MY_BEACON
38 * RM_OTHER_BEACON
39 * RM_MY_CLAIM
40 * RM_TRT_EXP
41 * RM_VALID_CLAIM
42 *
43 */
44
45#include "h/types.h"
46#include "h/fddi.h"
47#include "h/smc.h"
48
49#define KERNEL
50#include "h/smtstate.h"
51
52#ifndef lint
53static const char ID_sccs[] = "@(#)rmt.c 2.13 99/07/02 (C) SK " ;
54#endif
55
56/*
57 * FSM Macros
58 */
59#define AFLAG 0x10
60#define GO_STATE(x) (smc->mib.m[MAC0].fddiMACRMTState = (x)|AFLAG)
61#define ACTIONS_DONE() (smc->mib.m[MAC0].fddiMACRMTState &= ~AFLAG)
62#define ACTIONS(x) (x|AFLAG)
63
64#define RM0_ISOLATED 0
65#define RM1_NON_OP 1 /* not operational */
66#define RM2_RING_OP 2 /* ring operational */
67#define RM3_DETECT 3 /* detect dupl addresses */
68#define RM4_NON_OP_DUP 4 /* dupl. addr detected */
69#define RM5_RING_OP_DUP 5 /* ring oper. with dupl. addr */
70#define RM6_DIRECTED 6 /* sending directed beacons */
71#define RM7_TRACE 7 /* trace initiated */
72
73#ifdef DEBUG
74/*
75 * symbolic state names
76 */
77static const char * const rmt_states[] = {
78 "RM0_ISOLATED","RM1_NON_OP","RM2_RING_OP","RM3_DETECT",
79 "RM4_NON_OP_DUP","RM5_RING_OP_DUP","RM6_DIRECTED",
80 "RM7_TRACE"
81} ;
82
83/*
84 * symbolic event names
85 */
86static const char * const rmt_events[] = {
87 "NONE","RM_RING_OP","RM_RING_NON_OP","RM_MY_BEACON",
88 "RM_OTHER_BEACON","RM_MY_CLAIM","RM_TRT_EXP","RM_VALID_CLAIM",
89 "RM_JOIN","RM_LOOP","RM_DUP_ADDR","RM_ENABLE_FLAG",
90 "RM_TIMEOUT_NON_OP","RM_TIMEOUT_T_STUCK",
91 "RM_TIMEOUT_ANNOUNCE","RM_TIMEOUT_T_DIRECT",
92 "RM_TIMEOUT_D_MAX","RM_TIMEOUT_POLL","RM_TX_STATE_CHANGE"
93} ;
94#endif
95
96/*
97 * Globals
98 * in struct s_rmt
99 */
100
101
102/*
103 * function declarations
104 */
105static void rmt_fsm(struct s_smc *smc, int cmd);
106static void start_rmt_timer0(struct s_smc *smc, u_long value, int event);
107static void start_rmt_timer1(struct s_smc *smc, u_long value, int event);
108static void start_rmt_timer2(struct s_smc *smc, u_long value, int event);
109static void stop_rmt_timer0(struct s_smc *smc);
110static void stop_rmt_timer1(struct s_smc *smc);
111static void stop_rmt_timer2(struct s_smc *smc);
112static void rmt_dup_actions(struct s_smc *smc);
113static void rmt_reinsert_actions(struct s_smc *smc);
114static void rmt_leave_actions(struct s_smc *smc);
115static void rmt_new_dup_actions(struct s_smc *smc);
116
117#ifndef SUPERNET_3
118extern void restart_trt_for_dbcn() ;
119#endif /*SUPERNET_3*/
120
121/*
122 init RMT state machine
123 clear all RMT vars and flags
124*/
125void rmt_init(struct s_smc *smc)
126{
127 smc->mib.m[MAC0].fddiMACRMTState = ACTIONS(RM0_ISOLATED) ;
128 smc->r.dup_addr_test = DA_NONE ;
129 smc->r.da_flag = 0 ;
130 smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = FALSE ;
131 smc->r.sm_ma_avail = FALSE ;
132 smc->r.loop_avail = 0 ;
133 smc->r.bn_flag = 0 ;
134 smc->r.jm_flag = 0 ;
135 smc->r.no_flag = TRUE ;
136}
137
138/*
139 RMT state machine
140 called by dispatcher
141
142 do
143 display state change
144 process event
145 until SM is stable
146*/
147void rmt(struct s_smc *smc, int event)
148{
149 int state ;
150
151 do {
152 DB_RMT("RMT : state %s%s",
153 (smc->mib.m[MAC0].fddiMACRMTState & AFLAG) ? "ACTIONS " : "",
154 rmt_states[smc->mib.m[MAC0].fddiMACRMTState & ~AFLAG]) ;
155 DB_RMT(" event %s\n",rmt_events[event],0) ;
156 state = smc->mib.m[MAC0].fddiMACRMTState ;
157 rmt_fsm(smc,event) ;
158 event = 0 ;
159 } while (state != smc->mib.m[MAC0].fddiMACRMTState) ;
160 rmt_state_change(smc,(int)smc->mib.m[MAC0].fddiMACRMTState) ;
161}
162
163/*
164 process RMT event
165*/
166static void rmt_fsm(struct s_smc *smc, int cmd)
167{
168 /*
169 * RM00-RM70 : from all states
170 */
171 if (!smc->r.rm_join && !smc->r.rm_loop &&
172 smc->mib.m[MAC0].fddiMACRMTState != ACTIONS(RM0_ISOLATED) &&
173 smc->mib.m[MAC0].fddiMACRMTState != RM0_ISOLATED) {
174 RS_SET(smc,RS_NORINGOP) ;
175 rmt_indication(smc,0) ;
176 GO_STATE(RM0_ISOLATED) ;
177 return ;
178 }
179
180 switch(smc->mib.m[MAC0].fddiMACRMTState) {
181 case ACTIONS(RM0_ISOLATED) :
182 stop_rmt_timer0(smc) ;
183 stop_rmt_timer1(smc) ;
184 stop_rmt_timer2(smc) ;
185
186 /*
187 * Disable MAC.
188 */
189 sm_ma_control(smc,MA_OFFLINE) ;
190 smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = FALSE ;
191 smc->r.loop_avail = FALSE ;
192 smc->r.sm_ma_avail = FALSE ;
193 smc->r.no_flag = TRUE ;
194 DB_RMTN(1,"RMT : ISOLATED\n",0,0) ;
195 ACTIONS_DONE() ;
196 break ;
197 case RM0_ISOLATED :
198 /*RM01*/
199 if (smc->r.rm_join || smc->r.rm_loop) {
200 /*
201 * According to the standard the MAC must be reset
202 * here. The FORMAC will be initialized and Claim
203 * and Beacon Frames will be uploaded to the MAC.
204 * So any change of Treq will take effect NOW.
205 */
206 sm_ma_control(smc,MA_RESET) ;
207 GO_STATE(RM1_NON_OP) ;
208 break ;
209 }
210 break ;
211 case ACTIONS(RM1_NON_OP) :
212 start_rmt_timer0(smc,smc->s.rmt_t_non_op,RM_TIMEOUT_NON_OP) ;
213 stop_rmt_timer1(smc) ;
214 stop_rmt_timer2(smc) ;
215 sm_ma_control(smc,MA_BEACON) ;
216 DB_RMTN(1,"RMT : RING DOWN\n",0,0) ;
217 RS_SET(smc,RS_NORINGOP) ;
218 smc->r.sm_ma_avail = FALSE ;
219 rmt_indication(smc,0) ;
220 ACTIONS_DONE() ;
221 break ;
222 case RM1_NON_OP :
223 /*RM12*/
224 if (cmd == RM_RING_OP) {
225 RS_SET(smc,RS_RINGOPCHANGE) ;
226 GO_STATE(RM2_RING_OP) ;
227 break ;
228 }
229 /*RM13*/
230 else if (cmd == RM_TIMEOUT_NON_OP) {
231 smc->r.bn_flag = FALSE ;
232 smc->r.no_flag = TRUE ;
233 GO_STATE(RM3_DETECT) ;
234 break ;
235 }
236 break ;
237 case ACTIONS(RM2_RING_OP) :
238 stop_rmt_timer0(smc) ;
239 stop_rmt_timer1(smc) ;
240 stop_rmt_timer2(smc) ;
241 smc->r.no_flag = FALSE ;
242 if (smc->r.rm_loop)
243 smc->r.loop_avail = TRUE ;
244 if (smc->r.rm_join) {
245 smc->r.sm_ma_avail = TRUE ;
246 if (smc->mib.m[MAC0].fddiMACMA_UnitdataEnable)
247 smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = TRUE ;
248 else
249 smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = FALSE ;
250 }
251 DB_RMTN(1,"RMT : RING UP\n",0,0) ;
252 RS_CLEAR(smc,RS_NORINGOP) ;
253 RS_SET(smc,RS_RINGOPCHANGE) ;
254 rmt_indication(smc,1) ;
255 smt_stat_counter(smc,0) ;
256 ACTIONS_DONE() ;
257 break ;
258 case RM2_RING_OP :
259 /*RM21*/
260 if (cmd == RM_RING_NON_OP) {
261 smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = FALSE ;
262 smc->r.loop_avail = FALSE ;
263 RS_SET(smc,RS_RINGOPCHANGE) ;
264 GO_STATE(RM1_NON_OP) ;
265 break ;
266 }
267 /*RM22a*/
268 else if (cmd == RM_ENABLE_FLAG) {
269 if (smc->mib.m[MAC0].fddiMACMA_UnitdataEnable)
270 smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = TRUE ;
271 else
272 smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = FALSE ;
273 }
274 /*RM25*/
275 else if (smc->r.dup_addr_test == DA_FAILED) {
276 smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = FALSE ;
277 smc->r.loop_avail = FALSE ;
278 smc->r.da_flag = TRUE ;
279 GO_STATE(RM5_RING_OP_DUP) ;
280 break ;
281 }
282 break ;
283 case ACTIONS(RM3_DETECT) :
284 start_rmt_timer0(smc,smc->s.mac_d_max*2,RM_TIMEOUT_D_MAX) ;
285 start_rmt_timer1(smc,smc->s.rmt_t_stuck,RM_TIMEOUT_T_STUCK) ;
286 start_rmt_timer2(smc,smc->s.rmt_t_poll,RM_TIMEOUT_POLL) ;
287 sm_mac_check_beacon_claim(smc) ;
288 DB_RMTN(1,"RMT : RM3_DETECT\n",0,0) ;
289 ACTIONS_DONE() ;
290 break ;
291 case RM3_DETECT :
292 if (cmd == RM_TIMEOUT_POLL) {
293 start_rmt_timer2(smc,smc->s.rmt_t_poll,RM_TIMEOUT_POLL);
294 sm_mac_check_beacon_claim(smc) ;
295 break ;
296 }
297 if (cmd == RM_TIMEOUT_D_MAX) {
298 smc->r.timer0_exp = TRUE ;
299 }
300 /*
301 *jd(22-Feb-1999)
302 * We need a time ">= 2*mac_d_max" since we had finished
303 * Claim or Beacon state. So we will restart timer0 at
304 * every state change.
305 */
306 if (cmd == RM_TX_STATE_CHANGE) {
307 start_rmt_timer0(smc,
308 smc->s.mac_d_max*2,
309 RM_TIMEOUT_D_MAX) ;
310 }
311 /*RM32*/
312 if (cmd == RM_RING_OP) {
313 GO_STATE(RM2_RING_OP) ;
314 break ;
315 }
316 /*RM33a*/
317 else if ((cmd == RM_MY_BEACON || cmd == RM_OTHER_BEACON)
318 && smc->r.bn_flag) {
319 smc->r.bn_flag = FALSE ;
320 }
321 /*RM33b*/
322 else if (cmd == RM_TRT_EXP && !smc->r.bn_flag) {
323 int tx ;
324 /*
325 * set bn_flag only if in state T4 or T5:
326 * only if we're the beaconer should we start the
327 * trace !
328 */
329 if ((tx = sm_mac_get_tx_state(smc)) == 4 || tx == 5) {
330 DB_RMTN(2,"RMT : DETECT && TRT_EXPIRED && T4/T5\n",0,0);
331 smc->r.bn_flag = TRUE ;
332 /*
333 * If one of the upstream stations beaconed
334 * and the link to the upstream neighbor is
335 * lost we need to restart the stuck timer to
336 * check the "stuck beacon" condition.
337 */
338 start_rmt_timer1(smc,smc->s.rmt_t_stuck,
339 RM_TIMEOUT_T_STUCK) ;
340 }
341 /*
342 * We do NOT need to clear smc->r.bn_flag in case of
343 * not being in state T4 or T5, because the flag
344 * must be cleared in order to get in this condition.
345 */
346
347 DB_RMTN(2,
348 "RMT : sm_mac_get_tx_state() = %d (bn_flag = %d)\n",
349 tx,smc->r.bn_flag) ;
350 }
351 /*RM34a*/
352 else if (cmd == RM_MY_CLAIM && smc->r.timer0_exp) {
353 rmt_new_dup_actions(smc) ;
354 GO_STATE(RM4_NON_OP_DUP) ;
355 break ;
356 }
357 /*RM34b*/
358 else if (cmd == RM_MY_BEACON && smc->r.timer0_exp) {
359 rmt_new_dup_actions(smc) ;
360 GO_STATE(RM4_NON_OP_DUP) ;
361 break ;
362 }
363 /*RM34c*/
364 else if (cmd == RM_VALID_CLAIM) {
365 rmt_new_dup_actions(smc) ;
366 GO_STATE(RM4_NON_OP_DUP) ;
367 break ;
368 }
369 /*RM36*/
370 else if (cmd == RM_TIMEOUT_T_STUCK &&
371 smc->r.rm_join && smc->r.bn_flag) {
372 GO_STATE(RM6_DIRECTED) ;
373 break ;
374 }
375 break ;
376 case ACTIONS(RM4_NON_OP_DUP) :
377 start_rmt_timer0(smc,smc->s.rmt_t_announce,RM_TIMEOUT_ANNOUNCE);
378 start_rmt_timer1(smc,smc->s.rmt_t_stuck,RM_TIMEOUT_T_STUCK) ;
379 start_rmt_timer2(smc,smc->s.rmt_t_poll,RM_TIMEOUT_POLL) ;
380 sm_mac_check_beacon_claim(smc) ;
381 DB_RMTN(1,"RMT : RM4_NON_OP_DUP\n",0,0) ;
382 ACTIONS_DONE() ;
383 break ;
384 case RM4_NON_OP_DUP :
385 if (cmd == RM_TIMEOUT_POLL) {
386 start_rmt_timer2(smc,smc->s.rmt_t_poll,RM_TIMEOUT_POLL);
387 sm_mac_check_beacon_claim(smc) ;
388 break ;
389 }
390 /*RM41*/
391 if (!smc->r.da_flag) {
392 GO_STATE(RM1_NON_OP) ;
393 break ;
394 }
395 /*RM44a*/
396 else if ((cmd == RM_MY_BEACON || cmd == RM_OTHER_BEACON) &&
397 smc->r.bn_flag) {
398 smc->r.bn_flag = FALSE ;
399 }
400 /*RM44b*/
401 else if (cmd == RM_TRT_EXP && !smc->r.bn_flag) {
402 int tx ;
403 /*
404 * set bn_flag only if in state T4 or T5:
405 * only if we're the beaconer should we start the
406 * trace !
407 */
408 if ((tx = sm_mac_get_tx_state(smc)) == 4 || tx == 5) {
409 DB_RMTN(2,"RMT : NOPDUP && TRT_EXPIRED && T4/T5\n",0,0);
410 smc->r.bn_flag = TRUE ;
411 /*
412 * If one of the upstream stations beaconed
413 * and the link to the upstream neighbor is
414 * lost we need to restart the stuck timer to
415 * check the "stuck beacon" condition.
416 */
417 start_rmt_timer1(smc,smc->s.rmt_t_stuck,
418 RM_TIMEOUT_T_STUCK) ;
419 }
420 /*
421 * We do NOT need to clear smc->r.bn_flag in case of
422 * not being in state T4 or T5, because the flag
423 * must be cleared in order to get in this condition.
424 */
425
426 DB_RMTN(2,
427 "RMT : sm_mac_get_tx_state() = %d (bn_flag = %d)\n",
428 tx,smc->r.bn_flag) ;
429 }
430 /*RM44c*/
431 else if (cmd == RM_TIMEOUT_ANNOUNCE && !smc->r.bn_flag) {
432 rmt_dup_actions(smc) ;
433 }
434 /*RM45*/
435 else if (cmd == RM_RING_OP) {
436 smc->r.no_flag = FALSE ;
437 GO_STATE(RM5_RING_OP_DUP) ;
438 break ;
439 }
440 /*RM46*/
441 else if (cmd == RM_TIMEOUT_T_STUCK &&
442 smc->r.rm_join && smc->r.bn_flag) {
443 GO_STATE(RM6_DIRECTED) ;
444 break ;
445 }
446 break ;
447 case ACTIONS(RM5_RING_OP_DUP) :
448 stop_rmt_timer0(smc) ;
449 stop_rmt_timer1(smc) ;
450 stop_rmt_timer2(smc) ;
451 DB_RMTN(1,"RMT : RM5_RING_OP_DUP\n",0,0) ;
452 ACTIONS_DONE() ;
453 break;
454 case RM5_RING_OP_DUP :
455 /*RM52*/
456 if (smc->r.dup_addr_test == DA_PASSED) {
457 smc->r.da_flag = FALSE ;
458 GO_STATE(RM2_RING_OP) ;
459 break ;
460 }
461 /*RM54*/
462 else if (cmd == RM_RING_NON_OP) {
463 smc->r.jm_flag = FALSE ;
464 smc->r.bn_flag = FALSE ;
465 GO_STATE(RM4_NON_OP_DUP) ;
466 break ;
467 }
468 break ;
469 case ACTIONS(RM6_DIRECTED) :
470 start_rmt_timer0(smc,smc->s.rmt_t_direct,RM_TIMEOUT_T_DIRECT) ;
471 stop_rmt_timer1(smc) ;
472 start_rmt_timer2(smc,smc->s.rmt_t_poll,RM_TIMEOUT_POLL) ;
473 sm_ma_control(smc,MA_DIRECTED) ;
474 RS_SET(smc,RS_BEACON) ;
475 DB_RMTN(1,"RMT : RM6_DIRECTED\n",0,0) ;
476 ACTIONS_DONE() ;
477 break ;
478 case RM6_DIRECTED :
479 /*RM63*/
480 if (cmd == RM_TIMEOUT_POLL) {
481 start_rmt_timer2(smc,smc->s.rmt_t_poll,RM_TIMEOUT_POLL);
482 sm_mac_check_beacon_claim(smc) ;
483#ifndef SUPERNET_3
484 /* Because of problems with the Supernet II chip set
485 * sending of Directed Beacon will stop after 165ms
486 * therefore restart_trt_for_dbcn(smc) will be called
487 * to prevent this.
488 */
489 restart_trt_for_dbcn(smc) ;
490#endif /*SUPERNET_3*/
491 break ;
492 }
493 if ((cmd == RM_MY_BEACON || cmd == RM_OTHER_BEACON) &&
494 !smc->r.da_flag) {
495 smc->r.bn_flag = FALSE ;
496 GO_STATE(RM3_DETECT) ;
497 break ;
498 }
499 /*RM64*/
500 else if ((cmd == RM_MY_BEACON || cmd == RM_OTHER_BEACON) &&
501 smc->r.da_flag) {
502 smc->r.bn_flag = FALSE ;
503 GO_STATE(RM4_NON_OP_DUP) ;
504 break ;
505 }
506 /*RM67*/
507 else if (cmd == RM_TIMEOUT_T_DIRECT) {
508 GO_STATE(RM7_TRACE) ;
509 break ;
510 }
511 break ;
512 case ACTIONS(RM7_TRACE) :
513 stop_rmt_timer0(smc) ;
514 stop_rmt_timer1(smc) ;
515 stop_rmt_timer2(smc) ;
516 smc->e.trace_prop |= ENTITY_BIT(ENTITY_MAC) ;
517 queue_event(smc,EVENT_ECM,EC_TRACE_PROP) ;
518 DB_RMTN(1,"RMT : RM7_TRACE\n",0,0) ;
519 ACTIONS_DONE() ;
520 break ;
521 case RM7_TRACE :
522 break ;
523 default:
524 SMT_PANIC(smc,SMT_E0122, SMT_E0122_MSG) ;
525 break;
526 }
527}
528
529/*
530 * (jd) RMT duplicate address actions
531 * leave the ring or reinsert just as configured
532 */
533static void rmt_dup_actions(struct s_smc *smc)
534{
535 if (smc->r.jm_flag) {
536 }
537 else {
538 if (smc->s.rmt_dup_mac_behavior) {
539 SMT_ERR_LOG(smc,SMT_E0138, SMT_E0138_MSG) ;
540 rmt_reinsert_actions(smc) ;
541 }
542 else {
543 SMT_ERR_LOG(smc,SMT_E0135, SMT_E0135_MSG) ;
544 rmt_leave_actions(smc) ;
545 }
546 }
547}
548
549/*
550 * Reconnect to the Ring
551 */
552static void rmt_reinsert_actions(struct s_smc *smc)
553{
554 queue_event(smc,EVENT_ECM,EC_DISCONNECT) ;
555 queue_event(smc,EVENT_ECM,EC_CONNECT) ;
556}
557
558/*
559 * duplicate address detected
560 */
561static void rmt_new_dup_actions(struct s_smc *smc)
562{
563 smc->r.da_flag = TRUE ;
564 smc->r.bn_flag = FALSE ;
565 smc->r.jm_flag = FALSE ;
566 /*
567 * we have three options : change address, jam or leave
568 * we leave the ring as default
569 * Optionally it's possible to reinsert after leaving the Ring
570 * but this will not conform with SMT Spec.
571 */
572 if (smc->s.rmt_dup_mac_behavior) {
573 SMT_ERR_LOG(smc,SMT_E0138, SMT_E0138_MSG) ;
574 rmt_reinsert_actions(smc) ;
575 }
576 else {
577 SMT_ERR_LOG(smc,SMT_E0135, SMT_E0135_MSG) ;
578 rmt_leave_actions(smc) ;
579 }
580}
581
582
583/*
584 * leave the ring
585 */
586static void rmt_leave_actions(struct s_smc *smc)
587{
588 queue_event(smc,EVENT_ECM,EC_DISCONNECT) ;
589 /*
590 * Note: Do NOT try again later. (with please reconnect)
591 * The station must be left from the ring!
592 */
593}
594
595/*
596 * SMT timer interface
597 * start RMT timer 0
598 */
599static void start_rmt_timer0(struct s_smc *smc, u_long value, int event)
600{
601 smc->r.timer0_exp = FALSE ; /* clear timer event flag */
602 smt_timer_start(smc,&smc->r.rmt_timer0,value,EV_TOKEN(EVENT_RMT,event));
603}
604
605/*
606 * SMT timer interface
607 * start RMT timer 1
608 */
609static void start_rmt_timer1(struct s_smc *smc, u_long value, int event)
610{
611 smc->r.timer1_exp = FALSE ; /* clear timer event flag */
612 smt_timer_start(smc,&smc->r.rmt_timer1,value,EV_TOKEN(EVENT_RMT,event));
613}
614
615/*
616 * SMT timer interface
617 * start RMT timer 2
618 */
619static void start_rmt_timer2(struct s_smc *smc, u_long value, int event)
620{
621 smc->r.timer2_exp = FALSE ; /* clear timer event flag */
622 smt_timer_start(smc,&smc->r.rmt_timer2,value,EV_TOKEN(EVENT_RMT,event));
623}
624
625/*
626 * SMT timer interface
627 * stop RMT timer 0
628 */
629static void stop_rmt_timer0(struct s_smc *smc)
630{
631 if (smc->r.rmt_timer0.tm_active)
632 smt_timer_stop(smc,&smc->r.rmt_timer0) ;
633}
634
635/*
636 * SMT timer interface
637 * stop RMT timer 1
638 */
639static void stop_rmt_timer1(struct s_smc *smc)
640{
641 if (smc->r.rmt_timer1.tm_active)
642 smt_timer_stop(smc,&smc->r.rmt_timer1) ;
643}
644
645/*
646 * SMT timer interface
647 * stop RMT timer 2
648 */
649static void stop_rmt_timer2(struct s_smc *smc)
650{
651 if (smc->r.rmt_timer2.tm_active)
652 smt_timer_stop(smc,&smc->r.rmt_timer2) ;
653}
654
diff --git a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c
new file mode 100644
index 000000000000..c88aad6edd74
--- /dev/null
+++ b/drivers/net/skfp/skfddi.c
@@ -0,0 +1,2293 @@
1/*
2 * File Name:
3 * skfddi.c
4 *
5 * Copyright Information:
6 * Copyright SysKonnect 1998,1999.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * The information in this file is provided "AS IS" without warranty.
14 *
15 * Abstract:
16 * A Linux device driver supporting the SysKonnect FDDI PCI controller
17 * familie.
18 *
19 * Maintainers:
20 * CG Christoph Goos (cgoos@syskonnect.de)
21 *
22 * Contributors:
23 * DM David S. Miller
24 *
25 * Address all question to:
26 * linux@syskonnect.de
27 *
28 * The technical manual for the adapters is available from SysKonnect's
29 * web pages: www.syskonnect.com
30 * Goto "Support" and search Knowledge Base for "manual".
31 *
32 * Driver Architecture:
33 * The driver architecture is based on the DEC FDDI driver by
34 * Lawrence V. Stefani and several ethernet drivers.
35 * I also used an existing Windows NT miniport driver.
36 * All hardware dependent fuctions are handled by the SysKonnect
37 * Hardware Module.
38 * The only headerfiles that are directly related to this source
39 * are skfddi.c, h/types.h, h/osdef1st.h, h/targetos.h.
40 * The others belong to the SysKonnect FDDI Hardware Module and
41 * should better not be changed.
42 *
43 * Modification History:
44 * Date Name Description
45 * 02-Mar-98 CG Created.
46 *
47 * 10-Mar-99 CG Support for 2.2.x added.
48 * 25-Mar-99 CG Corrected IRQ routing for SMP (APIC)
49 * 26-Oct-99 CG Fixed compilation error on 2.2.13
50 * 12-Nov-99 CG Source code release
51 * 22-Nov-99 CG Included in kernel source.
52 * 07-May-00 DM 64 bit fixes, new dma interface
53 * 31-Jul-03 DB Audit copy_*_user in skfp_ioctl
54 * Daniele Bellucci <bellucda@tiscali.it>
55 * 03-Dec-03 SH Convert to PCI device model
56 *
57 * Compilation options (-Dxxx):
58 * DRIVERDEBUG print lots of messages to log file
59 * DUMPPACKETS print received/transmitted packets to logfile
60 *
61 * Tested cpu architectures:
62 * - i386
63 * - sparc64
64 */
65
66/* Version information string - should be updated prior to */
67/* each new release!!! */
68#define VERSION "2.07"
69
70static const char *boot_msg =
71 "SysKonnect FDDI PCI Adapter driver v" VERSION " for\n"
72 " SK-55xx/SK-58xx adapters (SK-NET FDDI-FP/UP/LP)";
73
74/* Include files */
75
76#include <linux/module.h>
77#include <linux/kernel.h>
78#include <linux/errno.h>
79#include <linux/ioport.h>
80#include <linux/slab.h>
81#include <linux/interrupt.h>
82#include <linux/pci.h>
83#include <linux/netdevice.h>
84#include <linux/fddidevice.h>
85#include <linux/skbuff.h>
86#include <linux/bitops.h>
87
88#include <asm/byteorder.h>
89#include <asm/io.h>
90#include <asm/uaccess.h>
91
92#include "h/types.h"
93#undef ADDR // undo Linux definition
94#include "h/skfbi.h"
95#include "h/fddi.h"
96#include "h/smc.h"
97#include "h/smtstate.h"
98
99
100// Define module-wide (static) routines
101static int skfp_driver_init(struct net_device *dev);
102static int skfp_open(struct net_device *dev);
103static int skfp_close(struct net_device *dev);
104static irqreturn_t skfp_interrupt(int irq, void *dev_id, struct pt_regs *regs);
105static struct net_device_stats *skfp_ctl_get_stats(struct net_device *dev);
106static void skfp_ctl_set_multicast_list(struct net_device *dev);
107static void skfp_ctl_set_multicast_list_wo_lock(struct net_device *dev);
108static int skfp_ctl_set_mac_address(struct net_device *dev, void *addr);
109static int skfp_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
110static int skfp_send_pkt(struct sk_buff *skb, struct net_device *dev);
111static void send_queued_packets(struct s_smc *smc);
112static void CheckSourceAddress(unsigned char *frame, unsigned char *hw_addr);
113static void ResetAdapter(struct s_smc *smc);
114
115
116// Functions needed by the hardware module
117void *mac_drv_get_space(struct s_smc *smc, u_int size);
118void *mac_drv_get_desc_mem(struct s_smc *smc, u_int size);
119unsigned long mac_drv_virt2phys(struct s_smc *smc, void *virt);
120unsigned long dma_master(struct s_smc *smc, void *virt, int len, int flag);
121void dma_complete(struct s_smc *smc, volatile union s_fp_descr *descr,
122 int flag);
123void mac_drv_tx_complete(struct s_smc *smc, volatile struct s_smt_fp_txd *txd);
124void llc_restart_tx(struct s_smc *smc);
125void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
126 int frag_count, int len);
127void mac_drv_requeue_rxd(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
128 int frag_count);
129void mac_drv_fill_rxd(struct s_smc *smc);
130void mac_drv_clear_rxd(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
131 int frag_count);
132int mac_drv_rx_init(struct s_smc *smc, int len, int fc, char *look_ahead,
133 int la_len);
134void dump_data(unsigned char *Data, int length);
135
136// External functions from the hardware module
137extern u_int mac_drv_check_space(void);
138extern void read_address(struct s_smc *smc, u_char * mac_addr);
139extern void card_stop(struct s_smc *smc);
140extern int mac_drv_init(struct s_smc *smc);
141extern void hwm_tx_frag(struct s_smc *smc, char far * virt, u_long phys,
142 int len, int frame_status);
143extern int hwm_tx_init(struct s_smc *smc, u_char fc, int frag_count,
144 int frame_len, int frame_status);
145extern int init_smt(struct s_smc *smc, u_char * mac_addr);
146extern void fddi_isr(struct s_smc *smc);
147extern void hwm_rx_frag(struct s_smc *smc, char far * virt, u_long phys,
148 int len, int frame_status);
149extern void mac_drv_rx_mode(struct s_smc *smc, int mode);
150extern void mac_drv_clear_rx_queue(struct s_smc *smc);
151extern void enable_tx_irq(struct s_smc *smc, u_short queue);
152extern void mac_drv_clear_txd(struct s_smc *smc);
153
154static struct pci_device_id skfddi_pci_tbl[] = {
155 { PCI_VENDOR_ID_SK, PCI_DEVICE_ID_SK_FP, PCI_ANY_ID, PCI_ANY_ID, },
156 { } /* Terminating entry */
157};
158MODULE_DEVICE_TABLE(pci, skfddi_pci_tbl);
159MODULE_LICENSE("GPL");
160MODULE_AUTHOR("Mirko Lindner <mlindner@syskonnect.de>");
161
162// Define module-wide (static) variables
163
164static int num_boards; /* total number of adapters configured */
165
166#ifdef DRIVERDEBUG
167#define PRINTK(s, args...) printk(s, ## args)
168#else
169#define PRINTK(s, args...)
170#endif // DRIVERDEBUG
171
172/*
173 * =================
174 * = skfp_init_one =
175 * =================
176 *
177 * Overview:
178 * Probes for supported FDDI PCI controllers
179 *
180 * Returns:
181 * Condition code
182 *
183 * Arguments:
184 * pdev - pointer to PCI device information
185 *
186 * Functional Description:
187 * This is now called by PCI driver registration process
188 * for each board found.
189 *
190 * Return Codes:
191 * 0 - This device (fddi0, fddi1, etc) configured successfully
192 * -ENODEV - No devices present, or no SysKonnect FDDI PCI device
193 * present for this device name
194 *
195 *
196 * Side Effects:
197 * Device structures for FDDI adapters (fddi0, fddi1, etc) are
198 * initialized and the board resources are read and stored in
199 * the device structure.
200 */
201static int skfp_init_one(struct pci_dev *pdev,
202 const struct pci_device_id *ent)
203{
204 struct net_device *dev;
205 struct s_smc *smc; /* board pointer */
206 void __iomem *mem;
207 int err;
208
209 PRINTK(KERN_INFO "entering skfp_init_one\n");
210
211 if (num_boards == 0)
212 printk("%s\n", boot_msg);
213
214 err = pci_enable_device(pdev);
215 if (err)
216 return err;
217
218 err = pci_request_regions(pdev, "skfddi");
219 if (err)
220 goto err_out1;
221
222 pci_set_master(pdev);
223
224#ifdef MEM_MAPPED_IO
225 if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
226 printk(KERN_ERR "skfp: region is not an MMIO resource\n");
227 err = -EIO;
228 goto err_out2;
229 }
230
231 mem = ioremap(pci_resource_start(pdev, 0), 0x4000);
232#else
233 if (!(pci_resource_flags(pdev, 1) & IO_RESOURCE_IO)) {
234 printk(KERN_ERR "skfp: region is not PIO resource\n");
235 err = -EIO;
236 goto err_out2;
237 }
238
239 mem = ioport_map(pci_resource_start(pdev, 1), FP_IO_LEN);
240#endif
241 if (!mem) {
242 printk(KERN_ERR "skfp: Unable to map register, "
243 "FDDI adapter will be disabled.\n");
244 err = -EIO;
245 goto err_out2;
246 }
247
248 dev = alloc_fddidev(sizeof(struct s_smc));
249 if (!dev) {
250 printk(KERN_ERR "skfp: Unable to allocate fddi device, "
251 "FDDI adapter will be disabled.\n");
252 err = -ENOMEM;
253 goto err_out3;
254 }
255
256 dev->irq = pdev->irq;
257 dev->get_stats = &skfp_ctl_get_stats;
258 dev->open = &skfp_open;
259 dev->stop = &skfp_close;
260 dev->hard_start_xmit = &skfp_send_pkt;
261 dev->set_multicast_list = &skfp_ctl_set_multicast_list;
262 dev->set_mac_address = &skfp_ctl_set_mac_address;
263 dev->do_ioctl = &skfp_ioctl;
264 dev->header_cache_update = NULL; /* not supported */
265
266 SET_MODULE_OWNER(dev);
267 SET_NETDEV_DEV(dev, &pdev->dev);
268
269 /* Initialize board structure with bus-specific info */
270 smc = netdev_priv(dev);
271 smc->os.dev = dev;
272 smc->os.bus_type = SK_BUS_TYPE_PCI;
273 smc->os.pdev = *pdev;
274 smc->os.QueueSkb = MAX_TX_QUEUE_LEN;
275 smc->os.MaxFrameSize = MAX_FRAME_SIZE;
276 smc->os.dev = dev;
277 smc->hw.slot = -1;
278 smc->hw.iop = mem;
279 smc->os.ResetRequested = FALSE;
280 skb_queue_head_init(&smc->os.SendSkbQueue);
281
282 dev->base_addr = (unsigned long)mem;
283
284 err = skfp_driver_init(dev);
285 if (err)
286 goto err_out4;
287
288 err = register_netdev(dev);
289 if (err)
290 goto err_out5;
291
292 ++num_boards;
293 pci_set_drvdata(pdev, dev);
294
295 if ((pdev->subsystem_device & 0xff00) == 0x5500 ||
296 (pdev->subsystem_device & 0xff00) == 0x5800)
297 printk("%s: SysKonnect FDDI PCI adapter"
298 " found (SK-%04X)\n", dev->name,
299 pdev->subsystem_device);
300 else
301 printk("%s: FDDI PCI adapter found\n", dev->name);
302
303 return 0;
304err_out5:
305 if (smc->os.SharedMemAddr)
306 pci_free_consistent(pdev, smc->os.SharedMemSize,
307 smc->os.SharedMemAddr,
308 smc->os.SharedMemDMA);
309 pci_free_consistent(pdev, MAX_FRAME_SIZE,
310 smc->os.LocalRxBuffer, smc->os.LocalRxBufferDMA);
311err_out4:
312 free_netdev(dev);
313err_out3:
314#ifdef MEM_MAPPED_IO
315 iounmap(mem);
316#else
317 ioport_unmap(mem);
318#endif
319err_out2:
320 pci_release_regions(pdev);
321err_out1:
322 pci_disable_device(pdev);
323 return err;
324}
325
326/*
327 * Called for each adapter board from pci_unregister_driver
328 */
329static void __devexit skfp_remove_one(struct pci_dev *pdev)
330{
331 struct net_device *p = pci_get_drvdata(pdev);
332 struct s_smc *lp = netdev_priv(p);
333
334 unregister_netdev(p);
335
336 if (lp->os.SharedMemAddr) {
337 pci_free_consistent(&lp->os.pdev,
338 lp->os.SharedMemSize,
339 lp->os.SharedMemAddr,
340 lp->os.SharedMemDMA);
341 lp->os.SharedMemAddr = NULL;
342 }
343 if (lp->os.LocalRxBuffer) {
344 pci_free_consistent(&lp->os.pdev,
345 MAX_FRAME_SIZE,
346 lp->os.LocalRxBuffer,
347 lp->os.LocalRxBufferDMA);
348 lp->os.LocalRxBuffer = NULL;
349 }
350#ifdef MEM_MAPPED_IO
351 iounmap(lp->hw.iop);
352#else
353 ioport_unmap(lp->hw.iop);
354#endif
355 pci_release_regions(pdev);
356 free_netdev(p);
357
358 pci_disable_device(pdev);
359 pci_set_drvdata(pdev, NULL);
360}
361
362/*
363 * ====================
364 * = skfp_driver_init =
365 * ====================
366 *
367 * Overview:
368 * Initializes remaining adapter board structure information
369 * and makes sure adapter is in a safe state prior to skfp_open().
370 *
371 * Returns:
372 * Condition code
373 *
374 * Arguments:
375 * dev - pointer to device information
376 *
377 * Functional Description:
378 * This function allocates additional resources such as the host memory
379 * blocks needed by the adapter.
380 * The adapter is also reset. The OS must call skfp_open() to open
381 * the adapter and bring it on-line.
382 *
383 * Return Codes:
384 * 0 - initialization succeeded
385 * -1 - initialization failed
386 */
387static int skfp_driver_init(struct net_device *dev)
388{
389 struct s_smc *smc = netdev_priv(dev);
390 skfddi_priv *bp = &smc->os;
391 int err = -EIO;
392
393 PRINTK(KERN_INFO "entering skfp_driver_init\n");
394
395 // set the io address in private structures
396 bp->base_addr = dev->base_addr;
397
398 // Get the interrupt level from the PCI Configuration Table
399 smc->hw.irq = dev->irq;
400
401 spin_lock_init(&bp->DriverLock);
402
403 // Allocate invalid frame
404 bp->LocalRxBuffer = pci_alloc_consistent(&bp->pdev, MAX_FRAME_SIZE, &bp->LocalRxBufferDMA);
405 if (!bp->LocalRxBuffer) {
406 printk("could not allocate mem for ");
407 printk("LocalRxBuffer: %d byte\n", MAX_FRAME_SIZE);
408 goto fail;
409 }
410
411 // Determine the required size of the 'shared' memory area.
412 bp->SharedMemSize = mac_drv_check_space();
413 PRINTK(KERN_INFO "Memory for HWM: %ld\n", bp->SharedMemSize);
414 if (bp->SharedMemSize > 0) {
415 bp->SharedMemSize += 16; // for descriptor alignment
416
417 bp->SharedMemAddr = pci_alloc_consistent(&bp->pdev,
418 bp->SharedMemSize,
419 &bp->SharedMemDMA);
420 if (!bp->SharedMemSize) {
421 printk("could not allocate mem for ");
422 printk("hardware module: %ld byte\n",
423 bp->SharedMemSize);
424 goto fail;
425 }
426 bp->SharedMemHeap = 0; // Nothing used yet.
427
428 } else {
429 bp->SharedMemAddr = NULL;
430 bp->SharedMemHeap = 0;
431 } // SharedMemSize > 0
432
433 memset(bp->SharedMemAddr, 0, bp->SharedMemSize);
434
435 card_stop(smc); // Reset adapter.
436
437 PRINTK(KERN_INFO "mac_drv_init()..\n");
438 if (mac_drv_init(smc) != 0) {
439 PRINTK(KERN_INFO "mac_drv_init() failed.\n");
440 goto fail;
441 }
442 read_address(smc, NULL);
443 PRINTK(KERN_INFO "HW-Addr: %02x %02x %02x %02x %02x %02x\n",
444 smc->hw.fddi_canon_addr.a[0],
445 smc->hw.fddi_canon_addr.a[1],
446 smc->hw.fddi_canon_addr.a[2],
447 smc->hw.fddi_canon_addr.a[3],
448 smc->hw.fddi_canon_addr.a[4],
449 smc->hw.fddi_canon_addr.a[5]);
450 memcpy(dev->dev_addr, smc->hw.fddi_canon_addr.a, 6);
451
452 smt_reset_defaults(smc, 0);
453
454 return (0);
455
456fail:
457 if (bp->SharedMemAddr) {
458 pci_free_consistent(&bp->pdev,
459 bp->SharedMemSize,
460 bp->SharedMemAddr,
461 bp->SharedMemDMA);
462 bp->SharedMemAddr = NULL;
463 }
464 if (bp->LocalRxBuffer) {
465 pci_free_consistent(&bp->pdev, MAX_FRAME_SIZE,
466 bp->LocalRxBuffer, bp->LocalRxBufferDMA);
467 bp->LocalRxBuffer = NULL;
468 }
469 return err;
470} // skfp_driver_init
471
472
473/*
474 * =============
475 * = skfp_open =
476 * =============
477 *
478 * Overview:
479 * Opens the adapter
480 *
481 * Returns:
482 * Condition code
483 *
484 * Arguments:
485 * dev - pointer to device information
486 *
487 * Functional Description:
488 * This function brings the adapter to an operational state.
489 *
490 * Return Codes:
491 * 0 - Adapter was successfully opened
492 * -EAGAIN - Could not register IRQ
493 */
494static int skfp_open(struct net_device *dev)
495{
496 struct s_smc *smc = netdev_priv(dev);
497 int err;
498
499 PRINTK(KERN_INFO "entering skfp_open\n");
500 /* Register IRQ - support shared interrupts by passing device ptr */
501 err = request_irq(dev->irq, (void *) skfp_interrupt, SA_SHIRQ,
502 dev->name, dev);
503 if (err)
504 return err;
505
506 /*
507 * Set current address to factory MAC address
508 *
509 * Note: We've already done this step in skfp_driver_init.
510 * However, it's possible that a user has set a node
511 * address override, then closed and reopened the
512 * adapter. Unless we reset the device address field
513 * now, we'll continue to use the existing modified
514 * address.
515 */
516 read_address(smc, NULL);
517 memcpy(dev->dev_addr, smc->hw.fddi_canon_addr.a, 6);
518
519 init_smt(smc, NULL);
520 smt_online(smc, 1);
521 STI_FBI();
522
523 /* Clear local multicast address tables */
524 mac_clear_multicast(smc);
525
526 /* Disable promiscuous filter settings */
527 mac_drv_rx_mode(smc, RX_DISABLE_PROMISC);
528
529 netif_start_queue(dev);
530 return (0);
531} // skfp_open
532
533
534/*
535 * ==============
536 * = skfp_close =
537 * ==============
538 *
539 * Overview:
540 * Closes the device/module.
541 *
542 * Returns:
543 * Condition code
544 *
545 * Arguments:
546 * dev - pointer to device information
547 *
548 * Functional Description:
549 * This routine closes the adapter and brings it to a safe state.
550 * The interrupt service routine is deregistered with the OS.
551 * The adapter can be opened again with another call to skfp_open().
552 *
553 * Return Codes:
554 * Always return 0.
555 *
556 * Assumptions:
557 * No further requests for this adapter are made after this routine is
558 * called. skfp_open() can be called to reset and reinitialize the
559 * adapter.
560 */
561static int skfp_close(struct net_device *dev)
562{
563 struct s_smc *smc = netdev_priv(dev);
564 skfddi_priv *bp = &smc->os;
565
566 CLI_FBI();
567 smt_reset_defaults(smc, 1);
568 card_stop(smc);
569 mac_drv_clear_tx_queue(smc);
570 mac_drv_clear_rx_queue(smc);
571
572 netif_stop_queue(dev);
573 /* Deregister (free) IRQ */
574 free_irq(dev->irq, dev);
575
576 skb_queue_purge(&bp->SendSkbQueue);
577 bp->QueueSkb = MAX_TX_QUEUE_LEN;
578
579 return (0);
580} // skfp_close
581
582
583/*
584 * ==================
585 * = skfp_interrupt =
586 * ==================
587 *
588 * Overview:
589 * Interrupt processing routine
590 *
591 * Returns:
592 * None
593 *
594 * Arguments:
595 * irq - interrupt vector
596 * dev_id - pointer to device information
597 * regs - pointer to registers structure
598 *
599 * Functional Description:
600 * This routine calls the interrupt processing routine for this adapter. It
601 * disables and reenables adapter interrupts, as appropriate. We can support
602 * shared interrupts since the incoming dev_id pointer provides our device
603 * structure context. All the real work is done in the hardware module.
604 *
605 * Return Codes:
606 * None
607 *
608 * Assumptions:
609 * The interrupt acknowledgement at the hardware level (eg. ACKing the PIC
610 * on Intel-based systems) is done by the operating system outside this
611 * routine.
612 *
613 * System interrupts are enabled through this call.
614 *
615 * Side Effects:
616 * Interrupts are disabled, then reenabled at the adapter.
617 */
618
619irqreturn_t skfp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
620{
621 struct net_device *dev = (struct net_device *) dev_id;
622 struct s_smc *smc; /* private board structure pointer */
623 skfddi_priv *bp;
624
625 if (dev == NULL) {
626 printk("%s: irq %d for unknown device\n", dev->name, irq);
627 return IRQ_NONE;
628 }
629
630 smc = netdev_priv(dev);
631 bp = &smc->os;
632
633 // IRQs enabled or disabled ?
634 if (inpd(ADDR(B0_IMSK)) == 0) {
635 // IRQs are disabled: must be shared interrupt
636 return IRQ_NONE;
637 }
638 // Note: At this point, IRQs are enabled.
639 if ((inpd(ISR_A) & smc->hw.is_imask) == 0) { // IRQ?
640 // Adapter did not issue an IRQ: must be shared interrupt
641 return IRQ_NONE;
642 }
643 CLI_FBI(); // Disable IRQs from our adapter.
644 spin_lock(&bp->DriverLock);
645
646 // Call interrupt handler in hardware module (HWM).
647 fddi_isr(smc);
648
649 if (smc->os.ResetRequested) {
650 ResetAdapter(smc);
651 smc->os.ResetRequested = FALSE;
652 }
653 spin_unlock(&bp->DriverLock);
654 STI_FBI(); // Enable IRQs from our adapter.
655
656 return IRQ_HANDLED;
657} // skfp_interrupt
658
659
660/*
661 * ======================
662 * = skfp_ctl_get_stats =
663 * ======================
664 *
665 * Overview:
666 * Get statistics for FDDI adapter
667 *
668 * Returns:
669 * Pointer to FDDI statistics structure
670 *
671 * Arguments:
672 * dev - pointer to device information
673 *
674 * Functional Description:
675 * Gets current MIB objects from adapter, then
676 * returns FDDI statistics structure as defined
677 * in if_fddi.h.
678 *
679 * Note: Since the FDDI statistics structure is
680 * still new and the device structure doesn't
681 * have an FDDI-specific get statistics handler,
682 * we'll return the FDDI statistics structure as
683 * a pointer to an Ethernet statistics structure.
684 * That way, at least the first part of the statistics
685 * structure can be decoded properly.
686 * We'll have to pay attention to this routine as the
687 * device structure becomes more mature and LAN media
688 * independent.
689 *
690 */
691struct net_device_stats *skfp_ctl_get_stats(struct net_device *dev)
692{
693 struct s_smc *bp = netdev_priv(dev);
694
695 /* Fill the bp->stats structure with driver-maintained counters */
696
697 bp->os.MacStat.port_bs_flag[0] = 0x1234;
698 bp->os.MacStat.port_bs_flag[1] = 0x5678;
699// goos: need to fill out fddi statistic
700#if 0
701 /* Get FDDI SMT MIB objects */
702
703/* Fill the bp->stats structure with the SMT MIB object values */
704
705 memcpy(bp->stats.smt_station_id, &bp->cmd_rsp_virt->smt_mib_get.smt_station_id, sizeof(bp->cmd_rsp_virt->smt_mib_get.smt_station_id));
706 bp->stats.smt_op_version_id = bp->cmd_rsp_virt->smt_mib_get.smt_op_version_id;
707 bp->stats.smt_hi_version_id = bp->cmd_rsp_virt->smt_mib_get.smt_hi_version_id;
708 bp->stats.smt_lo_version_id = bp->cmd_rsp_virt->smt_mib_get.smt_lo_version_id;
709 memcpy(bp->stats.smt_user_data, &bp->cmd_rsp_virt->smt_mib_get.smt_user_data, sizeof(bp->cmd_rsp_virt->smt_mib_get.smt_user_data));
710 bp->stats.smt_mib_version_id = bp->cmd_rsp_virt->smt_mib_get.smt_mib_version_id;
711 bp->stats.smt_mac_cts = bp->cmd_rsp_virt->smt_mib_get.smt_mac_ct;
712 bp->stats.smt_non_master_cts = bp->cmd_rsp_virt->smt_mib_get.smt_non_master_ct;
713 bp->stats.smt_master_cts = bp->cmd_rsp_virt->smt_mib_get.smt_master_ct;
714 bp->stats.smt_available_paths = bp->cmd_rsp_virt->smt_mib_get.smt_available_paths;
715 bp->stats.smt_config_capabilities = bp->cmd_rsp_virt->smt_mib_get.smt_config_capabilities;
716 bp->stats.smt_config_policy = bp->cmd_rsp_virt->smt_mib_get.smt_config_policy;
717 bp->stats.smt_connection_policy = bp->cmd_rsp_virt->smt_mib_get.smt_connection_policy;
718 bp->stats.smt_t_notify = bp->cmd_rsp_virt->smt_mib_get.smt_t_notify;
719 bp->stats.smt_stat_rpt_policy = bp->cmd_rsp_virt->smt_mib_get.smt_stat_rpt_policy;
720 bp->stats.smt_trace_max_expiration = bp->cmd_rsp_virt->smt_mib_get.smt_trace_max_expiration;
721 bp->stats.smt_bypass_present = bp->cmd_rsp_virt->smt_mib_get.smt_bypass_present;
722 bp->stats.smt_ecm_state = bp->cmd_rsp_virt->smt_mib_get.smt_ecm_state;
723 bp->stats.smt_cf_state = bp->cmd_rsp_virt->smt_mib_get.smt_cf_state;
724 bp->stats.smt_remote_disconnect_flag = bp->cmd_rsp_virt->smt_mib_get.smt_remote_disconnect_flag;
725 bp->stats.smt_station_status = bp->cmd_rsp_virt->smt_mib_get.smt_station_status;
726 bp->stats.smt_peer_wrap_flag = bp->cmd_rsp_virt->smt_mib_get.smt_peer_wrap_flag;
727 bp->stats.smt_time_stamp = bp->cmd_rsp_virt->smt_mib_get.smt_msg_time_stamp.ls;
728 bp->stats.smt_transition_time_stamp = bp->cmd_rsp_virt->smt_mib_get.smt_transition_time_stamp.ls;
729 bp->stats.mac_frame_status_functions = bp->cmd_rsp_virt->smt_mib_get.mac_frame_status_functions;
730 bp->stats.mac_t_max_capability = bp->cmd_rsp_virt->smt_mib_get.mac_t_max_capability;
731 bp->stats.mac_tvx_capability = bp->cmd_rsp_virt->smt_mib_get.mac_tvx_capability;
732 bp->stats.mac_available_paths = bp->cmd_rsp_virt->smt_mib_get.mac_available_paths;
733 bp->stats.mac_current_path = bp->cmd_rsp_virt->smt_mib_get.mac_current_path;
734 memcpy(bp->stats.mac_upstream_nbr, &bp->cmd_rsp_virt->smt_mib_get.mac_upstream_nbr, FDDI_K_ALEN);
735 memcpy(bp->stats.mac_downstream_nbr, &bp->cmd_rsp_virt->smt_mib_get.mac_downstream_nbr, FDDI_K_ALEN);
736 memcpy(bp->stats.mac_old_upstream_nbr, &bp->cmd_rsp_virt->smt_mib_get.mac_old_upstream_nbr, FDDI_K_ALEN);
737 memcpy(bp->stats.mac_old_downstream_nbr, &bp->cmd_rsp_virt->smt_mib_get.mac_old_downstream_nbr, FDDI_K_ALEN);
738 bp->stats.mac_dup_address_test = bp->cmd_rsp_virt->smt_mib_get.mac_dup_address_test;
739 bp->stats.mac_requested_paths = bp->cmd_rsp_virt->smt_mib_get.mac_requested_paths;
740 bp->stats.mac_downstream_port_type = bp->cmd_rsp_virt->smt_mib_get.mac_downstream_port_type;
741 memcpy(bp->stats.mac_smt_address, &bp->cmd_rsp_virt->smt_mib_get.mac_smt_address, FDDI_K_ALEN);
742 bp->stats.mac_t_req = bp->cmd_rsp_virt->smt_mib_get.mac_t_req;
743 bp->stats.mac_t_neg = bp->cmd_rsp_virt->smt_mib_get.mac_t_neg;
744 bp->stats.mac_t_max = bp->cmd_rsp_virt->smt_mib_get.mac_t_max;
745 bp->stats.mac_tvx_value = bp->cmd_rsp_virt->smt_mib_get.mac_tvx_value;
746 bp->stats.mac_frame_error_threshold = bp->cmd_rsp_virt->smt_mib_get.mac_frame_error_threshold;
747 bp->stats.mac_frame_error_ratio = bp->cmd_rsp_virt->smt_mib_get.mac_frame_error_ratio;
748 bp->stats.mac_rmt_state = bp->cmd_rsp_virt->smt_mib_get.mac_rmt_state;
749 bp->stats.mac_da_flag = bp->cmd_rsp_virt->smt_mib_get.mac_da_flag;
750 bp->stats.mac_una_da_flag = bp->cmd_rsp_virt->smt_mib_get.mac_unda_flag;
751 bp->stats.mac_frame_error_flag = bp->cmd_rsp_virt->smt_mib_get.mac_frame_error_flag;
752 bp->stats.mac_ma_unitdata_available = bp->cmd_rsp_virt->smt_mib_get.mac_ma_unitdata_available;
753 bp->stats.mac_hardware_present = bp->cmd_rsp_virt->smt_mib_get.mac_hardware_present;
754 bp->stats.mac_ma_unitdata_enable = bp->cmd_rsp_virt->smt_mib_get.mac_ma_unitdata_enable;
755 bp->stats.path_tvx_lower_bound = bp->cmd_rsp_virt->smt_mib_get.path_tvx_lower_bound;
756 bp->stats.path_t_max_lower_bound = bp->cmd_rsp_virt->smt_mib_get.path_t_max_lower_bound;
757 bp->stats.path_max_t_req = bp->cmd_rsp_virt->smt_mib_get.path_max_t_req;
758 memcpy(bp->stats.path_configuration, &bp->cmd_rsp_virt->smt_mib_get.path_configuration, sizeof(bp->cmd_rsp_virt->smt_mib_get.path_configuration));
759 bp->stats.port_my_type[0] = bp->cmd_rsp_virt->smt_mib_get.port_my_type[0];
760 bp->stats.port_my_type[1] = bp->cmd_rsp_virt->smt_mib_get.port_my_type[1];
761 bp->stats.port_neighbor_type[0] = bp->cmd_rsp_virt->smt_mib_get.port_neighbor_type[0];
762 bp->stats.port_neighbor_type[1] = bp->cmd_rsp_virt->smt_mib_get.port_neighbor_type[1];
763 bp->stats.port_connection_policies[0] = bp->cmd_rsp_virt->smt_mib_get.port_connection_policies[0];
764 bp->stats.port_connection_policies[1] = bp->cmd_rsp_virt->smt_mib_get.port_connection_policies[1];
765 bp->stats.port_mac_indicated[0] = bp->cmd_rsp_virt->smt_mib_get.port_mac_indicated[0];
766 bp->stats.port_mac_indicated[1] = bp->cmd_rsp_virt->smt_mib_get.port_mac_indicated[1];
767 bp->stats.port_current_path[0] = bp->cmd_rsp_virt->smt_mib_get.port_current_path[0];
768 bp->stats.port_current_path[1] = bp->cmd_rsp_virt->smt_mib_get.port_current_path[1];
769 memcpy(&bp->stats.port_requested_paths[0 * 3], &bp->cmd_rsp_virt->smt_mib_get.port_requested_paths[0], 3);
770 memcpy(&bp->stats.port_requested_paths[1 * 3], &bp->cmd_rsp_virt->smt_mib_get.port_requested_paths[1], 3);
771 bp->stats.port_mac_placement[0] = bp->cmd_rsp_virt->smt_mib_get.port_mac_placement[0];
772 bp->stats.port_mac_placement[1] = bp->cmd_rsp_virt->smt_mib_get.port_mac_placement[1];
773 bp->stats.port_available_paths[0] = bp->cmd_rsp_virt->smt_mib_get.port_available_paths[0];
774 bp->stats.port_available_paths[1] = bp->cmd_rsp_virt->smt_mib_get.port_available_paths[1];
775 bp->stats.port_pmd_class[0] = bp->cmd_rsp_virt->smt_mib_get.port_pmd_class[0];
776 bp->stats.port_pmd_class[1] = bp->cmd_rsp_virt->smt_mib_get.port_pmd_class[1];
777 bp->stats.port_connection_capabilities[0] = bp->cmd_rsp_virt->smt_mib_get.port_connection_capabilities[0];
778 bp->stats.port_connection_capabilities[1] = bp->cmd_rsp_virt->smt_mib_get.port_connection_capabilities[1];
779 bp->stats.port_bs_flag[0] = bp->cmd_rsp_virt->smt_mib_get.port_bs_flag[0];
780 bp->stats.port_bs_flag[1] = bp->cmd_rsp_virt->smt_mib_get.port_bs_flag[1];
781 bp->stats.port_ler_estimate[0] = bp->cmd_rsp_virt->smt_mib_get.port_ler_estimate[0];
782 bp->stats.port_ler_estimate[1] = bp->cmd_rsp_virt->smt_mib_get.port_ler_estimate[1];
783 bp->stats.port_ler_cutoff[0] = bp->cmd_rsp_virt->smt_mib_get.port_ler_cutoff[0];
784 bp->stats.port_ler_cutoff[1] = bp->cmd_rsp_virt->smt_mib_get.port_ler_cutoff[1];
785 bp->stats.port_ler_alarm[0] = bp->cmd_rsp_virt->smt_mib_get.port_ler_alarm[0];
786 bp->stats.port_ler_alarm[1] = bp->cmd_rsp_virt->smt_mib_get.port_ler_alarm[1];
787 bp->stats.port_connect_state[0] = bp->cmd_rsp_virt->smt_mib_get.port_connect_state[0];
788 bp->stats.port_connect_state[1] = bp->cmd_rsp_virt->smt_mib_get.port_connect_state[1];
789 bp->stats.port_pcm_state[0] = bp->cmd_rsp_virt->smt_mib_get.port_pcm_state[0];
790 bp->stats.port_pcm_state[1] = bp->cmd_rsp_virt->smt_mib_get.port_pcm_state[1];
791 bp->stats.port_pc_withhold[0] = bp->cmd_rsp_virt->smt_mib_get.port_pc_withhold[0];
792 bp->stats.port_pc_withhold[1] = bp->cmd_rsp_virt->smt_mib_get.port_pc_withhold[1];
793 bp->stats.port_ler_flag[0] = bp->cmd_rsp_virt->smt_mib_get.port_ler_flag[0];
794 bp->stats.port_ler_flag[1] = bp->cmd_rsp_virt->smt_mib_get.port_ler_flag[1];
795 bp->stats.port_hardware_present[0] = bp->cmd_rsp_virt->smt_mib_get.port_hardware_present[0];
796 bp->stats.port_hardware_present[1] = bp->cmd_rsp_virt->smt_mib_get.port_hardware_present[1];
797
798
799 /* Fill the bp->stats structure with the FDDI counter values */
800
801 bp->stats.mac_frame_cts = bp->cmd_rsp_virt->cntrs_get.cntrs.frame_cnt.ls;
802 bp->stats.mac_copied_cts = bp->cmd_rsp_virt->cntrs_get.cntrs.copied_cnt.ls;
803 bp->stats.mac_transmit_cts = bp->cmd_rsp_virt->cntrs_get.cntrs.transmit_cnt.ls;
804 bp->stats.mac_error_cts = bp->cmd_rsp_virt->cntrs_get.cntrs.error_cnt.ls;
805 bp->stats.mac_lost_cts = bp->cmd_rsp_virt->cntrs_get.cntrs.lost_cnt.ls;
806 bp->stats.port_lct_fail_cts[0] = bp->cmd_rsp_virt->cntrs_get.cntrs.lct_rejects[0].ls;
807 bp->stats.port_lct_fail_cts[1] = bp->cmd_rsp_virt->cntrs_get.cntrs.lct_rejects[1].ls;
808 bp->stats.port_lem_reject_cts[0] = bp->cmd_rsp_virt->cntrs_get.cntrs.lem_rejects[0].ls;
809 bp->stats.port_lem_reject_cts[1] = bp->cmd_rsp_virt->cntrs_get.cntrs.lem_rejects[1].ls;
810 bp->stats.port_lem_cts[0] = bp->cmd_rsp_virt->cntrs_get.cntrs.link_errors[0].ls;
811 bp->stats.port_lem_cts[1] = bp->cmd_rsp_virt->cntrs_get.cntrs.link_errors[1].ls;
812
813#endif
814 return ((struct net_device_stats *) &bp->os.MacStat);
815} // ctl_get_stat
816
817
818/*
819 * ==============================
820 * = skfp_ctl_set_multicast_list =
821 * ==============================
822 *
823 * Overview:
824 * Enable/Disable LLC frame promiscuous mode reception
825 * on the adapter and/or update multicast address table.
826 *
827 * Returns:
828 * None
829 *
830 * Arguments:
831 * dev - pointer to device information
832 *
833 * Functional Description:
834 * This function acquires the driver lock and only calls
835 * skfp_ctl_set_multicast_list_wo_lock then.
836 * This routine follows a fairly simple algorithm for setting the
837 * adapter filters and CAM:
838 *
839 * if IFF_PROMISC flag is set
840 * enable promiscuous mode
841 * else
842 * disable promiscuous mode
843 * if number of multicast addresses <= max. multicast number
844 * add mc addresses to adapter table
845 * else
846 * enable promiscuous mode
847 * update adapter filters
848 *
849 * Assumptions:
850 * Multicast addresses are presented in canonical (LSB) format.
851 *
852 * Side Effects:
853 * On-board adapter filters are updated.
854 */
855static void skfp_ctl_set_multicast_list(struct net_device *dev)
856{
857 struct s_smc *smc = netdev_priv(dev);
858 skfddi_priv *bp = &smc->os;
859 unsigned long Flags;
860
861 spin_lock_irqsave(&bp->DriverLock, Flags);
862 skfp_ctl_set_multicast_list_wo_lock(dev);
863 spin_unlock_irqrestore(&bp->DriverLock, Flags);
864 return;
865} // skfp_ctl_set_multicast_list
866
867
868
869static void skfp_ctl_set_multicast_list_wo_lock(struct net_device *dev)
870{
871 struct s_smc *smc = netdev_priv(dev);
872 struct dev_mc_list *dmi; /* ptr to multicast addr entry */
873 int i;
874
875 /* Enable promiscuous mode, if necessary */
876 if (dev->flags & IFF_PROMISC) {
877 mac_drv_rx_mode(smc, RX_ENABLE_PROMISC);
878 PRINTK(KERN_INFO "PROMISCUOUS MODE ENABLED\n");
879 }
880 /* Else, update multicast address table */
881 else {
882 mac_drv_rx_mode(smc, RX_DISABLE_PROMISC);
883 PRINTK(KERN_INFO "PROMISCUOUS MODE DISABLED\n");
884
885 // Reset all MC addresses
886 mac_clear_multicast(smc);
887 mac_drv_rx_mode(smc, RX_DISABLE_ALLMULTI);
888
889 if (dev->flags & IFF_ALLMULTI) {
890 mac_drv_rx_mode(smc, RX_ENABLE_ALLMULTI);
891 PRINTK(KERN_INFO "ENABLE ALL MC ADDRESSES\n");
892 } else if (dev->mc_count > 0) {
893 if (dev->mc_count <= FPMAX_MULTICAST) {
894 /* use exact filtering */
895
896 // point to first multicast addr
897 dmi = dev->mc_list;
898
899 for (i = 0; i < dev->mc_count; i++) {
900 mac_add_multicast(smc,
901 (struct fddi_addr *)dmi->dmi_addr,
902 1);
903
904 PRINTK(KERN_INFO "ENABLE MC ADDRESS:");
905 PRINTK(" %02x %02x %02x ",
906 dmi->dmi_addr[0],
907 dmi->dmi_addr[1],
908 dmi->dmi_addr[2]);
909 PRINTK("%02x %02x %02x\n",
910 dmi->dmi_addr[3],
911 dmi->dmi_addr[4],
912 dmi->dmi_addr[5]);
913 dmi = dmi->next;
914 } // for
915
916 } else { // more MC addresses than HW supports
917
918 mac_drv_rx_mode(smc, RX_ENABLE_ALLMULTI);
919 PRINTK(KERN_INFO "ENABLE ALL MC ADDRESSES\n");
920 }
921 } else { // no MC addresses
922
923 PRINTK(KERN_INFO "DISABLE ALL MC ADDRESSES\n");
924 }
925
926 /* Update adapter filters */
927 mac_update_multicast(smc);
928 }
929 return;
930} // skfp_ctl_set_multicast_list_wo_lock
931
932
933/*
934 * ===========================
935 * = skfp_ctl_set_mac_address =
936 * ===========================
937 *
938 * Overview:
939 * set new mac address on adapter and update dev_addr field in device table.
940 *
941 * Returns:
942 * None
943 *
944 * Arguments:
945 * dev - pointer to device information
946 * addr - pointer to sockaddr structure containing unicast address to set
947 *
948 * Assumptions:
949 * The address pointed to by addr->sa_data is a valid unicast
950 * address and is presented in canonical (LSB) format.
951 */
952static int skfp_ctl_set_mac_address(struct net_device *dev, void *addr)
953{
954 struct s_smc *smc = netdev_priv(dev);
955 struct sockaddr *p_sockaddr = (struct sockaddr *) addr;
956 skfddi_priv *bp = &smc->os;
957 unsigned long Flags;
958
959
960 memcpy(dev->dev_addr, p_sockaddr->sa_data, FDDI_K_ALEN);
961 spin_lock_irqsave(&bp->DriverLock, Flags);
962 ResetAdapter(smc);
963 spin_unlock_irqrestore(&bp->DriverLock, Flags);
964
965 return (0); /* always return zero */
966} // skfp_ctl_set_mac_address
967
968
969/*
970 * ==============
971 * = skfp_ioctl =
972 * ==============
973 *
974 * Overview:
975 *
976 * Perform IOCTL call functions here. Some are privileged operations and the
977 * effective uid is checked in those cases.
978 *
979 * Returns:
980 * status value
981 * 0 - success
982 * other - failure
983 *
984 * Arguments:
985 * dev - pointer to device information
986 * rq - pointer to ioctl request structure
987 * cmd - ?
988 *
989 */
990
991
992static int skfp_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
993{
994 struct s_smc *smc = netdev_priv(dev);
995 skfddi_priv *lp = &smc->os;
996 struct s_skfp_ioctl ioc;
997 int status = 0;
998
999 if (copy_from_user(&ioc, rq->ifr_data, sizeof(struct s_skfp_ioctl)))
1000 return -EFAULT;
1001
1002 switch (ioc.cmd) {
1003 case SKFP_GET_STATS: /* Get the driver statistics */
1004 ioc.len = sizeof(lp->MacStat);
1005 status = copy_to_user(ioc.data, skfp_ctl_get_stats(dev), ioc.len)
1006 ? -EFAULT : 0;
1007 break;
1008 case SKFP_CLR_STATS: /* Zero out the driver statistics */
1009 if (!capable(CAP_NET_ADMIN)) {
1010 memset(&lp->MacStat, 0, sizeof(lp->MacStat));
1011 } else {
1012 status = -EPERM;
1013 }
1014 break;
1015 default:
1016 printk("ioctl for %s: unknow cmd: %04x\n", dev->name, ioc.cmd);
1017 status = -EOPNOTSUPP;
1018
1019 } // switch
1020
1021 return status;
1022} // skfp_ioctl
1023
1024
1025/*
1026 * =====================
1027 * = skfp_send_pkt =
1028 * =====================
1029 *
1030 * Overview:
1031 * Queues a packet for transmission and try to transmit it.
1032 *
1033 * Returns:
1034 * Condition code
1035 *
1036 * Arguments:
1037 * skb - pointer to sk_buff to queue for transmission
1038 * dev - pointer to device information
1039 *
1040 * Functional Description:
1041 * Here we assume that an incoming skb transmit request
1042 * is contained in a single physically contiguous buffer
1043 * in which the virtual address of the start of packet
1044 * (skb->data) can be converted to a physical address
1045 * by using pci_map_single().
1046 *
1047 * We have an internal queue for packets we can not send
1048 * immediately. Packets in this queue can be given to the
1049 * adapter if transmit buffers are freed.
1050 *
1051 * We can't free the skb until after it's been DMA'd
1052 * out by the adapter, so we'll keep it in the driver and
1053 * return it in mac_drv_tx_complete.
1054 *
1055 * Return Codes:
1056 * 0 - driver has queued and/or sent packet
1057 * 1 - caller should requeue the sk_buff for later transmission
1058 *
1059 * Assumptions:
1060 * The entire packet is stored in one physically
1061 * contiguous buffer which is not cached and whose
1062 * 32-bit physical address can be determined.
1063 *
1064 * It's vital that this routine is NOT reentered for the
1065 * same board and that the OS is not in another section of
1066 * code (eg. skfp_interrupt) for the same board on a
1067 * different thread.
1068 *
1069 * Side Effects:
1070 * None
1071 */
1072static int skfp_send_pkt(struct sk_buff *skb, struct net_device *dev)
1073{
1074 struct s_smc *smc = netdev_priv(dev);
1075 skfddi_priv *bp = &smc->os;
1076
1077 PRINTK(KERN_INFO "skfp_send_pkt\n");
1078
1079 /*
1080 * Verify that incoming transmit request is OK
1081 *
1082 * Note: The packet size check is consistent with other
1083 * Linux device drivers, although the correct packet
1084 * size should be verified before calling the
1085 * transmit routine.
1086 */
1087
1088 if (!(skb->len >= FDDI_K_LLC_ZLEN && skb->len <= FDDI_K_LLC_LEN)) {
1089 bp->MacStat.gen.tx_errors++; /* bump error counter */
1090 // dequeue packets from xmt queue and send them
1091 netif_start_queue(dev);
1092 dev_kfree_skb(skb);
1093 return (0); /* return "success" */
1094 }
1095 if (bp->QueueSkb == 0) { // return with tbusy set: queue full
1096
1097 netif_stop_queue(dev);
1098 return 1;
1099 }
1100 bp->QueueSkb--;
1101 skb_queue_tail(&bp->SendSkbQueue, skb);
1102 send_queued_packets(netdev_priv(dev));
1103 if (bp->QueueSkb == 0) {
1104 netif_stop_queue(dev);
1105 }
1106 dev->trans_start = jiffies;
1107 return 0;
1108
1109} // skfp_send_pkt
1110
1111
1112/*
1113 * =======================
1114 * = send_queued_packets =
1115 * =======================
1116 *
1117 * Overview:
1118 * Send packets from the driver queue as long as there are some and
1119 * transmit resources are available.
1120 *
1121 * Returns:
1122 * None
1123 *
1124 * Arguments:
1125 * smc - pointer to smc (adapter) structure
1126 *
1127 * Functional Description:
1128 * Take a packet from queue if there is any. If not, then we are done.
1129 * Check if there are resources to send the packet. If not, requeue it
1130 * and exit.
1131 * Set packet descriptor flags and give packet to adapter.
1132 * Check if any send resources can be freed (we do not use the
1133 * transmit complete interrupt).
1134 */
1135static void send_queued_packets(struct s_smc *smc)
1136{
1137 skfddi_priv *bp = &smc->os;
1138 struct sk_buff *skb;
1139 unsigned char fc;
1140 int queue;
1141 struct s_smt_fp_txd *txd; // Current TxD.
1142 dma_addr_t dma_address;
1143 unsigned long Flags;
1144
1145 int frame_status; // HWM tx frame status.
1146
1147 PRINTK(KERN_INFO "send queued packets\n");
1148 for (;;) {
1149 // send first buffer from queue
1150 skb = skb_dequeue(&bp->SendSkbQueue);
1151
1152 if (!skb) {
1153 PRINTK(KERN_INFO "queue empty\n");
1154 return;
1155 } // queue empty !
1156
1157 spin_lock_irqsave(&bp->DriverLock, Flags);
1158 fc = skb->data[0];
1159 queue = (fc & FC_SYNC_BIT) ? QUEUE_S : QUEUE_A0;
1160#ifdef ESS
1161 // Check if the frame may/must be sent as a synchronous frame.
1162
1163 if ((fc & ~(FC_SYNC_BIT | FC_LLC_PRIOR)) == FC_ASYNC_LLC) {
1164 // It's an LLC frame.
1165 if (!smc->ess.sync_bw_available)
1166 fc &= ~FC_SYNC_BIT; // No bandwidth available.
1167
1168 else { // Bandwidth is available.
1169
1170 if (smc->mib.fddiESSSynchTxMode) {
1171 // Send as sync. frame.
1172 fc |= FC_SYNC_BIT;
1173 }
1174 }
1175 }
1176#endif // ESS
1177 frame_status = hwm_tx_init(smc, fc, 1, skb->len, queue);
1178
1179 if ((frame_status & (LOC_TX | LAN_TX)) == 0) {
1180 // Unable to send the frame.
1181
1182 if ((frame_status & RING_DOWN) != 0) {
1183 // Ring is down.
1184 PRINTK("Tx attempt while ring down.\n");
1185 } else if ((frame_status & OUT_OF_TXD) != 0) {
1186 PRINTK("%s: out of TXDs.\n", bp->dev->name);
1187 } else {
1188 PRINTK("%s: out of transmit resources",
1189 bp->dev->name);
1190 }
1191
1192 // Note: We will retry the operation as soon as
1193 // transmit resources become available.
1194 skb_queue_head(&bp->SendSkbQueue, skb);
1195 spin_unlock_irqrestore(&bp->DriverLock, Flags);
1196 return; // Packet has been queued.
1197
1198 } // if (unable to send frame)
1199
1200 bp->QueueSkb++; // one packet less in local queue
1201
1202 // source address in packet ?
1203 CheckSourceAddress(skb->data, smc->hw.fddi_canon_addr.a);
1204
1205 txd = (struct s_smt_fp_txd *) HWM_GET_CURR_TXD(smc, queue);
1206
1207 dma_address = pci_map_single(&bp->pdev, skb->data,
1208 skb->len, PCI_DMA_TODEVICE);
1209 if (frame_status & LAN_TX) {
1210 txd->txd_os.skb = skb; // save skb
1211 txd->txd_os.dma_addr = dma_address; // save dma mapping
1212 }
1213 hwm_tx_frag(smc, skb->data, dma_address, skb->len,
1214 frame_status | FIRST_FRAG | LAST_FRAG | EN_IRQ_EOF);
1215
1216 if (!(frame_status & LAN_TX)) { // local only frame
1217 pci_unmap_single(&bp->pdev, dma_address,
1218 skb->len, PCI_DMA_TODEVICE);
1219 dev_kfree_skb_irq(skb);
1220 }
1221 spin_unlock_irqrestore(&bp->DriverLock, Flags);
1222 } // for
1223
1224 return; // never reached
1225
1226} // send_queued_packets
1227
1228
1229/************************
1230 *
1231 * CheckSourceAddress
1232 *
1233 * Verify if the source address is set. Insert it if necessary.
1234 *
1235 ************************/
1236void CheckSourceAddress(unsigned char *frame, unsigned char *hw_addr)
1237{
1238 unsigned char SRBit;
1239
1240 if ((((unsigned long) frame[1 + 6]) & ~0x01) != 0) // source routing bit
1241
1242 return;
1243 if ((unsigned short) frame[1 + 10] != 0)
1244 return;
1245 SRBit = frame[1 + 6] & 0x01;
1246 memcpy(&frame[1 + 6], hw_addr, 6);
1247 frame[8] |= SRBit;
1248} // CheckSourceAddress
1249
1250
1251/************************
1252 *
1253 * ResetAdapter
1254 *
1255 * Reset the adapter and bring it back to operational mode.
1256 * Args
1257 * smc - A pointer to the SMT context struct.
1258 * Out
1259 * Nothing.
1260 *
1261 ************************/
1262static void ResetAdapter(struct s_smc *smc)
1263{
1264
1265 PRINTK(KERN_INFO "[fddi: ResetAdapter]\n");
1266
1267 // Stop the adapter.
1268
1269 card_stop(smc); // Stop all activity.
1270
1271 // Clear the transmit and receive descriptor queues.
1272 mac_drv_clear_tx_queue(smc);
1273 mac_drv_clear_rx_queue(smc);
1274
1275 // Restart the adapter.
1276
1277 smt_reset_defaults(smc, 1); // Initialize the SMT module.
1278
1279 init_smt(smc, (smc->os.dev)->dev_addr); // Initialize the hardware.
1280
1281 smt_online(smc, 1); // Insert into the ring again.
1282 STI_FBI();
1283
1284 // Restore original receive mode (multicasts, promiscuous, etc.).
1285 skfp_ctl_set_multicast_list_wo_lock(smc->os.dev);
1286} // ResetAdapter
1287
1288
1289//--------------- functions called by hardware module ----------------
1290
1291/************************
1292 *
1293 * llc_restart_tx
1294 *
1295 * The hardware driver calls this routine when the transmit complete
1296 * interrupt bits (end of frame) for the synchronous or asynchronous
1297 * queue is set.
1298 *
1299 * NOTE The hardware driver calls this function also if no packets are queued.
1300 * The routine must be able to handle this case.
1301 * Args
1302 * smc - A pointer to the SMT context struct.
1303 * Out
1304 * Nothing.
1305 *
1306 ************************/
1307void llc_restart_tx(struct s_smc *smc)
1308{
1309 skfddi_priv *bp = &smc->os;
1310
1311 PRINTK(KERN_INFO "[llc_restart_tx]\n");
1312
1313 // Try to send queued packets
1314 spin_unlock(&bp->DriverLock);
1315 send_queued_packets(smc);
1316 spin_lock(&bp->DriverLock);
1317 netif_start_queue(bp->dev);// system may send again if it was blocked
1318
1319} // llc_restart_tx
1320
1321
1322/************************
1323 *
1324 * mac_drv_get_space
1325 *
1326 * The hardware module calls this function to allocate the memory
1327 * for the SMT MBufs if the define MB_OUTSIDE_SMC is specified.
1328 * Args
1329 * smc - A pointer to the SMT context struct.
1330 *
1331 * size - Size of memory in bytes to allocate.
1332 * Out
1333 * != 0 A pointer to the virtual address of the allocated memory.
1334 * == 0 Allocation error.
1335 *
1336 ************************/
1337void *mac_drv_get_space(struct s_smc *smc, unsigned int size)
1338{
1339 void *virt;
1340
1341 PRINTK(KERN_INFO "mac_drv_get_space (%d bytes), ", size);
1342 virt = (void *) (smc->os.SharedMemAddr + smc->os.SharedMemHeap);
1343
1344 if ((smc->os.SharedMemHeap + size) > smc->os.SharedMemSize) {
1345 printk("Unexpected SMT memory size requested: %d\n", size);
1346 return (NULL);
1347 }
1348 smc->os.SharedMemHeap += size; // Move heap pointer.
1349
1350 PRINTK(KERN_INFO "mac_drv_get_space end\n");
1351 PRINTK(KERN_INFO "virt addr: %lx\n", (ulong) virt);
1352 PRINTK(KERN_INFO "bus addr: %lx\n", (ulong)
1353 (smc->os.SharedMemDMA +
1354 ((char *) virt - (char *)smc->os.SharedMemAddr)));
1355 return (virt);
1356} // mac_drv_get_space
1357
1358
1359/************************
1360 *
1361 * mac_drv_get_desc_mem
1362 *
1363 * This function is called by the hardware dependent module.
1364 * It allocates the memory for the RxD and TxD descriptors.
1365 *
1366 * This memory must be non-cached, non-movable and non-swappable.
1367 * This memory should start at a physical page boundary.
1368 * Args
1369 * smc - A pointer to the SMT context struct.
1370 *
1371 * size - Size of memory in bytes to allocate.
1372 * Out
1373 * != 0 A pointer to the virtual address of the allocated memory.
1374 * == 0 Allocation error.
1375 *
1376 ************************/
1377void *mac_drv_get_desc_mem(struct s_smc *smc, unsigned int size)
1378{
1379
1380 char *virt;
1381
1382 PRINTK(KERN_INFO "mac_drv_get_desc_mem\n");
1383
1384 // Descriptor memory must be aligned on 16-byte boundary.
1385
1386 virt = mac_drv_get_space(smc, size);
1387
1388 size = (u_int) (16 - (((unsigned long) virt) & 15UL));
1389 size = size % 16;
1390
1391 PRINTK("Allocate %u bytes alignment gap ", size);
1392 PRINTK("for descriptor memory.\n");
1393
1394 if (!mac_drv_get_space(smc, size)) {
1395 printk("fddi: Unable to align descriptor memory.\n");
1396 return (NULL);
1397 }
1398 return (virt + size);
1399} // mac_drv_get_desc_mem
1400
1401
1402/************************
1403 *
1404 * mac_drv_virt2phys
1405 *
1406 * Get the physical address of a given virtual address.
1407 * Args
1408 * smc - A pointer to the SMT context struct.
1409 *
1410 * virt - A (virtual) pointer into our 'shared' memory area.
1411 * Out
1412 * Physical address of the given virtual address.
1413 *
1414 ************************/
1415unsigned long mac_drv_virt2phys(struct s_smc *smc, void *virt)
1416{
1417 return (smc->os.SharedMemDMA +
1418 ((char *) virt - (char *)smc->os.SharedMemAddr));
1419} // mac_drv_virt2phys
1420
1421
1422/************************
1423 *
1424 * dma_master
1425 *
1426 * The HWM calls this function, when the driver leads through a DMA
1427 * transfer. If the OS-specific module must prepare the system hardware
1428 * for the DMA transfer, it should do it in this function.
1429 *
1430 * The hardware module calls this dma_master if it wants to send an SMT
1431 * frame. This means that the virt address passed in here is part of
1432 * the 'shared' memory area.
1433 * Args
1434 * smc - A pointer to the SMT context struct.
1435 *
1436 * virt - The virtual address of the data.
1437 *
1438 * len - The length in bytes of the data.
1439 *
1440 * flag - Indicates the transmit direction and the buffer type:
1441 * DMA_RD (0x01) system RAM ==> adapter buffer memory
1442 * DMA_WR (0x02) adapter buffer memory ==> system RAM
1443 * SMT_BUF (0x80) SMT buffer
1444 *
1445 * >> NOTE: SMT_BUF and DMA_RD are always set for PCI. <<
1446 * Out
1447 * Returns the pyhsical address for the DMA transfer.
1448 *
1449 ************************/
1450u_long dma_master(struct s_smc * smc, void *virt, int len, int flag)
1451{
1452 return (smc->os.SharedMemDMA +
1453 ((char *) virt - (char *)smc->os.SharedMemAddr));
1454} // dma_master
1455
1456
1457/************************
1458 *
1459 * dma_complete
1460 *
1461 * The hardware module calls this routine when it has completed a DMA
1462 * transfer. If the operating system dependent module has set up the DMA
1463 * channel via dma_master() (e.g. Windows NT or AIX) it should clean up
1464 * the DMA channel.
1465 * Args
1466 * smc - A pointer to the SMT context struct.
1467 *
1468 * descr - A pointer to a TxD or RxD, respectively.
1469 *
1470 * flag - Indicates the DMA transfer direction / SMT buffer:
1471 * DMA_RD (0x01) system RAM ==> adapter buffer memory
1472 * DMA_WR (0x02) adapter buffer memory ==> system RAM
1473 * SMT_BUF (0x80) SMT buffer (managed by HWM)
1474 * Out
1475 * Nothing.
1476 *
1477 ************************/
1478void dma_complete(struct s_smc *smc, volatile union s_fp_descr *descr, int flag)
1479{
1480 /* For TX buffers, there are two cases. If it is an SMT transmit
1481 * buffer, there is nothing to do since we use consistent memory
1482 * for the 'shared' memory area. The other case is for normal
1483 * transmit packets given to us by the networking stack, and in
1484 * that case we cleanup the PCI DMA mapping in mac_drv_tx_complete
1485 * below.
1486 *
1487 * For RX buffers, we have to unmap dynamic PCI DMA mappings here
1488 * because the hardware module is about to potentially look at
1489 * the contents of the buffer. If we did not call the PCI DMA
1490 * unmap first, the hardware module could read inconsistent data.
1491 */
1492 if (flag & DMA_WR) {
1493 skfddi_priv *bp = &smc->os;
1494 volatile struct s_smt_fp_rxd *r = &descr->r;
1495
1496 /* If SKB is NULL, we used the local buffer. */
1497 if (r->rxd_os.skb && r->rxd_os.dma_addr) {
1498 int MaxFrameSize = bp->MaxFrameSize;
1499
1500 pci_unmap_single(&bp->pdev, r->rxd_os.dma_addr,
1501 MaxFrameSize, PCI_DMA_FROMDEVICE);
1502 r->rxd_os.dma_addr = 0;
1503 }
1504 }
1505} // dma_complete
1506
1507
1508/************************
1509 *
1510 * mac_drv_tx_complete
1511 *
1512 * Transmit of a packet is complete. Release the tx staging buffer.
1513 *
1514 * Args
1515 * smc - A pointer to the SMT context struct.
1516 *
1517 * txd - A pointer to the last TxD which is used by the frame.
1518 * Out
1519 * Returns nothing.
1520 *
1521 ************************/
1522void mac_drv_tx_complete(struct s_smc *smc, volatile struct s_smt_fp_txd *txd)
1523{
1524 struct sk_buff *skb;
1525
1526 PRINTK(KERN_INFO "entering mac_drv_tx_complete\n");
1527 // Check if this TxD points to a skb
1528
1529 if (!(skb = txd->txd_os.skb)) {
1530 PRINTK("TXD with no skb assigned.\n");
1531 return;
1532 }
1533 txd->txd_os.skb = NULL;
1534
1535 // release the DMA mapping
1536 pci_unmap_single(&smc->os.pdev, txd->txd_os.dma_addr,
1537 skb->len, PCI_DMA_TODEVICE);
1538 txd->txd_os.dma_addr = 0;
1539
1540 smc->os.MacStat.gen.tx_packets++; // Count transmitted packets.
1541 smc->os.MacStat.gen.tx_bytes+=skb->len; // Count bytes
1542
1543 // free the skb
1544 dev_kfree_skb_irq(skb);
1545
1546 PRINTK(KERN_INFO "leaving mac_drv_tx_complete\n");
1547} // mac_drv_tx_complete
1548
1549
1550/************************
1551 *
1552 * dump packets to logfile
1553 *
1554 ************************/
1555#ifdef DUMPPACKETS
1556void dump_data(unsigned char *Data, int length)
1557{
1558 int i, j;
1559 unsigned char s[255], sh[10];
1560 if (length > 64) {
1561 length = 64;
1562 }
1563 printk(KERN_INFO "---Packet start---\n");
1564 for (i = 0, j = 0; i < length / 8; i++, j += 8)
1565 printk(KERN_INFO "%02x %02x %02x %02x %02x %02x %02x %02x\n",
1566 Data[j + 0], Data[j + 1], Data[j + 2], Data[j + 3],
1567 Data[j + 4], Data[j + 5], Data[j + 6], Data[j + 7]);
1568 strcpy(s, "");
1569 for (i = 0; i < length % 8; i++) {
1570 sprintf(sh, "%02x ", Data[j + i]);
1571 strcat(s, sh);
1572 }
1573 printk(KERN_INFO "%s\n", s);
1574 printk(KERN_INFO "------------------\n");
1575} // dump_data
1576#else
1577#define dump_data(data,len)
1578#endif // DUMPPACKETS
1579
1580/************************
1581 *
1582 * mac_drv_rx_complete
1583 *
1584 * The hardware module calls this function if an LLC frame is received
1585 * in a receive buffer. Also the SMT, NSA, and directed beacon frames
1586 * from the network will be passed to the LLC layer by this function
1587 * if passing is enabled.
1588 *
1589 * mac_drv_rx_complete forwards the frame to the LLC layer if it should
1590 * be received. It also fills the RxD ring with new receive buffers if
1591 * some can be queued.
1592 * Args
1593 * smc - A pointer to the SMT context struct.
1594 *
1595 * rxd - A pointer to the first RxD which is used by the receive frame.
1596 *
1597 * frag_count - Count of RxDs used by the received frame.
1598 *
1599 * len - Frame length.
1600 * Out
1601 * Nothing.
1602 *
1603 ************************/
1604void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
1605 int frag_count, int len)
1606{
1607 skfddi_priv *bp = &smc->os;
1608 struct sk_buff *skb;
1609 unsigned char *virt, *cp;
1610 unsigned short ri;
1611 u_int RifLength;
1612
1613 PRINTK(KERN_INFO "entering mac_drv_rx_complete (len=%d)\n", len);
1614 if (frag_count != 1) { // This is not allowed to happen.
1615
1616 printk("fddi: Multi-fragment receive!\n");
1617 goto RequeueRxd; // Re-use the given RXD(s).
1618
1619 }
1620 skb = rxd->rxd_os.skb;
1621 if (!skb) {
1622 PRINTK(KERN_INFO "No skb in rxd\n");
1623 smc->os.MacStat.gen.rx_errors++;
1624 goto RequeueRxd;
1625 }
1626 virt = skb->data;
1627
1628 // The DMA mapping was released in dma_complete above.
1629
1630 dump_data(skb->data, len);
1631
1632 /*
1633 * FDDI Frame format:
1634 * +-------+-------+-------+------------+--------+------------+
1635 * | FC[1] | DA[6] | SA[6] | RIF[0..18] | LLC[3] | Data[0..n] |
1636 * +-------+-------+-------+------------+--------+------------+
1637 *
1638 * FC = Frame Control
1639 * DA = Destination Address
1640 * SA = Source Address
1641 * RIF = Routing Information Field
1642 * LLC = Logical Link Control
1643 */
1644
1645 // Remove Routing Information Field (RIF), if present.
1646
1647 if ((virt[1 + 6] & FDDI_RII) == 0)
1648 RifLength = 0;
1649 else {
1650 int n;
1651// goos: RIF removal has still to be tested
1652 PRINTK(KERN_INFO "RIF found\n");
1653 // Get RIF length from Routing Control (RC) field.
1654 cp = virt + FDDI_MAC_HDR_LEN; // Point behind MAC header.
1655
1656 ri = ntohs(*((unsigned short *) cp));
1657 RifLength = ri & FDDI_RCF_LEN_MASK;
1658 if (len < (int) (FDDI_MAC_HDR_LEN + RifLength)) {
1659 printk("fddi: Invalid RIF.\n");
1660 goto RequeueRxd; // Discard the frame.
1661
1662 }
1663 virt[1 + 6] &= ~FDDI_RII; // Clear RII bit.
1664 // regions overlap
1665
1666 virt = cp + RifLength;
1667 for (n = FDDI_MAC_HDR_LEN; n; n--)
1668 *--virt = *--cp;
1669 // adjust sbd->data pointer
1670 skb_pull(skb, RifLength);
1671 len -= RifLength;
1672 RifLength = 0;
1673 }
1674
1675 // Count statistics.
1676 smc->os.MacStat.gen.rx_packets++; // Count indicated receive
1677 // packets.
1678 smc->os.MacStat.gen.rx_bytes+=len; // Count bytes.
1679
1680 // virt points to header again
1681 if (virt[1] & 0x01) { // Check group (multicast) bit.
1682
1683 smc->os.MacStat.gen.multicast++;
1684 }
1685
1686 // deliver frame to system
1687 rxd->rxd_os.skb = NULL;
1688 skb_trim(skb, len);
1689 skb->protocol = fddi_type_trans(skb, bp->dev);
1690 skb->dev = bp->dev; /* pass up device pointer */
1691
1692 netif_rx(skb);
1693 bp->dev->last_rx = jiffies;
1694
1695 HWM_RX_CHECK(smc, RX_LOW_WATERMARK);
1696 return;
1697
1698 RequeueRxd:
1699 PRINTK(KERN_INFO "Rx: re-queue RXD.\n");
1700 mac_drv_requeue_rxd(smc, rxd, frag_count);
1701 smc->os.MacStat.gen.rx_errors++; // Count receive packets
1702 // not indicated.
1703
1704} // mac_drv_rx_complete
1705
1706
1707/************************
1708 *
1709 * mac_drv_requeue_rxd
1710 *
1711 * The hardware module calls this function to request the OS-specific
1712 * module to queue the receive buffer(s) represented by the pointer
1713 * to the RxD and the frag_count into the receive queue again. This
1714 * buffer was filled with an invalid frame or an SMT frame.
1715 * Args
1716 * smc - A pointer to the SMT context struct.
1717 *
1718 * rxd - A pointer to the first RxD which is used by the receive frame.
1719 *
1720 * frag_count - Count of RxDs used by the received frame.
1721 * Out
1722 * Nothing.
1723 *
1724 ************************/
1725void mac_drv_requeue_rxd(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
1726 int frag_count)
1727{
1728 volatile struct s_smt_fp_rxd *next_rxd;
1729 volatile struct s_smt_fp_rxd *src_rxd;
1730 struct sk_buff *skb;
1731 int MaxFrameSize;
1732 unsigned char *v_addr;
1733 dma_addr_t b_addr;
1734
1735 if (frag_count != 1) // This is not allowed to happen.
1736
1737 printk("fddi: Multi-fragment requeue!\n");
1738
1739 MaxFrameSize = smc->os.MaxFrameSize;
1740 src_rxd = rxd;
1741 for (; frag_count > 0; frag_count--) {
1742 next_rxd = src_rxd->rxd_next;
1743 rxd = HWM_GET_CURR_RXD(smc);
1744
1745 skb = src_rxd->rxd_os.skb;
1746 if (skb == NULL) { // this should not happen
1747
1748 PRINTK("Requeue with no skb in rxd!\n");
1749 skb = alloc_skb(MaxFrameSize + 3, GFP_ATOMIC);
1750 if (skb) {
1751 // we got a skb
1752 rxd->rxd_os.skb = skb;
1753 skb_reserve(skb, 3);
1754 skb_put(skb, MaxFrameSize);
1755 v_addr = skb->data;
1756 b_addr = pci_map_single(&smc->os.pdev,
1757 v_addr,
1758 MaxFrameSize,
1759 PCI_DMA_FROMDEVICE);
1760 rxd->rxd_os.dma_addr = b_addr;
1761 } else {
1762 // no skb available, use local buffer
1763 PRINTK("Queueing invalid buffer!\n");
1764 rxd->rxd_os.skb = NULL;
1765 v_addr = smc->os.LocalRxBuffer;
1766 b_addr = smc->os.LocalRxBufferDMA;
1767 }
1768 } else {
1769 // we use skb from old rxd
1770 rxd->rxd_os.skb = skb;
1771 v_addr = skb->data;
1772 b_addr = pci_map_single(&smc->os.pdev,
1773 v_addr,
1774 MaxFrameSize,
1775 PCI_DMA_FROMDEVICE);
1776 rxd->rxd_os.dma_addr = b_addr;
1777 }
1778 hwm_rx_frag(smc, v_addr, b_addr, MaxFrameSize,
1779 FIRST_FRAG | LAST_FRAG);
1780
1781 src_rxd = next_rxd;
1782 }
1783} // mac_drv_requeue_rxd
1784
1785
1786/************************
1787 *
1788 * mac_drv_fill_rxd
1789 *
1790 * The hardware module calls this function at initialization time
1791 * to fill the RxD ring with receive buffers. It is also called by
1792 * mac_drv_rx_complete if rx_free is large enough to queue some new
1793 * receive buffers into the RxD ring. mac_drv_fill_rxd queues new
1794 * receive buffers as long as enough RxDs and receive buffers are
1795 * available.
1796 * Args
1797 * smc - A pointer to the SMT context struct.
1798 * Out
1799 * Nothing.
1800 *
1801 ************************/
1802void mac_drv_fill_rxd(struct s_smc *smc)
1803{
1804 int MaxFrameSize;
1805 unsigned char *v_addr;
1806 unsigned long b_addr;
1807 struct sk_buff *skb;
1808 volatile struct s_smt_fp_rxd *rxd;
1809
1810 PRINTK(KERN_INFO "entering mac_drv_fill_rxd\n");
1811
1812 // Walk through the list of free receive buffers, passing receive
1813 // buffers to the HWM as long as RXDs are available.
1814
1815 MaxFrameSize = smc->os.MaxFrameSize;
1816 // Check if there is any RXD left.
1817 while (HWM_GET_RX_FREE(smc) > 0) {
1818 PRINTK(KERN_INFO ".\n");
1819
1820 rxd = HWM_GET_CURR_RXD(smc);
1821 skb = alloc_skb(MaxFrameSize + 3, GFP_ATOMIC);
1822 if (skb) {
1823 // we got a skb
1824 skb_reserve(skb, 3);
1825 skb_put(skb, MaxFrameSize);
1826 v_addr = skb->data;
1827 b_addr = pci_map_single(&smc->os.pdev,
1828 v_addr,
1829 MaxFrameSize,
1830 PCI_DMA_FROMDEVICE);
1831 rxd->rxd_os.dma_addr = b_addr;
1832 } else {
1833 // no skb available, use local buffer
1834 // System has run out of buffer memory, but we want to
1835 // keep the receiver running in hope of better times.
1836 // Multiple descriptors may point to this local buffer,
1837 // so data in it must be considered invalid.
1838 PRINTK("Queueing invalid buffer!\n");
1839 v_addr = smc->os.LocalRxBuffer;
1840 b_addr = smc->os.LocalRxBufferDMA;
1841 }
1842
1843 rxd->rxd_os.skb = skb;
1844
1845 // Pass receive buffer to HWM.
1846 hwm_rx_frag(smc, v_addr, b_addr, MaxFrameSize,
1847 FIRST_FRAG | LAST_FRAG);
1848 }
1849 PRINTK(KERN_INFO "leaving mac_drv_fill_rxd\n");
1850} // mac_drv_fill_rxd
1851
1852
1853/************************
1854 *
1855 * mac_drv_clear_rxd
1856 *
1857 * The hardware module calls this function to release unused
1858 * receive buffers.
1859 * Args
1860 * smc - A pointer to the SMT context struct.
1861 *
1862 * rxd - A pointer to the first RxD which is used by the receive buffer.
1863 *
1864 * frag_count - Count of RxDs used by the receive buffer.
1865 * Out
1866 * Nothing.
1867 *
1868 ************************/
1869void mac_drv_clear_rxd(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
1870 int frag_count)
1871{
1872
1873 struct sk_buff *skb;
1874
1875 PRINTK("entering mac_drv_clear_rxd\n");
1876
1877 if (frag_count != 1) // This is not allowed to happen.
1878
1879 printk("fddi: Multi-fragment clear!\n");
1880
1881 for (; frag_count > 0; frag_count--) {
1882 skb = rxd->rxd_os.skb;
1883 if (skb != NULL) {
1884 skfddi_priv *bp = &smc->os;
1885 int MaxFrameSize = bp->MaxFrameSize;
1886
1887 pci_unmap_single(&bp->pdev, rxd->rxd_os.dma_addr,
1888 MaxFrameSize, PCI_DMA_FROMDEVICE);
1889
1890 dev_kfree_skb(skb);
1891 rxd->rxd_os.skb = NULL;
1892 }
1893 rxd = rxd->rxd_next; // Next RXD.
1894
1895 }
1896} // mac_drv_clear_rxd
1897
1898
1899/************************
1900 *
1901 * mac_drv_rx_init
1902 *
1903 * The hardware module calls this routine when an SMT or NSA frame of the
1904 * local SMT should be delivered to the LLC layer.
1905 *
1906 * It is necessary to have this function, because there is no other way to
1907 * copy the contents of SMT MBufs into receive buffers.
1908 *
1909 * mac_drv_rx_init allocates the required target memory for this frame,
1910 * and receives the frame fragment by fragment by calling mac_drv_rx_frag.
1911 * Args
1912 * smc - A pointer to the SMT context struct.
1913 *
1914 * len - The length (in bytes) of the received frame (FC, DA, SA, Data).
1915 *
1916 * fc - The Frame Control field of the received frame.
1917 *
1918 * look_ahead - A pointer to the lookahead data buffer (may be NULL).
1919 *
1920 * la_len - The length of the lookahead data stored in the lookahead
1921 * buffer (may be zero).
1922 * Out
1923 * Always returns zero (0).
1924 *
1925 ************************/
1926int mac_drv_rx_init(struct s_smc *smc, int len, int fc,
1927 char *look_ahead, int la_len)
1928{
1929 struct sk_buff *skb;
1930
1931 PRINTK("entering mac_drv_rx_init(len=%d)\n", len);
1932
1933 // "Received" a SMT or NSA frame of the local SMT.
1934
1935 if (len != la_len || len < FDDI_MAC_HDR_LEN || !look_ahead) {
1936 PRINTK("fddi: Discard invalid local SMT frame\n");
1937 PRINTK(" len=%d, la_len=%d, (ULONG) look_ahead=%08lXh.\n",
1938 len, la_len, (unsigned long) look_ahead);
1939 return (0);
1940 }
1941 skb = alloc_skb(len + 3, GFP_ATOMIC);
1942 if (!skb) {
1943 PRINTK("fddi: Local SMT: skb memory exhausted.\n");
1944 return (0);
1945 }
1946 skb_reserve(skb, 3);
1947 skb_put(skb, len);
1948 memcpy(skb->data, look_ahead, len);
1949
1950 // deliver frame to system
1951 skb->protocol = fddi_type_trans(skb, smc->os.dev);
1952 skb->dev->last_rx = jiffies;
1953 netif_rx(skb);
1954
1955 return (0);
1956} // mac_drv_rx_init
1957
1958
1959/************************
1960 *
1961 * smt_timer_poll
1962 *
1963 * This routine is called periodically by the SMT module to clean up the
1964 * driver.
1965 *
1966 * Return any queued frames back to the upper protocol layers if the ring
1967 * is down.
1968 * Args
1969 * smc - A pointer to the SMT context struct.
1970 * Out
1971 * Nothing.
1972 *
1973 ************************/
1974void smt_timer_poll(struct s_smc *smc)
1975{
1976} // smt_timer_poll
1977
1978
1979/************************
1980 *
1981 * ring_status_indication
1982 *
1983 * This function indicates a change of the ring state.
1984 * Args
1985 * smc - A pointer to the SMT context struct.
1986 *
1987 * status - The current ring status.
1988 * Out
1989 * Nothing.
1990 *
1991 ************************/
1992void ring_status_indication(struct s_smc *smc, u_long status)
1993{
1994 PRINTK("ring_status_indication( ");
1995 if (status & RS_RES15)
1996 PRINTK("RS_RES15 ");
1997 if (status & RS_HARDERROR)
1998 PRINTK("RS_HARDERROR ");
1999 if (status & RS_SOFTERROR)
2000 PRINTK("RS_SOFTERROR ");
2001 if (status & RS_BEACON)
2002 PRINTK("RS_BEACON ");
2003 if (status & RS_PATHTEST)
2004 PRINTK("RS_PATHTEST ");
2005 if (status & RS_SELFTEST)
2006 PRINTK("RS_SELFTEST ");
2007 if (status & RS_RES9)
2008 PRINTK("RS_RES9 ");
2009 if (status & RS_DISCONNECT)
2010 PRINTK("RS_DISCONNECT ");
2011 if (status & RS_RES7)
2012 PRINTK("RS_RES7 ");
2013 if (status & RS_DUPADDR)
2014 PRINTK("RS_DUPADDR ");
2015 if (status & RS_NORINGOP)
2016 PRINTK("RS_NORINGOP ");
2017 if (status & RS_VERSION)
2018 PRINTK("RS_VERSION ");
2019 if (status & RS_STUCKBYPASSS)
2020 PRINTK("RS_STUCKBYPASSS ");
2021 if (status & RS_EVENT)
2022 PRINTK("RS_EVENT ");
2023 if (status & RS_RINGOPCHANGE)
2024 PRINTK("RS_RINGOPCHANGE ");
2025 if (status & RS_RES0)
2026 PRINTK("RS_RES0 ");
2027 PRINTK("]\n");
2028} // ring_status_indication
2029
2030
2031/************************
2032 *
2033 * smt_get_time
2034 *
2035 * Gets the current time from the system.
2036 * Args
2037 * None.
2038 * Out
2039 * The current time in TICKS_PER_SECOND.
2040 *
2041 * TICKS_PER_SECOND has the unit 'count of timer ticks per second'. It is
2042 * defined in "targetos.h". The definition of TICKS_PER_SECOND must comply
2043 * to the time returned by smt_get_time().
2044 *
2045 ************************/
2046unsigned long smt_get_time(void)
2047{
2048 return jiffies;
2049} // smt_get_time
2050
2051
2052/************************
2053 *
2054 * smt_stat_counter
2055 *
2056 * Status counter update (ring_op, fifo full).
2057 * Args
2058 * smc - A pointer to the SMT context struct.
2059 *
2060 * stat - = 0: A ring operational change occurred.
2061 * = 1: The FORMAC FIFO buffer is full / FIFO overflow.
2062 * Out
2063 * Nothing.
2064 *
2065 ************************/
2066void smt_stat_counter(struct s_smc *smc, int stat)
2067{
2068// BOOLEAN RingIsUp ;
2069
2070 PRINTK(KERN_INFO "smt_stat_counter\n");
2071 switch (stat) {
2072 case 0:
2073 PRINTK(KERN_INFO "Ring operational change.\n");
2074 break;
2075 case 1:
2076 PRINTK(KERN_INFO "Receive fifo overflow.\n");
2077 smc->os.MacStat.gen.rx_errors++;
2078 break;
2079 default:
2080 PRINTK(KERN_INFO "Unknown status (%d).\n", stat);
2081 break;
2082 }
2083} // smt_stat_counter
2084
2085
2086/************************
2087 *
2088 * cfm_state_change
2089 *
2090 * Sets CFM state in custom statistics.
2091 * Args
2092 * smc - A pointer to the SMT context struct.
2093 *
2094 * c_state - Possible values are:
2095 *
2096 * EC0_OUT, EC1_IN, EC2_TRACE, EC3_LEAVE, EC4_PATH_TEST,
2097 * EC5_INSERT, EC6_CHECK, EC7_DEINSERT
2098 * Out
2099 * Nothing.
2100 *
2101 ************************/
2102void cfm_state_change(struct s_smc *smc, int c_state)
2103{
2104#ifdef DRIVERDEBUG
2105 char *s;
2106
2107 switch (c_state) {
2108 case SC0_ISOLATED:
2109 s = "SC0_ISOLATED";
2110 break;
2111 case SC1_WRAP_A:
2112 s = "SC1_WRAP_A";
2113 break;
2114 case SC2_WRAP_B:
2115 s = "SC2_WRAP_B";
2116 break;
2117 case SC4_THRU_A:
2118 s = "SC4_THRU_A";
2119 break;
2120 case SC5_THRU_B:
2121 s = "SC5_THRU_B";
2122 break;
2123 case SC7_WRAP_S:
2124 s = "SC7_WRAP_S";
2125 break;
2126 case SC9_C_WRAP_A:
2127 s = "SC9_C_WRAP_A";
2128 break;
2129 case SC10_C_WRAP_B:
2130 s = "SC10_C_WRAP_B";
2131 break;
2132 case SC11_C_WRAP_S:
2133 s = "SC11_C_WRAP_S";
2134 break;
2135 default:
2136 PRINTK(KERN_INFO "cfm_state_change: unknown %d\n", c_state);
2137 return;
2138 }
2139 PRINTK(KERN_INFO "cfm_state_change: %s\n", s);
2140#endif // DRIVERDEBUG
2141} // cfm_state_change
2142
2143
2144/************************
2145 *
2146 * ecm_state_change
2147 *
2148 * Sets ECM state in custom statistics.
2149 * Args
2150 * smc - A pointer to the SMT context struct.
2151 *
2152 * e_state - Possible values are:
2153 *
2154 * SC0_ISOLATED, SC1_WRAP_A (5), SC2_WRAP_B (6), SC4_THRU_A (12),
2155 * SC5_THRU_B (7), SC7_WRAP_S (8)
2156 * Out
2157 * Nothing.
2158 *
2159 ************************/
2160void ecm_state_change(struct s_smc *smc, int e_state)
2161{
2162#ifdef DRIVERDEBUG
2163 char *s;
2164
2165 switch (e_state) {
2166 case EC0_OUT:
2167 s = "EC0_OUT";
2168 break;
2169 case EC1_IN:
2170 s = "EC1_IN";
2171 break;
2172 case EC2_TRACE:
2173 s = "EC2_TRACE";
2174 break;
2175 case EC3_LEAVE:
2176 s = "EC3_LEAVE";
2177 break;
2178 case EC4_PATH_TEST:
2179 s = "EC4_PATH_TEST";
2180 break;
2181 case EC5_INSERT:
2182 s = "EC5_INSERT";
2183 break;
2184 case EC6_CHECK:
2185 s = "EC6_CHECK";
2186 break;
2187 case EC7_DEINSERT:
2188 s = "EC7_DEINSERT";
2189 break;
2190 default:
2191 s = "unknown";
2192 break;
2193 }
2194 PRINTK(KERN_INFO "ecm_state_change: %s\n", s);
2195#endif //DRIVERDEBUG
2196} // ecm_state_change
2197
2198
2199/************************
2200 *
2201 * rmt_state_change
2202 *
2203 * Sets RMT state in custom statistics.
2204 * Args
2205 * smc - A pointer to the SMT context struct.
2206 *
2207 * r_state - Possible values are:
2208 *
2209 * RM0_ISOLATED, RM1_NON_OP, RM2_RING_OP, RM3_DETECT,
2210 * RM4_NON_OP_DUP, RM5_RING_OP_DUP, RM6_DIRECTED, RM7_TRACE
2211 * Out
2212 * Nothing.
2213 *
2214 ************************/
2215void rmt_state_change(struct s_smc *smc, int r_state)
2216{
2217#ifdef DRIVERDEBUG
2218 char *s;
2219
2220 switch (r_state) {
2221 case RM0_ISOLATED:
2222 s = "RM0_ISOLATED";
2223 break;
2224 case RM1_NON_OP:
2225 s = "RM1_NON_OP - not operational";
2226 break;
2227 case RM2_RING_OP:
2228 s = "RM2_RING_OP - ring operational";
2229 break;
2230 case RM3_DETECT:
2231 s = "RM3_DETECT - detect dupl addresses";
2232 break;
2233 case RM4_NON_OP_DUP:
2234 s = "RM4_NON_OP_DUP - dupl. addr detected";
2235 break;
2236 case RM5_RING_OP_DUP:
2237 s = "RM5_RING_OP_DUP - ring oper. with dupl. addr";
2238 break;
2239 case RM6_DIRECTED:
2240 s = "RM6_DIRECTED - sending directed beacons";
2241 break;
2242 case RM7_TRACE:
2243 s = "RM7_TRACE - trace initiated";
2244 break;
2245 default:
2246 s = "unknown";
2247 break;
2248 }
2249 PRINTK(KERN_INFO "[rmt_state_change: %s]\n", s);
2250#endif // DRIVERDEBUG
2251} // rmt_state_change
2252
2253
2254/************************
2255 *
2256 * drv_reset_indication
2257 *
2258 * This function is called by the SMT when it has detected a severe
2259 * hardware problem. The driver should perform a reset on the adapter
2260 * as soon as possible, but not from within this function.
2261 * Args
2262 * smc - A pointer to the SMT context struct.
2263 * Out
2264 * Nothing.
2265 *
2266 ************************/
2267void drv_reset_indication(struct s_smc *smc)
2268{
2269 PRINTK(KERN_INFO "entering drv_reset_indication\n");
2270
2271 smc->os.ResetRequested = TRUE; // Set flag.
2272
2273} // drv_reset_indication
2274
2275static struct pci_driver skfddi_pci_driver = {
2276 .name = "skfddi",
2277 .id_table = skfddi_pci_tbl,
2278 .probe = skfp_init_one,
2279 .remove = __devexit_p(skfp_remove_one),
2280};
2281
2282static int __init skfd_init(void)
2283{
2284 return pci_module_init(&skfddi_pci_driver);
2285}
2286
2287static void __exit skfd_exit(void)
2288{
2289 pci_unregister_driver(&skfddi_pci_driver);
2290}
2291
2292module_init(skfd_init);
2293module_exit(skfd_exit);
diff --git a/drivers/net/skfp/smt.c b/drivers/net/skfp/smt.c
new file mode 100644
index 000000000000..71935eaf9d4e
--- /dev/null
+++ b/drivers/net/skfp/smt.c
@@ -0,0 +1,2097 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * See the file "skfddi.c" for further information.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * The information in this file is provided "AS IS" without warranty.
14 *
15 ******************************************************************************/
16
17#include "h/types.h"
18#include "h/fddi.h"
19#include "h/smc.h"
20#include "h/smt_p.h"
21
22#define KERNEL
23#include "h/smtstate.h"
24
25#ifndef lint
26static const char ID_sccs[] = "@(#)smt.c 2.43 98/11/23 (C) SK " ;
27#endif
28
29extern const u_char canonical[256] ;
30
31/*
32 * FC in SMbuf
33 */
34#define m_fc(mb) ((mb)->sm_data[0])
35
36#define SMT_TID_MAGIC 0x1f0a7b3c
37
38#ifdef DEBUG
39static const char *const smt_type_name[] = {
40 "SMT_00??", "SMT_INFO", "SMT_02??", "SMT_03??",
41 "SMT_04??", "SMT_05??", "SMT_06??", "SMT_07??",
42 "SMT_08??", "SMT_09??", "SMT_0A??", "SMT_0B??",
43 "SMT_0C??", "SMT_0D??", "SMT_0E??", "SMT_NSA"
44} ;
45
46static const char *const smt_class_name[] = {
47 "UNKNOWN","NIF","SIF_CONFIG","SIF_OPER","ECF","RAF","RDF",
48 "SRF","PMF_GET","PMF_SET","ESF"
49} ;
50#endif
51#define LAST_CLASS (SMT_PMF_SET)
52
53static const struct fddi_addr SMT_Unknown = {
54 { 0,0,0x1f,0,0,0 }
55} ;
56
57/*
58 * external variables
59 */
60extern const struct fddi_addr fddi_broadcast ;
61
62/*
63 * external functions
64 */
65int pcm_status_twisted(struct s_smc *smc);
66
67/*
68 * function prototypes
69 */
70#ifdef LITTLE_ENDIAN
71static int smt_swap_short(u_short s);
72#endif
73static int mac_index(struct s_smc *smc, int mac);
74static int phy_index(struct s_smc *smc, int phy);
75static int mac_con_resource_index(struct s_smc *smc, int mac);
76static int phy_con_resource_index(struct s_smc *smc, int phy);
77static void smt_send_rdf(struct s_smc *smc, SMbuf *rej, int fc, int reason,
78 int local);
79static void smt_send_nif(struct s_smc *smc, const struct fddi_addr *dest,
80 int fc, u_long tid, int type, int local);
81static void smt_send_ecf(struct s_smc *smc, struct fddi_addr *dest, int fc,
82 u_long tid, int type, int len);
83static void smt_echo_test(struct s_smc *smc, int dna);
84static void smt_send_sif_config(struct s_smc *smc, struct fddi_addr *dest,
85 u_long tid, int local);
86static void smt_send_sif_operation(struct s_smc *smc, struct fddi_addr *dest,
87 u_long tid, int local);
88#ifdef LITTLE_ENDIAN
89static void smt_string_swap(void);
90#endif
91static void smt_add_frame_len(SMbuf *mb, int len);
92static void smt_fill_una(struct s_smc *smc, struct smt_p_una *una);
93static void smt_fill_sde(struct s_smc *smc, struct smt_p_sde *sde);
94static void smt_fill_state(struct s_smc *smc, struct smt_p_state *state);
95static void smt_fill_timestamp(struct s_smc *smc, struct smt_p_timestamp *ts);
96static void smt_fill_policy(struct s_smc *smc, struct smt_p_policy *policy);
97static void smt_fill_latency(struct s_smc *smc, struct smt_p_latency *latency);
98static void smt_fill_neighbor(struct s_smc *smc, struct smt_p_neighbor *neighbor);
99static int smt_fill_path(struct s_smc *smc, struct smt_p_path *path);
100static void smt_fill_mac_status(struct s_smc *smc, struct smt_p_mac_status *st);
101static void smt_fill_lem(struct s_smc *smc, struct smt_p_lem *lem, int phy);
102static void smt_fill_version(struct s_smc *smc, struct smt_p_version *vers);
103static void smt_fill_fsc(struct s_smc *smc, struct smt_p_fsc *fsc);
104static void smt_fill_mac_counter(struct s_smc *smc, struct smt_p_mac_counter *mc);
105static void smt_fill_mac_fnc(struct s_smc *smc, struct smt_p_mac_fnc *fnc);
106static void smt_fill_manufacturer(struct s_smc *smc,
107 struct smp_p_manufacturer *man);
108static void smt_fill_user(struct s_smc *smc, struct smp_p_user *user);
109static void smt_fill_setcount(struct s_smc *smc, struct smt_p_setcount *setcount);
110static void smt_fill_echo(struct s_smc *smc, struct smt_p_echo *echo, u_long seed,
111 int len);
112
113void smt_clear_una_dna(struct s_smc *smc);
114static void smt_clear_old_una_dna(struct s_smc *smc);
115#ifdef CONCENTRATOR
116static int entity_to_index(void);
117#endif
118static void update_dac(struct s_smc *smc, int report);
119static int div_ratio(u_long upper, u_long lower);
120#ifdef USE_CAN_ADDR
121void hwm_conv_can(struct s_smc *smc, char *data, int len);
122#else
123#define hwm_conv_can(smc,data,len)
124#endif
125
126
127static inline int is_my_addr(const struct s_smc *smc,
128 const struct fddi_addr *addr)
129{
130 return(*(short *)(&addr->a[0]) ==
131 *(short *)(&smc->mib.m[MAC0].fddiMACSMTAddress.a[0])
132 && *(short *)(&addr->a[2]) ==
133 *(short *)(&smc->mib.m[MAC0].fddiMACSMTAddress.a[2])
134 && *(short *)(&addr->a[4]) ==
135 *(short *)(&smc->mib.m[MAC0].fddiMACSMTAddress.a[4])) ;
136}
137
138static inline int is_broadcast(const struct fddi_addr *addr)
139{
140 return(*(u_short *)(&addr->a[0]) == 0xffff &&
141 *(u_short *)(&addr->a[2]) == 0xffff &&
142 *(u_short *)(&addr->a[4]) == 0xffff ) ;
143}
144
145static inline int is_individual(const struct fddi_addr *addr)
146{
147 return(!(addr->a[0] & GROUP_ADDR)) ;
148}
149
150static inline int is_equal(const struct fddi_addr *addr1,
151 const struct fddi_addr *addr2)
152{
153 return(*(u_short *)(&addr1->a[0]) == *(u_short *)(&addr2->a[0]) &&
154 *(u_short *)(&addr1->a[2]) == *(u_short *)(&addr2->a[2]) &&
155 *(u_short *)(&addr1->a[4]) == *(u_short *)(&addr2->a[4]) ) ;
156}
157
158/*
159 * list of mandatory paras in frames
160 */
161static const u_short plist_nif[] = { SMT_P_UNA,SMT_P_SDE,SMT_P_STATE,0 } ;
162
163/*
164 * init SMT agent
165 */
166void smt_agent_init(struct s_smc *smc)
167{
168 int i ;
169
170 /*
171 * get MAC address
172 */
173 smc->mib.m[MAC0].fddiMACSMTAddress = smc->hw.fddi_home_addr ;
174
175 /*
176 * get OUI address from driver (bia == built-in-address)
177 */
178 smc->mib.fddiSMTStationId.sid_oem[0] = 0 ;
179 smc->mib.fddiSMTStationId.sid_oem[1] = 0 ;
180 driver_get_bia(smc,&smc->mib.fddiSMTStationId.sid_node) ;
181 for (i = 0 ; i < 6 ; i ++) {
182 smc->mib.fddiSMTStationId.sid_node.a[i] =
183 canonical[smc->mib.fddiSMTStationId.sid_node.a[i]] ;
184 }
185 smc->mib.fddiSMTManufacturerData[0] =
186 smc->mib.fddiSMTStationId.sid_node.a[0] ;
187 smc->mib.fddiSMTManufacturerData[1] =
188 smc->mib.fddiSMTStationId.sid_node.a[1] ;
189 smc->mib.fddiSMTManufacturerData[2] =
190 smc->mib.fddiSMTStationId.sid_node.a[2] ;
191 smc->sm.smt_tid = 0 ;
192 smc->mib.m[MAC0].fddiMACDupAddressTest = DA_NONE ;
193 smc->mib.m[MAC0].fddiMACUNDA_Flag = FALSE ;
194#ifndef SLIM_SMT
195 smt_clear_una_dna(smc) ;
196 smt_clear_old_una_dna(smc) ;
197#endif
198 for (i = 0 ; i < SMT_MAX_TEST ; i++)
199 smc->sm.pend[i] = 0 ;
200 smc->sm.please_reconnect = 0 ;
201 smc->sm.uniq_ticks = 0 ;
202}
203
204/*
205 * SMT task
206 * forever
207 * delay 30 seconds
208 * send NIF
209 * check tvu & tvd
210 * end
211 */
212void smt_agent_task(struct s_smc *smc)
213{
214 smt_timer_start(smc,&smc->sm.smt_timer, (u_long)1000000L,
215 EV_TOKEN(EVENT_SMT,SM_TIMER)) ;
216 DB_SMT("SMT agent task\n",0,0) ;
217}
218
219void smt_please_reconnect(struct s_smc *smc, int reconn_time)
220/* struct s_smc *smc; Pointer to SMT context */
221/* int reconn_time; Wait for reconnect time in seconds */
222{
223 /*
224 * The please reconnect variable is used as a timer.
225 * It is decremented each time smt_event is called.
226 * This happens every second or when smt_force_irq is called.
227 * Note: smt_force_irq () is called on some packet receives and
228 * when a multicast address is changed. Since nothing
229 * is received during the disconnect and the multicast
230 * address changes can be viewed as not very often and
231 * the timer runs out close to its given value
232 * (reconn_time).
233 */
234 smc->sm.please_reconnect = reconn_time ;
235}
236
237#ifndef SMT_REAL_TOKEN_CT
238void smt_emulate_token_ct(struct s_smc *smc, int mac_index)
239{
240 u_long count;
241 u_long time;
242
243
244 time = smt_get_time();
245 count = ((time - smc->sm.last_tok_time[mac_index]) *
246 100)/TICKS_PER_SECOND;
247
248 /*
249 * Only when ring is up we will have a token count. The
250 * flag is unfortunatly a single instance value. This
251 * doesn't matter now, because we currently have only
252 * one MAC instance.
253 */
254 if (smc->hw.mac_ring_is_up){
255 smc->mib.m[mac_index].fddiMACToken_Ct += count;
256 }
257
258 /* Remember current time */
259 smc->sm.last_tok_time[mac_index] = time;
260
261}
262#endif
263
264/*ARGSUSED1*/
265void smt_event(struct s_smc *smc, int event)
266{
267 u_long time ;
268#ifndef SMT_REAL_TOKEN_CT
269 int i ;
270#endif
271
272
273 if (smc->sm.please_reconnect) {
274 smc->sm.please_reconnect -- ;
275 if (smc->sm.please_reconnect == 0) {
276 /* Counted down */
277 queue_event(smc,EVENT_ECM,EC_CONNECT) ;
278 }
279 }
280
281 if (event == SM_FAST)
282 return ;
283
284 /*
285 * timer for periodic cleanup in driver
286 * reset and start the watchdog (FM2)
287 * ESS timer
288 * SBA timer
289 */
290 smt_timer_poll(smc) ;
291 smt_start_watchdog(smc) ;
292#ifndef SLIM_SMT
293#ifndef BOOT
294#ifdef ESS
295 ess_timer_poll(smc) ;
296#endif
297#endif
298#ifdef SBA
299 sba_timer_poll(smc) ;
300#endif
301
302 smt_srf_event(smc,0,0,0) ;
303
304#endif /* no SLIM_SMT */
305
306 time = smt_get_time() ;
307
308 if (time - smc->sm.smt_last_lem >= TICKS_PER_SECOND*8) {
309 /*
310 * Use 8 sec. for the time intervall, it simplifies the
311 * LER estimation.
312 */
313 struct fddi_mib_m *mib ;
314 u_long upper ;
315 u_long lower ;
316 int cond ;
317 int port;
318 struct s_phy *phy ;
319 /*
320 * calculate LEM bit error rate
321 */
322 sm_lem_evaluate(smc) ;
323 smc->sm.smt_last_lem = time ;
324
325 /*
326 * check conditions
327 */
328#ifndef SLIM_SMT
329 mac_update_counter(smc) ;
330 mib = smc->mib.m ;
331 upper =
332 (mib->fddiMACLost_Ct - mib->fddiMACOld_Lost_Ct) +
333 (mib->fddiMACError_Ct - mib->fddiMACOld_Error_Ct) ;
334 lower =
335 (mib->fddiMACFrame_Ct - mib->fddiMACOld_Frame_Ct) +
336 (mib->fddiMACLost_Ct - mib->fddiMACOld_Lost_Ct) ;
337 mib->fddiMACFrameErrorRatio = div_ratio(upper,lower) ;
338
339 cond =
340 ((!mib->fddiMACFrameErrorThreshold &&
341 mib->fddiMACError_Ct != mib->fddiMACOld_Error_Ct) ||
342 (mib->fddiMACFrameErrorRatio >
343 mib->fddiMACFrameErrorThreshold)) ;
344
345 if (cond != mib->fddiMACFrameErrorFlag)
346 smt_srf_event(smc,SMT_COND_MAC_FRAME_ERROR,
347 INDEX_MAC,cond) ;
348
349 upper =
350 (mib->fddiMACNotCopied_Ct - mib->fddiMACOld_NotCopied_Ct) ;
351 lower =
352 upper +
353 (mib->fddiMACCopied_Ct - mib->fddiMACOld_Copied_Ct) ;
354 mib->fddiMACNotCopiedRatio = div_ratio(upper,lower) ;
355
356 cond =
357 ((!mib->fddiMACNotCopiedThreshold &&
358 mib->fddiMACNotCopied_Ct !=
359 mib->fddiMACOld_NotCopied_Ct)||
360 (mib->fddiMACNotCopiedRatio >
361 mib->fddiMACNotCopiedThreshold)) ;
362
363 if (cond != mib->fddiMACNotCopiedFlag)
364 smt_srf_event(smc,SMT_COND_MAC_NOT_COPIED,
365 INDEX_MAC,cond) ;
366
367 /*
368 * set old values
369 */
370 mib->fddiMACOld_Frame_Ct = mib->fddiMACFrame_Ct ;
371 mib->fddiMACOld_Copied_Ct = mib->fddiMACCopied_Ct ;
372 mib->fddiMACOld_Error_Ct = mib->fddiMACError_Ct ;
373 mib->fddiMACOld_Lost_Ct = mib->fddiMACLost_Ct ;
374 mib->fddiMACOld_NotCopied_Ct = mib->fddiMACNotCopied_Ct ;
375
376 /*
377 * Check port EBError Condition
378 */
379 for (port = 0; port < NUMPHYS; port ++) {
380 phy = &smc->y[port] ;
381
382 if (!phy->mib->fddiPORTHardwarePresent) {
383 continue;
384 }
385
386 cond = (phy->mib->fddiPORTEBError_Ct -
387 phy->mib->fddiPORTOldEBError_Ct > 5) ;
388
389 /* If ratio is more than 5 in 8 seconds
390 * Set the condition.
391 */
392 smt_srf_event(smc,SMT_COND_PORT_EB_ERROR,
393 (int) (INDEX_PORT+ phy->np) ,cond) ;
394
395 /*
396 * set old values
397 */
398 phy->mib->fddiPORTOldEBError_Ct =
399 phy->mib->fddiPORTEBError_Ct ;
400 }
401
402#endif /* no SLIM_SMT */
403 }
404
405#ifndef SLIM_SMT
406
407 if (time - smc->sm.smt_last_notify >= (u_long)
408 (smc->mib.fddiSMTTT_Notify * TICKS_PER_SECOND) ) {
409 /*
410 * we can either send an announcement or a request
411 * a request will trigger a reply so that we can update
412 * our dna
413 * note: same tid must be used until reply is received
414 */
415 if (!smc->sm.pend[SMT_TID_NIF])
416 smc->sm.pend[SMT_TID_NIF] = smt_get_tid(smc) ;
417 smt_send_nif(smc,&fddi_broadcast, FC_SMT_NSA,
418 smc->sm.pend[SMT_TID_NIF], SMT_REQUEST,0) ;
419 smc->sm.smt_last_notify = time ;
420 }
421
422 /*
423 * check timer
424 */
425 if (smc->sm.smt_tvu &&
426 time - smc->sm.smt_tvu > 228*TICKS_PER_SECOND) {
427 DB_SMT("SMT : UNA expired\n",0,0) ;
428 smc->sm.smt_tvu = 0 ;
429
430 if (!is_equal(&smc->mib.m[MAC0].fddiMACUpstreamNbr,
431 &SMT_Unknown)){
432 /* Do not update unknown address */
433 smc->mib.m[MAC0].fddiMACOldUpstreamNbr=
434 smc->mib.m[MAC0].fddiMACUpstreamNbr ;
435 }
436 smc->mib.m[MAC0].fddiMACUpstreamNbr = SMT_Unknown ;
437 smc->mib.m[MAC0].fddiMACUNDA_Flag = FALSE ;
438 /*
439 * Make sure the fddiMACUNDA_Flag = FALSE is
440 * included in the SRF so we don't generate
441 * a separate SRF for the deassertion of this
442 * condition
443 */
444 update_dac(smc,0) ;
445 smt_srf_event(smc, SMT_EVENT_MAC_NEIGHBOR_CHANGE,
446 INDEX_MAC,0) ;
447 }
448 if (smc->sm.smt_tvd &&
449 time - smc->sm.smt_tvd > 228*TICKS_PER_SECOND) {
450 DB_SMT("SMT : DNA expired\n",0,0) ;
451 smc->sm.smt_tvd = 0 ;
452 if (!is_equal(&smc->mib.m[MAC0].fddiMACDownstreamNbr,
453 &SMT_Unknown)){
454 /* Do not update unknown address */
455 smc->mib.m[MAC0].fddiMACOldDownstreamNbr=
456 smc->mib.m[MAC0].fddiMACDownstreamNbr ;
457 }
458 smc->mib.m[MAC0].fddiMACDownstreamNbr = SMT_Unknown ;
459 smt_srf_event(smc, SMT_EVENT_MAC_NEIGHBOR_CHANGE,
460 INDEX_MAC,0) ;
461 }
462
463#endif /* no SLIM_SMT */
464
465#ifndef SMT_REAL_TOKEN_CT
466 /*
467 * Token counter emulation section. If hardware supports the token
468 * count, the token counter will be updated in mac_update_counter.
469 */
470 for (i = MAC0; i < NUMMACS; i++ ){
471 if (time - smc->sm.last_tok_time[i] > 2*TICKS_PER_SECOND ){
472 smt_emulate_token_ct( smc, i );
473 }
474 }
475#endif
476
477 smt_timer_start(smc,&smc->sm.smt_timer, (u_long)1000000L,
478 EV_TOKEN(EVENT_SMT,SM_TIMER)) ;
479}
480
481static int div_ratio(u_long upper, u_long lower)
482{
483 if ((upper<<16L) < upper)
484 upper = 0xffff0000L ;
485 else
486 upper <<= 16L ;
487 if (!lower)
488 return(0) ;
489 return((int)(upper/lower)) ;
490}
491
492#ifndef SLIM_SMT
493
494/*
495 * receive packet handler
496 */
497void smt_received_pack(struct s_smc *smc, SMbuf *mb, int fs)
498/* int fs; frame status */
499{
500 struct smt_header *sm ;
501 int local ;
502
503 int illegal = 0 ;
504
505 switch (m_fc(mb)) {
506 case FC_SMT_INFO :
507 case FC_SMT_LAN_LOC :
508 case FC_SMT_LOC :
509 case FC_SMT_NSA :
510 break ;
511 default :
512 smt_free_mbuf(smc,mb) ;
513 return ;
514 }
515
516 smc->mib.m[MAC0].fddiMACSMTCopied_Ct++ ;
517 sm = smtod(mb,struct smt_header *) ;
518 local = ((fs & L_INDICATOR) != 0) ;
519 hwm_conv_can(smc,(char *)sm,12) ;
520
521 /* check destination address */
522 if (is_individual(&sm->smt_dest) && !is_my_addr(smc,&sm->smt_dest)) {
523 smt_free_mbuf(smc,mb) ;
524 return ;
525 }
526#if 0 /* for DUP recognition, do NOT filter them */
527 /* ignore loop back packets */
528 if (is_my_addr(smc,&sm->smt_source) && !local) {
529 smt_free_mbuf(smc,mb) ;
530 return ;
531 }
532#endif
533
534 smt_swap_para(sm,(int) mb->sm_len,1) ;
535 DB_SMT("SMT : received packet [%s] at 0x%x\n",
536 smt_type_name[m_fc(mb) & 0xf],sm) ;
537 DB_SMT("SMT : version %d, class %s\n",sm->smt_version,
538 smt_class_name[(sm->smt_class>LAST_CLASS)?0 : sm->smt_class]) ;
539
540#ifdef SBA
541 /*
542 * check if NSA frame
543 */
544 if (m_fc(mb) == FC_SMT_NSA && sm->smt_class == SMT_NIF &&
545 (sm->smt_type == SMT_ANNOUNCE || sm->smt_type == SMT_REQUEST)) {
546 smc->sba.sm = sm ;
547 sba(smc,NIF) ;
548 }
549#endif
550
551 /*
552 * ignore any packet with NSA and A-indicator set
553 */
554 if ( (fs & A_INDICATOR) && m_fc(mb) == FC_SMT_NSA) {
555 DB_SMT("SMT : ignoring NSA with A-indicator set from %s\n",
556 addr_to_string(&sm->smt_source),0) ;
557 smt_free_mbuf(smc,mb) ;
558 return ;
559 }
560
561 /*
562 * ignore frames with illegal length
563 */
564 if (((sm->smt_class == SMT_ECF) && (sm->smt_len > SMT_MAX_ECHO_LEN)) ||
565 ((sm->smt_class != SMT_ECF) && (sm->smt_len > SMT_MAX_INFO_LEN))) {
566 smt_free_mbuf(smc,mb) ;
567 return ;
568 }
569
570 /*
571 * check SMT version
572 */
573 switch (sm->smt_class) {
574 case SMT_NIF :
575 case SMT_SIF_CONFIG :
576 case SMT_SIF_OPER :
577 case SMT_ECF :
578 if (sm->smt_version != SMT_VID)
579 illegal = 1;
580 break ;
581 default :
582 if (sm->smt_version != SMT_VID_2)
583 illegal = 1;
584 break ;
585 }
586 if (illegal) {
587 DB_SMT("SMT : version = %d, dest = %s\n",
588 sm->smt_version,addr_to_string(&sm->smt_source)) ;
589 smt_send_rdf(smc,mb,m_fc(mb),SMT_RDF_VERSION,local) ;
590 smt_free_mbuf(smc,mb) ;
591 return ;
592 }
593 if ((sm->smt_len > mb->sm_len - sizeof(struct smt_header)) ||
594 ((sm->smt_len & 3) && (sm->smt_class != SMT_ECF))) {
595 DB_SMT("SMT: info length error, len = %d\n",sm->smt_len,0) ;
596 smt_send_rdf(smc,mb,m_fc(mb),SMT_RDF_LENGTH,local) ;
597 smt_free_mbuf(smc,mb) ;
598 return ;
599 }
600 switch (sm->smt_class) {
601 case SMT_NIF :
602 if (smt_check_para(smc,sm,plist_nif)) {
603 DB_SMT("SMT: NIF with para problem, ignoring\n",0,0) ;
604 break ;
605 } ;
606 switch (sm->smt_type) {
607 case SMT_ANNOUNCE :
608 case SMT_REQUEST :
609 if (!(fs & C_INDICATOR) && m_fc(mb) == FC_SMT_NSA
610 && is_broadcast(&sm->smt_dest)) {
611 struct smt_p_state *st ;
612
613 /* set my UNA */
614 if (!is_equal(
615 &smc->mib.m[MAC0].fddiMACUpstreamNbr,
616 &sm->smt_source)) {
617 DB_SMT("SMT : updated my UNA = %s\n",
618 addr_to_string(&sm->smt_source),0) ;
619 if (!is_equal(&smc->mib.m[MAC0].
620 fddiMACUpstreamNbr,&SMT_Unknown)){
621 /* Do not update unknown address */
622 smc->mib.m[MAC0].fddiMACOldUpstreamNbr=
623 smc->mib.m[MAC0].fddiMACUpstreamNbr ;
624 }
625
626 smc->mib.m[MAC0].fddiMACUpstreamNbr =
627 sm->smt_source ;
628 smt_srf_event(smc,
629 SMT_EVENT_MAC_NEIGHBOR_CHANGE,
630 INDEX_MAC,0) ;
631 smt_echo_test(smc,0) ;
632 }
633 smc->sm.smt_tvu = smt_get_time() ;
634 st = (struct smt_p_state *)
635 sm_to_para(smc,sm,SMT_P_STATE) ;
636 if (st) {
637 smc->mib.m[MAC0].fddiMACUNDA_Flag =
638 (st->st_dupl_addr & SMT_ST_MY_DUPA) ?
639 TRUE : FALSE ;
640 update_dac(smc,1) ;
641 }
642 }
643 if ((sm->smt_type == SMT_REQUEST) &&
644 is_individual(&sm->smt_source) &&
645 ((!(fs & A_INDICATOR) && m_fc(mb) == FC_SMT_NSA) ||
646 (m_fc(mb) != FC_SMT_NSA))) {
647 DB_SMT("SMT : replying to NIF request %s\n",
648 addr_to_string(&sm->smt_source),0) ;
649 smt_send_nif(smc,&sm->smt_source,
650 FC_SMT_INFO,
651 sm->smt_tid,
652 SMT_REPLY,local) ;
653 }
654 break ;
655 case SMT_REPLY :
656 DB_SMT("SMT : received NIF response from %s\n",
657 addr_to_string(&sm->smt_source),0) ;
658 if (fs & A_INDICATOR) {
659 smc->sm.pend[SMT_TID_NIF] = 0 ;
660 DB_SMT("SMT : duplicate address\n",0,0) ;
661 smc->mib.m[MAC0].fddiMACDupAddressTest =
662 DA_FAILED ;
663 smc->r.dup_addr_test = DA_FAILED ;
664 queue_event(smc,EVENT_RMT,RM_DUP_ADDR) ;
665 smc->mib.m[MAC0].fddiMACDA_Flag = TRUE ;
666 update_dac(smc,1) ;
667 break ;
668 }
669 if (sm->smt_tid == smc->sm.pend[SMT_TID_NIF]) {
670 smc->sm.pend[SMT_TID_NIF] = 0 ;
671 /* set my DNA */
672 if (!is_equal(
673 &smc->mib.m[MAC0].fddiMACDownstreamNbr,
674 &sm->smt_source)) {
675 DB_SMT("SMT : updated my DNA\n",0,0) ;
676 if (!is_equal(&smc->mib.m[MAC0].
677 fddiMACDownstreamNbr, &SMT_Unknown)){
678 /* Do not update unknown address */
679 smc->mib.m[MAC0].fddiMACOldDownstreamNbr =
680 smc->mib.m[MAC0].fddiMACDownstreamNbr ;
681 }
682
683 smc->mib.m[MAC0].fddiMACDownstreamNbr =
684 sm->smt_source ;
685 smt_srf_event(smc,
686 SMT_EVENT_MAC_NEIGHBOR_CHANGE,
687 INDEX_MAC,0) ;
688 smt_echo_test(smc,1) ;
689 }
690 smc->mib.m[MAC0].fddiMACDA_Flag = FALSE ;
691 update_dac(smc,1) ;
692 smc->sm.smt_tvd = smt_get_time() ;
693 smc->mib.m[MAC0].fddiMACDupAddressTest =
694 DA_PASSED ;
695 if (smc->r.dup_addr_test != DA_PASSED) {
696 smc->r.dup_addr_test = DA_PASSED ;
697 queue_event(smc,EVENT_RMT,RM_DUP_ADDR) ;
698 }
699 }
700 else if (sm->smt_tid ==
701 smc->sm.pend[SMT_TID_NIF_TEST]) {
702 DB_SMT("SMT : NIF test TID ok\n",0,0) ;
703 }
704 else {
705 DB_SMT("SMT : expected TID %lx, got %lx\n",
706 smc->sm.pend[SMT_TID_NIF],sm->smt_tid) ;
707 }
708 break ;
709 default :
710 illegal = 2 ;
711 break ;
712 }
713 break ;
714 case SMT_SIF_CONFIG : /* station information */
715 if (sm->smt_type != SMT_REQUEST)
716 break ;
717 DB_SMT("SMT : replying to SIF Config request from %s\n",
718 addr_to_string(&sm->smt_source),0) ;
719 smt_send_sif_config(smc,&sm->smt_source,sm->smt_tid,local) ;
720 break ;
721 case SMT_SIF_OPER : /* station information */
722 if (sm->smt_type != SMT_REQUEST)
723 break ;
724 DB_SMT("SMT : replying to SIF Operation request from %s\n",
725 addr_to_string(&sm->smt_source),0) ;
726 smt_send_sif_operation(smc,&sm->smt_source,sm->smt_tid,local) ;
727 break ;
728 case SMT_ECF : /* echo frame */
729 switch (sm->smt_type) {
730 case SMT_REPLY :
731 smc->mib.priv.fddiPRIVECF_Reply_Rx++ ;
732 DB_SMT("SMT: received ECF reply from %s\n",
733 addr_to_string(&sm->smt_source),0) ;
734 if (sm_to_para(smc,sm,SMT_P_ECHODATA) == 0) {
735 DB_SMT("SMT: ECHODATA missing\n",0,0) ;
736 break ;
737 }
738 if (sm->smt_tid == smc->sm.pend[SMT_TID_ECF]) {
739 DB_SMT("SMT : ECF test TID ok\n",0,0) ;
740 }
741 else if (sm->smt_tid == smc->sm.pend[SMT_TID_ECF_UNA]) {
742 DB_SMT("SMT : ECF test UNA ok\n",0,0) ;
743 }
744 else if (sm->smt_tid == smc->sm.pend[SMT_TID_ECF_DNA]) {
745 DB_SMT("SMT : ECF test DNA ok\n",0,0) ;
746 }
747 else {
748 DB_SMT("SMT : expected TID %lx, got %lx\n",
749 smc->sm.pend[SMT_TID_ECF],
750 sm->smt_tid) ;
751 }
752 break ;
753 case SMT_REQUEST :
754 smc->mib.priv.fddiPRIVECF_Req_Rx++ ;
755 {
756 if (sm->smt_len && !sm_to_para(smc,sm,SMT_P_ECHODATA)) {
757 DB_SMT("SMT: ECF with para problem,sending RDF\n",0,0) ;
758 smt_send_rdf(smc,mb,m_fc(mb),SMT_RDF_LENGTH,
759 local) ;
760 break ;
761 }
762 DB_SMT("SMT - sending ECF reply to %s\n",
763 addr_to_string(&sm->smt_source),0) ;
764
765 /* set destination addr. & reply */
766 sm->smt_dest = sm->smt_source ;
767 sm->smt_type = SMT_REPLY ;
768 dump_smt(smc,sm,"ECF REPLY") ;
769 smc->mib.priv.fddiPRIVECF_Reply_Tx++ ;
770 smt_send_frame(smc,mb,FC_SMT_INFO,local) ;
771 return ; /* DON'T free mbuf */
772 }
773 default :
774 illegal = 1 ;
775 break ;
776 }
777 break ;
778#ifndef BOOT
779 case SMT_RAF : /* resource allocation */
780#ifdef ESS
781 DB_ESSN(2,"ESS: RAF frame received\n",0,0) ;
782 fs = ess_raf_received_pack(smc,mb,sm,fs) ;
783#endif
784
785#ifdef SBA
786 DB_SBAN(2,"SBA: RAF frame received\n",0,0) ;
787 sba_raf_received_pack(smc,sm,fs) ;
788#endif
789 break ;
790 case SMT_RDF : /* request denied */
791 smc->mib.priv.fddiPRIVRDF_Rx++ ;
792 break ;
793 case SMT_ESF : /* extended service - not supported */
794 if (sm->smt_type == SMT_REQUEST) {
795 DB_SMT("SMT - received ESF, sending RDF\n",0,0) ;
796 smt_send_rdf(smc,mb,m_fc(mb),SMT_RDF_CLASS,local) ;
797 }
798 break ;
799 case SMT_PMF_GET :
800 case SMT_PMF_SET :
801 if (sm->smt_type != SMT_REQUEST)
802 break ;
803 /* update statistics */
804 if (sm->smt_class == SMT_PMF_GET)
805 smc->mib.priv.fddiPRIVPMF_Get_Rx++ ;
806 else
807 smc->mib.priv.fddiPRIVPMF_Set_Rx++ ;
808 /*
809 * ignore PMF SET with I/G set
810 */
811 if ((sm->smt_class == SMT_PMF_SET) &&
812 !is_individual(&sm->smt_dest)) {
813 DB_SMT("SMT: ignoring PMF-SET with I/G set\n",0,0) ;
814 break ;
815 }
816 smt_pmf_received_pack(smc,mb, local) ;
817 break ;
818 case SMT_SRF :
819 dump_smt(smc,sm,"SRF received") ;
820 break ;
821 default :
822 if (sm->smt_type != SMT_REQUEST)
823 break ;
824 /*
825 * For frames with unknown class:
826 * we need to send a RDF frame according to 8.1.3.1.1,
827 * only if it is a REQUEST.
828 */
829 DB_SMT("SMT : class = %d, send RDF to %s\n",
830 sm->smt_class, addr_to_string(&sm->smt_source)) ;
831
832 smt_send_rdf(smc,mb,m_fc(mb),SMT_RDF_CLASS,local) ;
833 break ;
834#endif
835 }
836 if (illegal) {
837 DB_SMT("SMT: discarding invalid frame, reason = %d\n",
838 illegal,0) ;
839 }
840 smt_free_mbuf(smc,mb) ;
841}
842
843static void update_dac(struct s_smc *smc, int report)
844{
845 int cond ;
846
847 cond = ( smc->mib.m[MAC0].fddiMACUNDA_Flag |
848 smc->mib.m[MAC0].fddiMACDA_Flag) != 0 ;
849 if (report && (cond != smc->mib.m[MAC0].fddiMACDuplicateAddressCond))
850 smt_srf_event(smc, SMT_COND_MAC_DUP_ADDR,INDEX_MAC,cond) ;
851 else
852 smc->mib.m[MAC0].fddiMACDuplicateAddressCond = cond ;
853}
854
855/*
856 * send SMT frame
857 * set source address
858 * set station ID
859 * send frame
860 */
861void smt_send_frame(struct s_smc *smc, SMbuf *mb, int fc, int local)
862/* SMbuf *mb; buffer to send */
863/* int fc; FC value */
864{
865 struct smt_header *sm ;
866
867 if (!smc->r.sm_ma_avail && !local) {
868 smt_free_mbuf(smc,mb) ;
869 return ;
870 }
871 sm = smtod(mb,struct smt_header *) ;
872 sm->smt_source = smc->mib.m[MAC0].fddiMACSMTAddress ;
873 sm->smt_sid = smc->mib.fddiSMTStationId ;
874
875 smt_swap_para(sm,(int) mb->sm_len,0) ; /* swap para & header */
876 hwm_conv_can(smc,(char *)sm,12) ; /* convert SA and DA */
877 smc->mib.m[MAC0].fddiMACSMTTransmit_Ct++ ;
878 smt_send_mbuf(smc,mb,local ? FC_SMT_LOC : fc) ;
879}
880
881/*
882 * generate and send RDF
883 */
884static void smt_send_rdf(struct s_smc *smc, SMbuf *rej, int fc, int reason,
885 int local)
886/* SMbuf *rej; mbuf of offending frame */
887/* int fc; FC of denied frame */
888/* int reason; reason code */
889{
890 SMbuf *mb ;
891 struct smt_header *sm ; /* header of offending frame */
892 struct smt_rdf *rdf ;
893 int len ;
894 int frame_len ;
895
896 sm = smtod(rej,struct smt_header *) ;
897 if (sm->smt_type != SMT_REQUEST)
898 return ;
899
900 DB_SMT("SMT: sending RDF to %s,reason = 0x%x\n",
901 addr_to_string(&sm->smt_source),reason) ;
902
903
904 /*
905 * note: get framelength from MAC length, NOT from SMT header
906 * smt header length is included in sm_len
907 */
908 frame_len = rej->sm_len ;
909
910 if (!(mb=smt_build_frame(smc,SMT_RDF,SMT_REPLY,sizeof(struct smt_rdf))))
911 return ;
912 rdf = smtod(mb,struct smt_rdf *) ;
913 rdf->smt.smt_tid = sm->smt_tid ; /* use TID from sm */
914 rdf->smt.smt_dest = sm->smt_source ; /* set dest = source */
915
916 /* set P12 */
917 rdf->reason.para.p_type = SMT_P_REASON ;
918 rdf->reason.para.p_len = sizeof(struct smt_p_reason) - PARA_LEN ;
919 rdf->reason.rdf_reason = reason ;
920
921 /* set P14 */
922 rdf->version.para.p_type = SMT_P_VERSION ;
923 rdf->version.para.p_len = sizeof(struct smt_p_version) - PARA_LEN ;
924 rdf->version.v_pad = 0 ;
925 rdf->version.v_n = 1 ;
926 rdf->version.v_index = 1 ;
927 rdf->version.v_version[0] = SMT_VID_2 ;
928 rdf->version.v_pad2 = 0 ;
929
930 /* set P13 */
931 if ((unsigned) frame_len <= SMT_MAX_INFO_LEN - sizeof(*rdf) +
932 2*sizeof(struct smt_header))
933 len = frame_len ;
934 else
935 len = SMT_MAX_INFO_LEN - sizeof(*rdf) +
936 2*sizeof(struct smt_header) ;
937 /* make length multiple of 4 */
938 len &= ~3 ;
939 rdf->refused.para.p_type = SMT_P_REFUSED ;
940 /* length of para is smt_frame + ref_fc */
941 rdf->refused.para.p_len = len + 4 ;
942 rdf->refused.ref_fc = fc ;
943
944 /* swap it back */
945 smt_swap_para(sm,frame_len,0) ;
946
947 memcpy((char *) &rdf->refused.ref_header,(char *) sm,len) ;
948
949 len -= sizeof(struct smt_header) ;
950 mb->sm_len += len ;
951 rdf->smt.smt_len += len ;
952
953 dump_smt(smc,(struct smt_header *)rdf,"RDF") ;
954 smc->mib.priv.fddiPRIVRDF_Tx++ ;
955 smt_send_frame(smc,mb,FC_SMT_INFO,local) ;
956}
957
958/*
959 * generate and send NIF
960 */
961static void smt_send_nif(struct s_smc *smc, const struct fddi_addr *dest,
962 int fc, u_long tid, int type, int local)
963/* struct fddi_addr *dest; dest address */
964/* int fc; frame control */
965/* u_long tid; transaction id */
966/* int type; frame type */
967{
968 struct smt_nif *nif ;
969 SMbuf *mb ;
970
971 if (!(mb = smt_build_frame(smc,SMT_NIF,type,sizeof(struct smt_nif))))
972 return ;
973 nif = smtod(mb, struct smt_nif *) ;
974 smt_fill_una(smc,&nif->una) ; /* set UNA */
975 smt_fill_sde(smc,&nif->sde) ; /* set station descriptor */
976 smt_fill_state(smc,&nif->state) ; /* set state information */
977#ifdef SMT6_10
978 smt_fill_fsc(smc,&nif->fsc) ; /* set frame status cap. */
979#endif
980 nif->smt.smt_dest = *dest ; /* destination address */
981 nif->smt.smt_tid = tid ; /* transaction ID */
982 dump_smt(smc,(struct smt_header *)nif,"NIF") ;
983 smt_send_frame(smc,mb,fc,local) ;
984}
985
986#ifdef DEBUG
987/*
988 * send NIF request (test purpose)
989 */
990static void smt_send_nif_request(struct s_smc *smc, struct fddi_addr *dest)
991{
992 smc->sm.pend[SMT_TID_NIF_TEST] = smt_get_tid(smc) ;
993 smt_send_nif(smc,dest, FC_SMT_INFO, smc->sm.pend[SMT_TID_NIF_TEST],
994 SMT_REQUEST,0) ;
995}
996
997/*
998 * send ECF request (test purpose)
999 */
1000static void smt_send_ecf_request(struct s_smc *smc, struct fddi_addr *dest,
1001 int len)
1002{
1003 smc->sm.pend[SMT_TID_ECF] = smt_get_tid(smc) ;
1004 smt_send_ecf(smc,dest, FC_SMT_INFO, smc->sm.pend[SMT_TID_ECF],
1005 SMT_REQUEST,len) ;
1006}
1007#endif
1008
1009/*
1010 * echo test
1011 */
1012static void smt_echo_test(struct s_smc *smc, int dna)
1013{
1014 u_long tid ;
1015
1016 smc->sm.pend[dna ? SMT_TID_ECF_DNA : SMT_TID_ECF_UNA] =
1017 tid = smt_get_tid(smc) ;
1018 smt_send_ecf(smc, dna ?
1019 &smc->mib.m[MAC0].fddiMACDownstreamNbr :
1020 &smc->mib.m[MAC0].fddiMACUpstreamNbr,
1021 FC_SMT_INFO,tid, SMT_REQUEST, (SMT_TEST_ECHO_LEN & ~3)-8) ;
1022}
1023
1024/*
1025 * generate and send ECF
1026 */
1027static void smt_send_ecf(struct s_smc *smc, struct fddi_addr *dest, int fc,
1028 u_long tid, int type, int len)
1029/* struct fddi_addr *dest; dest address */
1030/* int fc; frame control */
1031/* u_long tid; transaction id */
1032/* int type; frame type */
1033/* int len; frame length */
1034{
1035 struct smt_ecf *ecf ;
1036 SMbuf *mb ;
1037
1038 if (!(mb = smt_build_frame(smc,SMT_ECF,type,SMT_ECF_LEN + len)))
1039 return ;
1040 ecf = smtod(mb, struct smt_ecf *) ;
1041
1042 smt_fill_echo(smc,&ecf->ec_echo,tid,len) ; /* set ECHO */
1043 ecf->smt.smt_dest = *dest ; /* destination address */
1044 ecf->smt.smt_tid = tid ; /* transaction ID */
1045 smc->mib.priv.fddiPRIVECF_Req_Tx++ ;
1046 smt_send_frame(smc,mb,fc,0) ;
1047}
1048
1049/*
1050 * generate and send SIF config response
1051 */
1052
1053static void smt_send_sif_config(struct s_smc *smc, struct fddi_addr *dest,
1054 u_long tid, int local)
1055/* struct fddi_addr *dest; dest address */
1056/* u_long tid; transaction id */
1057{
1058 struct smt_sif_config *sif ;
1059 SMbuf *mb ;
1060 int len ;
1061 if (!(mb = smt_build_frame(smc,SMT_SIF_CONFIG,SMT_REPLY,
1062 SIZEOF_SMT_SIF_CONFIG)))
1063 return ;
1064
1065 sif = smtod(mb, struct smt_sif_config *) ;
1066 smt_fill_timestamp(smc,&sif->ts) ; /* set time stamp */
1067 smt_fill_sde(smc,&sif->sde) ; /* set station descriptor */
1068 smt_fill_version(smc,&sif->version) ; /* set version information */
1069 smt_fill_state(smc,&sif->state) ; /* set state information */
1070 smt_fill_policy(smc,&sif->policy) ; /* set station policy */
1071 smt_fill_latency(smc,&sif->latency); /* set station latency */
1072 smt_fill_neighbor(smc,&sif->neighbor); /* set station neighbor */
1073 smt_fill_setcount(smc,&sif->setcount) ; /* set count */
1074 len = smt_fill_path(smc,&sif->path); /* set station path descriptor*/
1075 sif->smt.smt_dest = *dest ; /* destination address */
1076 sif->smt.smt_tid = tid ; /* transaction ID */
1077 smt_add_frame_len(mb,len) ; /* adjust length fields */
1078 dump_smt(smc,(struct smt_header *)sif,"SIF Configuration Reply") ;
1079 smt_send_frame(smc,mb,FC_SMT_INFO,local) ;
1080}
1081
1082/*
1083 * generate and send SIF operation response
1084 */
1085
1086static void smt_send_sif_operation(struct s_smc *smc, struct fddi_addr *dest,
1087 u_long tid, int local)
1088/* struct fddi_addr *dest; dest address */
1089/* u_long tid; transaction id */
1090{
1091 struct smt_sif_operation *sif ;
1092 SMbuf *mb ;
1093 int ports ;
1094 int i ;
1095
1096 ports = NUMPHYS ;
1097#ifndef CONCENTRATOR
1098 if (smc->s.sas == SMT_SAS)
1099 ports = 1 ;
1100#endif
1101
1102 if (!(mb = smt_build_frame(smc,SMT_SIF_OPER,SMT_REPLY,
1103 SIZEOF_SMT_SIF_OPERATION+ports*sizeof(struct smt_p_lem))))
1104 return ;
1105 sif = smtod(mb, struct smt_sif_operation *) ;
1106 smt_fill_timestamp(smc,&sif->ts) ; /* set time stamp */
1107 smt_fill_mac_status(smc,&sif->status) ; /* set mac status */
1108 smt_fill_mac_counter(smc,&sif->mc) ; /* set mac counter field */
1109 smt_fill_mac_fnc(smc,&sif->fnc) ; /* set frame not copied counter */
1110 smt_fill_manufacturer(smc,&sif->man) ; /* set manufacturer field */
1111 smt_fill_user(smc,&sif->user) ; /* set user field */
1112 smt_fill_setcount(smc,&sif->setcount) ; /* set count */
1113 /*
1114 * set link error mon information
1115 */
1116 if (ports == 1) {
1117 smt_fill_lem(smc,sif->lem,PS) ;
1118 }
1119 else {
1120 for (i = 0 ; i < ports ; i++) {
1121 smt_fill_lem(smc,&sif->lem[i],i) ;
1122 }
1123 }
1124
1125 sif->smt.smt_dest = *dest ; /* destination address */
1126 sif->smt.smt_tid = tid ; /* transaction ID */
1127 dump_smt(smc,(struct smt_header *)sif,"SIF Operation Reply") ;
1128 smt_send_frame(smc,mb,FC_SMT_INFO,local) ;
1129}
1130
1131/*
1132 * get and initialize SMT frame
1133 */
1134SMbuf *smt_build_frame(struct s_smc *smc, int class, int type,
1135 int length)
1136{
1137 SMbuf *mb ;
1138 struct smt_header *smt ;
1139
1140#if 0
1141 if (!smc->r.sm_ma_avail) {
1142 return(0) ;
1143 }
1144#endif
1145 if (!(mb = smt_get_mbuf(smc)))
1146 return(mb) ;
1147
1148 mb->sm_len = length ;
1149 smt = smtod(mb, struct smt_header *) ;
1150 smt->smt_dest = fddi_broadcast ; /* set dest = broadcast */
1151 smt->smt_class = class ;
1152 smt->smt_type = type ;
1153 switch (class) {
1154 case SMT_NIF :
1155 case SMT_SIF_CONFIG :
1156 case SMT_SIF_OPER :
1157 case SMT_ECF :
1158 smt->smt_version = SMT_VID ;
1159 break ;
1160 default :
1161 smt->smt_version = SMT_VID_2 ;
1162 break ;
1163 }
1164 smt->smt_tid = smt_get_tid(smc) ; /* set transaction ID */
1165 smt->smt_pad = 0 ;
1166 smt->smt_len = length - sizeof(struct smt_header) ;
1167 return(mb) ;
1168}
1169
1170static void smt_add_frame_len(SMbuf *mb, int len)
1171{
1172 struct smt_header *smt ;
1173
1174 smt = smtod(mb, struct smt_header *) ;
1175 smt->smt_len += len ;
1176 mb->sm_len += len ;
1177}
1178
1179
1180
1181/*
1182 * fill values in UNA parameter
1183 */
1184static void smt_fill_una(struct s_smc *smc, struct smt_p_una *una)
1185{
1186 SMTSETPARA(una,SMT_P_UNA) ;
1187 una->una_pad = 0 ;
1188 una->una_node = smc->mib.m[MAC0].fddiMACUpstreamNbr ;
1189}
1190
1191/*
1192 * fill values in SDE parameter
1193 */
1194static void smt_fill_sde(struct s_smc *smc, struct smt_p_sde *sde)
1195{
1196 SMTSETPARA(sde,SMT_P_SDE) ;
1197 sde->sde_non_master = smc->mib.fddiSMTNonMaster_Ct ;
1198 sde->sde_master = smc->mib.fddiSMTMaster_Ct ;
1199 sde->sde_mac_count = NUMMACS ; /* only 1 MAC */
1200#ifdef CONCENTRATOR
1201 sde->sde_type = SMT_SDE_CONCENTRATOR ;
1202#else
1203 sde->sde_type = SMT_SDE_STATION ;
1204#endif
1205}
1206
1207/*
1208 * fill in values in station state parameter
1209 */
1210static void smt_fill_state(struct s_smc *smc, struct smt_p_state *state)
1211{
1212 int top ;
1213 int twist ;
1214
1215 SMTSETPARA(state,SMT_P_STATE) ;
1216 state->st_pad = 0 ;
1217
1218 /* determine topology */
1219 top = 0 ;
1220 if (smc->mib.fddiSMTPeerWrapFlag) {
1221 top |= SMT_ST_WRAPPED ; /* state wrapped */
1222 }
1223#ifdef CONCENTRATOR
1224 if (cfm_status_unattached(smc)) {
1225 top |= SMT_ST_UNATTACHED ; /* unattached concentrator */
1226 }
1227#endif
1228 if ((twist = pcm_status_twisted(smc)) & 1) {
1229 top |= SMT_ST_TWISTED_A ; /* twisted cable */
1230 }
1231 if (twist & 2) {
1232 top |= SMT_ST_TWISTED_B ; /* twisted cable */
1233 }
1234#ifdef OPT_SRF
1235 top |= SMT_ST_SRF ;
1236#endif
1237 if (pcm_rooted_station(smc))
1238 top |= SMT_ST_ROOTED_S ;
1239 if (smc->mib.a[0].fddiPATHSbaPayload != 0)
1240 top |= SMT_ST_SYNC_SERVICE ;
1241 state->st_topology = top ;
1242 state->st_dupl_addr =
1243 ((smc->mib.m[MAC0].fddiMACDA_Flag ? SMT_ST_MY_DUPA : 0 ) |
1244 (smc->mib.m[MAC0].fddiMACUNDA_Flag ? SMT_ST_UNA_DUPA : 0)) ;
1245}
1246
1247/*
1248 * fill values in timestamp parameter
1249 */
1250static void smt_fill_timestamp(struct s_smc *smc, struct smt_p_timestamp *ts)
1251{
1252
1253 SMTSETPARA(ts,SMT_P_TIMESTAMP) ;
1254 smt_set_timestamp(smc,ts->ts_time) ;
1255}
1256
1257void smt_set_timestamp(struct s_smc *smc, u_char *p)
1258{
1259 u_long time ;
1260 u_long utime ;
1261
1262 /*
1263 * timestamp is 64 bits long ; resolution is 80 nS
1264 * our clock resolution is 10mS
1265 * 10mS/80ns = 125000 ~ 2^17 = 131072
1266 */
1267 utime = smt_get_time() ;
1268 time = utime * 100 ;
1269 time /= TICKS_PER_SECOND ;
1270 p[0] = 0 ;
1271 p[1] = (u_char)((time>>(8+8+8+8-1)) & 1) ;
1272 p[2] = (u_char)(time>>(8+8+8-1)) ;
1273 p[3] = (u_char)(time>>(8+8-1)) ;
1274 p[4] = (u_char)(time>>(8-1)) ;
1275 p[5] = (u_char)(time<<1) ;
1276 p[6] = (u_char)(smc->sm.uniq_ticks>>8) ;
1277 p[7] = (u_char)smc->sm.uniq_ticks ;
1278 /*
1279 * make sure we don't wrap: restart whenever the upper digits change
1280 */
1281 if (utime != smc->sm.uniq_time) {
1282 smc->sm.uniq_ticks = 0 ;
1283 }
1284 smc->sm.uniq_ticks++ ;
1285 smc->sm.uniq_time = utime ;
1286}
1287
1288/*
1289 * fill values in station policy parameter
1290 */
1291static void smt_fill_policy(struct s_smc *smc, struct smt_p_policy *policy)
1292{
1293 int i ;
1294 u_char *map ;
1295 u_short in ;
1296 u_short out ;
1297
1298 /*
1299 * MIB para 101b (fddiSMTConnectionPolicy) coding
1300 * is different from 0005 coding
1301 */
1302 static u_char ansi_weirdness[16] = {
1303 0,7,5,3,8,1,6,4,9,10,2,11,12,13,14,15
1304 } ;
1305 SMTSETPARA(policy,SMT_P_POLICY) ;
1306
1307 out = 0 ;
1308 in = smc->mib.fddiSMTConnectionPolicy ;
1309 for (i = 0, map = ansi_weirdness ; i < 16 ; i++) {
1310 if (in & 1)
1311 out |= (1<<*map) ;
1312 in >>= 1 ;
1313 map++ ;
1314 }
1315 policy->pl_config = smc->mib.fddiSMTConfigPolicy ;
1316 policy->pl_connect = out ;
1317}
1318
1319/*
1320 * fill values in latency equivalent parameter
1321 */
1322static void smt_fill_latency(struct s_smc *smc, struct smt_p_latency *latency)
1323{
1324 SMTSETPARA(latency,SMT_P_LATENCY) ;
1325
1326 latency->lt_phyout_idx1 = phy_index(smc,0) ;
1327 latency->lt_latency1 = 10 ; /* in octets (byte clock) */
1328 /*
1329 * note: latency has two phy entries by definition
1330 * for a SAS, the 2nd one is null
1331 */
1332 if (smc->s.sas == SMT_DAS) {
1333 latency->lt_phyout_idx2 = phy_index(smc,1) ;
1334 latency->lt_latency2 = 10 ; /* in octets (byte clock) */
1335 }
1336 else {
1337 latency->lt_phyout_idx2 = 0 ;
1338 latency->lt_latency2 = 0 ;
1339 }
1340}
1341
1342/*
1343 * fill values in MAC neighbors parameter
1344 */
1345static void smt_fill_neighbor(struct s_smc *smc, struct smt_p_neighbor *neighbor)
1346{
1347 SMTSETPARA(neighbor,SMT_P_NEIGHBORS) ;
1348
1349 neighbor->nb_mib_index = INDEX_MAC ;
1350 neighbor->nb_mac_index = mac_index(smc,1) ;
1351 neighbor->nb_una = smc->mib.m[MAC0].fddiMACUpstreamNbr ;
1352 neighbor->nb_dna = smc->mib.m[MAC0].fddiMACDownstreamNbr ;
1353}
1354
1355/*
1356 * fill values in path descriptor
1357 */
1358#ifdef CONCENTRATOR
1359#define ALLPHYS NUMPHYS
1360#else
1361#define ALLPHYS ((smc->s.sas == SMT_SAS) ? 1 : 2)
1362#endif
1363
1364static int smt_fill_path(struct s_smc *smc, struct smt_p_path *path)
1365{
1366 SK_LOC_DECL(int,type) ;
1367 SK_LOC_DECL(int,state) ;
1368 SK_LOC_DECL(int,remote) ;
1369 SK_LOC_DECL(int,mac) ;
1370 int len ;
1371 int p ;
1372 int physp ;
1373 struct smt_phy_rec *phy ;
1374 struct smt_mac_rec *pd_mac ;
1375
1376 len = PARA_LEN +
1377 sizeof(struct smt_mac_rec) * NUMMACS +
1378 sizeof(struct smt_phy_rec) * ALLPHYS ;
1379 path->para.p_type = SMT_P_PATH ;
1380 path->para.p_len = len - PARA_LEN ;
1381
1382 /* PHYs */
1383 for (p = 0,phy = path->pd_phy ; p < ALLPHYS ; p++, phy++) {
1384 physp = p ;
1385#ifndef CONCENTRATOR
1386 if (smc->s.sas == SMT_SAS)
1387 physp = PS ;
1388#endif
1389 pcm_status_state(smc,physp,&type,&state,&remote,&mac) ;
1390#ifdef LITTLE_ENDIAN
1391 phy->phy_mib_index = smt_swap_short((u_short)p+INDEX_PORT) ;
1392#else
1393 phy->phy_mib_index = p+INDEX_PORT ;
1394#endif
1395 phy->phy_type = type ;
1396 phy->phy_connect_state = state ;
1397 phy->phy_remote_type = remote ;
1398 phy->phy_remote_mac = mac ;
1399 phy->phy_resource_idx = phy_con_resource_index(smc,p) ;
1400 }
1401
1402 /* MAC */
1403 pd_mac = (struct smt_mac_rec *) phy ;
1404 pd_mac->mac_addr = smc->mib.m[MAC0].fddiMACSMTAddress ;
1405 pd_mac->mac_resource_idx = mac_con_resource_index(smc,1) ;
1406 return(len) ;
1407}
1408
1409/*
1410 * fill values in mac status
1411 */
1412static void smt_fill_mac_status(struct s_smc *smc, struct smt_p_mac_status *st)
1413{
1414 SMTSETPARA(st,SMT_P_MAC_STATUS) ;
1415
1416 st->st_mib_index = INDEX_MAC ;
1417 st->st_mac_index = mac_index(smc,1) ;
1418
1419 mac_update_counter(smc) ;
1420 /*
1421 * timer values are represented in SMT as 2's complement numbers
1422 * units : internal : 2's complement BCLK
1423 */
1424 st->st_t_req = smc->mib.m[MAC0].fddiMACT_Req ;
1425 st->st_t_neg = smc->mib.m[MAC0].fddiMACT_Neg ;
1426 st->st_t_max = smc->mib.m[MAC0].fddiMACT_Max ;
1427 st->st_tvx_value = smc->mib.m[MAC0].fddiMACTvxValue ;
1428 st->st_t_min = smc->mib.m[MAC0].fddiMACT_Min ;
1429
1430 st->st_sba = smc->mib.a[PATH0].fddiPATHSbaPayload ;
1431 st->st_frame_ct = smc->mib.m[MAC0].fddiMACFrame_Ct ;
1432 st->st_error_ct = smc->mib.m[MAC0].fddiMACError_Ct ;
1433 st->st_lost_ct = smc->mib.m[MAC0].fddiMACLost_Ct ;
1434}
1435
1436/*
1437 * fill values in LEM status
1438 */
1439static void smt_fill_lem(struct s_smc *smc, struct smt_p_lem *lem, int phy)
1440{
1441 struct fddi_mib_p *mib ;
1442
1443 mib = smc->y[phy].mib ;
1444
1445 SMTSETPARA(lem,SMT_P_LEM) ;
1446 lem->lem_mib_index = phy+INDEX_PORT ;
1447 lem->lem_phy_index = phy_index(smc,phy) ;
1448 lem->lem_pad2 = 0 ;
1449 lem->lem_cutoff = mib->fddiPORTLer_Cutoff ;
1450 lem->lem_alarm = mib->fddiPORTLer_Alarm ;
1451 /* long term bit error rate */
1452 lem->lem_estimate = mib->fddiPORTLer_Estimate ;
1453 /* # of rejected connections */
1454 lem->lem_reject_ct = mib->fddiPORTLem_Reject_Ct ;
1455 lem->lem_ct = mib->fddiPORTLem_Ct ; /* total number of errors */
1456}
1457
1458/*
1459 * fill version parameter
1460 */
1461static void smt_fill_version(struct s_smc *smc, struct smt_p_version *vers)
1462{
1463 SK_UNUSED(smc) ;
1464 SMTSETPARA(vers,SMT_P_VERSION) ;
1465 vers->v_pad = 0 ;
1466 vers->v_n = 1 ; /* one version is enough .. */
1467 vers->v_index = 1 ;
1468 vers->v_version[0] = SMT_VID_2 ;
1469 vers->v_pad2 = 0 ;
1470}
1471
1472#ifdef SMT6_10
1473/*
1474 * fill frame status capabilities
1475 */
1476/*
1477 * note: this para 200B is NOT in swap table, because it's also set in
1478 * PMF add_para
1479 */
1480static void smt_fill_fsc(struct s_smc *smc, struct smt_p_fsc *fsc)
1481{
1482 SK_UNUSED(smc) ;
1483 SMTSETPARA(fsc,SMT_P_FSC) ;
1484 fsc->fsc_pad0 = 0 ;
1485 fsc->fsc_mac_index = INDEX_MAC ; /* this is MIB ; MIB is NOT
1486 * mac_index ()i !
1487 */
1488 fsc->fsc_pad1 = 0 ;
1489 fsc->fsc_value = FSC_TYPE0 ; /* "normal" node */
1490#ifdef LITTLE_ENDIAN
1491 fsc->fsc_mac_index = smt_swap_short(INDEX_MAC) ;
1492 fsc->fsc_value = smt_swap_short(FSC_TYPE0) ;
1493#endif
1494}
1495#endif
1496
1497/*
1498 * fill mac counter field
1499 */
1500static void smt_fill_mac_counter(struct s_smc *smc, struct smt_p_mac_counter *mc)
1501{
1502 SMTSETPARA(mc,SMT_P_MAC_COUNTER) ;
1503 mc->mc_mib_index = INDEX_MAC ;
1504 mc->mc_index = mac_index(smc,1) ;
1505 mc->mc_receive_ct = smc->mib.m[MAC0].fddiMACCopied_Ct ;
1506 mc->mc_transmit_ct = smc->mib.m[MAC0].fddiMACTransmit_Ct ;
1507}
1508
1509/*
1510 * fill mac frame not copied counter
1511 */
1512static void smt_fill_mac_fnc(struct s_smc *smc, struct smt_p_mac_fnc *fnc)
1513{
1514 SMTSETPARA(fnc,SMT_P_MAC_FNC) ;
1515 fnc->nc_mib_index = INDEX_MAC ;
1516 fnc->nc_index = mac_index(smc,1) ;
1517 fnc->nc_counter = smc->mib.m[MAC0].fddiMACNotCopied_Ct ;
1518}
1519
1520
1521/*
1522 * fill manufacturer field
1523 */
1524static void smt_fill_manufacturer(struct s_smc *smc,
1525 struct smp_p_manufacturer *man)
1526{
1527 SMTSETPARA(man,SMT_P_MANUFACTURER) ;
1528 memcpy((char *) man->mf_data,
1529 (char *) smc->mib.fddiSMTManufacturerData,
1530 sizeof(man->mf_data)) ;
1531}
1532
1533/*
1534 * fill user field
1535 */
1536static void smt_fill_user(struct s_smc *smc, struct smp_p_user *user)
1537{
1538 SMTSETPARA(user,SMT_P_USER) ;
1539 memcpy((char *) user->us_data,
1540 (char *) smc->mib.fddiSMTUserData,
1541 sizeof(user->us_data)) ;
1542}
1543
1544/*
1545 * fill set count
1546 */
1547static void smt_fill_setcount(struct s_smc *smc, struct smt_p_setcount *setcount)
1548{
1549 SK_UNUSED(smc) ;
1550 SMTSETPARA(setcount,SMT_P_SETCOUNT) ;
1551 setcount->count = smc->mib.fddiSMTSetCount.count ;
1552 memcpy((char *)setcount->timestamp,
1553 (char *)smc->mib.fddiSMTSetCount.timestamp,8) ;
1554}
1555
1556/*
1557 * fill echo data
1558 */
1559static void smt_fill_echo(struct s_smc *smc, struct smt_p_echo *echo, u_long seed,
1560 int len)
1561{
1562 u_char *p ;
1563
1564 SK_UNUSED(smc) ;
1565 SMTSETPARA(echo,SMT_P_ECHODATA) ;
1566 echo->para.p_len = len ;
1567 for (p = echo->ec_data ; len ; len--) {
1568 *p++ = (u_char) seed ;
1569 seed += 13 ;
1570 }
1571}
1572
1573/*
1574 * clear DNA and UNA
1575 * called from CFM if configuration changes
1576 */
1577void smt_clear_una_dna(struct s_smc *smc)
1578{
1579 smc->mib.m[MAC0].fddiMACUpstreamNbr = SMT_Unknown ;
1580 smc->mib.m[MAC0].fddiMACDownstreamNbr = SMT_Unknown ;
1581}
1582
1583static void smt_clear_old_una_dna(struct s_smc *smc)
1584{
1585 smc->mib.m[MAC0].fddiMACOldUpstreamNbr = SMT_Unknown ;
1586 smc->mib.m[MAC0].fddiMACOldDownstreamNbr = SMT_Unknown ;
1587}
1588
1589u_long smt_get_tid(struct s_smc *smc)
1590{
1591 u_long tid ;
1592 while ((tid = ++(smc->sm.smt_tid) ^ SMT_TID_MAGIC) == 0)
1593 ;
1594 return(tid & 0x3fffffffL) ;
1595}
1596
1597
1598/*
1599 * table of parameter lengths
1600 */
1601static const struct smt_pdef {
1602 int ptype ;
1603 int plen ;
1604 const char *pswap ;
1605} smt_pdef[] = {
1606 { SMT_P_UNA, sizeof(struct smt_p_una) ,
1607 SWAP_SMT_P_UNA } ,
1608 { SMT_P_SDE, sizeof(struct smt_p_sde) ,
1609 SWAP_SMT_P_SDE } ,
1610 { SMT_P_STATE, sizeof(struct smt_p_state) ,
1611 SWAP_SMT_P_STATE } ,
1612 { SMT_P_TIMESTAMP,sizeof(struct smt_p_timestamp) ,
1613 SWAP_SMT_P_TIMESTAMP } ,
1614 { SMT_P_POLICY, sizeof(struct smt_p_policy) ,
1615 SWAP_SMT_P_POLICY } ,
1616 { SMT_P_LATENCY, sizeof(struct smt_p_latency) ,
1617 SWAP_SMT_P_LATENCY } ,
1618 { SMT_P_NEIGHBORS,sizeof(struct smt_p_neighbor) ,
1619 SWAP_SMT_P_NEIGHBORS } ,
1620 { SMT_P_PATH, sizeof(struct smt_p_path) ,
1621 SWAP_SMT_P_PATH } ,
1622 { SMT_P_MAC_STATUS,sizeof(struct smt_p_mac_status) ,
1623 SWAP_SMT_P_MAC_STATUS } ,
1624 { SMT_P_LEM, sizeof(struct smt_p_lem) ,
1625 SWAP_SMT_P_LEM } ,
1626 { SMT_P_MAC_COUNTER,sizeof(struct smt_p_mac_counter) ,
1627 SWAP_SMT_P_MAC_COUNTER } ,
1628 { SMT_P_MAC_FNC,sizeof(struct smt_p_mac_fnc) ,
1629 SWAP_SMT_P_MAC_FNC } ,
1630 { SMT_P_PRIORITY,sizeof(struct smt_p_priority) ,
1631 SWAP_SMT_P_PRIORITY } ,
1632 { SMT_P_EB,sizeof(struct smt_p_eb) ,
1633 SWAP_SMT_P_EB } ,
1634 { SMT_P_MANUFACTURER,sizeof(struct smp_p_manufacturer) ,
1635 SWAP_SMT_P_MANUFACTURER } ,
1636 { SMT_P_REASON, sizeof(struct smt_p_reason) ,
1637 SWAP_SMT_P_REASON } ,
1638 { SMT_P_REFUSED, sizeof(struct smt_p_refused) ,
1639 SWAP_SMT_P_REFUSED } ,
1640 { SMT_P_VERSION, sizeof(struct smt_p_version) ,
1641 SWAP_SMT_P_VERSION } ,
1642#ifdef ESS
1643 { SMT_P0015, sizeof(struct smt_p_0015) , SWAP_SMT_P0015 } ,
1644 { SMT_P0016, sizeof(struct smt_p_0016) , SWAP_SMT_P0016 } ,
1645 { SMT_P0017, sizeof(struct smt_p_0017) , SWAP_SMT_P0017 } ,
1646 { SMT_P0018, sizeof(struct smt_p_0018) , SWAP_SMT_P0018 } ,
1647 { SMT_P0019, sizeof(struct smt_p_0019) , SWAP_SMT_P0019 } ,
1648 { SMT_P001A, sizeof(struct smt_p_001a) , SWAP_SMT_P001A } ,
1649 { SMT_P001B, sizeof(struct smt_p_001b) , SWAP_SMT_P001B } ,
1650 { SMT_P001C, sizeof(struct smt_p_001c) , SWAP_SMT_P001C } ,
1651 { SMT_P001D, sizeof(struct smt_p_001d) , SWAP_SMT_P001D } ,
1652#endif
1653#if 0
1654 { SMT_P_FSC, sizeof(struct smt_p_fsc) ,
1655 SWAP_SMT_P_FSC } ,
1656#endif
1657
1658 { SMT_P_SETCOUNT,0, SWAP_SMT_P_SETCOUNT } ,
1659 { SMT_P1048, 0, SWAP_SMT_P1048 } ,
1660 { SMT_P208C, 0, SWAP_SMT_P208C } ,
1661 { SMT_P208D, 0, SWAP_SMT_P208D } ,
1662 { SMT_P208E, 0, SWAP_SMT_P208E } ,
1663 { SMT_P208F, 0, SWAP_SMT_P208F } ,
1664 { SMT_P2090, 0, SWAP_SMT_P2090 } ,
1665#ifdef ESS
1666 { SMT_P320B, sizeof(struct smt_p_320b) , SWAP_SMT_P320B } ,
1667 { SMT_P320F, sizeof(struct smt_p_320f) , SWAP_SMT_P320F } ,
1668 { SMT_P3210, sizeof(struct smt_p_3210) , SWAP_SMT_P3210 } ,
1669#endif
1670 { SMT_P4050, 0, SWAP_SMT_P4050 } ,
1671 { SMT_P4051, 0, SWAP_SMT_P4051 } ,
1672 { SMT_P4052, 0, SWAP_SMT_P4052 } ,
1673 { SMT_P4053, 0, SWAP_SMT_P4053 } ,
1674} ;
1675
1676#define N_SMT_PLEN (sizeof(smt_pdef)/sizeof(smt_pdef[0]))
1677
1678int smt_check_para(struct s_smc *smc, struct smt_header *sm,
1679 const u_short list[])
1680{
1681 const u_short *p = list ;
1682 while (*p) {
1683 if (!sm_to_para(smc,sm,(int) *p)) {
1684 DB_SMT("SMT: smt_check_para - missing para %x\n",*p,0);
1685 return(-1) ;
1686 }
1687 p++ ;
1688 }
1689 return(0) ;
1690}
1691
1692void *sm_to_para(struct s_smc *smc, struct smt_header *sm, int para)
1693{
1694 char *p ;
1695 int len ;
1696 int plen ;
1697 void *found = NULL;
1698
1699 SK_UNUSED(smc) ;
1700
1701 len = sm->smt_len ;
1702 p = (char *)(sm+1) ; /* pointer to info */
1703 while (len > 0 ) {
1704 if (((struct smt_para *)p)->p_type == para)
1705 found = (void *) p ;
1706 plen = ((struct smt_para *)p)->p_len + PARA_LEN ;
1707 p += plen ;
1708 len -= plen ;
1709 if (len < 0) {
1710 DB_SMT("SMT : sm_to_para - length error %d\n",plen,0) ;
1711 return NULL;
1712 }
1713 if ((plen & 3) && (para != SMT_P_ECHODATA)) {
1714 DB_SMT("SMT : sm_to_para - odd length %d\n",plen,0) ;
1715 return NULL;
1716 }
1717 if (found)
1718 return(found) ;
1719 }
1720 return NULL;
1721}
1722
1723#if 0
1724/*
1725 * send ANTC data test frame
1726 */
1727void fddi_send_antc(struct s_smc *smc, struct fddi_addr *dest)
1728{
1729 SK_UNUSED(smc) ;
1730 SK_UNUSED(dest) ;
1731#if 0
1732 SMbuf *mb ;
1733 struct smt_header *smt ;
1734 int i ;
1735 char *p ;
1736
1737 mb = smt_get_mbuf() ;
1738 mb->sm_len = 3000+12 ;
1739 p = smtod(mb, char *) + 12 ;
1740 for (i = 0 ; i < 3000 ; i++)
1741 *p++ = 1 << (i&7) ;
1742
1743 smt = smtod(mb, struct smt_header *) ;
1744 smt->smt_dest = *dest ;
1745 smt->smt_source = smc->mib.m[MAC0].fddiMACSMTAddress ;
1746 smt_send_mbuf(smc,mb,FC_ASYNC_LLC) ;
1747#endif
1748}
1749#endif
1750
1751#ifdef DEBUG
1752#define hextoasc(x) "0123456789abcdef"[x]
1753
1754char *addr_to_string(struct fddi_addr *addr)
1755{
1756 int i ;
1757 static char string[6*3] = "****" ;
1758
1759 for (i = 0 ; i < 6 ; i++) {
1760 string[i*3] = hextoasc((addr->a[i]>>4)&0xf) ;
1761 string[i*3+1] = hextoasc((addr->a[i])&0xf) ;
1762 string[i*3+2] = ':' ;
1763 }
1764 string[5*3+2] = 0 ;
1765 return(string) ;
1766}
1767#endif
1768
1769#ifdef AM29K
1770smt_ifconfig(int argc, char *argv[])
1771{
1772 if (argc >= 2 && !strcmp(argv[0],"opt_bypass") &&
1773 !strcmp(argv[1],"yes")) {
1774 smc->mib.fddiSMTBypassPresent = 1 ;
1775 return(0) ;
1776 }
1777 return(amdfddi_config(0,argc,argv)) ;
1778}
1779#endif
1780
1781/*
1782 * return static mac index
1783 */
1784static int mac_index(struct s_smc *smc, int mac)
1785{
1786 SK_UNUSED(mac) ;
1787#ifdef CONCENTRATOR
1788 SK_UNUSED(smc) ;
1789 return(NUMPHYS+1) ;
1790#else
1791 return((smc->s.sas == SMT_SAS) ? 2 : 3) ;
1792#endif
1793}
1794
1795/*
1796 * return static phy index
1797 */
1798static int phy_index(struct s_smc *smc, int phy)
1799{
1800 SK_UNUSED(smc) ;
1801 return(phy+1);
1802}
1803
1804/*
1805 * return dynamic mac connection resource index
1806 */
1807static int mac_con_resource_index(struct s_smc *smc, int mac)
1808{
1809#ifdef CONCENTRATOR
1810 SK_UNUSED(smc) ;
1811 SK_UNUSED(mac) ;
1812 return(entity_to_index(smc,cem_get_downstream(smc,ENTITY_MAC))) ;
1813#else
1814 SK_UNUSED(mac) ;
1815 switch (smc->mib.fddiSMTCF_State) {
1816 case SC9_C_WRAP_A :
1817 case SC5_THRU_B :
1818 case SC11_C_WRAP_S :
1819 return(1) ;
1820 case SC10_C_WRAP_B :
1821 case SC4_THRU_A :
1822 return(2) ;
1823 }
1824 return(smc->s.sas == SMT_SAS ? 2 : 3) ;
1825#endif
1826}
1827
1828/*
1829 * return dynamic phy connection resource index
1830 */
1831static int phy_con_resource_index(struct s_smc *smc, int phy)
1832{
1833#ifdef CONCENTRATOR
1834 return(entity_to_index(smc,cem_get_downstream(smc,ENTITY_PHY(phy)))) ;
1835#else
1836 switch (smc->mib.fddiSMTCF_State) {
1837 case SC9_C_WRAP_A :
1838 return(phy == PA ? 3 : 2) ;
1839 case SC10_C_WRAP_B :
1840 return(phy == PA ? 1 : 3) ;
1841 case SC4_THRU_A :
1842 return(phy == PA ? 3 : 1) ;
1843 case SC5_THRU_B :
1844 return(phy == PA ? 2 : 3) ;
1845 case SC11_C_WRAP_S :
1846 return(2) ;
1847 }
1848 return(phy) ;
1849#endif
1850}
1851
1852#ifdef CONCENTRATOR
1853static int entity_to_index(struct s_smc *smc, int e)
1854{
1855 if (e == ENTITY_MAC)
1856 return(mac_index(smc,1)) ;
1857 else
1858 return(phy_index(smc,e - ENTITY_PHY(0))) ;
1859}
1860#endif
1861
1862#ifdef LITTLE_ENDIAN
1863static int smt_swap_short(u_short s)
1864{
1865 return(((s>>8)&0xff)|((s&0xff)<<8)) ;
1866}
1867
1868void smt_swap_para(struct smt_header *sm, int len, int direction)
1869/* int direction; 0 encode 1 decode */
1870{
1871 struct smt_para *pa ;
1872 const struct smt_pdef *pd ;
1873 char *p ;
1874 int plen ;
1875 int type ;
1876 int i ;
1877
1878/* printf("smt_swap_para sm %x len %d dir %d\n",
1879 sm,len,direction) ;
1880 */
1881 smt_string_swap((char *)sm,SWAP_SMTHEADER,len) ;
1882
1883 /* swap args */
1884 len -= sizeof(struct smt_header) ;
1885
1886 p = (char *) (sm + 1) ;
1887 while (len > 0) {
1888 pa = (struct smt_para *) p ;
1889 plen = pa->p_len ;
1890 type = pa->p_type ;
1891 pa->p_type = smt_swap_short(pa->p_type) ;
1892 pa->p_len = smt_swap_short(pa->p_len) ;
1893 if (direction) {
1894 plen = pa->p_len ;
1895 type = pa->p_type ;
1896 }
1897 /*
1898 * note: paras can have 0 length !
1899 */
1900 if (plen < 0)
1901 break ;
1902 plen += PARA_LEN ;
1903 for (i = N_SMT_PLEN, pd = smt_pdef; i ; i--,pd++) {
1904 if (pd->ptype == type)
1905 break ;
1906 }
1907 if (i && pd->pswap) {
1908 smt_string_swap(p+PARA_LEN,pd->pswap,len) ;
1909 }
1910 len -= plen ;
1911 p += plen ;
1912 }
1913}
1914
1915static void smt_string_swap(char *data, const char *format, int len)
1916{
1917 const char *open_paren = 0 ;
1918 int x ;
1919
1920 while (len > 0 && *format) {
1921 switch (*format) {
1922 case '[' :
1923 open_paren = format ;
1924 break ;
1925 case ']' :
1926 format = open_paren ;
1927 break ;
1928 case '1' :
1929 case '2' :
1930 case '3' :
1931 case '4' :
1932 case '5' :
1933 case '6' :
1934 case '7' :
1935 case '8' :
1936 case '9' :
1937 data += *format - '0' ;
1938 len -= *format - '0' ;
1939 break ;
1940 case 'c':
1941 data++ ;
1942 len-- ;
1943 break ;
1944 case 's' :
1945 x = data[0] ;
1946 data[0] = data[1] ;
1947 data[1] = x ;
1948 data += 2 ;
1949 len -= 2 ;
1950 break ;
1951 case 'l' :
1952 x = data[0] ;
1953 data[0] = data[3] ;
1954 data[3] = x ;
1955 x = data[1] ;
1956 data[1] = data[2] ;
1957 data[2] = x ;
1958 data += 4 ;
1959 len -= 4 ;
1960 break ;
1961 }
1962 format++ ;
1963 }
1964}
1965#else
1966void smt_swap_para(struct smt_header *sm, int len, int direction)
1967/* int direction; 0 encode 1 decode */
1968{
1969 SK_UNUSED(sm) ;
1970 SK_UNUSED(len) ;
1971 SK_UNUSED(direction) ;
1972}
1973#endif
1974
1975/*
1976 * PMF actions
1977 */
1978int smt_action(struct s_smc *smc, int class, int code, int index)
1979{
1980 int event ;
1981 int port ;
1982 DB_SMT("SMT: action %d code %d\n",class,code) ;
1983 switch(class) {
1984 case SMT_STATION_ACTION :
1985 switch(code) {
1986 case SMT_STATION_ACTION_CONNECT :
1987 smc->mib.fddiSMTRemoteDisconnectFlag = FALSE ;
1988 queue_event(smc,EVENT_ECM,EC_CONNECT) ;
1989 break ;
1990 case SMT_STATION_ACTION_DISCONNECT :
1991 queue_event(smc,EVENT_ECM,EC_DISCONNECT) ;
1992 smc->mib.fddiSMTRemoteDisconnectFlag = TRUE ;
1993 RS_SET(smc,RS_DISCONNECT) ;
1994 AIX_EVENT(smc, (u_long) FDDI_RING_STATUS, (u_long)
1995 FDDI_SMT_EVENT, (u_long) FDDI_REMOTE_DISCONNECT,
1996 smt_get_event_word(smc));
1997 break ;
1998 case SMT_STATION_ACTION_PATHTEST :
1999 AIX_EVENT(smc, (u_long) FDDI_RING_STATUS, (u_long)
2000 FDDI_SMT_EVENT, (u_long) FDDI_PATH_TEST,
2001 smt_get_event_word(smc));
2002 break ;
2003 case SMT_STATION_ACTION_SELFTEST :
2004 AIX_EVENT(smc, (u_long) FDDI_RING_STATUS, (u_long)
2005 FDDI_SMT_EVENT, (u_long) FDDI_REMOTE_SELF_TEST,
2006 smt_get_event_word(smc));
2007 break ;
2008 case SMT_STATION_ACTION_DISABLE_A :
2009 if (smc->y[PA].pc_mode == PM_PEER) {
2010 RS_SET(smc,RS_EVENT) ;
2011 queue_event(smc,EVENT_PCM+PA,PC_DISABLE) ;
2012 }
2013 break ;
2014 case SMT_STATION_ACTION_DISABLE_B :
2015 if (smc->y[PB].pc_mode == PM_PEER) {
2016 RS_SET(smc,RS_EVENT) ;
2017 queue_event(smc,EVENT_PCM+PB,PC_DISABLE) ;
2018 }
2019 break ;
2020 case SMT_STATION_ACTION_DISABLE_M :
2021 for (port = 0 ; port < NUMPHYS ; port++) {
2022 if (smc->mib.p[port].fddiPORTMy_Type != TM)
2023 continue ;
2024 RS_SET(smc,RS_EVENT) ;
2025 queue_event(smc,EVENT_PCM+port,PC_DISABLE) ;
2026 }
2027 break ;
2028 default :
2029 return(1) ;
2030 }
2031 break ;
2032 case SMT_PORT_ACTION :
2033 switch(code) {
2034 case SMT_PORT_ACTION_ENABLE :
2035 event = PC_ENABLE ;
2036 break ;
2037 case SMT_PORT_ACTION_DISABLE :
2038 event = PC_DISABLE ;
2039 break ;
2040 case SMT_PORT_ACTION_MAINT :
2041 event = PC_MAINT ;
2042 break ;
2043 case SMT_PORT_ACTION_START :
2044 event = PC_START ;
2045 break ;
2046 case SMT_PORT_ACTION_STOP :
2047 event = PC_STOP ;
2048 break ;
2049 default :
2050 return(1) ;
2051 }
2052 queue_event(smc,EVENT_PCM+index,event) ;
2053 break ;
2054 default :
2055 return(1) ;
2056 }
2057 return(0) ;
2058}
2059
2060/*
2061 * change tneg
2062 * set T_Req in MIB (Path Attribute)
2063 * calculate new values for MAC
2064 * if change required
2065 * disconnect
2066 * set reconnect
2067 * end
2068 */
2069void smt_change_t_neg(struct s_smc *smc, u_long tneg)
2070{
2071 smc->mib.a[PATH0].fddiPATHMaxT_Req = tneg ;
2072
2073 if (smt_set_mac_opvalues(smc)) {
2074 RS_SET(smc,RS_EVENT) ;
2075 smc->sm.please_reconnect = 1 ;
2076 queue_event(smc,EVENT_ECM,EC_DISCONNECT) ;
2077 }
2078}
2079
2080/*
2081 * canonical conversion of <len> bytes beginning form *data
2082 */
2083#ifdef USE_CAN_ADDR
2084void hwm_conv_can(struct s_smc *smc, char *data, int len)
2085{
2086 int i ;
2087
2088 SK_UNUSED(smc) ;
2089
2090 for (i = len; i ; i--, data++) {
2091 *data = canonical[*(u_char *)data] ;
2092 }
2093}
2094#endif
2095
2096#endif /* no SLIM_SMT */
2097
diff --git a/drivers/net/skfp/smtdef.c b/drivers/net/skfp/smtdef.c
new file mode 100644
index 000000000000..5a0c8db816d8
--- /dev/null
+++ b/drivers/net/skfp/smtdef.c
@@ -0,0 +1,360 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * See the file "skfddi.c" for further information.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * The information in this file is provided "AS IS" without warranty.
14 *
15 ******************************************************************************/
16
17/*
18 SMT/CMT defaults
19*/
20
21#include "h/types.h"
22#include "h/fddi.h"
23#include "h/smc.h"
24
25#ifndef OEM_USER_DATA
26#define OEM_USER_DATA "SK-NET FDDI V2.0 Userdata"
27#endif
28
29#ifndef lint
30static const char ID_sccs[] = "@(#)smtdef.c 2.53 99/08/11 (C) SK " ;
31#endif
32
33/*
34 * defaults
35 */
36#define TTMS(x) ((u_long)(x)*1000L)
37#define TTS(x) ((u_long)(x)*1000000L)
38#define TTUS(x) ((u_long)(x))
39
40#define DEFAULT_TB_MIN TTMS(5)
41#define DEFAULT_TB_MAX TTMS(50)
42#define DEFAULT_C_MIN TTUS(1600)
43#define DEFAULT_T_OUT TTMS(100+5)
44#define DEFAULT_TL_MIN TTUS(30)
45#define DEFAULT_LC_SHORT TTMS(50+5)
46#define DEFAULT_LC_MEDIUM TTMS(500+20)
47#define DEFAULT_LC_LONG TTS(5)+TTMS(50)
48#define DEFAULT_LC_EXTENDED TTS(50)+TTMS(50)
49#define DEFAULT_T_NEXT_9 TTMS(200+10)
50#define DEFAULT_NS_MAX TTUS(1310)
51#define DEFAULT_I_MAX TTMS(25)
52#define DEFAULT_IN_MAX TTMS(40)
53#define DEFAULT_TD_MIN TTMS(5)
54#define DEFAULT_T_NON_OP TTS(1)
55#define DEFAULT_T_STUCK TTS(8)
56#define DEFAULT_T_DIRECT TTMS(370)
57#define DEFAULT_T_JAM TTMS(370)
58#define DEFAULT_T_ANNOUNCE TTMS(2500)
59#define DEFAULT_D_MAX TTUS(1617)
60#define DEFAULT_LEM_ALARM (8)
61#define DEFAULT_LEM_CUTOFF (7)
62#define DEFAULT_TEST_DONE TTS(1)
63#define DEFAULT_CHECK_POLL TTS(1)
64#define DEFAULT_POLL TTMS(50)
65
66/*
67 * LCT errors threshold
68 */
69#define DEFAULT_LCT_SHORT 1
70#define DEFAULT_LCT_MEDIUM 3
71#define DEFAULT_LCT_LONG 5
72#define DEFAULT_LCT_EXTEND 50
73
74/* Forward declarations */
75void smt_reset_defaults(struct s_smc *smc, int level);
76static void smt_init_mib(struct s_smc *smc, int level);
77static int set_min_max(int maxflag, u_long mib, u_long limit, u_long *oper);
78
79void smt_set_defaults(struct s_smc *smc)
80{
81 smt_reset_defaults(smc,0) ;
82}
83
84#define MS2BCLK(x) ((x)*12500L)
85#define US2BCLK(x) ((x)*1250L)
86
87void smt_reset_defaults(struct s_smc *smc, int level)
88{
89 struct smt_config *smt ;
90 int i ;
91 u_long smt_boot_time;
92
93
94 smt_init_mib(smc,level) ;
95
96 smc->os.smc_version = SMC_VERSION ;
97 smt_boot_time = smt_get_time();
98 for( i = 0; i < NUMMACS; i++ )
99 smc->sm.last_tok_time[i] = smt_boot_time ;
100 smt = &smc->s ;
101 smt->attach_s = 0 ;
102 smt->build_ring_map = 1 ;
103 smt->sas = SMT_DAS ;
104 smt->numphys = NUMPHYS ;
105 smt->pcm_tb_min = DEFAULT_TB_MIN ;
106 smt->pcm_tb_max = DEFAULT_TB_MAX ;
107 smt->pcm_c_min = DEFAULT_C_MIN ;
108 smt->pcm_t_out = DEFAULT_T_OUT ;
109 smt->pcm_tl_min = DEFAULT_TL_MIN ;
110 smt->pcm_lc_short = DEFAULT_LC_SHORT ;
111 smt->pcm_lc_medium = DEFAULT_LC_MEDIUM ;
112 smt->pcm_lc_long = DEFAULT_LC_LONG ;
113 smt->pcm_lc_extended = DEFAULT_LC_EXTENDED ;
114 smt->pcm_t_next_9 = DEFAULT_T_NEXT_9 ;
115 smt->pcm_ns_max = DEFAULT_NS_MAX ;
116 smt->ecm_i_max = DEFAULT_I_MAX ;
117 smt->ecm_in_max = DEFAULT_IN_MAX ;
118 smt->ecm_td_min = DEFAULT_TD_MIN ;
119 smt->ecm_test_done = DEFAULT_TEST_DONE ;
120 smt->ecm_check_poll = DEFAULT_CHECK_POLL ;
121 smt->rmt_t_non_op = DEFAULT_T_NON_OP ;
122 smt->rmt_t_stuck = DEFAULT_T_STUCK ;
123 smt->rmt_t_direct = DEFAULT_T_DIRECT ;
124 smt->rmt_t_jam = DEFAULT_T_JAM ;
125 smt->rmt_t_announce = DEFAULT_T_ANNOUNCE ;
126 smt->rmt_t_poll = DEFAULT_POLL ;
127 smt->rmt_dup_mac_behavior = FALSE ; /* See Struct smt_config */
128 smt->mac_d_max = DEFAULT_D_MAX ;
129
130 smt->lct_short = DEFAULT_LCT_SHORT ;
131 smt->lct_medium = DEFAULT_LCT_MEDIUM ;
132 smt->lct_long = DEFAULT_LCT_LONG ;
133 smt->lct_extended = DEFAULT_LCT_EXTEND ;
134
135#ifndef SLIM_SMT
136#ifdef ESS
137 if (level == 0) {
138 smc->ess.sync_bw_available = FALSE ;
139 smc->mib.fddiESSPayload = 0 ;
140 smc->mib.fddiESSOverhead = 0 ;
141 smc->mib.fddiESSMaxTNeg = (u_long)(- MS2BCLK(25)) ;
142 smc->mib.fddiESSMinSegmentSize = 1 ;
143 smc->mib.fddiESSCategory = SB_STATIC ;
144 smc->mib.fddiESSSynchTxMode = FALSE ;
145 smc->ess.raf_act_timer_poll = FALSE ;
146 smc->ess.timer_count = 7 ; /* first RAF alc req after 3s */
147 }
148 smc->ess.local_sba_active = FALSE ;
149 smc->ess.sba_reply_pend = NULL ;
150#endif
151#ifdef SBA
152 smt_init_sba(smc,level) ;
153#endif
154#endif /* no SLIM_SMT */
155#ifdef TAG_MODE
156 if (level == 0) {
157 smc->hw.pci_fix_value = 0 ;
158 }
159#endif
160}
161
162/*
163 * manufacturer data
164 */
165static const char man_data[32] =
166/* 01234567890123456789012345678901 */
167 "xxxSK-NET FDDI SMT 7.3 - V2.8.8" ;
168
169static void smt_init_mib(struct s_smc *smc, int level)
170{
171 struct fddi_mib *mib ;
172 struct fddi_mib_p *pm ;
173 int port ;
174 int path ;
175
176 mib = &smc->mib ;
177 if (level == 0) {
178 /*
179 * set EVERYTHING to ZERO
180 * EXCEPT hw and os
181 */
182 memset(((char *)smc)+
183 sizeof(struct s_smt_os)+sizeof(struct s_smt_hw), 0,
184 sizeof(struct s_smc) -
185 sizeof(struct s_smt_os) - sizeof(struct s_smt_hw)) ;
186 }
187 else {
188 mib->fddiSMTRemoteDisconnectFlag = 0 ;
189 mib->fddiSMTPeerWrapFlag = 0 ;
190 }
191
192 mib->fddiSMTOpVersionId = 2 ;
193 mib->fddiSMTHiVersionId = 2 ;
194 mib->fddiSMTLoVersionId = 2 ;
195 memcpy((char *) mib->fddiSMTManufacturerData,man_data,32) ;
196 if (level == 0) {
197 strcpy(mib->fddiSMTUserData,OEM_USER_DATA) ;
198 }
199 mib->fddiSMTMIBVersionId = 1 ;
200 mib->fddiSMTMac_Ct = NUMMACS ;
201 mib->fddiSMTConnectionPolicy = POLICY_MM | POLICY_AA | POLICY_BB ;
202
203 /*
204 * fddiSMTNonMaster_Ct and fddiSMTMaster_Ct are set in smt_fixup_mib
205 * s.sas is not set yet (is set in init driver)
206 */
207 mib->fddiSMTAvailablePaths = MIB_PATH_P | MIB_PATH_S ;
208
209 mib->fddiSMTConfigCapabilities = 0 ; /* no hold,no wrap_ab*/
210 mib->fddiSMTTT_Notify = 10 ;
211 mib->fddiSMTStatRptPolicy = TRUE ;
212 mib->fddiSMTTrace_MaxExpiration = SEC2MIB(7) ;
213 mib->fddiSMTMACIndexes = INDEX_MAC ;
214 mib->fddiSMTStationStatus = MIB_SMT_STASTA_SEPA ; /* separated */
215
216 mib->m[MAC0].fddiMACIndex = INDEX_MAC ;
217 mib->m[MAC0].fddiMACFrameStatusFunctions = FSC_TYPE0 ;
218 mib->m[MAC0].fddiMACRequestedPaths =
219 MIB_P_PATH_LOCAL |
220 MIB_P_PATH_SEC_ALTER |
221 MIB_P_PATH_PRIM_ALTER ;
222 mib->m[MAC0].fddiMACAvailablePaths = MIB_PATH_P ;
223 mib->m[MAC0].fddiMACCurrentPath = MIB_PATH_PRIMARY ;
224 mib->m[MAC0].fddiMACT_MaxCapabilitiy = (u_long)(- MS2BCLK(165)) ;
225 mib->m[MAC0].fddiMACTVXCapabilitiy = (u_long)(- US2BCLK(52)) ;
226 if (level == 0) {
227 mib->m[MAC0].fddiMACTvxValue = (u_long)(- US2BCLK(27)) ;
228 mib->m[MAC0].fddiMACTvxValueMIB = (u_long)(- US2BCLK(27)) ;
229 mib->m[MAC0].fddiMACT_Req = (u_long)(- MS2BCLK(165)) ;
230 mib->m[MAC0].fddiMACT_ReqMIB = (u_long)(- MS2BCLK(165)) ;
231 mib->m[MAC0].fddiMACT_Max = (u_long)(- MS2BCLK(165)) ;
232 mib->m[MAC0].fddiMACT_MaxMIB = (u_long)(- MS2BCLK(165)) ;
233 mib->m[MAC0].fddiMACT_Min = (u_long)(- MS2BCLK(4)) ;
234 }
235 mib->m[MAC0].fddiMACHardwarePresent = TRUE ;
236 mib->m[MAC0].fddiMACMA_UnitdataEnable = TRUE ;
237 mib->m[MAC0].fddiMACFrameErrorThreshold = 1 ;
238 mib->m[MAC0].fddiMACNotCopiedThreshold = 1 ;
239 /*
240 * Path attributes
241 */
242 for (path = 0 ; path < NUMPATHS ; path++) {
243 mib->a[path].fddiPATHIndex = INDEX_PATH + path ;
244 if (level == 0) {
245 mib->a[path].fddiPATHTVXLowerBound =
246 (u_long)(- US2BCLK(27)) ;
247 mib->a[path].fddiPATHT_MaxLowerBound =
248 (u_long)(- MS2BCLK(165)) ;
249 mib->a[path].fddiPATHMaxT_Req =
250 (u_long)(- MS2BCLK(165)) ;
251 }
252 }
253
254
255 /*
256 * Port attributes
257 */
258 pm = mib->p ;
259 for (port = 0 ; port < NUMPHYS ; port++) {
260 /*
261 * set MIB pointer in phy
262 */
263 /* Attention: don't initialize mib pointer here! */
264 /* It must be initialized during phase 2 */
265 smc->y[port].mib = NULL;
266 mib->fddiSMTPORTIndexes[port] = port+INDEX_PORT ;
267
268 pm->fddiPORTIndex = port+INDEX_PORT ;
269 pm->fddiPORTHardwarePresent = TRUE ;
270 if (level == 0) {
271 pm->fddiPORTLer_Alarm = DEFAULT_LEM_ALARM ;
272 pm->fddiPORTLer_Cutoff = DEFAULT_LEM_CUTOFF ;
273 }
274 /*
275 * fddiPORTRequestedPaths are set in pcmplc.c
276 * we don't know the port type yet !
277 */
278 pm->fddiPORTRequestedPaths[1] = 0 ;
279 pm->fddiPORTRequestedPaths[2] = 0 ;
280 pm->fddiPORTRequestedPaths[3] = 0 ;
281 pm->fddiPORTAvailablePaths = MIB_PATH_P ;
282 pm->fddiPORTPMDClass = MIB_PMDCLASS_MULTI ;
283 pm++ ;
284 }
285
286 (void) smt_set_mac_opvalues(smc) ;
287}
288
289int smt_set_mac_opvalues(struct s_smc *smc)
290{
291 int st ;
292 int st2 ;
293
294 st = set_min_max(1,smc->mib.m[MAC0].fddiMACTvxValueMIB,
295 smc->mib.a[PATH0].fddiPATHTVXLowerBound,
296 &smc->mib.m[MAC0].fddiMACTvxValue) ;
297 st |= set_min_max(0,smc->mib.m[MAC0].fddiMACT_MaxMIB,
298 smc->mib.a[PATH0].fddiPATHT_MaxLowerBound,
299 &smc->mib.m[MAC0].fddiMACT_Max) ;
300 st |= (st2 = set_min_max(0,smc->mib.m[MAC0].fddiMACT_ReqMIB,
301 smc->mib.a[PATH0].fddiPATHMaxT_Req,
302 &smc->mib.m[MAC0].fddiMACT_Req)) ;
303 if (st2) {
304 /* Treq attribute changed remotely. So send an AIX_EVENT to the
305 * user
306 */
307 AIX_EVENT(smc, (u_long) FDDI_RING_STATUS, (u_long)
308 FDDI_SMT_EVENT, (u_long) FDDI_REMOTE_T_REQ,
309 smt_get_event_word(smc));
310 }
311 return(st) ;
312}
313
314void smt_fixup_mib(struct s_smc *smc)
315{
316#ifdef CONCENTRATOR
317 switch (smc->s.sas) {
318 case SMT_SAS :
319 smc->mib.fddiSMTNonMaster_Ct = 1 ;
320 break ;
321 case SMT_DAS :
322 smc->mib.fddiSMTNonMaster_Ct = 2 ;
323 break ;
324 case SMT_NAC :
325 smc->mib.fddiSMTNonMaster_Ct = 0 ;
326 break ;
327 }
328 smc->mib.fddiSMTMaster_Ct = NUMPHYS - smc->mib.fddiSMTNonMaster_Ct ;
329#else
330 switch (smc->s.sas) {
331 case SMT_SAS :
332 smc->mib.fddiSMTNonMaster_Ct = 1 ;
333 break ;
334 case SMT_DAS :
335 smc->mib.fddiSMTNonMaster_Ct = 2 ;
336 break ;
337 }
338 smc->mib.fddiSMTMaster_Ct = 0 ;
339#endif
340}
341
342/*
343 * determine new setting for operational value
344 * if limit is lower than mib
345 * use limit
346 * else
347 * use mib
348 * NOTE : numbers are negative, negate comparison !
349 */
350static int set_min_max(int maxflag, u_long mib, u_long limit, u_long *oper)
351{
352 u_long old ;
353 old = *oper ;
354 if ((limit > mib) ^ maxflag)
355 *oper = limit ;
356 else
357 *oper = mib ;
358 return(old != *oper) ;
359}
360
diff --git a/drivers/net/skfp/smtinit.c b/drivers/net/skfp/smtinit.c
new file mode 100644
index 000000000000..3c8964ce1837
--- /dev/null
+++ b/drivers/net/skfp/smtinit.c
@@ -0,0 +1,125 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * See the file "skfddi.c" for further information.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * The information in this file is provided "AS IS" without warranty.
14 *
15 ******************************************************************************/
16
17/*
18 Init SMT
19 call all module level initialization routines
20*/
21
22#include "h/types.h"
23#include "h/fddi.h"
24#include "h/smc.h"
25
26#ifndef lint
27static const char ID_sccs[] = "@(#)smtinit.c 1.15 97/05/06 (C) SK " ;
28#endif
29
30void init_fddi_driver(struct s_smc *smc, u_char *mac_addr);
31
32/* define global debug variable */
33#if defined(DEBUG) && !defined(DEBUG_BRD)
34struct smt_debug debug;
35#endif
36
37#ifndef MULT_OEM
38#define OEMID(smc,i) oem_id[i]
39 extern u_char oem_id[] ;
40#else /* MULT_OEM */
41#define OEMID(smc,i) smc->hw.oem_id->oi_mark[i]
42 extern struct s_oem_ids oem_ids[] ;
43#endif /* MULT_OEM */
44
45/*
46 * Set OEM specific values
47 *
48 * Can not be called in smt_reset_defaults, because it is not sure that
49 * the OEM ID is already defined.
50 */
51static void set_oem_spec_val(struct s_smc *smc)
52{
53 struct fddi_mib *mib ;
54
55 mib = &smc->mib ;
56
57 /*
58 * set IBM specific values
59 */
60 if (OEMID(smc,0) == 'I') {
61 mib->fddiSMTConnectionPolicy = POLICY_MM ;
62 }
63}
64
65/*
66 * Init SMT
67 */
68int init_smt(struct s_smc *smc, u_char *mac_addr)
69/* u_char *mac_addr; canonical address or NULL */
70{
71 int p ;
72
73#if defined(DEBUG) && !defined(DEBUG_BRD)
74 debug.d_smt = 0 ;
75 debug.d_smtf = 0 ;
76 debug.d_rmt = 0 ;
77 debug.d_ecm = 0 ;
78 debug.d_pcm = 0 ;
79 debug.d_cfm = 0 ;
80
81 debug.d_plc = 0 ;
82#ifdef ESS
83 debug.d_ess = 0 ;
84#endif
85#ifdef SBA
86 debug.d_sba = 0 ;
87#endif
88#endif /* DEBUG && !DEBUG_BRD */
89
90 /* First initialize the ports mib->pointers */
91 for ( p = 0; p < NUMPHYS; p ++ ) {
92 smc->y[p].mib = & smc->mib.p[p] ;
93 }
94
95 set_oem_spec_val(smc) ;
96 (void) smt_set_mac_opvalues(smc) ;
97 init_fddi_driver(smc,mac_addr) ; /* HW driver */
98 smt_fixup_mib(smc) ; /* update values that depend on s.sas */
99
100 ev_init(smc) ; /* event queue */
101#ifndef SLIM_SMT
102 smt_init_evc(smc) ; /* evcs in MIB */
103#endif /* no SLIM_SMT */
104 smt_timer_init(smc) ; /* timer package */
105 smt_agent_init(smc) ; /* SMT frame manager */
106
107 pcm_init(smc) ; /* PCM state machine */
108 ecm_init(smc) ; /* ECM state machine */
109 cfm_init(smc) ; /* CFM state machine */
110 rmt_init(smc) ; /* RMT state machine */
111
112 for (p = 0 ; p < NUMPHYS ; p++) {
113 pcm(smc,p,0) ; /* PCM A state machine */
114 }
115 ecm(smc,0) ; /* ECM state machine */
116 cfm(smc,0) ; /* CFM state machine */
117 rmt(smc,0) ; /* RMT state machine */
118
119 smt_agent_task(smc) ; /* NIF FSM etc */
120
121 PNMI_INIT(smc) ; /* PNMI initialization */
122
123 return(0) ;
124}
125
diff --git a/drivers/net/skfp/smtparse.c b/drivers/net/skfp/smtparse.c
new file mode 100644
index 000000000000..d5779e414dbe
--- /dev/null
+++ b/drivers/net/skfp/smtparse.c
@@ -0,0 +1,467 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * See the file "skfddi.c" for further information.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * The information in this file is provided "AS IS" without warranty.
14 *
15 ******************************************************************************/
16
17
18/*
19 parser for SMT parameters
20*/
21
22#include "h/types.h"
23#include "h/fddi.h"
24#include "h/smc.h"
25#include "h/smt_p.h"
26
27#define KERNEL
28#include "h/smtstate.h"
29
30#ifndef lint
31static const char ID_sccs[] = "@(#)smtparse.c 1.12 98/10/06 (C) SK " ;
32#endif
33
34#ifdef sun
35#define _far
36#endif
37
38/*
39 * convert to BCLK units
40 */
41#define MS2BCLK(x) ((x)*12500L)
42#define US2BCLK(x) ((x/10)*125L)
43
44/*
45 * parameter table
46 */
47static struct s_ptab {
48 char *pt_name ;
49 u_short pt_num ;
50 u_short pt_type ;
51 u_long pt_min ;
52 u_long pt_max ;
53} ptab[] = {
54 { "PMFPASSWD",0, 0 } ,
55 { "USERDATA",1, 0 } ,
56 { "LERCUTOFFA",2, 1, 4, 15 } ,
57 { "LERCUTOFFB",3, 1, 4, 15 } ,
58 { "LERALARMA",4, 1, 4, 15 } ,
59 { "LERALARMB",5, 1, 4, 15 } ,
60 { "TMAX",6, 1, 5, 165 } ,
61 { "TMIN",7, 1, 5, 165 } ,
62 { "TREQ",8, 1, 5, 165 } ,
63 { "TVX",9, 1, 2500, 10000 } ,
64#ifdef ESS
65 { "SBAPAYLOAD",10, 1, 0, 1562 } ,
66 { "SBAOVERHEAD",11, 1, 50, 5000 } ,
67 { "MAXTNEG",12, 1, 5, 165 } ,
68 { "MINSEGMENTSIZE",13, 1, 0, 4478 } ,
69 { "SBACATEGORY",14, 1, 0, 0xffff } ,
70 { "SYNCHTXMODE",15, 0 } ,
71#endif
72#ifdef SBA
73 { "SBACOMMAND",16, 0 } ,
74 { "SBAAVAILABLE",17, 1, 0, 100 } ,
75#endif
76 { NULL }
77} ;
78
79/* Define maximum string size for values and keybuffer */
80#define MAX_VAL 40
81
82/*
83 * local function declarations
84 */
85static u_long parse_num(int type, char _far *value, char *v, u_long mn,
86 u_long mx, int scale);
87static int parse_word(char *buf, char _far *text);
88
89#ifdef SIM
90#define DB_MAIN(a,b,c) printf(a,b,c)
91#else
92#define DB_MAIN(a,b,c)
93#endif
94
95/*
96 * BEGIN_MANUAL_ENTRY()
97 *
98 * int smt_parse_arg(struct s_smc *,char _far *keyword,int type,
99 char _far *value)
100 *
101 * parse SMT parameter
102 * *keyword
103 * pointer to keyword, must be \0, \n or \r terminated
104 * *value pointer to value, either char * or u_long *
105 * if char *
106 * pointer to value, must be \0, \n or \r terminated
107 * if u_long *
108 * contains binary value
109 *
110 * type 0: integer
111 * 1: string
112 * return
113 * 0 parameter parsed ok
114 * != 0 error
115 * NOTE:
116 * function can be called with DS != SS
117 *
118 *
119 * END_MANUAL_ENTRY()
120 */
121int smt_parse_arg(struct s_smc *smc, char _far *keyword, int type,
122 char _far *value)
123{
124 char keybuf[MAX_VAL+1];
125 char valbuf[MAX_VAL+1];
126 char c ;
127 char *p ;
128 char *v ;
129 char *d ;
130 u_long val = 0 ;
131 struct s_ptab *pt ;
132 int st ;
133 int i ;
134
135 /*
136 * parse keyword
137 */
138 if ((st = parse_word(keybuf,keyword)))
139 return(st) ;
140 /*
141 * parse value if given as string
142 */
143 if (type == 1) {
144 if ((st = parse_word(valbuf,value)))
145 return(st) ;
146 }
147 /*
148 * search in table
149 */
150 st = 0 ;
151 for (pt = ptab ; (v = pt->pt_name) ; pt++) {
152 for (p = keybuf ; (c = *p) ; p++,v++) {
153 if (c != *v)
154 break ;
155 }
156 if (!c && !*v)
157 break ;
158 }
159 if (!v)
160 return(-1) ;
161#if 0
162 printf("=>%s<==>%s<=\n",pt->pt_name,valbuf) ;
163#endif
164 /*
165 * set value in MIB
166 */
167 if (pt->pt_type)
168 val = parse_num(type,value,valbuf,pt->pt_min,pt->pt_max,1) ;
169 switch (pt->pt_num) {
170 case 0 :
171 v = valbuf ;
172 d = (char *) smc->mib.fddiPRPMFPasswd ;
173 for (i = 0 ; i < (signed)sizeof(smc->mib.fddiPRPMFPasswd) ; i++)
174 *d++ = *v++ ;
175 DB_MAIN("SET %s = %s\n",pt->pt_name,smc->mib.fddiPRPMFPasswd) ;
176 break ;
177 case 1 :
178 v = valbuf ;
179 d = (char *) smc->mib.fddiSMTUserData ;
180 for (i = 0 ; i < (signed)sizeof(smc->mib.fddiSMTUserData) ; i++)
181 *d++ = *v++ ;
182 DB_MAIN("SET %s = %s\n",pt->pt_name,smc->mib.fddiSMTUserData) ;
183 break ;
184 case 2 :
185 smc->mib.p[PA].fddiPORTLer_Cutoff = (u_char) val ;
186 DB_MAIN("SET %s = %d\n",
187 pt->pt_name,smc->mib.p[PA].fddiPORTLer_Cutoff) ;
188 break ;
189 case 3 :
190 smc->mib.p[PB].fddiPORTLer_Cutoff = (u_char) val ;
191 DB_MAIN("SET %s = %d\n",
192 pt->pt_name,smc->mib.p[PB].fddiPORTLer_Cutoff) ;
193 break ;
194 case 4 :
195 smc->mib.p[PA].fddiPORTLer_Alarm = (u_char) val ;
196 DB_MAIN("SET %s = %d\n",
197 pt->pt_name,smc->mib.p[PA].fddiPORTLer_Alarm) ;
198 break ;
199 case 5 :
200 smc->mib.p[PB].fddiPORTLer_Alarm = (u_char) val ;
201 DB_MAIN("SET %s = %d\n",
202 pt->pt_name,smc->mib.p[PB].fddiPORTLer_Alarm) ;
203 break ;
204 case 6 : /* TMAX */
205 DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
206 smc->mib.a[PATH0].fddiPATHT_MaxLowerBound =
207 (u_long) -MS2BCLK((long)val) ;
208 break ;
209 case 7 : /* TMIN */
210 DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
211 smc->mib.m[MAC0].fddiMACT_Min =
212 (u_long) -MS2BCLK((long)val) ;
213 break ;
214 case 8 : /* TREQ */
215 DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
216 smc->mib.a[PATH0].fddiPATHMaxT_Req =
217 (u_long) -MS2BCLK((long)val) ;
218 break ;
219 case 9 : /* TVX */
220 DB_MAIN("SET %s = %d \n",pt->pt_name,val) ;
221 smc->mib.a[PATH0].fddiPATHTVXLowerBound =
222 (u_long) -US2BCLK((long)val) ;
223 break ;
224#ifdef ESS
225 case 10 : /* SBAPAYLOAD */
226 DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
227 if (smc->mib.fddiESSPayload != val) {
228 smc->ess.raf_act_timer_poll = TRUE ;
229 smc->mib.fddiESSPayload = val ;
230 }
231 break ;
232 case 11 : /* SBAOVERHEAD */
233 DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
234 smc->mib.fddiESSOverhead = val ;
235 break ;
236 case 12 : /* MAXTNEG */
237 DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
238 smc->mib.fddiESSMaxTNeg = (u_long) -MS2BCLK((long)val) ;
239 break ;
240 case 13 : /* MINSEGMENTSIZE */
241 DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
242 smc->mib.fddiESSMinSegmentSize = val ;
243 break ;
244 case 14 : /* SBACATEGORY */
245 DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
246 smc->mib.fddiESSCategory =
247 (smc->mib.fddiESSCategory & 0xffff) |
248 ((u_long)(val << 16)) ;
249 break ;
250 case 15 : /* SYNCHTXMODE */
251 /* do not use memcmp(valbuf,"ALL",3) because DS != SS */
252 if (valbuf[0] == 'A' && valbuf[1] == 'L' && valbuf[2] == 'L') {
253 smc->mib.fddiESSSynchTxMode = TRUE ;
254 DB_MAIN("SET %s = %s\n",pt->pt_name,valbuf) ;
255 }
256 /* if (!memcmp(valbuf,"SPLIT",5)) { */
257 if (valbuf[0] == 'S' && valbuf[1] == 'P' && valbuf[2] == 'L' &&
258 valbuf[3] == 'I' && valbuf[4] == 'T') {
259 DB_MAIN("SET %s = %s\n",pt->pt_name,valbuf) ;
260 smc->mib.fddiESSSynchTxMode = FALSE ;
261 }
262 break ;
263#endif
264#ifdef SBA
265 case 16 : /* SBACOMMAND */
266 /* if (!memcmp(valbuf,"START",5)) { */
267 if (valbuf[0] == 'S' && valbuf[1] == 'T' && valbuf[2] == 'A' &&
268 valbuf[3] == 'R' && valbuf[4] == 'T') {
269 DB_MAIN("SET %s = %s\n",pt->pt_name,valbuf) ;
270 smc->mib.fddiSBACommand = SB_START ;
271 }
272 /* if (!memcmp(valbuf,"STOP",4)) { */
273 if (valbuf[0] == 'S' && valbuf[1] == 'T' && valbuf[2] == 'O' &&
274 valbuf[3] == 'P') {
275 DB_MAIN("SET %s = %s\n",pt->pt_name,valbuf) ;
276 smc->mib.fddiSBACommand = SB_STOP ;
277 }
278 break ;
279 case 17 : /* SBAAVAILABLE */
280 DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
281 smc->mib.fddiSBAAvailable = (u_char) val ;
282 break ;
283#endif
284 }
285 return(0) ;
286}
287
288static int parse_word(char *buf, char _far *text)
289{
290 char c ;
291 char *p ;
292 int p_len ;
293 int quote ;
294 int i ;
295 int ok ;
296
297 /*
298 * skip leading white space
299 */
300 p = buf ;
301 for (i = 0 ; i < MAX_VAL ; i++)
302 *p++ = 0 ;
303 p = buf ;
304 p_len = 0 ;
305 ok = 0 ;
306 while ( (c = *text++) && (c != '\n') && (c != '\r')) {
307 if ((c != ' ') && (c != '\t')) {
308 ok = 1 ;
309 break ;
310 }
311 }
312 if (!ok)
313 return(-1) ;
314 if (c == '"') {
315 quote = 1 ;
316 }
317 else {
318 quote = 0 ;
319 text-- ;
320 }
321 /*
322 * parse valbuf
323 */
324 ok = 0 ;
325 while (!ok && p_len < MAX_VAL-1 && (c = *text++) && (c != '\n')
326 && (c != '\r')) {
327 switch (quote) {
328 case 0 :
329 if ((c == ' ') || (c == '\t') || (c == '=')) {
330 ok = 1 ;
331 break ;
332 }
333 *p++ = c ;
334 p_len++ ;
335 break ;
336 case 2 :
337 *p++ = c ;
338 p_len++ ;
339 quote = 1 ;
340 break ;
341 case 1 :
342 switch (c) {
343 case '"' :
344 ok = 1 ;
345 break ;
346 case '\\' :
347 quote = 2 ;
348 break ;
349 default :
350 *p++ = c ;
351 p_len++ ;
352 }
353 }
354 }
355 *p++ = 0 ;
356 for (p = buf ; (c = *p) ; p++) {
357 if (c >= 'a' && c <= 'z')
358 *p = c + 'A' - 'a' ;
359 }
360 return(0) ;
361}
362
363static u_long parse_num(int type, char _far *value, char *v, u_long mn,
364 u_long mx, int scale)
365{
366 u_long x = 0 ;
367 char c ;
368
369 if (type == 0) { /* integer */
370 u_long _far *l ;
371 u_long u1 ;
372
373 l = (u_long _far *) value ;
374 u1 = *l ;
375 /*
376 * if the value is negative take the lower limit
377 */
378 if ((long)u1 < 0) {
379 if (- ((long)u1) > (long) mx) {
380 u1 = 0 ;
381 }
382 else {
383 u1 = (u_long) - ((long)u1) ;
384 }
385 }
386 x = u1 ;
387 }
388 else { /* string */
389 int sign = 0 ;
390
391 if (*v == '-') {
392 sign = 1 ;
393 }
394 while ((c = *v++) && (c >= '0') && (c <= '9')) {
395 x = x * 10 + c - '0' ;
396 }
397 if (scale == 10) {
398 x *= 10 ;
399 if (c == '.') {
400 if ((c = *v++) && (c >= '0') && (c <= '9')) {
401 x += c - '0' ;
402 }
403 }
404 }
405 if (sign)
406 x = (u_long) - ((long)x) ;
407 }
408 /*
409 * if the value is negative
410 * and the absolute value is outside the limits
411 * take the lower limit
412 * else
413 * take the absoute value
414 */
415 if ((long)x < 0) {
416 if (- ((long)x) > (long) mx) {
417 x = 0 ;
418 }
419 else {
420 x = (u_long) - ((long)x) ;
421 }
422 }
423 if (x < mn)
424 return(mn) ;
425 else if (x > mx)
426 return(mx) ;
427 return(x) ;
428}
429
430#if 0
431struct s_smc SMC ;
432main()
433{
434 char *p ;
435 char *v ;
436 char buf[100] ;
437 int toggle = 0 ;
438
439 while (gets(buf)) {
440 p = buf ;
441 while (*p && ((*p == ' ') || (*p == '\t')))
442 p++ ;
443
444 while (*p && ((*p != ' ') && (*p != '\t')))
445 p++ ;
446
447 v = p ;
448 while (*v && ((*v == ' ') || (*v == '\t')))
449 v++ ;
450 if ((*v >= '0') && (*v <= '9')) {
451 toggle = !toggle ;
452 if (toggle) {
453 u_long l ;
454 l = atol(v) ;
455 smt_parse_arg(&SMC,buf,0,(char _far *)&l) ;
456 }
457 else
458 smt_parse_arg(&SMC,buf,1,(char _far *)p) ;
459 }
460 else {
461 smt_parse_arg(&SMC,buf,1,(char _far *)p) ;
462 }
463 }
464 exit(0) ;
465}
466#endif
467
diff --git a/drivers/net/skfp/smttimer.c b/drivers/net/skfp/smttimer.c
new file mode 100644
index 000000000000..531795e98c30
--- /dev/null
+++ b/drivers/net/skfp/smttimer.c
@@ -0,0 +1,156 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * See the file "skfddi.c" for further information.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * The information in this file is provided "AS IS" without warranty.
14 *
15 ******************************************************************************/
16
17/*
18 SMT timer
19*/
20
21#include "h/types.h"
22#include "h/fddi.h"
23#include "h/smc.h"
24
25#ifndef lint
26static const char ID_sccs[] = "@(#)smttimer.c 2.4 97/08/04 (C) SK " ;
27#endif
28
29static void timer_done(struct s_smc *smc, int restart);
30
31void smt_timer_init(struct s_smc *smc)
32{
33 smc->t.st_queue = NULL;
34 smc->t.st_fast.tm_active = FALSE ;
35 smc->t.st_fast.tm_next = NULL;
36 hwt_init(smc) ;
37}
38
39void smt_timer_stop(struct s_smc *smc, struct smt_timer *timer)
40{
41 struct smt_timer **prev ;
42 struct smt_timer *tm ;
43
44 /*
45 * remove timer from queue
46 */
47 timer->tm_active = FALSE ;
48 if (smc->t.st_queue == timer && !timer->tm_next) {
49 hwt_stop(smc) ;
50 }
51 for (prev = &smc->t.st_queue ; (tm = *prev) ; prev = &tm->tm_next ) {
52 if (tm == timer) {
53 *prev = tm->tm_next ;
54 if (tm->tm_next) {
55 tm->tm_next->tm_delta += tm->tm_delta ;
56 }
57 return ;
58 }
59 }
60}
61
62void smt_timer_start(struct s_smc *smc, struct smt_timer *timer, u_long time,
63 u_long token)
64{
65 struct smt_timer **prev ;
66 struct smt_timer *tm ;
67 u_long delta = 0 ;
68
69 time /= 16 ; /* input is uS, clock ticks are 16uS */
70 if (!time)
71 time = 1 ;
72 smt_timer_stop(smc,timer) ;
73 timer->tm_smc = smc ;
74 timer->tm_token = token ;
75 timer->tm_active = TRUE ;
76 if (!smc->t.st_queue) {
77 smc->t.st_queue = timer ;
78 timer->tm_next = NULL;
79 timer->tm_delta = time ;
80 hwt_start(smc,time) ;
81 return ;
82 }
83 /*
84 * timer correction
85 */
86 timer_done(smc,0) ;
87
88 /*
89 * find position in queue
90 */
91 delta = 0 ;
92 for (prev = &smc->t.st_queue ; (tm = *prev) ; prev = &tm->tm_next ) {
93 if (delta + tm->tm_delta > time) {
94 break ;
95 }
96 delta += tm->tm_delta ;
97 }
98 /* insert in queue */
99 *prev = timer ;
100 timer->tm_next = tm ;
101 timer->tm_delta = time - delta ;
102 if (tm)
103 tm->tm_delta -= timer->tm_delta ;
104 /*
105 * start new with first
106 */
107 hwt_start(smc,smc->t.st_queue->tm_delta) ;
108}
109
110void smt_force_irq(struct s_smc *smc)
111{
112 smt_timer_start(smc,&smc->t.st_fast,32L, EV_TOKEN(EVENT_SMT,SM_FAST));
113}
114
115void smt_timer_done(struct s_smc *smc)
116{
117 timer_done(smc,1) ;
118}
119
120static void timer_done(struct s_smc *smc, int restart)
121{
122 u_long delta ;
123 struct smt_timer *tm ;
124 struct smt_timer *next ;
125 struct smt_timer **last ;
126 int done = 0 ;
127
128 delta = hwt_read(smc) ;
129 last = &smc->t.st_queue ;
130 tm = smc->t.st_queue ;
131 while (tm && !done) {
132 if (delta >= tm->tm_delta) {
133 tm->tm_active = FALSE ;
134 delta -= tm->tm_delta ;
135 last = &tm->tm_next ;
136 tm = tm->tm_next ;
137 }
138 else {
139 tm->tm_delta -= delta ;
140 delta = 0 ;
141 done = 1 ;
142 }
143 }
144 *last = NULL;
145 next = smc->t.st_queue ;
146 smc->t.st_queue = tm ;
147
148 for ( tm = next ; tm ; tm = next) {
149 next = tm->tm_next ;
150 timer_event(smc,tm->tm_token) ;
151 }
152
153 if (restart && smc->t.st_queue)
154 hwt_start(smc,smc->t.st_queue->tm_delta) ;
155}
156
diff --git a/drivers/net/skfp/srf.c b/drivers/net/skfp/srf.c
new file mode 100644
index 000000000000..16573aca8b62
--- /dev/null
+++ b/drivers/net/skfp/srf.c
@@ -0,0 +1,429 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * See the file "skfddi.c" for further information.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * The information in this file is provided "AS IS" without warranty.
14 *
15 ******************************************************************************/
16
17/*
18 SMT 7.2 Status Response Frame Implementation
19 SRF state machine and frame generation
20*/
21
22#include "h/types.h"
23#include "h/fddi.h"
24#include "h/smc.h"
25#include "h/smt_p.h"
26
27#define KERNEL
28#include "h/smtstate.h"
29
30#ifndef SLIM_SMT
31#ifndef BOOT
32
33#ifndef lint
34static const char ID_sccs[] = "@(#)srf.c 1.18 97/08/04 (C) SK " ;
35#endif
36
37
38/*
39 * function declarations
40 */
41static void clear_all_rep(struct s_smc *smc);
42static void clear_reported(struct s_smc *smc);
43static void smt_send_srf(struct s_smc *smc);
44static struct s_srf_evc *smt_get_evc(struct s_smc *smc, int code, int index);
45
46#define MAX_EVCS (sizeof(smc->evcs)/sizeof(smc->evcs[0]))
47
48struct evc_init {
49 u_char code ;
50 u_char index ;
51 u_char n ;
52 u_short para ;
53} ;
54
55static const struct evc_init evc_inits[] = {
56 { SMT_COND_SMT_PEER_WRAP, 0,1,SMT_P1048 } ,
57
58 { SMT_COND_MAC_DUP_ADDR, INDEX_MAC, NUMMACS,SMT_P208C } ,
59 { SMT_COND_MAC_FRAME_ERROR, INDEX_MAC, NUMMACS,SMT_P208D } ,
60 { SMT_COND_MAC_NOT_COPIED, INDEX_MAC, NUMMACS,SMT_P208E } ,
61 { SMT_EVENT_MAC_NEIGHBOR_CHANGE, INDEX_MAC, NUMMACS,SMT_P208F } ,
62 { SMT_EVENT_MAC_PATH_CHANGE, INDEX_MAC, NUMMACS,SMT_P2090 } ,
63
64 { SMT_COND_PORT_LER, INDEX_PORT,NUMPHYS,SMT_P4050 } ,
65 { SMT_COND_PORT_EB_ERROR, INDEX_PORT,NUMPHYS,SMT_P4052 } ,
66 { SMT_EVENT_PORT_CONNECTION, INDEX_PORT,NUMPHYS,SMT_P4051 } ,
67 { SMT_EVENT_PORT_PATH_CHANGE, INDEX_PORT,NUMPHYS,SMT_P4053 } ,
68} ;
69
70#define MAX_INIT_EVC (sizeof(evc_inits)/sizeof(evc_inits[0]))
71
72void smt_init_evc(struct s_smc *smc)
73{
74 struct s_srf_evc *evc ;
75 const struct evc_init *init ;
76 int i ;
77 int index ;
78 int offset ;
79
80 static u_char fail_safe = FALSE ;
81
82 memset((char *)smc->evcs,0,sizeof(smc->evcs)) ;
83
84 evc = smc->evcs ;
85 init = evc_inits ;
86
87 for (i = 0 ; (unsigned) i < MAX_INIT_EVC ; i++) {
88 for (index = 0 ; index < init->n ; index++) {
89 evc->evc_code = init->code ;
90 evc->evc_para = init->para ;
91 evc->evc_index = init->index + index ;
92#ifndef DEBUG
93 evc->evc_multiple = &fail_safe ;
94 evc->evc_cond_state = &fail_safe ;
95#endif
96 evc++ ;
97 }
98 init++ ;
99 }
100
101 if ((unsigned) (evc - smc->evcs) > MAX_EVCS) {
102 SMT_PANIC(smc,SMT_E0127, SMT_E0127_MSG) ;
103 }
104
105 /*
106 * conditions
107 */
108 smc->evcs[0].evc_cond_state = &smc->mib.fddiSMTPeerWrapFlag ;
109 smc->evcs[1].evc_cond_state =
110 &smc->mib.m[MAC0].fddiMACDuplicateAddressCond ;
111 smc->evcs[2].evc_cond_state =
112 &smc->mib.m[MAC0].fddiMACFrameErrorFlag ;
113 smc->evcs[3].evc_cond_state =
114 &smc->mib.m[MAC0].fddiMACNotCopiedFlag ;
115
116 /*
117 * events
118 */
119 smc->evcs[4].evc_multiple = &smc->mib.m[MAC0].fddiMACMultiple_N ;
120 smc->evcs[5].evc_multiple = &smc->mib.m[MAC0].fddiMACMultiple_P ;
121
122 offset = 6 ;
123 for (i = 0 ; i < NUMPHYS ; i++) {
124 /*
125 * conditions
126 */
127 smc->evcs[offset + 0*NUMPHYS].evc_cond_state =
128 &smc->mib.p[i].fddiPORTLerFlag ;
129 smc->evcs[offset + 1*NUMPHYS].evc_cond_state =
130 &smc->mib.p[i].fddiPORTEB_Condition ;
131
132 /*
133 * events
134 */
135 smc->evcs[offset + 2*NUMPHYS].evc_multiple =
136 &smc->mib.p[i].fddiPORTMultiple_U ;
137 smc->evcs[offset + 3*NUMPHYS].evc_multiple =
138 &smc->mib.p[i].fddiPORTMultiple_P ;
139 offset++ ;
140 }
141#ifdef DEBUG
142 for (i = 0, evc = smc->evcs ; (unsigned) i < MAX_EVCS ; i++, evc++) {
143 if (SMT_IS_CONDITION(evc->evc_code)) {
144 if (!evc->evc_cond_state) {
145 SMT_PANIC(smc,SMT_E0128, SMT_E0128_MSG) ;
146 }
147 evc->evc_multiple = &fail_safe ;
148 }
149 else {
150 if (!evc->evc_multiple) {
151 SMT_PANIC(smc,SMT_E0129, SMT_E0129_MSG) ;
152 }
153 evc->evc_cond_state = &fail_safe ;
154 }
155 }
156#endif
157 smc->srf.TSR = smt_get_time() ;
158 smc->srf.sr_state = SR0_WAIT ;
159}
160
161static struct s_srf_evc *smt_get_evc(struct s_smc *smc, int code, int index)
162{
163 int i ;
164 struct s_srf_evc *evc ;
165
166 for (i = 0, evc = smc->evcs ; (unsigned) i < MAX_EVCS ; i++, evc++) {
167 if (evc->evc_code == code && evc->evc_index == index)
168 return(evc) ;
169 }
170 return NULL;
171}
172
173#define THRESHOLD_2 (2*TICKS_PER_SECOND)
174#define THRESHOLD_32 (32*TICKS_PER_SECOND)
175
176#ifdef DEBUG
177static const char * const srf_names[] = {
178 "None","MACPathChangeEvent", "MACNeighborChangeEvent",
179 "PORTPathChangeEvent", "PORTUndesiredConnectionAttemptEvent",
180 "SMTPeerWrapCondition", "SMTHoldCondition",
181 "MACFrameErrorCondition", "MACDuplicateAddressCondition",
182 "MACNotCopiedCondition", "PORTEBErrorCondition",
183 "PORTLerCondition"
184} ;
185#endif
186
187void smt_srf_event(struct s_smc *smc, int code, int index, int cond)
188{
189 struct s_srf_evc *evc ;
190 int cond_asserted = 0 ;
191 int cond_deasserted = 0 ;
192 int event_occurred = 0 ;
193 int tsr ;
194 int T_Limit = 2*TICKS_PER_SECOND ;
195
196 if (code == SMT_COND_MAC_DUP_ADDR && cond) {
197 RS_SET(smc,RS_DUPADDR) ;
198 }
199
200 if (code) {
201 DB_SMT("SRF: %s index %d\n",srf_names[code],index) ;
202
203 if (!(evc = smt_get_evc(smc,code,index))) {
204 DB_SMT("SRF : smt_get_evc() failed\n",0,0) ;
205 return ;
206 }
207 /*
208 * ignore condition if no change
209 */
210 if (SMT_IS_CONDITION(code)) {
211 if (*evc->evc_cond_state == cond)
212 return ;
213 }
214
215 /*
216 * set transition time stamp
217 */
218 smt_set_timestamp(smc,smc->mib.fddiSMTTransitionTimeStamp) ;
219 if (SMT_IS_CONDITION(code)) {
220 DB_SMT("SRF: condition is %s\n",cond ? "ON":"OFF",0) ;
221 if (cond) {
222 *evc->evc_cond_state = TRUE ;
223 evc->evc_rep_required = TRUE ;
224 smc->srf.any_report = TRUE ;
225 cond_asserted = TRUE ;
226 }
227 else {
228 *evc->evc_cond_state = FALSE ;
229 cond_deasserted = TRUE ;
230 }
231 }
232 else {
233 if (evc->evc_rep_required) {
234 *evc->evc_multiple = TRUE ;
235 }
236 else {
237 evc->evc_rep_required = TRUE ;
238 *evc->evc_multiple = FALSE ;
239 }
240 smc->srf.any_report = TRUE ;
241 event_occurred = TRUE ;
242 }
243#ifdef FDDI_MIB
244 snmp_srf_event(smc,evc) ;
245#endif /* FDDI_MIB */
246 }
247 tsr = smt_get_time() - smc->srf.TSR ;
248
249 switch (smc->srf.sr_state) {
250 case SR0_WAIT :
251 /* SR01a */
252 if (cond_asserted && tsr < T_Limit) {
253 smc->srf.SRThreshold = THRESHOLD_2 ;
254 smc->srf.sr_state = SR1_HOLDOFF ;
255 break ;
256 }
257 /* SR01b */
258 if (cond_deasserted && tsr < T_Limit) {
259 smc->srf.sr_state = SR1_HOLDOFF ;
260 break ;
261 }
262 /* SR01c */
263 if (event_occurred && tsr < T_Limit) {
264 smc->srf.sr_state = SR1_HOLDOFF ;
265 break ;
266 }
267 /* SR00b */
268 if (cond_asserted && tsr >= T_Limit) {
269 smc->srf.SRThreshold = THRESHOLD_2 ;
270 smc->srf.TSR = smt_get_time() ;
271 smt_send_srf(smc) ;
272 break ;
273 }
274 /* SR00c */
275 if (cond_deasserted && tsr >= T_Limit) {
276 smc->srf.TSR = smt_get_time() ;
277 smt_send_srf(smc) ;
278 break ;
279 }
280 /* SR00d */
281 if (event_occurred && tsr >= T_Limit) {
282 smc->srf.TSR = smt_get_time() ;
283 smt_send_srf(smc) ;
284 break ;
285 }
286 /* SR00e */
287 if (smc->srf.any_report && (u_long) tsr >=
288 smc->srf.SRThreshold) {
289 smc->srf.SRThreshold *= 2 ;
290 if (smc->srf.SRThreshold > THRESHOLD_32)
291 smc->srf.SRThreshold = THRESHOLD_32 ;
292 smc->srf.TSR = smt_get_time() ;
293 smt_send_srf(smc) ;
294 break ;
295 }
296 /* SR02 */
297 if (!smc->mib.fddiSMTStatRptPolicy) {
298 smc->srf.sr_state = SR2_DISABLED ;
299 break ;
300 }
301 break ;
302 case SR1_HOLDOFF :
303 /* SR10b */
304 if (tsr >= T_Limit) {
305 smc->srf.sr_state = SR0_WAIT ;
306 smc->srf.TSR = smt_get_time() ;
307 smt_send_srf(smc) ;
308 break ;
309 }
310 /* SR11a */
311 if (cond_asserted) {
312 smc->srf.SRThreshold = THRESHOLD_2 ;
313 }
314 /* SR11b */
315 /* SR11c */
316 /* handled above */
317 /* SR12 */
318 if (!smc->mib.fddiSMTStatRptPolicy) {
319 smc->srf.sr_state = SR2_DISABLED ;
320 break ;
321 }
322 break ;
323 case SR2_DISABLED :
324 if (smc->mib.fddiSMTStatRptPolicy) {
325 smc->srf.sr_state = SR0_WAIT ;
326 smc->srf.TSR = smt_get_time() ;
327 smc->srf.SRThreshold = THRESHOLD_2 ;
328 clear_all_rep(smc) ;
329 break ;
330 }
331 break ;
332 }
333}
334
335static void clear_all_rep(struct s_smc *smc)
336{
337 struct s_srf_evc *evc ;
338 int i ;
339
340 for (i = 0, evc = smc->evcs ; (unsigned) i < MAX_EVCS ; i++, evc++) {
341 evc->evc_rep_required = FALSE ;
342 if (SMT_IS_CONDITION(evc->evc_code))
343 *evc->evc_cond_state = FALSE ;
344 }
345 smc->srf.any_report = FALSE ;
346}
347
348static void clear_reported(struct s_smc *smc)
349{
350 struct s_srf_evc *evc ;
351 int i ;
352
353 smc->srf.any_report = FALSE ;
354 for (i = 0, evc = smc->evcs ; (unsigned) i < MAX_EVCS ; i++, evc++) {
355 if (SMT_IS_CONDITION(evc->evc_code)) {
356 if (*evc->evc_cond_state == FALSE)
357 evc->evc_rep_required = FALSE ;
358 else
359 smc->srf.any_report = TRUE ;
360 }
361 else {
362 evc->evc_rep_required = FALSE ;
363 *evc->evc_multiple = FALSE ;
364 }
365 }
366}
367
368/*
369 * build and send SMT SRF frame
370 */
371static void smt_send_srf(struct s_smc *smc)
372{
373
374 struct smt_header *smt ;
375 struct s_srf_evc *evc ;
376 SK_LOC_DECL(struct s_pcon,pcon) ;
377 SMbuf *mb ;
378 int i ;
379
380 static const struct fddi_addr SMT_SRF_DA = {
381 { 0x80, 0x01, 0x43, 0x00, 0x80, 0x08 }
382 } ;
383
384 /*
385 * build SMT header
386 */
387 if (!smc->r.sm_ma_avail)
388 return ;
389 if (!(mb = smt_build_frame(smc,SMT_SRF,SMT_ANNOUNCE,0)))
390 return ;
391
392 RS_SET(smc,RS_SOFTERROR) ;
393
394 smt = smtod(mb, struct smt_header *) ;
395 smt->smt_dest = SMT_SRF_DA ; /* DA == SRF multicast */
396
397 /*
398 * setup parameter status
399 */
400 pcon.pc_len = SMT_MAX_INFO_LEN ; /* max para length */
401 pcon.pc_err = 0 ; /* no error */
402 pcon.pc_badset = 0 ; /* no bad set count */
403 pcon.pc_p = (void *) (smt + 1) ; /* paras start here */
404
405 smt_add_para(smc,&pcon,(u_short) SMT_P1033,0,0) ;
406 smt_add_para(smc,&pcon,(u_short) SMT_P1034,0,0) ;
407
408 for (i = 0, evc = smc->evcs ; (unsigned) i < MAX_EVCS ; i++, evc++) {
409 if (evc->evc_rep_required) {
410 smt_add_para(smc,&pcon,evc->evc_para,
411 (int)evc->evc_index,0) ;
412 }
413 }
414 smt->smt_len = SMT_MAX_INFO_LEN - pcon.pc_len ;
415 mb->sm_len = smt->smt_len + sizeof(struct smt_header) ;
416
417 DB_SMT("SRF: sending SRF at %x, len %d \n",smt,mb->sm_len) ;
418 DB_SMT("SRF: state SR%d Threshold %d\n",
419 smc->srf.sr_state,smc->srf.SRThreshold/TICKS_PER_SECOND) ;
420#ifdef DEBUG
421 dump_smt(smc,smt,"SRF Send") ;
422#endif
423 smt_send_frame(smc,mb,FC_SMT_INFO,0) ;
424 clear_reported(smc) ;
425}
426
427#endif /* no BOOT */
428#endif /* no SLIM_SMT */
429