1 /* -*- linux-c -*- */
2 /*
3  * Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version
8  * 2 of the License, or (at your option) any later version.
9  *
10  **/
11 
12 #include <linux/module.h>
13 #include <linux/kernel.h>
14 #include <linux/pci.h>
15 #include <linux/stddef.h>
16 #include <linux/string.h>
17 #include <linux/sockios.h>
18 #include <asm/io.h>
19 #include <asm/byteorder.h>
20 #include <asm/pgtable.h>
21 #include <linux/skbuff.h>
22 #include <linux/if_arp.h>
23 #include <linux/fs.h>
24 #include <linux/sched.h>
25 #include <asm/uaccess.h>
26 #include <linux/version.h>
27 #include <linux/etherdevice.h>
28 #include "Reg9050.h"
29 #include "8253xctl.h"
30 #include "ring.h"
31 #include "8253x.h"
32 #include "crc32dcl.h"
33 #include "8253xmcs.h"
34 #include "sp502.h"
35 
36 /* Just to guarantee that strings are null terminated */
37 #define MEMCPY(dest, src, cnt) \
38 { \
39 	memcpy((dest), (src), (cnt)); \
40 	(dest)[cnt] = 0; \
41 }
42 
43 static unsigned char sp502progbyte[] =
44 {
45 	SP502_OFF,
46 	SP502_RS232,
47 	SP502_RS422,
48 	SP502_RS485,
49 	SP502_RS449,
50 	SP502_EIA530,
51 	SP502_V35
52 };
53 
54 /*
55  * The following routines are the multichannel server I2C serial EPROM routines.
56  */
57 
58 /*
59  * Set the clock and the data lines of the SEP.
60  */
61 static void
mcs_sep_set(mcs_sep_t * msp,unsigned sdavalid,unsigned sda,unsigned sclvalid,unsigned scl)62 mcs_sep_set(mcs_sep_t *msp, unsigned sdavalid, unsigned sda,
63 	    unsigned sclvalid, unsigned scl)
64 {
65 #ifdef MAX
66 #undef MAX
67 #endif		/* MAX */
68 
69 #define MAX(x, y)	((x) > (y) ? (x) : (y))
70 
71 	unsigned char csr;
72 	unsigned int sleeptime;
73 
74 	/*
75 	 * Ensure sufficient clock
76 	 */
77 
78 	sleeptime = 0;
79 
80 	if (sclvalid)
81 	{
82 		if (msp->s_scl && !scl)
83 		{   /* do we have a downgoing transition? */
84 			sleeptime = MAX(1, sleeptime);
85 		}
86 		else if (!msp->s_scl && scl)
87 		{	/* upgoing */
88 			sleeptime = MAX(2, sleeptime);
89 		}
90 		msp->s_scl = scl;
91 	}
92 
93 	if (sdavalid)
94 	{
95 		if ((msp->s_sda && !sda) || (!msp->s_sda && sda))
96 		{
97 			sleeptime = MAX(1, sleeptime);
98 		}
99 
100 		msp->s_sda = sda;
101 	}
102 
103 	if (sleeptime > 0)
104 	{
105 		udelay(sleeptime);
106 	}
107 
108 	/*
109 	 * Construct the CSR byte.
110 	 */
111 	csr = 0;
112 	if (msp->s_sda)
113 	{
114 		csr |= CIMCMD_CIMCSR_SDA;
115 	}
116 
117 	if (msp->s_scl)
118 	{
119 		csr |= CIMCMD_CIMCSR_SCL;
120 	}
121 
122 	writeb((unsigned char) csr, msp->s_wrptr);
123 }
124 
125 static void
mcs_sep_start(mcs_sep_t * msp)126 mcs_sep_start(mcs_sep_t *msp)
127 {
128 	/*
129 	 * Generate a START condition
130 	 */
131 	mcs_sep_set(msp, TRUE, TRUE, TRUE, TRUE);
132 	mcs_sep_set(msp, TRUE, FALSE, TRUE, TRUE);
133 }
134 
135 static void
mcs_sep_stop(mcs_sep_t * msp)136 mcs_sep_stop(mcs_sep_t *msp)
137 {
138 	/*
139 	 * Generate a STOP condition
140 	 */
141 	mcs_sep_set(msp, TRUE, FALSE, TRUE, TRUE);
142 	mcs_sep_set(msp, TRUE, TRUE, TRUE, TRUE);
143 }
144 
145 /*
146  * Send out a single byte.
147  */
148 static void
mcs_sep_byte(mcs_sep_t * msp,unsigned char val)149 mcs_sep_byte(mcs_sep_t *msp, unsigned char val)
150 {
151 	register int	 bitcount;
152 
153 	/* Clock may be high ... lower the clock */
154 	mcs_sep_set(msp, TRUE, FALSE, TRUE, FALSE);
155 
156 	bitcount = 8;
157 
158 	while (TRUE)
159 	{
160 		mcs_sep_set(msp, TRUE, (val & 0x80) != 0, TRUE, FALSE);
161 		mcs_sep_set(msp, TRUE, (val & 0x80) != 0, TRUE, TRUE);
162 
163 		bitcount--;
164 		if (bitcount == 0)
165 		{
166 			break;
167 		}
168 		val <<= 1;
169 	}
170 
171 	/* Clock is high ... lower the clock */
172 	mcs_sep_set(msp, FALSE, FALSE, TRUE, FALSE);
173 }
174 
175 /*
176  * Wait for an acknowledge cycle.  Expects the clock to be low.
177  */
178 static unsigned
mcs_sep_waitsep(mcs_sep_t * msp)179 mcs_sep_waitsep(mcs_sep_t *msp)
180 {
181 	int loopcount;
182 	unsigned char cimcsr;
183 
184 	/* Stop driving SDA */
185 	mcs_sep_set(msp, TRUE, TRUE, FALSE, FALSE);
186 	/* Raise the clock */
187 	mcs_sep_set(msp, FALSE, FALSE, TRUE, TRUE);
188 
189 	loopcount = 1000;
190 	while (loopcount != 0)
191 	{
192 		cimcsr = readb(msp->s_rdptr);
193 
194 		if ((cimcsr & CIMCMD_CIMCSR_SDA) == 0)
195 		{
196 			break;
197 		}
198 		loopcount--;
199 	}
200 
201 	/* Lower the clock */
202 	mcs_sep_set(msp, FALSE, FALSE, TRUE, FALSE);
203 
204 	if (loopcount == 0)
205 	{
206 		return FALSE;
207 	}
208 	else
209 	{
210 		return TRUE;
211 	}
212 }
213 
214 /*
215  * Read the given CIM's SEP, starting at the given address, into
216  *  the given buffer, for the given length.
217  *
218  * Returns -1 if there was a failure, otherwise the byte count.
219  */
220 
221 static int
mcs_sep_read(mcs_sep_t * msp,unsigned short addr,unsigned char * buf,unsigned int nbytes)222 mcs_sep_read(mcs_sep_t *msp, unsigned short addr,
223 	     unsigned char *buf, unsigned int nbytes)
224 {
225 	unsigned char cmdaddr, val, cimcsr;
226 	unsigned int bytecount, bitcount;
227 
228 	mcs_sep_start(msp);
229 
230 	/*
231 	 * First, send out a dummy WRITE command with no data.
232 	 */
233 
234 	cmdaddr = 0xa0 | (((addr >> 8) & 0x7) << 1) | 0x0;
235 
236 	mcs_sep_byte(msp, cmdaddr);
237 
238 	if (!mcs_sep_waitsep(msp))
239 	{
240 		return -1;
241 	}
242 
243 	/*
244 	 * Now, send the reset of the address.
245 	 */
246 
247 	mcs_sep_byte(msp, (unsigned char) addr);
248 
249 	if (!mcs_sep_waitsep(msp))
250 	{
251 		return -1;
252 	}
253 
254 	/*
255 	 * Now, restart with a read command.
256 	 */
257 
258 	mcs_sep_start(msp);
259 
260 	cmdaddr = 0xa0 | (((addr >> 8) & 0x7) << 1) | 0x1;
261 
262 	mcs_sep_byte(msp, cmdaddr);
263 
264 	if (!mcs_sep_waitsep(msp))
265 	{
266 		return -1;
267 	}
268 
269 	/*
270 	 * Now, start reading the bytes.
271 	 */
272 	bytecount = 0;
273 	while (TRUE)
274 	{
275 		bitcount = 8;
276 		val = 0;
277 		while (TRUE)
278 		{
279 			mcs_sep_set(msp, TRUE, TRUE, TRUE, TRUE);
280 
281 			cimcsr = readb(msp->s_rdptr);
282 
283 			if ((cimcsr & CIMCMD_CIMCSR_SDA) != 0)
284 			{
285 				val |= 0x01;
286 			}
287 
288 			mcs_sep_set(msp, FALSE, FALSE, TRUE, FALSE);
289 			bitcount--;
290 
291 			if (bitcount == 0)
292 			{
293 				break;
294 			}
295 			val <<= 1;
296 		}
297 
298 		*buf++ = val;
299 		bytecount++;
300 		nbytes--;
301 
302 		if (nbytes == 0)
303 		{
304 			break;
305 		}
306 
307 		/*
308 		 * Send the acknowledge.
309 		 */
310 
311 		mcs_sep_set(msp, FALSE, FALSE, TRUE, FALSE);
312 		mcs_sep_set(msp, TRUE, FALSE, TRUE, TRUE);
313 		mcs_sep_set(msp, FALSE, FALSE, TRUE, FALSE);
314 	}
315 
316 	mcs_sep_stop(msp);
317 
318 	return (int) bytecount;
319 }
320 
321 
mcs_ciminit(SAB_BOARD * bptr,AURA_CIM * cim)322 unsigned int mcs_ciminit(SAB_BOARD *bptr, AURA_CIM *cim)
323 {
324 	mcs_sep_t		 ms;
325 
326 	ms.s_rdptr = (unsigned char *)
327 		(bptr->CIMCMD_REG + (CIMCMD_RDCIMCSR | (cim->ci_num << CIMCMD_CIMSHIFT)));
328 	ms.s_wrptr = (unsigned char *)
329 		(bptr->CIMCMD_REG + (CIMCMD_WRCIMCSR | (cim->ci_num << CIMCMD_CIMSHIFT)));
330 	ms.s_scl = ms.s_sda = FALSE;
331 
332 	if (mcs_sep_read(&ms, (unsigned short) 0, &(cim->ci_sep[0]),
333 			 sizeof(cim->ci_sep)) != sizeof(cim->ci_sep)
334 	    || cim->ci_sep[MCS_SEP_MAGIC] != MCS_SEP_MAGICVAL)
335 	{
336 
337 		if (cim->ci_sep[MCS_SEP_MAGIC] != MCS_SEP_MAGICVAL)
338 		{
339 			DEBUGPRINT((KERN_ALERT
340 				    "auraXX20: invalid CIM %d serial EPROM on board %d",
341 				    cim->ci_num, bptr->board_number));
342 		}
343 		else
344 		{
345 			DEBUGPRINT((KERN_ALERT
346 				    "auraXX20: error reading CIM %d serial EPROM on board %d",
347 				    cim->ci_num, bptr->board_number));
348 		}
349 
350 		cim->ci_clkspeed = WANMCS_CLKSPEED;
351 		cim->ci_clkspdsrc = -1;
352 		cim->ci_spdgrd = 10;
353 		cim->ci_spdgrdsrc = -1;
354 		cim->ci_flags = 0;
355 		cim->ci_rev[0] = '\0';
356 		cim->ci_sn[0] = '\0';
357 		cim->ci_mfgdate[0] = '\0';
358 		cim->ci_mfgloc[0] = '\0';
359 
360 		/*
361 		 * Diddle the port setup registers to determine if this
362 		 *  CIM was built up for RS232 or SP502.
363 		 */
364 
365 		writew((unsigned short) 0xffff, (unsigned short *)
366 		       (bptr->CIMCMD_REG +
367 			(CIMCMD_WRSETUP | (cim->ci_num << CIMCMD_CIMSHIFT))));
368 
369 #ifdef RICHARD_DELAY
370 		udelay(1);
371 #endif		/* RICHARD_DELAY */
372 
373 		if (readw((unsigned short *)
374 			  (bptr->CIMCMD_REG +
375 			   (CIMCMD_RDSETUP | (cim->ci_num << CIMCMD_CIMSHIFT)))) == 0xffff)
376 		{
377 
378 			writew(0, (unsigned short *)
379 			       (bptr->CIMCMD_REG +
380 				(CIMCMD_WRSETUP | (cim->ci_num << CIMCMD_CIMSHIFT))));
381 
382 #ifdef RICHARD_DELAY
383 			udelay(1);
384 #endif		/* RICHARD_DELAY */
385 
386 			if (readw((unsigned short *)
387 				  (bptr->CIMCMD_REG +
388 				   (CIMCMD_RDSETUP | (cim->ci_num << CIMCMD_CIMSHIFT)))) == 0)
389 			{
390 
391 				cim->ci_type = CIM_SP502;
392 			}
393 			else
394 			{
395 				cim->ci_type = CIM_RS232;
396 			}
397 		}
398 		else
399 		{
400 			cim->ci_type = CIM_RS232;
401 		}
402 
403 		if (cim->ci_type == CIM_SP502)
404 		{
405 			cim->ci_flags |= CIM_SYNC;
406 		}
407 	}
408 	else
409 	{
410 		/*
411 		 * Pick through the serial EPROM contents and derive
412 		 *  the values we need.
413 		 */
414 		MEMCPY(&(cim->ci_rev[0]), &(cim->ci_sep[MCS_SEP_REV]),
415 		       MCS_SEP_REVLEN);
416 		MEMCPY(&(cim->ci_sn[0]), &(cim->ci_sep[MCS_SEP_SN]),
417 		       MCS_SEP_SNLEN);
418 		MEMCPY(&(cim->ci_mfgdate[0]), &(cim->ci_sep[MCS_SEP_MFGDATE]),
419 		       MCS_SEP_MFGDATELEN);
420 		MEMCPY(&(cim->ci_mfgloc[0]), &(cim->ci_sep[MCS_SEP_MFGLOC]),
421 		       MCS_SEP_MFGLOCLEN);
422 
423 		cim->ci_clkspeed = (unsigned long) cim->ci_sep[MCS_SEP_CLKSPD]
424 			| ((unsigned long) cim->ci_sep[MCS_SEP_CLKSPD + 1] << 8)
425 			| ((unsigned long) cim->ci_sep[MCS_SEP_CLKSPD + 2] << 16)
426 			| ((unsigned long) cim->ci_sep[MCS_SEP_CLKSPD + 3] << 24);
427 
428 		cim->ci_clkspdsrc = SEPROM;
429 
430 		cim->ci_spdgrd = (int) cim->ci_sep[MCS_SEP_SPDGRD];
431 		cim->ci_spdgrdsrc = SEPROM;
432 
433 		cim->ci_flags = (unsigned long) cim->ci_sep[MCS_SEP_FLAGS];
434 
435 		cim->ci_type = (int) cim->ci_sep[MCS_SEP_TYPE];
436 	}
437 
438 	/*
439 	 * Possibly initialize the port setup registers.
440 	 */
441 
442 	if (cim->ci_type == CIM_SP502)
443 	{
444 		unsigned short alloff;
445 #ifdef DEBUG_VERBOSE
446 		unsigned short readback;
447 #endif
448 		int offset;
449 
450 		/*
451 		 * Turn off all of the electrical interfaces.  The
452 		 *  hardware *should* initialize to this state, but the
453 		 *  prototype, at least, does not.  Note that this setting
454 		 *  is reflected in the SIF_OFF setting of l_interface in
455 		 *  mustard_lineinit, above.
456 		 */
457 
458 		alloff = (unsigned short) SP502_OFF
459 			| ((unsigned short) SP502_OFF << 4)
460 			| ((unsigned short) SP502_OFF << 8)
461 			| ((unsigned short) SP502_OFF << 12);
462 		for (offset = 0; offset < 8; offset++)
463 		{
464 #ifdef DEBUG_VERBOSE
465 			DEBUGPRINT((KERN_ALERT "cim %d setup reg #%d: writing 0x%x to 0x%x",
466 				    cim->ci_num, offset, (unsigned) alloff,
467 				    (CIMCMD_WRSETUP | (offset << 1) |
468 				     (cim->ci_num << CIMCMD_CIMSHIFT))));
469 #endif		 /* DEBUG_VERBOSE */
470 
471 			writew((unsigned short) alloff, (unsigned short *)
472 			       (bptr->CIMCMD_REG +
473 				(CIMCMD_WRSETUP | (offset << 1) |
474 				 (cim->ci_num << CIMCMD_CIMSHIFT))));
475 #ifdef RICHARD_DELAY
476 			udelay(1);
477 #endif		/* RICHARD_DELAY */
478 #ifdef DEBUG_VERBOSE
479 			readback = readw((unsigned short *)
480 					 (bptr->CIMCMD_REG +
481 					  (CIMCMD_RDSETUP | (offset << 1) |
482 					   (cim->ci_num << CIMCMD_CIMSHIFT))));
483 			if (readback != alloff)
484 			{
485 				DEBUGPRINT((KERN_ALERT "cim %d setup reg #%d: readback (0x%x) should be 0x%x",
486 					    cim->ci_num, offset, readback, alloff));
487 			}
488 #endif		/* DEBUG_VERBOSE */
489 		}
490 	}
491 
492 	/*
493 	 * Clear out the CIM CSR with the exception of the LED.
494 	 */
495 
496 	writeb((unsigned char) 0,
497 	       (unsigned char *) (bptr->CIMCMD_REG +
498 				  (CIMCMD_WRCIMCSR | (cim->ci_num << CIMCMD_CIMSHIFT))));
499 
500 	return TRUE;
501 }
502 
503 
wanmcs_reset(SAB_BOARD * bptr)504 int wanmcs_reset(SAB_BOARD* bptr) /* note the board is the host card not the
505 				   * individual extension boards
506 				   */
507 {
508 	int		 counter;
509 
510 #if 0				/* from the ASE driver */
511 	/*
512 	 * Program the AMCC to deactivate the write FIFO.
513 	 */
514 
515 	ASE_PUT32(cboard->b_bridgehandle,
516 		  (aseuint32_t *) (cboard->b_bridge + AMCC_PTCR),
517 		  ((aseuint32_t) (AMCC_PTMODE | AMCC_WRFIFODIS) << 24) |
518 		  ((aseuint32_t) (AMCC_PTMODE | AMCC_WRFIFODIS) << 16) |
519 		  ((aseuint32_t) (AMCC_PTMODE | AMCC_WRFIFODIS) << 8) |
520 		  (aseuint32_t) (AMCC_PTMODE | AMCC_WRFIFODIS));
521 #endif		/* 0 */
522 
523 	/*
524 	 * First thing: do a reset of the local bus on the MIC
525 	 *  by diddling the Add-On Reset bit in the RCR.
526 	 */
527 
528 	writel((unsigned int) AMCC_AORESET,
529 	       (unsigned int *)(bptr->AMCC_REG + AMCC_RCR));
530 
531 	udelay(10);		/* wait for 10 us. */
532 
533 	writel((unsigned int) 0,
534 	       (unsigned int *)(bptr->AMCC_REG + AMCC_RCR));
535 
536 	udelay(10);		/* wait for 10 us. */
537 
538 	/*
539 	 * Now the PCI bridge is reset.  Try to establish
540 	 *  a link through the Glink chipset.
541 	 */
542 
543 	for (counter = 1000; counter != 0; counter--)
544 	{
545 		writeb(0, (unsigned char*) (bptr->MICCMD_REG + MICCMD_MICCSR));
546 
547 		udelay(5);
548 
549 		if((readb((unsigned char*)
550 			  (bptr->MICCMD_REG + MICCMD_MICCSR)) & MICCMD_MICCSR_GLE) == 0)
551 		{
552 			break;
553 		}
554 	}
555 
556 	/*
557 	 * Did we run out of time?
558 	 */
559 
560 	if (counter == 0)
561 	{
562 		printk(KERN_ALERT
563 		       "AMCC5920: board %p: GLink did not reset -- is the MEB on?",
564 		       bptr);
565 
566 		return FALSE;
567 	}
568 
569 	/*
570 	 * Now, hit the reset in the MEB.
571 	 */
572 
573 	writeb(0, (unsigned int *) (bptr->CIMCMD_REG + CIMCMD_RESETENA));
574 
575 	udelay(5);
576 
577 	writeb(0, (unsigned int *) (bptr->CIMCMD_REG + CIMCMD_RESETDIS));
578 
579 	/*
580 	 * And we're done!
581 	 */
582 
583 	return TRUE;
584 }
585 
aura_sp502_program(SAB_PORT * port,register unsigned int sigindex)586 void aura_sp502_program(SAB_PORT *port, register unsigned int sigindex)
587 {
588 	register unsigned char prognibble;
589 	SAB_BOARD *bptr;
590 	unsigned int cimnum;
591 	unsigned int chipno;
592 	unsigned int portno;
593 	unsigned int rdaddressreceiver;
594 	unsigned int rdaddresstransmitter;
595 	unsigned int wraddressreceiver;
596 	unsigned int wraddresstransmitter;
597 	unsigned short datareceiver;
598 	unsigned short datatransmitter;
599 
600 	bptr = port->board;
601 	cimnum = port->chip->c_cim->ci_num;
602 	chipno = (port->chip->c_chipno & 1); /* chip number relative to EB not MCS */
603 	portno = (port->portno + (8 * chipno)); /* portno on a per EB basis */
604 
605 	prognibble = (sp502progbyte[sigindex] & 0x0F);
606 
607 				/* first 4 shorts contain receiver control bits */
608 	rdaddressreceiver =
609 		(((unsigned int)bptr->CIMCMD_REG) +
610 		 ((cimnum << CIMCMD_CIMSHIFT) | CIMCMD_RDSETUP | ((portno/4) << CIMCMD_CTRLSHIFT)));
611 				/* second 4 shorts contain transmitter control bits */
612 	rdaddresstransmitter =
613 		(((unsigned int)bptr->CIMCMD_REG) +
614 		 ((cimnum << CIMCMD_CIMSHIFT) | CIMCMD_RDSETUP | ((4+(portno/4)) << CIMCMD_CTRLSHIFT)));
615 
616 	wraddressreceiver =
617 		(((unsigned int)bptr->CIMCMD_REG) +
618 		 ((cimnum << CIMCMD_CIMSHIFT) | CIMCMD_WRSETUP | ((portno/4) << CIMCMD_CTRLSHIFT)));
619 	wraddresstransmitter =
620 		(((unsigned int)bptr->CIMCMD_REG) +
621 		 ((cimnum << CIMCMD_CIMSHIFT) | CIMCMD_WRSETUP | ((4+(portno/4)) << CIMCMD_CTRLSHIFT)));
622 
623 				/* read out the current receiver status */
624 	datareceiver = readw((unsigned short*) rdaddressreceiver);
625 				/* clear out nibble that corresponds to current port */
626 	datareceiver &= (unsigned short) ~(0x0F << ((3 - (portno % 4)) * 4));
627 				/* or in new receiver control field */
628 	datareceiver |= (prognibble << ((3 - (portno % 4)) * 4));
629 				/* write back the short that corresponds to 4 ports */
630 	writew(datareceiver, (unsigned short*) wraddressreceiver);
631 
632 				/* just as above except that next 4 shorts correspond to transmitters */
633 	datatransmitter = readw((unsigned short*) rdaddresstransmitter);
634 	datatransmitter &= (unsigned short) ~(0x0F << ((3 - (portno % 4)) * 4));
635 	datatransmitter |= (prognibble << ((3 - (portno % 4)) * 4));
636 	writew(datatransmitter, (unsigned short*) wraddresstransmitter);
637 }
638