Annotation of XNU/bsd/if/ppc/mace.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: /*
                     23:  * MACE Device-dependent code (some still lives in if_en.c):
                     24:  *
                     25:  * MACE Multicast Address scheme -
                     26:  *  Compute Enet CRC for each Mcast address; take high 6 bits of 32-bit
                     27:  *   crc, giving a "bit index" into a 64-bit register.  On packet receipt,
                     28:  *   if corresponding bit is set, accept packet.
                     29:  *  We keep track of requests in a per-hash-value table (16-bit counters
                     30:  *   should be sufficient).  Since we're hashing, we only care about the
                     31:  *   hash value of each address.
                     32:  *
                     33:  * Apple Confidential
                     34:  *
                     35:  * (C) COPYRIGHT Apple Computer, Inc., 1994-1997
                     36:  * All Rights Reserved
                     37:  *
                     38:  * Justin C. Walker
                     39:  */
                     40: #include <machdep/ppc/dbdma.h>
                     41: 
                     42: #import <sys/types.h>
                     43: #import <sys/param.h>
                     44: #import <sys/errno.h>
                     45: #import <sys/socket.h>
                     46: #import <net/if.h>
                     47: #import <net/etherdefs.h>
                     48: #import        <netinet/if_ether.h>
                     49: #import        <sys/sockio.h>
                     50: #import        <netinet/in_var.h>
                     51: #import        <netinet/in.h>
                     52: #import <sys/mbuf.h>
                     53: #import <mach/mach_types.h>
                     54: #import <ppc/powermac.h>
                     55: #import <ppc/interrupts.h>
                     56: #import <ppc/proc_reg.h>
                     57: #include <libkern/libkern.h>
                     58: #import "if_en.h"
                     59: #import "mace.h"
                     60: 
                     61: extern mace_t mace;
                     62: 
                     63: #define ENET_CRCPOLY 0x04c11db7
                     64: 
                     65: /* Real fast bit-reversal algorithm, 6-bit values */
                     66: int reverse6[] = 
                     67: {      0x0,0x20,0x10,0x30,0x8,0x28,0x18,0x38,
                     68:        0x4,0x24,0x14,0x34,0xc,0x2c,0x1c,0x3c,
                     69:        0x2,0x22,0x12,0x32,0xa,0x2a,0x1a,0x3a,
                     70:        0x6,0x26,0x16,0x36,0xe,0x2e,0x1e,0x3e,
                     71:        0x1,0x21,0x11,0x31,0x9,0x29,0x19,0x39,
                     72:        0x5,0x25,0x15,0x35,0xd,0x2d,0x1d,0x3d,
                     73:        0x3,0x23,0x13,0x33,0xb,0x2b,0x1b,0x3b,
                     74:        0x7,0x27,0x17,0x37,0xf,0x2f,0x1f,0x3f
                     75: };
                     76: 
                     77: unsigned int crc416(current, nxtval)
                     78: register unsigned int current;
                     79: register unsigned short nxtval;
                     80: {      register unsigned int counter;
                     81:        register int highCRCBitSet, lowDataBitSet;
                     82: 
                     83:        /* Swap bytes */
                     84:        nxtval = ((nxtval & 0x00FF) << 8) | (nxtval >> 8);
                     85: 
                     86:        /* Compute bit-by-bit */
                     87:        for (counter = 0; counter != 16; ++counter)
                     88:        {       /* is high CRC bit set? */
                     89:                if ((current & 0x80000000) == NULL)
                     90:                        highCRCBitSet = 0;
                     91:                else
                     92:                        highCRCBitSet = 1;
                     93:                
                     94:                current = current << 1;
                     95:        
                     96:                if ((nxtval & 0x0001) == NULL)
                     97:                        lowDataBitSet = 0;
                     98:                else
                     99:                        lowDataBitSet = 1;
                    100: 
                    101:                nxtval = nxtval >> 1;
                    102:        
                    103:                /* do the XOR */
                    104:                if (highCRCBitSet ^ lowDataBitSet)
                    105:                        current = current ^ ENET_CRCPOLY;
                    106:        }
                    107:        return current;
                    108: }
                    109: 
                    110: unsigned int mace_crc(unsigned short *address)
                    111: {      register unsigned int newcrc;
                    112: 
                    113:        newcrc = crc416(0xffffffff, *address);  /* address bits 47 - 32 */
                    114:        newcrc = crc416(newcrc, address[1]);    /* address bits 31 - 16 */
                    115:        newcrc = crc416(newcrc, address[2]);    /* address bits 15 - 0 */
                    116: 
                    117:        return(newcrc);
                    118: }
                    119: 
                    120: /*
                    121:  * Add requested mcast addr to Mace's filter.  Assume that the first
                    122:  *  address in the arpcom ac_multiaddrs list is the one we're interested in.
                    123:  */
                    124: int
                    125: mace_addmulti(register struct ifreq *ifr, register struct arpcom *ar)
                    126: {      register unsigned char *addr;
                    127:        unsigned int crc;
                    128:        unsigned char mask;
                    129: 
                    130:        addr = ar->ac_multiaddrs->enm_addrlo;
                    131: 
                    132:        crc = mace_crc((unsigned short *)addr)&0x3f; /* Big-endian alert! */
                    133:        crc = reverse6[crc];    /* Hyperfast bit-reversing algorithm */
                    134:        if (mace.multi_use[crc]++)
                    135:                return(0);              /* This bit is already set */
                    136:        mask = crc % 8;
                    137:        mask = (unsigned char)1 << mask;
                    138:        mace.multi_mask[crc/8] |= mask;
                    139:        return(1);
                    140: }
                    141: 
                    142: int
                    143: mace_delmulti(register struct ifreq *ifr, register struct arpcom *ar,
                    144:              struct ether_addr * enaddr)
                    145: {      register unsigned char *addr;
                    146:        unsigned int crc;
                    147:        unsigned char mask;
                    148: 
                    149:        addr = (char *)enaddr; /* XXX assumes addrlo == addrhi */
                    150: 
                    151:        /* Now, delete the address from the filter copy, as indicated */
                    152:        crc = mace_crc((unsigned short *)addr)&0x3f; /* Big-endian alert! */
                    153:        crc = reverse6[crc];    /* Hyperfast bit-reversing algorithm */
                    154:        if (mace.multi_use[crc] == 0)
                    155:                return(EINVAL);         /* That bit wasn't in use! */
                    156: 
                    157:        if (--mace.multi_use[crc])
                    158:                return(0);              /* That bit is still in use */
                    159: 
                    160:        mask = crc % 8;
                    161:        mask = ((unsigned char)1 << mask) ^ 0xff; /* To turn off bit */
                    162:        mace.multi_mask[crc/8] &= mask;
                    163:        return(1);
                    164: }
                    165: 
                    166: /*
                    167:  * Sync the adapter with the software copy of the multicast mask
                    168:  *  (logical address filter).
                    169:  * If we want all m-cast addresses, we just blast 1's into the filter.
                    170:  *  When we reverse this, we can use the current state of the (software)
                    171:  *  filter, which should have been kept up to date.
                    172:  */
                    173: void
                    174: mace_sync_mcast(register struct ifnet * ifp)
                    175: {      register unsigned long temp, temp1;
                    176:        register int      i;
                    177:        register char    *p;
                    178:        register struct mace_board *ereg = mace.ereg;
                    179: 
                    180:        temp = ereg->maccc;
                    181: 
                    182:        /*
                    183:         * Have to deal with early rev of chip for updating LAF
                    184:         * Don't know if any MacOSX systems still run this rev.
                    185:         */
                    186:        if (mace.chip_id == MACERevA2)
                    187:        {       /* First, turn off receiver */
                    188:                temp1 = temp&~MACCC_ENRCV;
                    189:                ereg->maccc = temp1;
                    190:                eieio();
                    191: 
                    192:                /* Then, check FIFO - frame being received will complete */
                    193:                temp1 = ereg->fifofc;
                    194: 
                    195:                mace.ereg->iac = IAC_LOGADDR;
                    196:                eieio();
                    197:        } else
                    198:        {       ereg->iac = IAC_ADDRCHG|IAC_LOGADDR;
                    199:                eieio();
                    200: 
                    201:                while (temp1 = ereg->iac)
                    202:                {       eieio();
                    203:                        if ((temp1&IAC_ADDRCHG) == 0)
                    204:                                break;
                    205:                }
                    206:        }
                    207: 
                    208:        if (ifp->if_flags & IFF_ALLMULTI)       /* Then want ALL m-cast pkts */
                    209:        {       /* set mask to all 1's */
                    210:                for (i=0;i<8;i++)
                    211:                {       ereg->ladrf = 0xff;
                    212:                        eieio();
                    213:                }
                    214:        } else
                    215:        {
                    216:                /* Assuming everything is big-endian */
                    217:                for (i=0, p = &mace.multi_mask[0];i<8;i++)
                    218:                {       ereg->ladrf = *p++;
                    219:                        eieio();
                    220:                }
                    221:        }
                    222: 
                    223:        ereg->maccc = temp;             /* Reset config ctrlr */
                    224:        eieio();
                    225: 
                    226: }
                    227: 
                    228: void
                    229: mace_sync_promisc(register struct ifnet *ifp)
                    230: {
                    231:        register u_long o_maccc, n_maccc;
                    232:        register struct mace_board *ereg = mace.ereg;
                    233: 
                    234:        /*
                    235:         * Save current state and disable receive.
                    236:         */
                    237:        o_maccc = ereg->maccc;
                    238:        n_maccc = o_maccc & ~MACCC_ENRCV;
                    239:        ereg->maccc = n_maccc;
                    240:        eieio();
                    241: 
                    242:        /*
                    243:         * Calculate new desired state
                    244:         */
                    245:        if (ifp->if_flags & IFF_PROMISC) {
                    246:                /* set PROMISC bit */
                    247:                o_maccc |= MACCC_PROM;
                    248:        } else {
                    249:                /* clear PROMISC bit */
                    250:                o_maccc &= ~MACCC_PROM;
                    251:        }
                    252: 
                    253:        /*
                    254:         * Note that the "old" mode includes the new promiscuous state now.
                    255:         */
                    256:        ereg->maccc = o_maccc;
                    257:        eieio();
                    258: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.