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