1/*-
2 * Copyright (c) 2012 The NetBSD Foundation, Inc.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to The NetBSD Foundation
6 * by Paul Fleischer <paul@xpg.dk>
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 */
29#include <sys/types.h>
30
31#include <lib/libsa/stand.h>
32
33#include <dev/ic/dm9000reg.h>
34
35/* Register defines which are not yet in dm9000reg */
36#define  DM9000_PHY_ANAR_CSMACD		0x01
37#define  DM9000_PHY_ANAR_10_HDX		(1<<5)
38#define  DM9000_PHY_ANAR_10_FDX		(1<<6)
39#define  DM9000_PHY_ANAR_TX_HDX		(1<<7)
40#define  DM9000_PHY_ANAR_TX_FDX		(1<<8)
41#define  DM9000_PHY_ANAR_T4		(1<<9)
42#define  DM9000_PHY_ANAR_FCS		(1<<10)
43#define  DM9000_PHY_ANAR_RF		(1<<13)
44#define  DM9000_PHY_ANAR_ACK		(1<<14)
45#define  DM9000_PHY_ANAR_NP		(1<<15)
46
47#define  DM9000_NCR_EXT_PHY     (1 << 7)
48
49#define  DM9000_EPAR_PHY(n)     ((n<<6) & 0xC0)
50
51/* IOMODE macros, which are no longer present in the real driver.
52   Keep them here until we rework this driver.
53 */
54#define  DM9000_IOMODE(n)       (n<<DM9000_IOMODE_SHIFT) & DM9000_IOMODE_MASK
55#define  DM9000_IOMODE_8BIT     DM9000_IOMODE(2)
56#define  DM9000_IOMODE_16BIT    DM9000_IOMODE(0)
57#define  DM9000_IOMODE_32BIT    DM9000_IOMODE(1)
58
59#include "dm9k.h"
60
61extern time_t getsecs(void);
62extern struct btinfo_net	bi_net;
63
64struct dm9k_sc {
65	unsigned int csr;
66	unsigned int tx;
67	int phy;
68};
69
70static struct dm9k_sc dm9k_sc;
71static uint8_t dm9k_mac[6] = {DM9000MAC};
72
73/* Inline memory access methods */
74static inline int
75CSR_READ_1(struct dm9k_sc *sc, int reg)
76{
77	*(volatile uint8_t*)(sc->csr) = reg;
78	return *(volatile uint8_t*)(sc->csr+4);
79}
80
81static inline int
82CSR_READ_2(struct dm9k_sc *sc, int reg)
83{
84	*(volatile uint8_t *)(sc->csr) = reg;
85	return *(volatile uint16_t *)(sc->csr + 4);
86}
87
88static inline void
89CSR_WRITE_1(struct dm9k_sc *sc, int reg, int data)
90{
91	*(volatile uint8_t *)(sc->csr) = reg;
92	*(volatile uint8_t *)(sc->csr + 4) = data;
93}
94
95static inline void
96CSR_WRITE_2(struct dm9k_sc *sc, int reg, int data)
97{
98	*(volatile uint8_t *)(sc->csr) = reg;
99	*(volatile uint16_t *)(sc->csr + 4) = data;
100}
101
102static u_int16_t   mii_read(struct dm9k_sc *sc, int phy, int reg);
103static void	   mii_write(struct dm9k_sc *sc, int phy, int reg,
104			     u_int16_t value);
105
106int
107dm9k_match(unsigned int tag, void *macaddr)
108{
109	struct dm9k_sc sc;
110	uint8_t *en = macaddr;
111	unsigned int val;
112
113	sc.csr = 0x20000000;
114
115	val = (CSR_READ_1(&sc, DM9000_PID0)) |
116	  (CSR_READ_1(&sc, DM9000_PID1)<<8);
117	val |=((CSR_READ_1(&sc, DM9000_VID0)) |
118	       (CSR_READ_1(&sc, DM9000_VID1)<<8)) << 16;
119
120	if( val != 0x0a469000 ) {
121		printf("DM9000 Chip not found\n");
122		return 0;
123	}
124
125	val = CSR_READ_1(&sc, DM9000_ISR) & DM9000_IOMODE_MASK;
126	switch (val) {
127	case DM9000_IOMODE_8BIT:
128		printf("Unsupported I/O Mode: 8 Bit\n");
129		return 0;
130		break;
131	case DM9000_IOMODE_16BIT:
132		break;
133	case DM9000_IOMODE_32BIT:
134		printf("Unsupported I/O Mode: 32 Bit\n");
135		return 0;
136		break;
137	}
138
139	if( en != NULL &&
140	    en[0] != 0x00 && en[1] != 0x00 &&
141	    en[2] != 0x00 && en[3] != 0x00 &&
142	    en[4] != 0x00 && en[5] != 0x00 ) {
143		/* Set dm9k mac-address if input is not zero */
144		memcpy(dm9k_mac, en, sizeof(dm9k_mac));
145	} else {
146		if( en != NULL ) {
147			/* Return dm9k mac-address */
148			memcpy(en, dm9k_mac, sizeof(dm9k_mac));
149		}
150	}
151
152	return 1;
153}
154
155void*
156dm9k_init(unsigned int tag, void *macaddr)
157{
158	uint8_t var;
159	int start;
160	struct dm9k_sc *sc = &dm9k_sc;
161
162	sc->csr = 0x20000000;
163	sc->phy = 1; /* Internal PHY */
164	sc->tx = 0;
165
166	CSR_WRITE_1(sc, DM9000_PAB0, dm9k_mac[0]);
167	CSR_WRITE_1(sc, DM9000_PAB1, dm9k_mac[1]);
168	CSR_WRITE_1(sc, DM9000_PAB2, dm9k_mac[2]);
169	CSR_WRITE_1(sc, DM9000_PAB3, dm9k_mac[3]);
170	CSR_WRITE_1(sc, DM9000_PAB4, dm9k_mac[4]);
171	CSR_WRITE_1(sc, DM9000_PAB5, dm9k_mac[5]);
172
173	printf("Davicom DM9000 NIC configured with MAC address: "
174	       "%x:%x:%x:%x:%x:%x\n",
175	       dm9k_mac[0], dm9k_mac[1], dm9k_mac[2],
176	       dm9k_mac[3], dm9k_mac[4], dm9k_mac[5]);
177
178	memcpy(macaddr, dm9k_mac, sizeof(dm9k_mac));
179
180	/* Recommended initialization procedure as described in the
181	 * DM9000 ISA Programming Guide section 2: */
182
183	/* (1) PHY Reset (Internal) */
184	mii_write(sc, sc->phy, DM9000_PHY_BMCR, DM9000_PHY_BMCR_RESET);
185
186	/* (2) PHY Power down */
187	var = CSR_READ_1(sc, DM9000_GPR);
188	CSR_WRITE_1(sc, DM9000_GPR, var | DM9000_GPR_PHY_PWROFF);
189
190	/* (3) Disable all interrupts & RX / TX */
191	CSR_WRITE_1(sc, DM9000_IMR, 0x0);
192	CSR_WRITE_1(sc, DM9000_TCR, 0x0);
193	CSR_WRITE_1(sc, DM9000_RCR, 0x0);
194
195	/* (4) Software Reset*/
196	CSR_WRITE_1(sc, DM9000_NCR, DM9000_NCR_RST |
197		    DM9000_NCR_LBK_MAC_INTERNAL);
198	while( CSR_READ_1(sc, DM9000_NCR) & DM9000_NCR_RST );
199
200	/* (5a) PHY Configuration */
201	/* Setup PHY auto-negotiation capabilities */
202	mii_write(sc, sc->phy, DM9000_PHY_ANAR,
203		  DM9000_PHY_ANAR_10_HDX | DM9000_PHY_ANAR_10_FDX |
204		  DM9000_PHY_ANAR_TX_HDX | DM9000_PHY_ANAR_TX_FDX);
205
206	/* Ask PHY to start auto-negotiation */
207	mii_write(sc, sc->phy, DM9000_PHY_BMCR, DM9000_PHY_BMCR_AUTO_NEG_EN |
208		  DM9000_PHY_BMCR_RESTART_AN);
209
210	/* (5b) PHY Enable */
211	var = CSR_READ_1(sc, DM9000_GPR);
212	CSR_WRITE_1(sc, DM9000_GPR, var & ~DM9000_GPR_PHY_PWROFF );
213	var = CSR_READ_1(sc, DM9000_GPCR);
214	CSR_WRITE_1(sc, DM9000_GPCR, var | DM9000_GPCR_GPIO0_OUT );
215
216	/* (6) Software Reset */
217	CSR_WRITE_1(sc, DM9000_NCR, DM9000_NCR_RST |
218		    DM9000_NCR_LBK_MAC_INTERNAL);
219	while( CSR_READ_1(sc, DM9000_NCR) & DM9000_NCR_RST );
220
221	/* (7) Setup Registers: Remainder of this function */
222
223	/* Select internal PHY, no wakeup event, no collosion mode, normal
224	   loopback mode, and full duplex mode (for external PHY only) */
225	var = DM9000_NCR_LBK_NORMAL;
226	if (sc->phy != 0x01) {
227		var = DM9000_NCR_EXT_PHY;
228	}
229	CSR_WRITE_1(sc, DM9000_NCR, var);
230
231	/* Will clear TX1END, TX2END, and WAKEST fields by reading DM9000_NSR
232	 */
233	CSR_READ_1(sc, DM9000_NSR);
234
235	/* Enable wraparound of read/write pointer. */
236	CSR_WRITE_1(sc, DM9000_IMR, DM9000_IMR_PAR);
237
238	/* Enable RX without watchdog */
239	CSR_WRITE_1(sc, DM9000_RCR, DM9000_RCR_RXEN | DM9000_RCR_WTDIS);
240
241	start = getsecs();
242	/* Wait for auto-negotiation to complete.
243	   Currently there is no timeout on this due to the fact that we
244	   have no way to signal an error -- and therefore the caller
245	   cannot retry.
246	 */
247	do {
248		if (getsecs() - start > 10) {
249			printf("No active link, check cable connection.\n");
250			start = getsecs();
251		}
252		/* We have no delay() function at this point, just busy-wait.*/
253	} while( !(mii_read(sc, sc->phy, DM9000_PHY_BMSR) &
254		   DM9000_PHY_BMSR_AUTO_NEG_COM));
255
256	return sc;
257}
258
259int
260dm9k_recv(void *priv, char *pkt, unsigned int len, unsigned int timo)
261{
262	struct dm9k_sc *sc = priv;
263	uint8_t buf;
264	uint8_t rx_status;
265	uint16_t data;
266	uint16_t frame_length;
267	time_t start_time;
268	int i;
269	int trailing_byte;
270
271	errno = 0;
272	trailing_byte = 0;
273
274	start_time = getsecs();
275
276	CSR_READ_2(sc, DM9000_MRCMDX);
277
278	/* Wait until data is available */
279	do {
280		buf = *(volatile uint8_t*)(sc->csr+4);
281	} while ( (buf == 0x00) && (getsecs()-start_time <= timo*10));
282
283	if (buf == 0x00) {
284		/* Timeout */
285		errno = ETIMEDOUT;
286		return -1;
287	}
288
289	if (buf != 0x01) {
290		panic("DM9000 needs to be reset, but this is not implemented yet!");
291	}
292
293	/* Get status */
294	rx_status = CSR_READ_1(sc, DM9000_MRCMD);
295
296	/* Frame has 4 CRC bytes at the end, that we do not deliver to the
297	   upper layer */
298	frame_length = *(volatile uint16_t*)(sc->csr+4);
299	if (frame_length-4 > len) {
300		errno = ENOBUFS;
301		printf("Received frame is too big for given buffer, ignoring data...\n");
302		printf("Expected maximum of %d bytes, but got %d bytes\n", len, frame_length-4);
303	}
304	len = frame_length - 4;
305
306	if (len & 0x01) {
307		trailing_byte = 1;
308		len--;
309	}
310
311	/* DM9000 is runing in 16-bit mode, transfer two bytes at a time */
312	for (i = 0; i<len; i+=2) {
313		data = *(volatile uint16_t*)(sc->csr+4);
314		if (errno == 0) {
315			pkt[i] = data & 0xFF;
316			pkt[i+1] = (data >> 8) & 0xFF;
317		}
318	}
319
320	if (trailing_byte) {
321		len++;
322		data = *(volatile uint16_t*)(sc->csr+4);
323		if (errno == 0) {
324			pkt[i] = data & 0xFF;
325		}
326	}
327
328	/* Read out the remaining part of the received frame, which
329	 * under normal circumstances are the 4 CRC bytes. */
330	for (i = 0; i<(frame_length-len); i+=2) {
331		data = *(volatile uint16_t*)(sc->csr+4);
332	}
333
334	if (errno)
335		return -1;
336
337	if (rx_status & (DM9000_RSR_CE | DM9000_RSR_PLE)) {
338		printf("Read error: %x\n", rx_status);
339		errno = EIO;
340		return -1;
341	}
342
343	return len;
344}
345
346int
347dm9k_send(void *priv, char *pkt, unsigned int len)
348{
349	struct dm9k_sc *sc = priv;
350	int i;
351	int finish_bit;
352	unsigned int cnt;
353	unsigned int bound;
354	uint16_t data;
355
356	cnt = len;
357	if (len & 0x01)
358		cnt--;
359
360	CSR_READ_1(sc, DM9000_MWCMD);
361
362	for(i = 0; i < cnt; i+=2) {
363		data = pkt[i] | (pkt[i+1] << 8);
364		*(volatile uint16_t*)(sc->csr+4) = data;
365	}
366
367	if (len & 0x01) {
368		/* Copy the remaining, last, byte  */
369		data = pkt[len-1];
370		*(volatile uint16_t*)(sc->csr+4) = data;
371	}
372
373	CSR_WRITE_1(sc, DM9000_TXPLL, len & 0xFF);
374	CSR_WRITE_1(sc, DM9000_TXPLH, len >> 8);
375
376	CSR_WRITE_1(sc, DM9000_TCR, DM9000_TCR_TXREQ);
377
378	finish_bit = (sc->tx) ? DM9000_NSR_TX2END : DM9000_NSR_TX1END;
379	bound = getsecs() + 1;
380	do {
381		if (CSR_READ_1(sc, DM9000_NSR) & finish_bit) {
382			goto success;
383		}
384	} while(getsecs() < bound);
385	printf("Transmit timeout\n");
386	return -1;
387
388 success:
389	sc->tx ^= 1;
390
391	return len;
392}
393
394u_int16_t
395mii_read(struct dm9k_sc *sc, int phy, int reg)
396{
397	u_int16_t val;
398	/* Select Register to read*/
399	CSR_WRITE_1(sc,
400		    DM9000_EPAR, DM9000_EPAR_PHY(phy) |
401		    (reg & DM9000_EPAR_EROA_MASK));
402	/* Select read operation (DM9000_EPCR_ERPRR) from the PHY */
403	CSR_WRITE_1(sc, DM9000_EPCR, DM9000_EPCR_ERPRR | DM9000_EPCR_EPOS_PHY);
404
405	/* Wait until access to PHY has completed */
406	while(CSR_READ_1(sc, DM9000_EPCR) & DM9000_EPCR_ERRE);
407
408	/* Reset ERPRR-bit */
409	CSR_WRITE_1(sc, DM9000_EPCR, DM9000_EPCR_EPOS_PHY);
410
411	val = CSR_READ_1(sc, DM9000_EPDRL);
412	val |= CSR_READ_1(sc, DM9000_EPDRH) << 8;
413
414	return val;
415}
416
417void
418mii_write(struct dm9k_sc *sc, int phy, int reg, u_int16_t value)
419{
420	/* Select Register to write*/
421	CSR_WRITE_1(sc, DM9000_EPAR,
422		    DM9000_EPAR_PHY(phy) | (reg & DM9000_EPAR_EROA_MASK));
423
424	/* Write data to the two data registers */
425	CSR_WRITE_1(sc, DM9000_EPDRL, value & 0xFF);
426	CSR_WRITE_1(sc, DM9000_EPDRH, (value >> 8) & 0xFF);
427
428	/* Select write operation (DM9000_EPCR_ERPRW) from the PHY */
429	CSR_WRITE_1(sc, DM9000_EPCR, DM9000_EPCR_ERPRW + DM9000_EPCR_EPOS_PHY);
430
431	/* Wait until access to PHY has completed */
432	while(CSR_READ_1(sc, DM9000_EPCR) & DM9000_EPCR_ERRE);
433
434	/* Reset ERPRR-bit */
435	CSR_WRITE_1(sc, DM9000_EPCR, DM9000_EPCR_EPOS_PHY);
436}
437