Initial import from FreeBSD RELENG_4:
[dragonfly.git] / sys / net / i4b / layer1 / isic / i4b_siemens_isurf.c
1 /*
2  *   Copyright (c) 1999, 2000 Udo Schweigert. All rights reserved.
3  *
4  *   Redistribution and use in source and binary forms, with or without
5  *   modification, are permitted provided that the following conditions
6  *   are met:
7  *
8  *   1. Redistributions of source code must retain the above copyright
9  *      notice, this list of conditions and the following disclaimer.
10  *   2. Redistributions in binary form must reproduce the above copyright
11  *      notice, this list of conditions and the following disclaimer in the
12  *      documentation and/or other materials provided with the distribution.
13  *   3. Neither the name of the author nor the names of any co-contributors
14  *      may be used to endorse or promote products derived from this software
15  *      without specific prior written permission.
16  *   4. Altered versions must be plainly marked as such, and must not be
17  *      misrepresented as being the original software and/or documentation.
18  *   
19  *   THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20  *   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  *   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  *   ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23  *   FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  *   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  *   OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  *   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  *   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  *   OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  *   SUCH DAMAGE.
30  *
31  *---------------------------------------------------------------------------
32   *
33  *      Siemens I-Surf 2.0 PnP specific routines for isic driver
34  *      --------------------------------------------------------
35  *
36  *      Based on ELSA Quickstep 1000pro PCI driver (i4b_elsa_qs1p.c)
37  *      In case of trouble please contact Udo Schweigert <ust@cert.siemens.de>
38  
39  * $FreeBSD: src/sys/i4b/layer1/isic/i4b_siemens_isurf.c,v 1.5.2.1 2001/08/10 14:08:38 obrien Exp $
40  *
41  *      last edit-date: [Wed Jan 24 09:13:25 2001]
42  *
43  *---------------------------------------------------------------------------*/
44
45 #include "isic.h"
46 #include "opt_i4b.h"
47
48 #if NISIC > 0 && defined(SIEMENS_ISURF2)
49
50 #include <sys/param.h>
51 #include <sys/systm.h>
52 #include <sys/socket.h>
53
54 #include <net/if.h>
55
56 #include <machine/i4b_ioctl.h>
57
58 #include <i4b/layer1/isic/i4b_isic.h>
59 #include <i4b/layer1/isic/i4b_ipac.h>
60
61 /* masks for register encoded in base addr */
62
63 #define SIE_ISURF_BASE_MASK             0x0ffff
64 #define SIE_ISURF_OFF_MASK              0xf0000
65
66 /* register id's to be encoded in base addr */
67
68 #define SIE_ISURF_IDISAC                0x00000
69 #define SIE_ISURF_IDHSCXA               0x10000
70 #define SIE_ISURF_IDHSCXB               0x20000
71 #define SIE_ISURF_IDIPAC                0x40000
72
73 /* offsets from base address */
74
75 #define SIE_ISURF_OFF_ALE               0x00
76 #define SIE_ISURF_OFF_RW                0x01
77
78 /*---------------------------------------------------------------------------*
79  *      Siemens I-Surf 2.0 PnP ISAC get fifo routine
80  *---------------------------------------------------------------------------*/
81 static void 
82 siemens_isurf_read_fifo(struct l1_softc *sc,int what,void *buf,size_t size)
83 {
84         bus_space_tag_t    t = rman_get_bustag(sc->sc_resources.io_base[0]);
85         bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
86
87         switch ( what )
88         {
89                 case ISIC_WHAT_ISAC:
90                         bus_space_write_1(t,h,SIE_ISURF_OFF_ALE,IPAC_ISAC_OFF);
91                         bus_space_read_multi_1(t,h,SIE_ISURF_OFF_RW,buf,size);
92                         break;
93                 case ISIC_WHAT_HSCXA:
94                         bus_space_write_1(t,h,SIE_ISURF_OFF_ALE,IPAC_HSCXA_OFF);
95                         bus_space_read_multi_1(t,h,SIE_ISURF_OFF_RW,buf,size);
96                         break;
97                 case ISIC_WHAT_HSCXB:
98                         bus_space_write_1(t,h,SIE_ISURF_OFF_ALE,IPAC_HSCXB_OFF);
99                         bus_space_read_multi_1(t,h,SIE_ISURF_OFF_RW,buf,size);
100                         break;
101         }
102 }
103
104 /*---------------------------------------------------------------------------*
105  *      Siemens I-Surf 2.0 PnP ISAC put fifo routine
106  *---------------------------------------------------------------------------*/
107 static void 
108 siemens_isurf_write_fifo(struct l1_softc *sc,int what,void *buf,size_t size)
109 {
110         bus_space_tag_t    t = rman_get_bustag(sc->sc_resources.io_base[0]);
111         bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
112
113         switch ( what )
114         {
115                 case ISIC_WHAT_ISAC:
116                         bus_space_write_1(t,h,SIE_ISURF_OFF_ALE,IPAC_ISAC_OFF);
117                         bus_space_write_multi_1(t,h,SIE_ISURF_OFF_RW,buf,size);
118                         break;
119                 case ISIC_WHAT_HSCXA:
120                         bus_space_write_1(t,h,SIE_ISURF_OFF_ALE,IPAC_HSCXA_OFF);
121                         bus_space_write_multi_1(t,h,SIE_ISURF_OFF_RW,buf,size);
122                         break;
123                 case ISIC_WHAT_HSCXB:
124                         bus_space_write_1(t,h,SIE_ISURF_OFF_ALE,IPAC_HSCXB_OFF);
125                         bus_space_write_multi_1(t,h,SIE_ISURF_OFF_RW,buf,size);
126                         break;
127         }
128 }
129
130 /*---------------------------------------------------------------------------*
131  *      Siemens I-Surf 2.0 PnP ISAC put register routine
132  *---------------------------------------------------------------------------*/
133 static void
134 siemens_isurf_write_reg(struct l1_softc *sc,int what,bus_size_t reg,u_int8_t data)
135 {
136         bus_space_tag_t    t = rman_get_bustag(sc->sc_resources.io_base[0]);
137         bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
138
139         switch ( what )
140         {
141                 case ISIC_WHAT_ISAC:
142                         bus_space_write_1(t,h,SIE_ISURF_OFF_ALE,reg+IPAC_ISAC_OFF);
143                         bus_space_write_1(t,h,SIE_ISURF_OFF_RW,data);
144                         break;
145                 case ISIC_WHAT_HSCXA:
146                         bus_space_write_1(t,h,SIE_ISURF_OFF_ALE,reg+IPAC_HSCXA_OFF);
147                         bus_space_write_1(t,h,SIE_ISURF_OFF_RW,data);
148                         break;
149                 case ISIC_WHAT_HSCXB:
150                         bus_space_write_1(t,h,SIE_ISURF_OFF_ALE,reg+IPAC_HSCXB_OFF);
151                         bus_space_write_1(t,h,SIE_ISURF_OFF_RW,data);
152                         break;
153                 case ISIC_WHAT_IPAC:
154                         bus_space_write_1(t,h,SIE_ISURF_OFF_ALE,reg+IPAC_IPAC_OFF);
155                         bus_space_write_1(t,h,SIE_ISURF_OFF_RW,data);
156                         break;
157         }
158 }
159
160 /*---------------------------------------------------------------------------*
161  *      Siemens I-Surf 2.0 PnP ISAC get register routine
162  *---------------------------------------------------------------------------*/
163 static u_int8_t
164 siemens_isurf_read_reg(struct l1_softc *sc,int what,bus_size_t reg)
165 {
166         bus_space_tag_t    t = rman_get_bustag(sc->sc_resources.io_base[0]);
167         bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
168
169         switch ( what )
170         {
171                 case ISIC_WHAT_ISAC:
172                         bus_space_write_1(t,h,SIE_ISURF_OFF_ALE,reg+IPAC_ISAC_OFF);
173                         return bus_space_read_1(t,h,SIE_ISURF_OFF_RW);
174                 case ISIC_WHAT_HSCXA:
175                         bus_space_write_1(t,h,SIE_ISURF_OFF_ALE,reg+IPAC_HSCXA_OFF);
176                         return bus_space_read_1(t,h,SIE_ISURF_OFF_RW);
177                 case ISIC_WHAT_HSCXB:
178                         bus_space_write_1(t,h,SIE_ISURF_OFF_ALE,reg+IPAC_HSCXB_OFF);
179                         return bus_space_read_1(t,h,SIE_ISURF_OFF_RW);
180                 case ISIC_WHAT_IPAC:
181                         bus_space_write_1(t,h,SIE_ISURF_OFF_ALE,reg+IPAC_IPAC_OFF);
182                         return bus_space_read_1(t,h,SIE_ISURF_OFF_RW);
183                 default:
184                         return 0;
185         }
186 }
187
188 /*---------------------------------------------------------------------------*
189  *      isic_attach_siemens_isurf - attach for Siemens I-Surf 2.0 PnP
190  *---------------------------------------------------------------------------*/
191 int
192 isic_attach_siemens_isurf(device_t dev)
193 {
194         int unit = device_get_unit(dev);
195         struct l1_softc *sc = &l1_sc[unit];     
196         
197         /* setup access routines */
198
199         sc->clearirq = NULL;
200         sc->readreg = siemens_isurf_read_reg;
201         sc->writereg = siemens_isurf_write_reg;
202
203         sc->readfifo = siemens_isurf_read_fifo;
204         sc->writefifo = siemens_isurf_write_fifo;
205
206         /* setup card type */
207         
208         sc->sc_cardtyp = CARD_TYPEP_SIE_ISURF2;
209
210         /* setup IOM bus type */
211         
212         sc->sc_bustyp = BUS_TYPE_IOM2;
213
214         /* setup chip type = IPAC ! */
215         
216         sc->sc_ipac = 1;
217         sc->sc_bfifolen = IPAC_BFIFO_LEN;
218
219         /* enable hscx/isac irq's */
220
221         IPAC_WRITE(IPAC_MASK, (IPAC_MASK_INT1 | IPAC_MASK_INT0));
222
223         IPAC_WRITE(IPAC_ACFG, 0);       /* outputs are open drain */
224         IPAC_WRITE(IPAC_AOE,            /* aux 5..2 are inputs, 7, 6 outputs */
225                 (IPAC_AOE_OE5 | IPAC_AOE_OE4 | IPAC_AOE_OE3 | IPAC_AOE_OE2));
226         IPAC_WRITE(IPAC_ATX, 0xff);     /* set all output lines high */
227
228         return(0);
229 }
230 #endif /* NISIC > 0 && defined(SIEMENS_ISURF2) */