|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.