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

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

unix.superglobalmegacorp.com

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