Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/hw/netif/dp8390/ne2000.c

    r7e752b2 re0854e3  
    11/*
    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:
    3  *
    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
    8  *
    9  *
    10  * Disclaimer
    11  *
    12  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS, AUTHORS, AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
     2 * Copyright (c) 2009 Lukas Mejdrech
     3 * Copyright (c) 2011 Martin Decky
     4 * All rights reserved.
     5 *
     6 * Redistribution and use in source and binary forms, with or without
     7 * modification, are permitted provided that the following conditions
     8 * are met:
     9 *
     10 * - Redistributions of source code must retain the above copyright
     11 *   notice, this list of conditions and the following disclaimer.
     12 * - Redistributions in binary form must reproduce the above copyright
     13 *   notice, this list of conditions and the following disclaimer in the
     14 *   documentation and/or other materials provided with the distribution.
     15 * - The name of the author may not be used to endorse or promote products
     16 *   derived from this software without specific prior written permission.
     17 *
     18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    1319 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    1420 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    15  * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ANY AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
    1622 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
    1723 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     
    2026 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    2127 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    22  *
    23  * Changes:
    24  *  2009 ported to HelenOS, Lukas Mejdrech
     28 */
     29
     30/*
     31 * This code is based upon the NE2000 driver for MINIX,
     32 * distributed according to a BSD-style license.
     33 *
     34 * Copyright (c) 1987, 1997, 2006 Vrije Universiteit
     35 * Copyright (c) 1992, 1994 Philip Homburg
     36 * Copyright (c) 1996 G. Falzoni
     37 *
    2538 */
    2639
     
    3548#include <stdio.h>
    3649#include <unistd.h>
    37 
    3850#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"
    5851#include "dp8390.h"
    5952#include "ne2000.h"
    6053
    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};
     54/** Number of bytes to transfer */
     55#define N  100
     56
     57typedef int (*testf_t)(dpeth_t *dep, int pos, uint8_t *pat);
     58
     59/** Data patterns */
     60uint8_t pat0[] = {0x00, 0x00, 0x00, 0x00};
     61uint8_t pat1[] = {0xFF, 0xFF, 0xFF, 0xFF};
     62uint8_t pat2[] = {0xA5, 0x5A, 0x69, 0x96};
     63uint8_t pat3[] = {0x96, 0x69, 0x5A, 0xA5};
    9364
    9465/** Tests 8 bit NE2000 network interface.
     
    9768 *  @param[in] pat The data pattern to be written.
    9869 *  @returns True on success.
    99  *  @returns FALSE otherwise.
    100  */
    101 static int test_8(dpeth_t *dep, int pos, u8_t *pat);
     70 *  @returns false otherwise.
     71 */
     72static int test_8(dpeth_t *dep, int pos, uint8_t *pat);
    10273
    10374/** Tests 16 bit NE2000 network interface.
     
    10677 *  @param[in] pat The data pattern to be written.
    10778 *  @returns True on success.
    108  *  @returns FALSE otherwise.
    109  */
    110 static int test_16(dpeth_t *dep, int pos, u8_t *pat);
     79 *  @returns false otherwise.
     80 */
     81static int test_16(dpeth_t *dep, int pos, uint8_t *pat);
    11182
    11283/** Stops the NE2000 network interface.
     
    11485 */
    11586static void ne_stop(dpeth_t *dep);
    116 //_PROTOTYPE(static void milli_delay, (unsigned long millis)            );
    11787
    11888/** Initializes the NE2000 network interface.
     
    12191void ne_init(struct dpeth *dep);
    12292
    123 /*===========================================================================*
    124  *                              ne_probe                                     *
    125  *===========================================================================*/
    126 int ne_probe(dep)
    127 dpeth_t *dep;
     93int ne_probe(dpeth_t *dep)
    12894{
    12995        int byte;
     
    13197        int loc1, loc2;
    13298        testf_t f;
    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
     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
    137104         * on board is reachable through the dp8390. Note that the
    138105         * ne1000 is an 8bit card and has a memory region distict from
    139106         * the 16bit ne2000
    140107         */
    141 
    142         for (dep->de_16bit= 0; dep->de_16bit < 2; dep->de_16bit++)
    143         {
     108       
     109        for (dep->de_16bit = 0; dep->de_16bit < 2; dep->de_16bit++) {
    144110                /* Reset the ethernet card */
    145111                byte= inb_ne(dep, NE_RESET);
    146                 milli_delay(2);
     112                usleep(2000);
    147113                outb_ne(dep, NE_RESET, byte);
    148                 milli_delay(2);
    149 
     114                usleep(2000);
     115               
    150116                /* Reset the dp8390 */
    151117                outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT);
    152                 for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) &ISR_RST) == 0); i++)
     118                for (i = 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RST) == 0); i++)
    153119                        ; /* Do nothing */
    154 
     120               
    155121                /* Check if the dp8390 is really there */
    156                 if ((inb_reg0(dep, DP_CR) &(CR_STP|CR_DM_ABORT)) !=
    157                         (CR_STP|CR_DM_ABORT))
    158                 {
     122                if ((inb_reg0(dep, DP_CR) & (CR_STP | CR_DM_ABORT)) !=
     123                    (CR_STP | CR_DM_ABORT))
    159124                        return 0;
    160                 }
    161 
     125               
    162126                /* Disable the receiver and init TCR and DCR. */
    163127                outb_reg0(dep, DP_RCR, RCR_MON);
    164128                outb_reg0(dep, DP_TCR, TCR_NORMAL);
    165                 if (dep->de_16bit)
    166                 {
     129                if (dep->de_16bit) {
    167130                        outb_reg0(dep, DP_DCR, DCR_WORDWIDE | DCR_8BYTES |
    168                                 DCR_BMS);
     131                            DCR_BMS);
     132                } else {
     133                        outb_reg0(dep, DP_DCR, DCR_BYTEWIDE | DCR_8BYTES |
     134                            DCR_BMS);
    169135                }
    170                 else
    171                 {
    172                         outb_reg0(dep, DP_DCR, DCR_BYTEWIDE | DCR_8BYTES |
    173                                 DCR_BMS);
    174                 }
    175 
    176                 if (dep->de_16bit)
    177                 {
     136               
     137                if (dep->de_16bit) {
    178138                        loc1= NE2000_START;
    179139                        loc2= NE2000_START + NE2000_SIZE - 4;
    180140                        f= test_16;
    181                 }
    182                 else
    183                 {
     141                } else {
    184142                        loc1= NE1000_START;
    185143                        loc2= NE1000_START + NE1000_SIZE - 4;
    186144                        f= test_8;
    187145                }
    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;
     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;
    199153                        return 1;
    200154                }
    201155        }
     156       
    202157        return 0;
    203158}
    204159
    205 /*===========================================================================*
    206  *                              ne_init                                      *
    207  *===========================================================================*/
    208 void ne_init(dep)
    209 dpeth_t *dep;
     160void ne_init(dpeth_t *dep)
    210161{
    211162        int i;
    212163        int word, sendq_nr;
    213 
     164       
    214165        /* Setup a transfer to get the ethernet address. */
    215166        if (dep->de_16bit)
     
    217168        else
    218169                outb_reg0(dep, DP_RBCR0, 6);
     170       
    219171        outb_reg0(dep, DP_RBCR1, 0);
    220172        outb_reg0(dep, DP_RSAR0, 0);
    221173        outb_reg0(dep, DP_RSAR1, 0);
    222174        outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
    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                 {
     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
    233181                        dep->de_address.ea_addr[i] = inb_ne(dep, NE_DATA);
    234                 }
    235         }
     182        }
     183       
    236184        dep->de_data_port= dep->de_base_port + NE_DATA;
    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 
     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       
    248193        /* Allocate one send buffer (1.5KB) per 8KB of on board memory. */
    249         sendq_nr= dep->de_ramsize / 0x2000;
     194        sendq_nr = dep->de_ramsize / 0x2000;
     195       
    250196        if (sendq_nr < 1)
    251                 sendq_nr= 1;
     197                sendq_nr = 1;
    252198        else if (sendq_nr > SENDQ_NR)
    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];
     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
     214static int test_8(dpeth_t *dep, int pos, uint8_t *pat)
     215{
     216        uint8_t buf[4];
    291217        int i;
    292         int r;
    293 
    294         outb_reg0(dep, DP_ISR, 0xFF);
    295 
     218       
     219        outb_reg0(dep, DP_ISR, 0xff);
     220       
    296221        /* Setup a transfer to put the pattern. */
    297222        outb_reg0(dep, DP_RBCR0, 4);
    298223        outb_reg0(dep, DP_RBCR1, 0);
    299         outb_reg0(dep, DP_RSAR0, pos &0xFF);
     224        outb_reg0(dep, DP_RSAR0, pos & 0xff);
    300225        outb_reg0(dep, DP_RSAR1, pos >> 8);
    301226        outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
    302 
    303         for (i= 0; i<4; i++)
     227       
     228        for (i = 0; i < 4; i++)
    304229                outb_ne(dep, NE_DATA, pat[i]);
    305 
    306         for (i= 0; i<N; i++)
    307         {
     230       
     231        for (i = 0; i < N; i++) {
     232                if (inb_reg0(dep, DP_ISR) & ISR_RDC)
     233                        break;
     234        }
     235       
     236        if (i == N) {
     237                printf("%s: NE1000 remote DMA test failed\n", dep->de_name);
     238                return 0;
     239        }
     240       
     241        outb_reg0(dep, DP_RBCR0, 4);
     242        outb_reg0(dep, DP_RBCR1, 0);
     243        outb_reg0(dep, DP_RSAR0, pos & 0xff);
     244        outb_reg0(dep, DP_RSAR1, pos >> 8);
     245        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
     253static int test_16(dpeth_t *dep, int pos, uint8_t *pat)
     254{
     255        uint8_t buf[4];
     256        int i;
     257       
     258        outb_reg0(dep, DP_ISR, 0xff);
     259       
     260        /* Setup a transfer to put the pattern. */
     261        outb_reg0(dep, DP_RBCR0, 4);
     262        outb_reg0(dep, DP_RBCR1, 0);
     263        outb_reg0(dep, DP_RSAR0, pos & 0xff);
     264        outb_reg0(dep, DP_RSAR1, pos >> 8);
     265        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++) {
    308271                if (inb_reg0(dep, DP_ISR) &ISR_RDC)
    309272                        break;
    310273        }
    311         if (i == N)
    312         {
    313                 if (debug)
    314                 {
    315                         printf("%s: NE1000 remote DMA test failed\n",
    316                                 dep->de_name);
    317                 }
     274       
     275        if (i == N) {
     276                printf("%s: NE2000 remote DMA test failed\n", dep->de_name);
    318277                return 0;
    319278        }
    320 
     279       
    321280        outb_reg0(dep, DP_RBCR0, 4);
    322281        outb_reg0(dep, DP_RBCR1, 0);
    323         outb_reg0(dep, DP_RSAR0, pos &0xFF);
     282        outb_reg0(dep, DP_RSAR0, pos & 0xff);
    324283        outb_reg0(dep, DP_RSAR1, pos >> 8);
    325284        outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
    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];
    343         int i;
    344         int r;
    345 
    346         outb_reg0(dep, DP_ISR, 0xFF);
    347 
    348         /* Setup a transfer to put the pattern. */
    349         outb_reg0(dep, DP_RBCR0, 4);
    350         outb_reg0(dep, DP_RBCR1, 0);
    351         outb_reg0(dep, DP_RSAR0, pos &0xFF);
    352         outb_reg0(dep, DP_RSAR1, pos >> 8);
    353         outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
    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         {
    362                 if (inb_reg0(dep, DP_ISR) &ISR_RDC)
    363                         break;
    364         }
    365         if (i == N)
    366         {
    367                 if (debug)
    368                 {
    369                         printf("%s: NE2000 remote DMA test failed\n",
    370                                 dep->de_name);
    371                 }
    372                 return 0;
    373         }
    374 
    375         outb_reg0(dep, DP_RBCR0, 4);
    376         outb_reg0(dep, DP_RBCR1, 0);
    377         outb_reg0(dep, DP_RSAR0, pos &0xFF);
    378         outb_reg0(dep, DP_RSAR1, pos >> 8);
    379         outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
    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 
     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
     292static void ne_stop(dpeth_t *dep)
     293{
    398294        /* Reset the ethernet card */
    399         byte= inb_ne(dep, NE_RESET);
    400         milli_delay(2);
     295        int byte = inb_ne(dep, NE_RESET);
     296        usleep(2000);
    401297        outb_ne(dep, NE_RESET, byte);
    402298}
    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  */
    414299
    415300/** @}
Note: See TracChangeset for help on using the changeset viewer.