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