Changes in uspace/srv/hw/netif/dp8390/ne2000.c [e0854e3:7e752b2] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hw/netif/dp8390/ne2000.c
re0854e3 r7e752b2 1 1 /* 2 * Copyright (c) 2009 Lukas Mejdrech 3 * Copyright (c) 2011 Martin Decky 4 * All rights reserved. 2 * Copyright (c) 1987,1997, 2006, Vrije Universiteit, Amsterdam, The Netherlands All rights reserved. Redistribution and use of the MINIX 3 operating system in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 5 3 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 4 * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 5 * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 6 * * Neither the name of the Vrije Universiteit nor the names of the software authors or contributors may be used to endorse or promote products derived from this software without specific prior written permission. 7 * * Any deviations from these conditions require written permission from the copyright holder in advance 9 8 * 10 * - Redistributions of source code must retain the above copyright11 * notice, this list of conditions and the following disclaimer.12 * - Redistributions in binary form must reproduce the above copyright13 * notice, this list of conditions and the following disclaimer in the14 * documentation and/or other materials provided with the distribution.15 * - The name of the author may not be used to endorse or promote products16 * derived from this software without specific prior written permission.17 9 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 10 * Disclaimer 11 * 12 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS, AUTHORS, AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR 19 13 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 14 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHORBE LIABLE FOR ANY DIRECT, INDIRECT,15 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ANY AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 22 16 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 17 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, … … 26 20 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 21 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */29 30 /*31 * This code is based upon the NE2000 driver for MINIX,32 * distributed according to a BSD-style license.33 22 * 34 * Copyright (c) 1987, 1997, 2006 Vrije Universiteit 35 * Copyright (c) 1992, 1994 Philip Homburg 36 * Copyright (c) 1996 G. Falzoni 37 * 23 * Changes: 24 * 2009 ported to HelenOS, Lukas Mejdrech 38 25 */ 39 26 … … 48 35 #include <stdio.h> 49 36 #include <unistd.h> 37 50 38 #include "dp8390_port.h" 39 40 /* 41 ne2000.c 42 43 Driver for the ne2000 ethernet cards. This file contains only the ne2000 44 specific code, the rest is in dp8390.c 45 46 Created: March 15, 1994 by Philip Homburg <philip@f-mnx.phicoh.com> 47 */ 48 49 //#include "../drivers.h" 50 51 //#include <net/gen/ether.h> 52 //#include <net/gen/eth_io.h> 53 //#if __minix_vmd 54 //#include "config.h" 55 //#endif 56 57 #include "local.h" 51 58 #include "dp8390.h" 52 59 #include "ne2000.h" 53 60 54 /** Number of bytes to transfer */ 55 #define N 100 56 57 typedef int (*testf_t)(dpeth_t *dep, int pos, uint8_t *pat); 58 59 /** Data patterns */ 60 uint8_t pat0[] = {0x00, 0x00, 0x00, 0x00}; 61 uint8_t pat1[] = {0xFF, 0xFF, 0xFF, 0xFF}; 62 uint8_t pat2[] = {0xA5, 0x5A, 0x69, 0x96}; 63 uint8_t pat3[] = {0x96, 0x69, 0x5A, 0xA5}; 61 #if ENABLE_NE2000 62 63 /** Number of bytes to transfer. 64 */ 65 #define N 100 66 67 //#define MILLIS_TO_TICKS(m) (((m)*HZ/1000)+1) 68 69 /** Sleeps for the defined millicesonds. 70 * @param[in] millis The number of milliseconds to sleep. 71 */ 72 #define milli_delay(millis) usleep((millis) * 1000) 73 74 /** Type definition of the testing function. 75 */ 76 _PROTOTYPE(typedef int (*testf_t), (dpeth_t *dep, int pos, u8_t *pat) ); 77 78 /** First data pattern. 79 */ 80 u8_t pat0[]= {0x00, 0x00, 0x00, 0x00}; 81 82 /** Second data pattern. 83 */ 84 u8_t pat1[]= {0xFF, 0xFF, 0xFF, 0xFF}; 85 86 /** Third data pattern. 87 */ 88 u8_t pat2[]= {0xA5, 0x5A, 0x69, 0x96}; 89 90 /** Fourth data pattern. 91 */ 92 u8_t pat3[]= {0x96, 0x69, 0x5A, 0xA5}; 64 93 65 94 /** Tests 8 bit NE2000 network interface. … … 68 97 * @param[in] pat The data pattern to be written. 69 98 * @returns True on success. 70 * @returns falseotherwise.71 */ 72 static int test_8(dpeth_t *dep, int pos, u int8_t *pat);99 * @returns FALSE otherwise. 100 */ 101 static int test_8(dpeth_t *dep, int pos, u8_t *pat); 73 102 74 103 /** Tests 16 bit NE2000 network interface. … … 77 106 * @param[in] pat The data pattern to be written. 78 107 * @returns True on success. 79 * @returns falseotherwise.80 */ 81 static int test_16(dpeth_t *dep, int pos, u int8_t *pat);108 * @returns FALSE otherwise. 109 */ 110 static int test_16(dpeth_t *dep, int pos, u8_t *pat); 82 111 83 112 /** Stops the NE2000 network interface. … … 85 114 */ 86 115 static void ne_stop(dpeth_t *dep); 116 //_PROTOTYPE(static void milli_delay, (unsigned long millis) ); 87 117 88 118 /** Initializes the NE2000 network interface. … … 91 121 void ne_init(struct dpeth *dep); 92 122 93 int ne_probe(dpeth_t *dep) 123 /*===========================================================================* 124 * ne_probe * 125 *===========================================================================*/ 126 int ne_probe(dep) 127 dpeth_t *dep; 94 128 { 95 129 int byte; … … 97 131 int loc1, loc2; 98 132 testf_t f; 99 100 dep->de_dp8390_port = dep->de_base_port + NE_DP8390; 101 102 /* 103 * We probe for an ne1000 or an ne2000 by testing whether the 133 134 dep->de_dp8390_port= dep->de_base_port + NE_DP8390; 135 136 /* We probe for an ne1000 or an ne2000 by testing whether the 104 137 * on board is reachable through the dp8390. Note that the 105 138 * ne1000 is an 8bit card and has a memory region distict from 106 139 * the 16bit ne2000 107 140 */ 108 109 for (dep->de_16bit = 0; dep->de_16bit < 2; dep->de_16bit++) { 141 142 for (dep->de_16bit= 0; dep->de_16bit < 2; dep->de_16bit++) 143 { 110 144 /* Reset the ethernet card */ 111 145 byte= inb_ne(dep, NE_RESET); 112 usleep(2000);146 milli_delay(2); 113 147 outb_ne(dep, NE_RESET, byte); 114 usleep(2000);115 148 milli_delay(2); 149 116 150 /* Reset the dp8390 */ 117 151 outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT); 118 for (i = 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) &ISR_RST) == 0); i++)152 for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) &ISR_RST) == 0); i++) 119 153 ; /* Do nothing */ 120 154 121 155 /* Check if the dp8390 is really there */ 122 if ((inb_reg0(dep, DP_CR) & (CR_STP | CR_DM_ABORT)) != 123 (CR_STP | CR_DM_ABORT)) 156 if ((inb_reg0(dep, DP_CR) &(CR_STP|CR_DM_ABORT)) != 157 (CR_STP|CR_DM_ABORT)) 158 { 124 159 return 0; 125 160 } 161 126 162 /* Disable the receiver and init TCR and DCR. */ 127 163 outb_reg0(dep, DP_RCR, RCR_MON); 128 164 outb_reg0(dep, DP_TCR, TCR_NORMAL); 129 if (dep->de_16bit) { 165 if (dep->de_16bit) 166 { 130 167 outb_reg0(dep, DP_DCR, DCR_WORDWIDE | DCR_8BYTES | 131 DCR_BMS); 132 } else { 168 DCR_BMS); 169 } 170 else 171 { 133 172 outb_reg0(dep, DP_DCR, DCR_BYTEWIDE | DCR_8BYTES | 134 DCR_BMS); 135 } 136 137 if (dep->de_16bit) { 173 DCR_BMS); 174 } 175 176 if (dep->de_16bit) 177 { 138 178 loc1= NE2000_START; 139 179 loc2= NE2000_START + NE2000_SIZE - 4; 140 180 f= test_16; 141 } else { 181 } 182 else 183 { 142 184 loc1= NE1000_START; 143 185 loc2= NE1000_START + NE1000_SIZE - 4; 144 186 f= test_8; 145 187 } 146 147 if (f(dep, loc1, pat0) && f(dep, loc1, pat1) && 148 f(dep, loc1, pat2) && f(dep, loc1, pat3) && 149 f(dep, loc2, pat0) && f(dep, loc2, pat1) && 150 f(dep, loc2, pat2) && f(dep, loc2, pat3)) { 151 dep->de_initf = ne_init; 152 dep->de_stopf = ne_stop; 188 if (f(dep, loc1, pat0) && f(dep, loc1, pat1) && 189 f(dep, loc1, pat2) && f(dep, loc1, pat3) && 190 f(dep, loc2, pat0) && f(dep, loc2, pat1) && 191 f(dep, loc2, pat2) && f(dep, loc2, pat3)) 192 { 193 /* We don't need a memory segment */ 194 dep->de_linmem= 0; 195 if (!dep->de_pci) 196 dep->de_initf= ne_init; 197 dep->de_stopf= ne_stop; 198 dep->de_prog_IO= 1; 153 199 return 1; 154 200 } 155 201 } 156 157 202 return 0; 158 203 } 159 204 160 void ne_init(dpeth_t *dep) 205 /*===========================================================================* 206 * ne_init * 207 *===========================================================================*/ 208 void ne_init(dep) 209 dpeth_t *dep; 161 210 { 162 211 int i; 163 212 int word, sendq_nr; 164 213 165 214 /* Setup a transfer to get the ethernet address. */ 166 215 if (dep->de_16bit) … … 168 217 else 169 218 outb_reg0(dep, DP_RBCR0, 6); 170 171 219 outb_reg0(dep, DP_RBCR1, 0); 172 220 outb_reg0(dep, DP_RSAR0, 0); 173 221 outb_reg0(dep, DP_RSAR1, 0); 174 222 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA); 175 176 for (i = 0; i < 6; i++) { 177 if (dep->de_16bit) { 178 word = inw_ne(dep, NE_DATA); 179 dep->de_address.ea_addr[i] = word; 180 } else 223 224 for (i= 0; i<6; i++) 225 { 226 if (dep->de_16bit) 227 { 228 word= inw_ne(dep, NE_DATA); 229 dep->de_address.ea_addr[i]= word; 230 } 231 else 232 { 181 233 dep->de_address.ea_addr[i] = inb_ne(dep, NE_DATA); 182 }183 234 } 235 } 184 236 dep->de_data_port= dep->de_base_port + NE_DATA; 185 if (dep->de_16bit) { 186 dep->de_ramsize = NE2000_SIZE; 187 dep->de_offset_page = NE2000_START / DP_PAGESIZE; 188 } else { 189 dep->de_ramsize = NE1000_SIZE; 190 dep->de_offset_page = NE1000_START / DP_PAGESIZE; 191 } 192 237 if (dep->de_16bit) 238 { 239 dep->de_ramsize= NE2000_SIZE; 240 dep->de_offset_page= NE2000_START / DP_PAGESIZE; 241 } 242 else 243 { 244 dep->de_ramsize= NE1000_SIZE; 245 dep->de_offset_page= NE1000_START / DP_PAGESIZE; 246 } 247 193 248 /* Allocate one send buffer (1.5KB) per 8KB of on board memory. */ 194 sendq_nr = dep->de_ramsize / 0x2000; 195 249 sendq_nr= dep->de_ramsize / 0x2000; 196 250 if (sendq_nr < 1) 197 sendq_nr 251 sendq_nr= 1; 198 252 else if (sendq_nr > SENDQ_NR) 199 sendq_nr = SENDQ_NR; 200 201 dep->de_sendq_nr = sendq_nr; 202 for (i = 0; i < sendq_nr; i++) 203 dep->de_sendq[i].sq_sendpage = dep->de_offset_page + i * SENDQ_PAGES; 204 205 dep->de_startpage = dep->de_offset_page + i * SENDQ_PAGES; 206 dep->de_stoppage = dep->de_offset_page + dep->de_ramsize / DP_PAGESIZE; 207 208 printf("%s: Novell NE%d000 ethernet card at I/O address " 209 "%#lx, memory size %#lx, irq %d\n", 210 dep->de_name, dep->de_16bit ? 2 : 1, 211 dep->de_base_port, dep->de_ramsize, dep->de_irq); 212 } 213 214 static int test_8(dpeth_t *dep, int pos, uint8_t *pat) 215 { 216 uint8_t buf[4]; 253 sendq_nr= SENDQ_NR; 254 dep->de_sendq_nr= sendq_nr; 255 for (i= 0; i<sendq_nr; i++) 256 { 257 dep->de_sendq[i].sq_sendpage= dep->de_offset_page + 258 i*SENDQ_PAGES; 259 } 260 261 dep->de_startpage= dep->de_offset_page + i*SENDQ_PAGES; 262 dep->de_stoppage= dep->de_offset_page + dep->de_ramsize / DP_PAGESIZE; 263 264 /* Can't override the default IRQ. */ 265 dep->de_irq &= ~DEI_DEFAULT; 266 267 if (!debug) 268 { 269 printf("%s: NE%d000 at %#lx:%d\n", 270 dep->de_name, dep->de_16bit ? 2 : 1, 271 dep->de_base_port, dep->de_irq); 272 } 273 else 274 { 275 printf("%s: Novell NE%d000 ethernet card at I/O address " 276 "%#lx, memory size %#lx, irq %d\n", 277 dep->de_name, dep->de_16bit ? 2 : 1, 278 dep->de_base_port, dep->de_ramsize, dep->de_irq); 279 } 280 } 281 282 /*===========================================================================* 283 * test_8 * 284 *===========================================================================*/ 285 static int test_8(dep, pos, pat) 286 dpeth_t *dep; 287 int pos; 288 u8_t *pat; 289 { 290 u8_t buf[4]; 217 291 int i; 218 219 outb_reg0(dep, DP_ISR, 0xff); 220 292 int r; 293 294 outb_reg0(dep, DP_ISR, 0xFF); 295 221 296 /* Setup a transfer to put the pattern. */ 222 297 outb_reg0(dep, DP_RBCR0, 4); 223 298 outb_reg0(dep, DP_RBCR1, 0); 224 outb_reg0(dep, DP_RSAR0, pos & 0xff);299 outb_reg0(dep, DP_RSAR0, pos &0xFF); 225 300 outb_reg0(dep, DP_RSAR1, pos >> 8); 226 301 outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA); 227 228 for (i = 0; i <4; i++)302 303 for (i= 0; i<4; i++) 229 304 outb_ne(dep, NE_DATA, pat[i]); 230 231 for (i = 0; i < N; i++) { 232 if (inb_reg0(dep, DP_ISR) & ISR_RDC) 305 306 for (i= 0; i<N; i++) 307 { 308 if (inb_reg0(dep, DP_ISR) &ISR_RDC) 233 309 break; 234 310 } 235 236 if (i == N) { 237 printf("%s: NE1000 remote DMA test failed\n", dep->de_name); 311 if (i == N) 312 { 313 if (debug) 314 { 315 printf("%s: NE1000 remote DMA test failed\n", 316 dep->de_name); 317 } 238 318 return 0; 239 319 } 240 320 241 321 outb_reg0(dep, DP_RBCR0, 4); 242 322 outb_reg0(dep, DP_RBCR1, 0); 243 outb_reg0(dep, DP_RSAR0, pos & 0xff);323 outb_reg0(dep, DP_RSAR0, pos &0xFF); 244 324 outb_reg0(dep, DP_RSAR1, pos >> 8); 245 325 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA); 246 247 for (i = 0; i < 4; i++) 248 buf[i] = inb_ne(dep, NE_DATA); 249 250 return (memcmp(buf, pat, 4) == 0); 251 } 252 253 static int test_16(dpeth_t *dep, int pos, uint8_t *pat) 254 { 255 uint8_t buf[4]; 326 327 for (i= 0; i<4; i++) 328 buf[i]= inb_ne(dep, NE_DATA); 329 330 r= (memcmp(buf, pat, 4) == 0); 331 return r; 332 } 333 334 /*===========================================================================* 335 * test_16 * 336 *===========================================================================*/ 337 static int test_16(dep, pos, pat) 338 dpeth_t *dep; 339 int pos; 340 u8_t *pat; 341 { 342 u8_t buf[4]; 256 343 int i; 257 258 outb_reg0(dep, DP_ISR, 0xff); 259 344 int r; 345 346 outb_reg0(dep, DP_ISR, 0xFF); 347 260 348 /* Setup a transfer to put the pattern. */ 261 349 outb_reg0(dep, DP_RBCR0, 4); 262 350 outb_reg0(dep, DP_RBCR1, 0); 263 outb_reg0(dep, DP_RSAR0, pos & 0xff);351 outb_reg0(dep, DP_RSAR0, pos &0xFF); 264 352 outb_reg0(dep, DP_RSAR1, pos >> 8); 265 353 outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA); 266 267 for (i = 0; i < 4; i += 2) 268 outw_ne(dep, NE_DATA, *(uint16_t *)(pat + i)); 269 270 for (i = 0; i < N; i++) { 354 355 for (i= 0; i<4; i += 2) 356 { 357 outw_ne(dep, NE_DATA, *(u16_t *)(pat+i)); 358 } 359 360 for (i= 0; i<N; i++) 361 { 271 362 if (inb_reg0(dep, DP_ISR) &ISR_RDC) 272 363 break; 273 364 } 274 275 if (i == N) { 276 printf("%s: NE2000 remote DMA test failed\n", dep->de_name); 365 if (i == N) 366 { 367 if (debug) 368 { 369 printf("%s: NE2000 remote DMA test failed\n", 370 dep->de_name); 371 } 277 372 return 0; 278 373 } 279 374 280 375 outb_reg0(dep, DP_RBCR0, 4); 281 376 outb_reg0(dep, DP_RBCR1, 0); 282 outb_reg0(dep, DP_RSAR0, pos & 0xff);377 outb_reg0(dep, DP_RSAR0, pos &0xFF); 283 378 outb_reg0(dep, DP_RSAR1, pos >> 8); 284 379 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA); 285 286 for (i = 0; i < 4; i += 2) 287 *(uint16_t *)(buf + i) = inw_ne(dep, NE_DATA); 288 289 return (memcmp(buf, pat, 4) == 0); 290 } 291 292 static void ne_stop(dpeth_t *dep) 293 { 380 381 for (i= 0; i<4; i += 2) 382 { 383 *(u16_t *)(buf+i)= inw_ne(dep, NE_DATA); 384 } 385 386 r= (memcmp(buf, pat, 4) == 0); 387 return r; 388 } 389 390 /*===========================================================================* 391 * ne_stop * 392 *===========================================================================*/ 393 static void ne_stop(dep) 394 dpeth_t *dep; 395 { 396 int byte; 397 294 398 /* Reset the ethernet card */ 295 int byte= inb_ne(dep, NE_RESET);296 usleep(2000);399 byte= inb_ne(dep, NE_RESET); 400 milli_delay(2); 297 401 outb_ne(dep, NE_RESET, byte); 298 402 } 403 /* 404 static void milli_delay(unsigned long millis) 405 { 406 tickdelay(MILLIS_TO_TICKS(millis)); 407 } 408 */ 409 #endif /* ENABLE_NE2000 */ 410 411 /* 412 * $PchId: ne2000.c,v 1.10 2004/08/03 12:03:00 philip Exp $ 413 */ 299 414 300 415 /** @}
Note:
See TracChangeset
for help on using the changeset viewer.