Annotation of kernel/bsd/if/ppc/mace.c, revision 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.