1*5256Slh155975 /* 2*5256Slh155975 * CDDL HEADER START 3*5256Slh155975 * 4*5256Slh155975 * The contents of this file are subject to the terms of the 5*5256Slh155975 * Common Development and Distribution License (the "License"). 6*5256Slh155975 * You may not use this file except in compliance with the License. 7*5256Slh155975 * 8*5256Slh155975 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*5256Slh155975 * or http://www.opensolaris.org/os/licensing. 10*5256Slh155975 * See the License for the specific language governing permissions 11*5256Slh155975 * and limitations under the License. 12*5256Slh155975 * 13*5256Slh155975 * When distributing Covered Code, include this CDDL HEADER in each 14*5256Slh155975 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*5256Slh155975 * If applicable, add the following below this CDDL HEADER, with the 16*5256Slh155975 * fields enclosed by brackets "[]" replaced with your own identifying 17*5256Slh155975 * information: Portions Copyright [yyyy] [name of copyright owner] 18*5256Slh155975 * 19*5256Slh155975 * CDDL HEADER END 20*5256Slh155975 */ 21*5256Slh155975 22*5256Slh155975 /* 23*5256Slh155975 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24*5256Slh155975 * Use is subject to license terms. 25*5256Slh155975 */ 26*5256Slh155975 27*5256Slh155975 #pragma ident "%Z%%M% %I% %E% SMI" 28*5256Slh155975 29*5256Slh155975 /* 30*5256Slh155975 * Copyright (c) 2001-2006 Advanced Micro Devices, Inc. All rights reserved. 31*5256Slh155975 * 32*5256Slh155975 * Redistribution and use in source and binary forms, with or without 33*5256Slh155975 * modification, are permitted provided that the following conditions are met: 34*5256Slh155975 * 35*5256Slh155975 * + Redistributions of source code must retain the above copyright notice, 36*5256Slh155975 * + this list of conditions and the following disclaimer. 37*5256Slh155975 * 38*5256Slh155975 * + Redistributions in binary form must reproduce the above copyright 39*5256Slh155975 * + notice, this list of conditions and the following disclaimer in the 40*5256Slh155975 * + documentation and/or other materials provided with the distribution. 41*5256Slh155975 * 42*5256Slh155975 * + Neither the name of Advanced Micro Devices, Inc. nor the names of its 43*5256Slh155975 * + contributors may be used to endorse or promote products derived from 44*5256Slh155975 * + this software without specific prior written permission. 45*5256Slh155975 * 46*5256Slh155975 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 47*5256Slh155975 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 48*5256Slh155975 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 49*5256Slh155975 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 50*5256Slh155975 * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. OR 51*5256Slh155975 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 52*5256Slh155975 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 53*5256Slh155975 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 54*5256Slh155975 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55*5256Slh155975 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 56*5256Slh155975 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 57*5256Slh155975 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 58*5256Slh155975 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 59*5256Slh155975 * 60*5256Slh155975 * Import/Export/Re-Export/Use/Release/Transfer Restrictions and 61*5256Slh155975 * Compliance with Applicable Laws. Notice is hereby given that 62*5256Slh155975 * the software may be subject to restrictions on use, release, 63*5256Slh155975 * transfer, importation, exportation and/or re-exportation under 64*5256Slh155975 * the laws and regulations of the United States or other 65*5256Slh155975 * countries ("Applicable Laws"), which include but are not 66*5256Slh155975 * limited to U.S. export control laws such as the Export 67*5256Slh155975 * Administration Regulations and national security controls as 68*5256Slh155975 * defined thereunder, as well as State Department controls under 69*5256Slh155975 * the U.S. Munitions List. Permission to use and/or 70*5256Slh155975 * redistribute the software is conditioned upon compliance with 71*5256Slh155975 * all Applicable Laws, including U.S. export control laws 72*5256Slh155975 * regarding specifically designated persons, countries and 73*5256Slh155975 * nationals of countries subject to national security controls. 74*5256Slh155975 */ 75*5256Slh155975 76*5256Slh155975 77*5256Slh155975 #include <sys/types.h> 78*5256Slh155975 #include <sys/cmn_err.h> 79*5256Slh155975 #include <sys/debug.h> 80*5256Slh155975 #include <sys/ddi.h> 81*5256Slh155975 #include <sys/sunddi.h> 82*5256Slh155975 #include "amd8111s_hw.h" 83*5256Slh155975 #include "amd8111s_main.h" 84*5256Slh155975 85*5256Slh155975 86*5256Slh155975 #pragma inline(mdlTransmit) 87*5256Slh155975 #pragma inline(mdlReceive) 88*5256Slh155975 89*5256Slh155975 #pragma inline(mdlReadInterrupt) 90*5256Slh155975 #pragma inline(mdlEnableInterrupt) 91*5256Slh155975 #pragma inline(mdlDisableInterrupt) 92*5256Slh155975 93*5256Slh155975 94*5256Slh155975 static void mdlEnableMagicPacketWakeUp(struct LayerPointers *); 95*5256Slh155975 96*5256Slh155975 /* PMR (Pattern Match RAM) */ 97*5256Slh155975 static void mdlAddWakeUpPattern(struct LayerPointers *, unsigned char *, 98*5256Slh155975 unsigned char *, unsigned long, unsigned long, int *); 99*5256Slh155975 static void mdlRemoveWakeUpPattern(struct LayerPointers *, unsigned char *, 100*5256Slh155975 unsigned long, int *); 101*5256Slh155975 102*5256Slh155975 static int mdlMulticastBitMapping(struct LayerPointers *, unsigned char *, int); 103*5256Slh155975 104*5256Slh155975 static unsigned int mdlCalculateCRC(unsigned int, unsigned char *); 105*5256Slh155975 106*5256Slh155975 static void mdlChangeFilter(struct LayerPointers *, unsigned long *); 107*5256Slh155975 static void mdlReceiveBroadCast(struct LayerPointers *); 108*5256Slh155975 static void mdlDisableReceiveBroadCast(struct LayerPointers *); 109*5256Slh155975 110*5256Slh155975 static void mdlRequestResources(ULONG *); 111*5256Slh155975 static void mdlSetResources(struct LayerPointers *, ULONG *); 112*5256Slh155975 static void mdlFreeResources(struct LayerPointers *, ULONG *); 113*5256Slh155975 114*5256Slh155975 /* 115*5256Slh155975 * Initialises the data used in Mdl. 116*5256Slh155975 */ 117*5256Slh155975 static void 118*5256Slh155975 mdlInitGlbds(struct LayerPointers *pLayerPointers) 119*5256Slh155975 { 120*5256Slh155975 struct mdl *pMdl = pLayerPointers->pMdl; 121*5256Slh155975 122*5256Slh155975 /* Disable Rx and Tx. */ 123*5256Slh155975 pMdl->init_blk->MODE = 0x0000; 124*5256Slh155975 125*5256Slh155975 /* Set Interrupt Delay Parameters */ 126*5256Slh155975 pMdl->IntrCoalescFlag = 1; 127*5256Slh155975 pMdl->rx_intrcoalesc_time = 0xC8; /* 200 */ 128*5256Slh155975 pMdl->rx_intrcoalesc_events = 5; 129*5256Slh155975 } 130*5256Slh155975 131*5256Slh155975 void 132*5256Slh155975 mdlPHYAutoNegotiation(struct LayerPointers *pLayerPointers, unsigned int type) 133*5256Slh155975 { 134*5256Slh155975 int iData = 0; 135*5256Slh155975 struct mdl *pMdl = pLayerPointers->pMdl; 136*5256Slh155975 137*5256Slh155975 /* PHY auto negotiation or force speed/duplex */ 138*5256Slh155975 switch (type) { 139*5256Slh155975 case PHY_AUTO_NEGOTIATION: /* Auto Negotiation */ 140*5256Slh155975 /* EN_PMGR: Disable the Port Manager */ 141*5256Slh155975 WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD3, EN_PMGR); 142*5256Slh155975 drv_usecwait(100000); 143*5256Slh155975 144*5256Slh155975 /* 145*5256Slh155975 * Enable Autonegotiation the Phy now 146*5256Slh155975 * XPHYANE(eXternal PHY Auto Negotiation Enable) 147*5256Slh155975 */ 148*5256Slh155975 WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CTRL2, 149*5256Slh155975 XPHYANE | XPHYRST); 150*5256Slh155975 151*5256Slh155975 /* EN_PMGR: Enable the Port Manager */ 152*5256Slh155975 WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD3, 153*5256Slh155975 VAL1 | EN_PMGR); 154*5256Slh155975 155*5256Slh155975 drv_usecwait(500000); 156*5256Slh155975 157*5256Slh155975 pMdl->Speed = 100; 158*5256Slh155975 pMdl->FullDuplex = B_TRUE; 159*5256Slh155975 160*5256Slh155975 break; 161*5256Slh155975 162*5256Slh155975 case PHY_FORCE_HD_100: /* 100Mbps HD */ 163*5256Slh155975 WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD3, EN_PMGR); 164*5256Slh155975 165*5256Slh155975 /* Force 100 Mbps, half duplex */ 166*5256Slh155975 iData |= XPHYSP; 167*5256Slh155975 WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CTRL2, iData); 168*5256Slh155975 169*5256Slh155975 WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD3, 170*5256Slh155975 VAL1 | EN_PMGR); 171*5256Slh155975 172*5256Slh155975 drv_usecwait(500000); 173*5256Slh155975 174*5256Slh155975 pMdl->Speed = 100; 175*5256Slh155975 pMdl->FullDuplex = B_FALSE; 176*5256Slh155975 177*5256Slh155975 break; 178*5256Slh155975 179*5256Slh155975 case PHY_FORCE_FD_100: /* 100Mbps FD */ 180*5256Slh155975 WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD3, EN_PMGR); 181*5256Slh155975 182*5256Slh155975 /* Force 100 Mbps, full duplex */ 183*5256Slh155975 iData |= (XPHYSP | XPHYFD); 184*5256Slh155975 WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CTRL2, iData); 185*5256Slh155975 186*5256Slh155975 WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD3, 187*5256Slh155975 VAL1 | EN_PMGR); 188*5256Slh155975 189*5256Slh155975 drv_usecwait(500000); 190*5256Slh155975 191*5256Slh155975 pMdl->Speed = 100; 192*5256Slh155975 pMdl->FullDuplex = B_TRUE; 193*5256Slh155975 194*5256Slh155975 break; 195*5256Slh155975 196*5256Slh155975 case PHY_FORCE_HD_10: /* 10 Mbps HD */ 197*5256Slh155975 /* Disable the Port Manager */ 198*5256Slh155975 WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD3, EN_PMGR); 199*5256Slh155975 WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CTRL2, iData); 200*5256Slh155975 WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD3, 201*5256Slh155975 VAL1 | EN_PMGR); 202*5256Slh155975 203*5256Slh155975 drv_usecwait(500000); 204*5256Slh155975 205*5256Slh155975 pMdl->Speed = 10; 206*5256Slh155975 pMdl->FullDuplex = B_FALSE; 207*5256Slh155975 208*5256Slh155975 break; 209*5256Slh155975 210*5256Slh155975 case PHY_FORCE_FD_10: /* 10Mbps FD */ 211*5256Slh155975 WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD3, EN_PMGR); 212*5256Slh155975 213*5256Slh155975 iData |= XPHYFD; 214*5256Slh155975 WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CTRL2, iData); 215*5256Slh155975 216*5256Slh155975 WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD3, 217*5256Slh155975 VAL1 | EN_PMGR); 218*5256Slh155975 219*5256Slh155975 drv_usecwait(500000); 220*5256Slh155975 221*5256Slh155975 pMdl->Speed = 10; 222*5256Slh155975 pMdl->FullDuplex = B_TRUE; 223*5256Slh155975 224*5256Slh155975 break; 225*5256Slh155975 } 226*5256Slh155975 } 227*5256Slh155975 228*5256Slh155975 /* 229*5256Slh155975 * Clear HW configuration. 230*5256Slh155975 */ 231*5256Slh155975 static void 232*5256Slh155975 mdlClearHWConfig(struct LayerPointers *pLayerPointers) 233*5256Slh155975 { 234*5256Slh155975 /* 235*5256Slh155975 * Before the network controller is ready for operation, 236*5256Slh155975 * several registers must be initialized. 237*5256Slh155975 */ 238*5256Slh155975 unsigned int data32; 239*5256Slh155975 int JumboFlag = JUMBO_DISABLED; 240*5256Slh155975 ULONG MemBaseAddress; 241*5256Slh155975 242*5256Slh155975 MemBaseAddress = pLayerPointers->pMdl->Mem_Address; 243*5256Slh155975 244*5256Slh155975 /* AUTOPOLL0 Register */ 245*5256Slh155975 WRITE_REG16(pLayerPointers, MemBaseAddress + AUTOPOLL0, 0x8101); 246*5256Slh155975 247*5256Slh155975 /* Clear RCV_RING_BASE_ADDR */ 248*5256Slh155975 WRITE_REG32(pLayerPointers, MemBaseAddress + RCV_RING_BASE_ADDR0, 0); 249*5256Slh155975 WRITE_REG32(pLayerPointers, MemBaseAddress + RCV_RING_BASE_ADDR1, 0); 250*5256Slh155975 WRITE_REG32(pLayerPointers, MemBaseAddress + RCV_RING_BASE_ADDR0, 0); 251*5256Slh155975 WRITE_REG32(pLayerPointers, MemBaseAddress + RCV_RING_BASE_ADDR2, 0); 252*5256Slh155975 WRITE_REG32(pLayerPointers, MemBaseAddress + RCV_RING_BASE_ADDR3, 0); 253*5256Slh155975 254*5256Slh155975 /* Clear XMT_RING_BASE_ADDR */ 255*5256Slh155975 WRITE_REG32(pLayerPointers, MemBaseAddress + XMT_RING_BASE_ADDR0, 0); 256*5256Slh155975 WRITE_REG32(pLayerPointers, MemBaseAddress + XMT_RING_BASE_ADDR1, 0); 257*5256Slh155975 WRITE_REG32(pLayerPointers, MemBaseAddress + XMT_RING_BASE_ADDR2, 0); 258*5256Slh155975 WRITE_REG32(pLayerPointers, MemBaseAddress + XMT_RING_BASE_ADDR3, 0); 259*5256Slh155975 260*5256Slh155975 /* Clear CMD0 / CMD2 */ 261*5256Slh155975 WRITE_REG32(pLayerPointers, MemBaseAddress + CMD0, 0x000F0F7F); 262*5256Slh155975 WRITE_REG32(pLayerPointers, MemBaseAddress + CMD2, 0x3F7F3F7F); 263*5256Slh155975 264*5256Slh155975 /* Enable Port Management */ 265*5256Slh155975 WRITE_REG32(pLayerPointers, MemBaseAddress + CMD3, VAL1 | EN_PMGR); 266*5256Slh155975 267*5256Slh155975 /* Clear CMD7 */ 268*5256Slh155975 WRITE_REG32(pLayerPointers, MemBaseAddress + CMD7, 0x1B); 269*5256Slh155975 270*5256Slh155975 /* Clear CTRL0/1 */ 271*5256Slh155975 WRITE_REG32(pLayerPointers, MemBaseAddress + CTRL1, XMTSP_MASK); 272*5256Slh155975 273*5256Slh155975 /* Clear DLY_INT_A/B */ 274*5256Slh155975 WRITE_REG32(pLayerPointers, MemBaseAddress + DLY_INT_A, 0); 275*5256Slh155975 WRITE_REG32(pLayerPointers, MemBaseAddress + DLY_INT_B, 0); 276*5256Slh155975 277*5256Slh155975 /* Clear FLOW_CONTROL */ 278*5256Slh155975 WRITE_REG32(pLayerPointers, MemBaseAddress + FLOW_CONTROL, 0); 279*5256Slh155975 280*5256Slh155975 /* Clear INT0 */ 281*5256Slh155975 data32 = READ_REG32(pLayerPointers, MemBaseAddress + INT0); 282*5256Slh155975 WRITE_REG32(pLayerPointers, MemBaseAddress + INT0, data32); 283*5256Slh155975 284*5256Slh155975 /* Clear STVAL */ 285*5256Slh155975 WRITE_REG32(pLayerPointers, MemBaseAddress + STVAL, 0); 286*5256Slh155975 287*5256Slh155975 /* Clear INTEN0 */ 288*5256Slh155975 WRITE_REG32(pLayerPointers, MemBaseAddress + INTEN0, 0x1F7F7F1F); 289*5256Slh155975 290*5256Slh155975 /* Clear LADRF */ 291*5256Slh155975 WRITE_REG32(pLayerPointers, MemBaseAddress + LADRF1, 0); 292*5256Slh155975 WRITE_REG32(pLayerPointers, MemBaseAddress + LADRF1 + 4, 0); 293*5256Slh155975 294*5256Slh155975 /* Clear LED0 */ 295*5256Slh155975 WRITE_REG32(pLayerPointers, MemBaseAddress + LED0, 0); 296*5256Slh155975 WRITE_REG32(pLayerPointers, MemBaseAddress + LED1, 0); 297*5256Slh155975 WRITE_REG32(pLayerPointers, MemBaseAddress + LED2, 0); 298*5256Slh155975 WRITE_REG32(pLayerPointers, MemBaseAddress + LED3, 0); 299*5256Slh155975 300*5256Slh155975 /* Set RCV_RING_CFG */ 301*5256Slh155975 WRITE_REG16(pLayerPointers, MemBaseAddress + RCV_RING_CFG, 1); 302*5256Slh155975 303*5256Slh155975 /* SRAM_SIZE & SRAM_BOUNDARY register combined */ 304*5256Slh155975 if (JumboFlag == JUMBO_ENABLED) { 305*5256Slh155975 WRITE_REG32(pLayerPointers, MemBaseAddress + SRAM_SIZE, 306*5256Slh155975 0xc0010); 307*5256Slh155975 } else { 308*5256Slh155975 WRITE_REG32(pLayerPointers, MemBaseAddress + SRAM_SIZE, 309*5256Slh155975 0x80010); 310*5256Slh155975 } 311*5256Slh155975 312*5256Slh155975 /* Clear XMT_RING0/1/2/3_LEN */ 313*5256Slh155975 WRITE_REG32(pLayerPointers, MemBaseAddress + XMT_RING_LEN0, 0); 314*5256Slh155975 WRITE_REG32(pLayerPointers, MemBaseAddress + XMT_RING_LEN1, 0); 315*5256Slh155975 WRITE_REG32(pLayerPointers, MemBaseAddress + XMT_RING_LEN2, 0); 316*5256Slh155975 WRITE_REG32(pLayerPointers, MemBaseAddress + XMT_RING_LEN3, 0); 317*5256Slh155975 318*5256Slh155975 /* Clear XMT_RING_LIMIT */ 319*5256Slh155975 WRITE_REG32(pLayerPointers, MemBaseAddress + XMT_RING_LIMIT, 0); 320*5256Slh155975 321*5256Slh155975 WRITE_REG16(pLayerPointers, MemBaseAddress + MIB_ADDR, MIB_CLEAR); 322*5256Slh155975 } 323*5256Slh155975 324*5256Slh155975 unsigned int 325*5256Slh155975 mdlReadMib(struct LayerPointers *pLayerPointers, char MIB_COUNTER) 326*5256Slh155975 { 327*5256Slh155975 unsigned int status; 328*5256Slh155975 unsigned int data; 329*5256Slh155975 unsigned long mmio = pLayerPointers->pMdl->Mem_Address; 330*5256Slh155975 331*5256Slh155975 WRITE_REG16(pLayerPointers, mmio + MIB_ADDR, MIB_RD_CMD | MIB_COUNTER); 332*5256Slh155975 do { 333*5256Slh155975 status = READ_REG16(pLayerPointers, mmio + MIB_ADDR); 334*5256Slh155975 } while ((status & MIB_CMD_ACTIVE)); 335*5256Slh155975 336*5256Slh155975 data = READ_REG32(pLayerPointers, mmio + MIB_DATA); 337*5256Slh155975 return (data); 338*5256Slh155975 } 339*5256Slh155975 340*5256Slh155975 /* Return 1 on success, return 0 on fail */ 341*5256Slh155975 unsigned int 342*5256Slh155975 mdlReadPHY(struct LayerPointers *pLayerPointers, unsigned char phyid, 343*5256Slh155975 unsigned char regaddr, unsigned int *value) 344*5256Slh155975 { 345*5256Slh155975 unsigned int status, data, count; 346*5256Slh155975 unsigned long mmio = pLayerPointers->pMdl->Mem_Address; 347*5256Slh155975 348*5256Slh155975 count = 0; 349*5256Slh155975 do { 350*5256Slh155975 status = READ_REG16(pLayerPointers, mmio + PHY_ACCESS); 351*5256Slh155975 count ++; 352*5256Slh155975 drv_usecwait(10); 353*5256Slh155975 } while ((status & PHY_CMD_ACTIVE) & (count < PHY_MAX_RETRY)); 354*5256Slh155975 355*5256Slh155975 if (count == PHY_MAX_RETRY) { 356*5256Slh155975 return (0); 357*5256Slh155975 } 358*5256Slh155975 359*5256Slh155975 data = ((regaddr & 0x1f) << 16) | ((phyid & 0x1f) << 21) | PHY_RD_CMD; 360*5256Slh155975 WRITE_REG32(pLayerPointers, mmio + PHY_ACCESS, data); 361*5256Slh155975 do { 362*5256Slh155975 status = READ_REG16(pLayerPointers, mmio + PHY_ACCESS); 363*5256Slh155975 drv_usecwait(10); 364*5256Slh155975 count ++; 365*5256Slh155975 } while ((status & PHY_CMD_ACTIVE) & (count < PHY_MAX_RETRY)); 366*5256Slh155975 367*5256Slh155975 if ((count == PHY_MAX_RETRY) || (status & PHY_RD_ERR)) { 368*5256Slh155975 return (0); 369*5256Slh155975 } 370*5256Slh155975 371*5256Slh155975 *value = status & 0xffff; 372*5256Slh155975 return (1); 373*5256Slh155975 } 374*5256Slh155975 375*5256Slh155975 void 376*5256Slh155975 mdlGetPHYID(struct LayerPointers *pLayerPointers) 377*5256Slh155975 { 378*5256Slh155975 unsigned int id1, id2, i; 379*5256Slh155975 for (i = 1; i < 32; i++) { 380*5256Slh155975 if (mdlReadPHY(pLayerPointers, i, MII_PHYSID1, &id1) == 0) 381*5256Slh155975 continue; 382*5256Slh155975 if (mdlReadPHY(pLayerPointers, i, MII_PHYSID2, &id2) == 0) 383*5256Slh155975 continue; 384*5256Slh155975 if ((id1 != 0xffff) & (id2 != 0xffff)) { 385*5256Slh155975 pLayerPointers->pMdl->phy_id = i; 386*5256Slh155975 return; 387*5256Slh155975 } 388*5256Slh155975 } 389*5256Slh155975 } 390*5256Slh155975 391*5256Slh155975 /* Return 1 on success, return 0 on fail */ 392*5256Slh155975 unsigned int 393*5256Slh155975 mdlWritePHY(struct LayerPointers *pLayerPointers, unsigned char phyid, 394*5256Slh155975 unsigned char regaddr, unsigned int value) 395*5256Slh155975 { 396*5256Slh155975 unsigned int status, data, count; 397*5256Slh155975 unsigned long mmio = pLayerPointers->pMdl->Mem_Address; 398*5256Slh155975 399*5256Slh155975 count = 0; 400*5256Slh155975 do { 401*5256Slh155975 status = READ_REG16(pLayerPointers, mmio + PHY_ACCESS); 402*5256Slh155975 count ++; 403*5256Slh155975 drv_usecwait(10); 404*5256Slh155975 } while ((status & PHY_CMD_ACTIVE) & (count < PHY_MAX_RETRY)); 405*5256Slh155975 406*5256Slh155975 if (count == PHY_MAX_RETRY) { 407*5256Slh155975 return (0); 408*5256Slh155975 } 409*5256Slh155975 410*5256Slh155975 data = ((regaddr & 0x1f) << 16) | ((phyid & 0x1f) << 21) | 411*5256Slh155975 (value & 0xffff) | PHY_WR_CMD; 412*5256Slh155975 WRITE_REG32(pLayerPointers, mmio + PHY_ACCESS, data); 413*5256Slh155975 414*5256Slh155975 do { 415*5256Slh155975 status = READ_REG16(pLayerPointers, mmio + PHY_ACCESS); 416*5256Slh155975 drv_usecwait(10); 417*5256Slh155975 count ++; 418*5256Slh155975 } while ((status & PHY_CMD_ACTIVE) & (count < PHY_MAX_RETRY)); 419*5256Slh155975 420*5256Slh155975 if ((count == PHY_MAX_RETRY) && (status & PHY_RD_ERR)) { 421*5256Slh155975 return (0); 422*5256Slh155975 } 423*5256Slh155975 424*5256Slh155975 return (1); 425*5256Slh155975 } 426*5256Slh155975 427*5256Slh155975 /* 428*5256Slh155975 * To Send the packet. 429*5256Slh155975 */ 430*5256Slh155975 void 431*5256Slh155975 mdlTransmit(struct LayerPointers *pLayerPointers) 432*5256Slh155975 { 433*5256Slh155975 WRITE_REG32(pLayerPointers, pLayerPointers->pMdl->Mem_Address + CMD0, 434*5256Slh155975 VAL1 | TDMD0); 435*5256Slh155975 } 436*5256Slh155975 437*5256Slh155975 /* 438*5256Slh155975 * To Receive a packet. 439*5256Slh155975 */ 440*5256Slh155975 void 441*5256Slh155975 mdlReceive(struct LayerPointers *pLayerPointers) 442*5256Slh155975 { 443*5256Slh155975 /* 444*5256Slh155975 * Receive Demand for ring 0, which when set causes the Descriptor 445*5256Slh155975 * Management Unit to access the Receive Descriptor Ring if it does 446*5256Slh155975 * not already own the next descriptor. 447*5256Slh155975 */ 448*5256Slh155975 WRITE_REG32(pLayerPointers, pLayerPointers->pMdl->Mem_Address + CMD0, 449*5256Slh155975 VAL2 | RDMD0); 450*5256Slh155975 } 451*5256Slh155975 452*5256Slh155975 /* 453*5256Slh155975 * Read the NIC interrupt. 454*5256Slh155975 * 455*5256Slh155975 * Returns: 456*5256Slh155975 * the value of interrupt causes register 457*5256Slh155975 */ 458*5256Slh155975 unsigned int 459*5256Slh155975 mdlReadInterrupt(struct LayerPointers *pLayerPointers) 460*5256Slh155975 { 461*5256Slh155975 unsigned int nINT0; 462*5256Slh155975 struct mdl *pMdl = 0; 463*5256Slh155975 464*5256Slh155975 pMdl = (struct mdl *)(pLayerPointers->pMdl); 465*5256Slh155975 466*5256Slh155975 /* 467*5256Slh155975 * INT0 identifies the source or sources of an interrupt. With the 468*5256Slh155975 * exception of INTR and INTPN, all bits in this register are "write 469*5256Slh155975 * 1 to clear" so that the CPU can clear the interrupt condition by 470*5256Slh155975 * reading the register and then writing back the same data that it 471*5256Slh155975 * read. Writing a 0 to a bit in this register has no effect. 472*5256Slh155975 */ 473*5256Slh155975 474*5256Slh155975 /* Read interrupt status */ 475*5256Slh155975 nINT0 = READ_REG32(pLayerPointers, pMdl->Mem_Address + INT0); 476*5256Slh155975 477*5256Slh155975 /* Process all the INT event until INTR bit is clear. */ 478*5256Slh155975 WRITE_REG32(pLayerPointers, pMdl->Mem_Address + INT0, nINT0); 479*5256Slh155975 return (nINT0); 480*5256Slh155975 } 481*5256Slh155975 482*5256Slh155975 void 483*5256Slh155975 mdlHWReset(struct LayerPointers *pLayerPointers) 484*5256Slh155975 { 485*5256Slh155975 struct mdl *pMdl = pLayerPointers->pMdl; 486*5256Slh155975 unsigned int ulData, i = 0; 487*5256Slh155975 int JumboFlag = JUMBO_DISABLED; 488*5256Slh155975 ULONG Mem_Address = pMdl->Mem_Address; 489*5256Slh155975 490*5256Slh155975 /* 491*5256Slh155975 * Stop the Card: 492*5256Slh155975 * First we make sure that the device is stopped and no 493*5256Slh155975 * more interrupts come out. Also some registers must be 494*5256Slh155975 * programmed with CSR0 STOP bit set. 495*5256Slh155975 */ 496*5256Slh155975 mdlStopChip(pLayerPointers); 497*5256Slh155975 498*5256Slh155975 /* 499*5256Slh155975 * MAC Address Setup: 500*5256Slh155975 * MAC Physical Address register. All bits in this register are 501*5256Slh155975 * restored to default values when the RST pin is asserted. 502*5256Slh155975 */ 503*5256Slh155975 for (i = 0; i < ETH_LENGTH_OF_ADDRESS; i++) { 504*5256Slh155975 WRITE_REG8(pLayerPointers, pMdl->Mem_Address + PADR + i, 505*5256Slh155975 pMdl->Mac[i]); 506*5256Slh155975 } 507*5256Slh155975 508*5256Slh155975 /* Set RCV_RING_CFG */ 509*5256Slh155975 510*5256Slh155975 if (JumboFlag == JUMBO_ENABLED) { 511*5256Slh155975 WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD2, 512*5256Slh155975 VAL0 | APAD_XMT | REX_RTRY | VAL1 | DXMTFCS | RPA | VAL2); 513*5256Slh155975 514*5256Slh155975 WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD3, 515*5256Slh155975 VAL2 | JUMBO); 516*5256Slh155975 } else { 517*5256Slh155975 /* 518*5256Slh155975 * APAD_XMT: Auto Pad Transmit. When set, APAD_XMT enables 519*5256Slh155975 * the automatic padding feature. Transmit frames are padded 520*5256Slh155975 * to extend them to 64 bytes including FCS. 521*5256Slh155975 * 522*5256Slh155975 * DXMTFCS: Disable Transmit CRC. When DXMTFCS is set to 1, no 523*5256Slh155975 * Transmit CRC is generated. DXMTFCS is overridden when 524*5256Slh155975 * ADD_FCS and ENP bits are set in the transmit descriptor. 525*5256Slh155975 * 526*5256Slh155975 * ASTRIP_RCV: Auto Strip Receive. When ASTRP_RCV is set to 1, 527*5256Slh155975 * the receiver automatically strips pad bytes from the 528*5256Slh155975 * received message by observing the value in the length field 529*5256Slh155975 * and by stripping excess bytes if this value is below the 530*5256Slh155975 * minimum data size (46 bytes). 531*5256Slh155975 */ 532*5256Slh155975 WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD2, 533*5256Slh155975 VAL0 | APAD_XMT | REX_RTRY | REX_UFLO | VAL1 | DXMTFCS 534*5256Slh155975 | ASTRIP_RCV | RPA | VAL2); 535*5256Slh155975 } 536*5256Slh155975 537*5256Slh155975 /* Transmit Start Point setting (csr80) */ 538*5256Slh155975 ulData = READ_REG32(pLayerPointers, Mem_Address + CTRL1); 539*5256Slh155975 ulData &= ~XMTSP_MASK; 540*5256Slh155975 541*5256Slh155975 WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CTRL1, 542*5256Slh155975 ulData | XMTSP_128); 543*5256Slh155975 /* Disable Prom */ 544*5256Slh155975 WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD2, PROM); 545*5256Slh155975 546*5256Slh155975 mdlPHYAutoNegotiation(pLayerPointers, pMdl->External_Phy); 547*5256Slh155975 548*5256Slh155975 pMdl->IpgValue = MIN_IPG_DEFAULT; 549*5256Slh155975 /* Set the IPG value */ 550*5256Slh155975 WRITE_REG16(pLayerPointers, pMdl->Mem_Address + IFS, 551*5256Slh155975 pMdl->IpgValue); 552*5256Slh155975 553*5256Slh155975 /* Disable Following Interrupts. */ 554*5256Slh155975 WRITE_REG32(pLayerPointers, pMdl->Mem_Address + INTEN0, 555*5256Slh155975 APINT5EN | APINT4EN | APINT3EN | 556*5256Slh155975 APINT2EN | APINT1EN | APINT0EN | MIIPDTINTEN | 557*5256Slh155975 MCCIINTEN | MCCINTEN | MREINTEN | 558*5256Slh155975 TINTEN0 | 559*5256Slh155975 SPNDINTEN | MPINTEN | SINTEN | LCINTEN); 560*5256Slh155975 561*5256Slh155975 /* Enable Following Interrupt */ 562*5256Slh155975 WRITE_REG32(pLayerPointers, pMdl->Mem_Address + INTEN0, 563*5256Slh155975 VAL0 | RINTEN0); 564*5256Slh155975 565*5256Slh155975 /* Base Address of Transmit Descriptor Ring 0. */ 566*5256Slh155975 WRITE_REG32(pLayerPointers, pMdl->Mem_Address + XMT_RING_BASE_ADDR0, 567*5256Slh155975 pMdl->init_blk->TDRA); 568*5256Slh155975 569*5256Slh155975 /* Base Address of Receive Descriptor Ring. */ 570*5256Slh155975 WRITE_REG32(pLayerPointers, pMdl->Mem_Address + RCV_RING_BASE_ADDR0, 571*5256Slh155975 pMdl->init_blk->RDRA); 572*5256Slh155975 573*5256Slh155975 /* The number of descriptors in Transmit Descriptor Ring 0 */ 574*5256Slh155975 WRITE_REG16(pLayerPointers, pMdl->Mem_Address + XMT_RING_LEN0, 575*5256Slh155975 (unsigned short)pLayerPointers->pMdl->TxRingSize); 576*5256Slh155975 577*5256Slh155975 /* 578*5256Slh155975 * Receive Descriptor Ring Length. All bits in this register are 579*5256Slh155975 * restored to default values when the RST pin is asserted. 580*5256Slh155975 */ 581*5256Slh155975 WRITE_REG16(pLayerPointers, pMdl->Mem_Address + RCV_RING_LEN0, 582*5256Slh155975 (unsigned short)pLayerPointers->pMdl->RxRingSize); 583*5256Slh155975 584*5256Slh155975 if (pLayerPointers->pMdl->IntrCoalescFlag) { 585*5256Slh155975 SetIntrCoalesc(pLayerPointers, B_TRUE); 586*5256Slh155975 } 587*5256Slh155975 588*5256Slh155975 /* Start the chip */ 589*5256Slh155975 mdlStartChip(pLayerPointers); 590*5256Slh155975 } 591*5256Slh155975 592*5256Slh155975 /* 593*5256Slh155975 * Perform the open oerations on the adapter. 594*5256Slh155975 */ 595*5256Slh155975 void 596*5256Slh155975 mdlOpen(struct LayerPointers *pLayerPointers) 597*5256Slh155975 { 598*5256Slh155975 int i, sum; 599*5256Slh155975 struct mdl *pMdl = pLayerPointers->pMdl; 600*5256Slh155975 601*5256Slh155975 /* Get Mac address */ 602*5256Slh155975 sum = 0; 603*5256Slh155975 for (i = 0; i < 6; i++) { 604*5256Slh155975 pMdl->Mac[i] = READ_REG8(pLayerPointers, 605*5256Slh155975 pMdl->Mem_Address + PADR + i); 606*5256Slh155975 sum += pMdl->Mac[i]; 607*5256Slh155975 } 608*5256Slh155975 if (sum == 0) { 609*5256Slh155975 for (i = 0; i < 6; i++) { 610*5256Slh155975 pMdl->Mac[i] = 0; 611*5256Slh155975 } 612*5256Slh155975 } 613*5256Slh155975 614*5256Slh155975 /* Initialize the hardware */ 615*5256Slh155975 mdlClearHWConfig(pLayerPointers); 616*5256Slh155975 mdlGetPHYID(pLayerPointers); 617*5256Slh155975 618*5256Slh155975 } 619*5256Slh155975 620*5256Slh155975 void 621*5256Slh155975 mdlGetMacAddress(struct LayerPointers *pLayerPointers, 622*5256Slh155975 unsigned char *macAddress) 623*5256Slh155975 { 624*5256Slh155975 struct mdl *pMdl = pLayerPointers->pMdl; 625*5256Slh155975 int i; 626*5256Slh155975 627*5256Slh155975 for (i = 0; i < 6; i++) { 628*5256Slh155975 macAddress[i] = pMdl->Mac[i] = READ_REG8(pLayerPointers, 629*5256Slh155975 pMdl->Mem_Address + PADR + i); 630*5256Slh155975 } 631*5256Slh155975 632*5256Slh155975 } 633*5256Slh155975 634*5256Slh155975 635*5256Slh155975 void 636*5256Slh155975 mdlSetMacAddress(struct LayerPointers *pLayerPointers, 637*5256Slh155975 unsigned char *macAddress) 638*5256Slh155975 { 639*5256Slh155975 int i; 640*5256Slh155975 struct mdl *pMdl = 0; 641*5256Slh155975 642*5256Slh155975 pMdl = (struct mdl *)(pLayerPointers->pMdl); 643*5256Slh155975 644*5256Slh155975 pMdl->Mac[0] = macAddress[0]; 645*5256Slh155975 pMdl->Mac[1] = macAddress[1]; 646*5256Slh155975 pMdl->Mac[2] = macAddress[2]; 647*5256Slh155975 pMdl->Mac[3] = macAddress[3]; 648*5256Slh155975 pMdl->Mac[4] = macAddress[4]; 649*5256Slh155975 pMdl->Mac[5] = macAddress[5]; 650*5256Slh155975 651*5256Slh155975 /* 652*5256Slh155975 * MAC Address Setup: 653*5256Slh155975 * MAC Physical Address register. All bits in this register are 654*5256Slh155975 * restored to default values when the RST pin is asserted. 655*5256Slh155975 */ 656*5256Slh155975 for (i = 0; i < ETH_LENGTH_OF_ADDRESS; i++) { 657*5256Slh155975 WRITE_REG8(pLayerPointers, pMdl->Mem_Address + PADR + i, 658*5256Slh155975 pMdl->Mac[i]); 659*5256Slh155975 } 660*5256Slh155975 } 661*5256Slh155975 662*5256Slh155975 /* 663*5256Slh155975 * This array is filled with the size of the memory required for 664*5256Slh155975 * allocating purposes. 665*5256Slh155975 */ 666*5256Slh155975 static void 667*5256Slh155975 mdlRequestResources(ULONG *mem_req_array) 668*5256Slh155975 { 669*5256Slh155975 /* 1) For mdl structure */ 670*5256Slh155975 *mem_req_array = VIRTUAL; /* Type */ 671*5256Slh155975 *(++mem_req_array) = sizeof (struct mdl); /* Size */ 672*5256Slh155975 673*5256Slh155975 /* 2) For PMR PtrList array (PMR_ptrList) */ 674*5256Slh155975 *(++mem_req_array) = VIRTUAL; /* Type */ 675*5256Slh155975 /* Size */ 676*5256Slh155975 *(++mem_req_array) = sizeof (unsigned int) * (MAX_ALLOWED_PATTERNS + 2); 677*5256Slh155975 678*5256Slh155975 /* 3) For PMR Pattern List array (PatternList) */ 679*5256Slh155975 *(++mem_req_array) = VIRTUAL; /* Type */ 680*5256Slh155975 /* Size */ 681*5256Slh155975 *(++mem_req_array) = sizeof (unsigned char) * (MAX_PATTERNS + 2); 682*5256Slh155975 683*5256Slh155975 /* 4) For pmr PatternLength array (PatternLength) */ 684*5256Slh155975 *(++mem_req_array) = VIRTUAL; /* Type */ 685*5256Slh155975 /* Size */ 686*5256Slh155975 *(++mem_req_array) = sizeof (unsigned int) * (MAX_ALLOWED_PATTERNS + 2); 687*5256Slh155975 688*5256Slh155975 /* 689*5256Slh155975 * 5) For the init_block (init_blk) 690*5256Slh155975 */ 691*5256Slh155975 *(++mem_req_array) = VIRTUAL; 692*5256Slh155975 *(++mem_req_array) = sizeof (struct init_block); 693*5256Slh155975 694*5256Slh155975 *(++mem_req_array) = 0; 695*5256Slh155975 mem_req_array++; 696*5256Slh155975 } 697*5256Slh155975 698*5256Slh155975 699*5256Slh155975 /* 700*5256Slh155975 * Purpose : 701*5256Slh155975 * This array contains the details of the allocated memory. The 702*5256Slh155975 * pointers are taken from the respective locations in the array & 703*5256Slh155975 * assigned appropriately to the respective structures. 704*5256Slh155975 * 705*5256Slh155975 * Arguments : 706*5256Slh155975 * pLayerPointers 707*5256Slh155975 * Pointer to the adapter structure. 708*5256Slh155975 * pmem_set_array 709*5256Slh155975 * Pointer to the array that holds the data after required 710*5256Slh155975 * allocating memory. 711*5256Slh155975 */ 712*5256Slh155975 static void 713*5256Slh155975 mdlSetResources(struct LayerPointers *pLayerPointers, ULONG *pmem_set_array) 714*5256Slh155975 { 715*5256Slh155975 struct mdl *pMdl = 0; 716*5256Slh155975 717*5256Slh155975 /* 1) For mdl structure */ 718*5256Slh155975 pmem_set_array++; /* Type */ 719*5256Slh155975 pmem_set_array++; /* Size */ 720*5256Slh155975 pLayerPointers->pMdl = (struct mdl *)(*pmem_set_array); 721*5256Slh155975 722*5256Slh155975 pMdl = (struct mdl *)(pLayerPointers->pMdl); 723*5256Slh155975 724*5256Slh155975 pMdl->RxRingLenBits = RX_RING_LEN_BITS; 725*5256Slh155975 pMdl->TxRingLenBits = TX_RING_LEN_BITS; 726*5256Slh155975 pMdl->TxRingSize = TX_RING_SIZE; 727*5256Slh155975 pMdl->RxRingSize = RX_RING_SIZE; 728*5256Slh155975 729*5256Slh155975 /* 730*5256Slh155975 * Default values that would be used if it does not enable 731*5256Slh155975 * enable dynamic ipg. 732*5256Slh155975 */ 733*5256Slh155975 734*5256Slh155975 /* 2) Set the pointers to the PMR Pointer List */ 735*5256Slh155975 pmem_set_array++; /* Type */ 736*5256Slh155975 pmem_set_array++; /* Size */ 737*5256Slh155975 pmem_set_array++; /* Virtual Addr of PtrList */ 738*5256Slh155975 pMdl->PMR_PtrList = (unsigned int *)(*pmem_set_array); 739*5256Slh155975 740*5256Slh155975 /* 3) Set the pointers to the PMR Pattern List */ 741*5256Slh155975 pmem_set_array++; /* Type */ 742*5256Slh155975 pmem_set_array++; /* Size */ 743*5256Slh155975 pmem_set_array++; /* Virtual Addr of PatternList */ 744*5256Slh155975 pMdl->PatternList = (unsigned char *)(*pmem_set_array); 745*5256Slh155975 746*5256Slh155975 /* 4) Set the pointers to the PMR Pattern Length */ 747*5256Slh155975 pmem_set_array++; /* Type */ 748*5256Slh155975 pmem_set_array++; /* Size */ 749*5256Slh155975 pmem_set_array++; /* Virtual Addr of PatternLength */ 750*5256Slh155975 pMdl->PatternLength = (unsigned int *)(*pmem_set_array); 751*5256Slh155975 752*5256Slh155975 /* 5) Set the pointers to the init block */ 753*5256Slh155975 pmem_set_array++; /* Type */ 754*5256Slh155975 pmem_set_array++; /* Size */ 755*5256Slh155975 pmem_set_array++; /* Virtual Addr of init_block */ 756*5256Slh155975 pMdl->init_blk = (struct init_block *)(*pmem_set_array); 757*5256Slh155975 758*5256Slh155975 pMdl->init_blk->TLEN = pMdl->TxRingLenBits; 759*5256Slh155975 pMdl->init_blk->RLEN = pMdl->RxRingLenBits; 760*5256Slh155975 761*5256Slh155975 pmem_set_array++; 762*5256Slh155975 763*5256Slh155975 *pmem_set_array = 0; 764*5256Slh155975 } 765*5256Slh155975 766*5256Slh155975 /* 767*5256Slh155975 * Purpose: 768*5256Slh155975 * This array is filled with the size of the structure & its 769*5256Slh155975 * pointer for freeing purposes. 770*5256Slh155975 * 771*5256Slh155975 * Arguments: 772*5256Slh155975 * pLayerPointers 773*5256Slh155975 * Pointer to the adapter structure. 774*5256Slh155975 * mem_free_array 775*5256Slh155975 * Pointer to the array that holds the data required for 776*5256Slh155975 * freeing. 777*5256Slh155975 */ 778*5256Slh155975 static void 779*5256Slh155975 mdlFreeResources(struct LayerPointers *pLayerPointers, ULONG *pmem_free_array) 780*5256Slh155975 { 781*5256Slh155975 struct mdl *pMdl = 0; 782*5256Slh155975 783*5256Slh155975 pMdl = (struct mdl *)(pLayerPointers->pMdl); 784*5256Slh155975 785*5256Slh155975 /* 1) For mdl structure */ 786*5256Slh155975 *(pmem_free_array) = VIRTUAL; /* Type */ 787*5256Slh155975 *(++pmem_free_array) = sizeof (struct mdl); /* Size */ 788*5256Slh155975 *(++pmem_free_array) = (ULONG)pMdl; /* VA */ 789*5256Slh155975 790*5256Slh155975 /* 2) For ptr list */ 791*5256Slh155975 *(++pmem_free_array) = VIRTUAL; /* Type */ 792*5256Slh155975 *(++pmem_free_array) = sizeof (unsigned int) 793*5256Slh155975 * (MAX_ALLOWED_PATTERNS + 2); /* Size */ 794*5256Slh155975 *(++pmem_free_array) = (ULONG)pMdl->PMR_PtrList; /* VA */ 795*5256Slh155975 796*5256Slh155975 /* 3) For pattern list */ 797*5256Slh155975 *(++pmem_free_array) = VIRTUAL; /* Type */ 798*5256Slh155975 /* Size */ 799*5256Slh155975 *(++pmem_free_array) = sizeof (unsigned char) * (MAX_PATTERNS + 2); 800*5256Slh155975 *(++pmem_free_array) = (ULONG)pMdl->PatternList; /* VA */ 801*5256Slh155975 802*5256Slh155975 /* 4) For pattern length */ 803*5256Slh155975 *(++pmem_free_array) = VIRTUAL; /* Type */ 804*5256Slh155975 *(++pmem_free_array) = sizeof (unsigned int) 805*5256Slh155975 * (MAX_ALLOWED_PATTERNS + 2); /* Size */ 806*5256Slh155975 *(++pmem_free_array) = (ULONG)pMdl->PatternLength; /* VA */ 807*5256Slh155975 808*5256Slh155975 /* 5) For init_blk structure */ 809*5256Slh155975 *(++pmem_free_array) = VIRTUAL; /* Type */ 810*5256Slh155975 /* Size */ 811*5256Slh155975 *(++pmem_free_array) = sizeof (struct init_block); 812*5256Slh155975 *(++pmem_free_array) = (ULONG)pMdl->init_blk; /* VA */ 813*5256Slh155975 814*5256Slh155975 *(++pmem_free_array) = 0; 815*5256Slh155975 } 816*5256Slh155975 817*5256Slh155975 void 818*5256Slh155975 mdlStartChip(struct LayerPointers *pLayerPointers) 819*5256Slh155975 { 820*5256Slh155975 /* Enable Receiver */ 821*5256Slh155975 WRITE_REG32(pLayerPointers, pLayerPointers->pMdl->Mem_Address + CMD0, 822*5256Slh155975 VAL2 | RDMD0); 823*5256Slh155975 824*5256Slh155975 /* Enable Interrupt and Start processing descriptor, Rx and Tx */ 825*5256Slh155975 WRITE_REG32(pLayerPointers, pLayerPointers->pMdl->Mem_Address + CMD0, 826*5256Slh155975 VAL0 | INTREN | RUN); 827*5256Slh155975 } 828*5256Slh155975 829*5256Slh155975 /* 830*5256Slh155975 * Stops the chip. 831*5256Slh155975 */ 832*5256Slh155975 void 833*5256Slh155975 mdlStopChip(struct LayerPointers *pLayerPointers) 834*5256Slh155975 { 835*5256Slh155975 int nINT0; 836*5256Slh155975 struct mdl *pMdl = 0; 837*5256Slh155975 838*5256Slh155975 pMdl = (struct mdl *)(pLayerPointers->pMdl); 839*5256Slh155975 840*5256Slh155975 /* Disable interrupt */ 841*5256Slh155975 WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD0, INTREN); 842*5256Slh155975 843*5256Slh155975 /* Clear interrupt status */ 844*5256Slh155975 nINT0 = READ_REG32(pLayerPointers, pMdl->Mem_Address + INT0); 845*5256Slh155975 WRITE_REG32(pLayerPointers, pMdl->Mem_Address + INT0, nINT0); 846*5256Slh155975 847*5256Slh155975 /* 848*5256Slh155975 * Setting the RUN bit enables the controller to start processing 849*5256Slh155975 * descriptors and transmitting and receiving packets. Clearing 850*5256Slh155975 * the RUN bit to 0 abruptly disables the transmitter, receiver, and 851*5256Slh155975 * descriptor processing logic, possibly while a frame is being 852*5256Slh155975 * transmitted or received. 853*5256Slh155975 * The act of changing the RUN bit from 1 to 0 causes the following 854*5256Slh155975 * bits to be reset to 0: TX_SPND, RX_SPND, TX_FAST_SPND, RX_FAST_SPND, 855*5256Slh155975 * RDMD, all TDMD bits, RINT, all TINT bits, MPINT, and SPNDINT. 856*5256Slh155975 */ 857*5256Slh155975 WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD0, RUN); 858*5256Slh155975 } 859*5256Slh155975 860*5256Slh155975 /* 861*5256Slh155975 * Enables the interrupt. 862*5256Slh155975 */ 863*5256Slh155975 void 864*5256Slh155975 mdlEnableInterrupt(struct LayerPointers *pLayerPointers) 865*5256Slh155975 { 866*5256Slh155975 /* 867*5256Slh155975 * Interrupt Enable Bit: 868*5256Slh155975 * This bit allows INTA to be asserted if any bit in the interrupt 869*5256Slh155975 * register is set. If INTREN is cleared to 0, INTA will not be 870*5256Slh155975 * asserted, regardless of the state of the interrupt register. 871*5256Slh155975 */ 872*5256Slh155975 WRITE_REG32(pLayerPointers, pLayerPointers->pMdl->Mem_Address + CMD0, 873*5256Slh155975 VAL0 | INTREN); 874*5256Slh155975 } 875*5256Slh155975 876*5256Slh155975 #ifdef AMD8111S_DEBUG 877*5256Slh155975 static void 878*5256Slh155975 mdlClearInterrupt(struct LayerPointers *pLayerPointers) 879*5256Slh155975 { 880*5256Slh155975 unsigned int nINT0; 881*5256Slh155975 struct mdl *pMdl = 0; 882*5256Slh155975 883*5256Slh155975 pMdl = (struct mdl *)(pLayerPointers->pMdl); 884*5256Slh155975 885*5256Slh155975 /* Clear interrupt status */ 886*5256Slh155975 nINT0 = READ_REG32(pLayerPointers, pMdl->Mem_Address + INT0); 887*5256Slh155975 WRITE_REG32(pLayerPointers, pMdl->Mem_Address + INT0, nINT0); 888*5256Slh155975 889*5256Slh155975 } 890*5256Slh155975 #endif 891*5256Slh155975 892*5256Slh155975 /* 893*5256Slh155975 * Disables the interrupt. 894*5256Slh155975 */ 895*5256Slh155975 void 896*5256Slh155975 mdlDisableInterrupt(struct LayerPointers *pLayerPointers) 897*5256Slh155975 { 898*5256Slh155975 /* Disable interrupt */ 899*5256Slh155975 WRITE_REG32(pLayerPointers, 900*5256Slh155975 pLayerPointers->pMdl->Mem_Address + CMD0, INTREN); 901*5256Slh155975 } 902*5256Slh155975 903*5256Slh155975 /* 904*5256Slh155975 * Reads the link status 905*5256Slh155975 */ 906*5256Slh155975 int 907*5256Slh155975 mdlReadLink(struct LayerPointers *pLayerPointers) 908*5256Slh155975 { 909*5256Slh155975 unsigned int link_status = 0; 910*5256Slh155975 911*5256Slh155975 link_status = READ_REG32(pLayerPointers, 912*5256Slh155975 pLayerPointers->pMdl->Mem_Address + STAT0); 913*5256Slh155975 914*5256Slh155975 if ((link_status & LINK_STAT)) { 915*5256Slh155975 return (LINK_UP); 916*5256Slh155975 } else { 917*5256Slh155975 return (LINK_DOWN); 918*5256Slh155975 } 919*5256Slh155975 } 920*5256Slh155975 921*5256Slh155975 /* 922*5256Slh155975 * Purpose : 923*5256Slh155975 * Adds the wakeup pattern given by the upper layer. 924*5256Slh155975 * 925*5256Slh155975 * Arguments : 926*5256Slh155975 * pLayerPointers 927*5256Slh155975 * Pointer to the Adapter structure. 928*5256Slh155975 * PatternMask 929*5256Slh155975 * The mask for the pattern to be added. 930*5256Slh155975 * Pattern 931*5256Slh155975 * The Pattern to be added. 932*5256Slh155975 * InfoBuffer_MaskSize 933*5256Slh155975 * The mask size as specified in the Information Buffer. 934*5256Slh155975 * PatternSize 935*5256Slh155975 * The PatternSize as specified in the Information Buffer. 936*5256Slh155975 */ 937*5256Slh155975 static void 938*5256Slh155975 mdlAddWakeUpPattern(struct LayerPointers *pLayerPointers, 939*5256Slh155975 unsigned char *PatternMask, unsigned char *Pattern, 940*5256Slh155975 unsigned long InfoBuffer_MaskSize, unsigned long PatternSize, int *retval) 941*5256Slh155975 { 942*5256Slh155975 unsigned long MaskSize; 943*5256Slh155975 unsigned long ReqSize; 944*5256Slh155975 unsigned char byteData = 0, tmpData; 945*5256Slh155975 unsigned char Skip = 0; 946*5256Slh155975 unsigned int i = 0, flag = 1, count = 1; 947*5256Slh155975 unsigned int j; 948*5256Slh155975 int PatternOffset, SearchForStartOfPattern = 1; 949*5256Slh155975 struct mdl *pMdl = 0; 950*5256Slh155975 951*5256Slh155975 pMdl = pLayerPointers->pMdl; 952*5256Slh155975 953*5256Slh155975 if (pMdl->TotalPatterns >= MAX_ALLOWED_PATTERNS) { 954*5256Slh155975 *retval = -1; 955*5256Slh155975 return; 956*5256Slh155975 } 957*5256Slh155975 958*5256Slh155975 MaskSize = PatternSize/4 + (PatternSize%4 ? 1 : 0); 959*5256Slh155975 960*5256Slh155975 ReqSize = PatternSize + MaskSize; 961*5256Slh155975 if (((PatternSize+MaskSize)%5) != 0) 962*5256Slh155975 ReqSize += 5 - ((PatternSize+MaskSize)%5); 963*5256Slh155975 964*5256Slh155975 if (ReqSize > 965*5256Slh155975 (unsigned long)(MAX_PATTERNS - pMdl->PatternList_FreeIndex)) { 966*5256Slh155975 *retval = -1; 967*5256Slh155975 return; 968*5256Slh155975 } 969*5256Slh155975 970*5256Slh155975 if (InfoBuffer_MaskSize != PatternSize/8 + (PatternSize%8 ? 1 : 0)) { 971*5256Slh155975 *retval = -1; 972*5256Slh155975 return; 973*5256Slh155975 } 974*5256Slh155975 975*5256Slh155975 i = pMdl->PatternList_FreeIndex; 976*5256Slh155975 977*5256Slh155975 pMdl->PMR_PtrList[pMdl->TotalPatterns] = i; 978*5256Slh155975 979*5256Slh155975 pMdl->PatternLength[pMdl->TotalPatterns] = (unsigned int)PatternSize; 980*5256Slh155975 981*5256Slh155975 while (i < (pMdl->PatternList_FreeIndex + PatternSize + MaskSize)) { 982*5256Slh155975 if (flag) { 983*5256Slh155975 byteData = *PatternMask; 984*5256Slh155975 pMdl->PatternList[i++] = 985*5256Slh155975 (unsigned int)((byteData & 0x0F) | (Skip<< 4)); 986*5256Slh155975 flag = 0; 987*5256Slh155975 } else { 988*5256Slh155975 pMdl->PatternList[i++] = (unsigned int) 989*5256Slh155975 (((unsigned)(byteData & 0xF0) >> 4) | (Skip << 4)); 990*5256Slh155975 PatternMask++; 991*5256Slh155975 flag = 1; 992*5256Slh155975 } 993*5256Slh155975 count = 1; 994*5256Slh155975 while ((count < 5) && (i < 995*5256Slh155975 pMdl->PatternList_FreeIndex + PatternSize + MaskSize)) { 996*5256Slh155975 tmpData = *Pattern; 997*5256Slh155975 Pattern++; 998*5256Slh155975 pMdl->PatternList[i++] = tmpData; 999*5256Slh155975 count++; 1000*5256Slh155975 } 1001*5256Slh155975 } 1002*5256Slh155975 1003*5256Slh155975 /* Filling up the extra byte blocks in the row to 0. */ 1004*5256Slh155975 for (i = (pMdl->PatternList_FreeIndex + PatternSize + MaskSize); 1005*5256Slh155975 i < (pMdl->PatternList_FreeIndex + ReqSize); i++) 1006*5256Slh155975 pMdl->PatternList[i] = 0; 1007*5256Slh155975 1008*5256Slh155975 /* Set the EOP bit for the last mask!!! */ 1009*5256Slh155975 pMdl->PatternList[pMdl->PatternList_FreeIndex + ReqSize - 5] |= 0x80; 1010*5256Slh155975 1011*5256Slh155975 for (j = 0; j < 8; j++) { 1012*5256Slh155975 pMdl->tmpPtrArray[j] = 0; 1013*5256Slh155975 } 1014*5256Slh155975 1015*5256Slh155975 /* Zeroing the skip value of all the pattern masks */ 1016*5256Slh155975 j = 0; 1017*5256Slh155975 while (j < (pMdl->PatternList_FreeIndex + ReqSize)) { 1018*5256Slh155975 pMdl->PatternList[j] &= 0x8f; 1019*5256Slh155975 j += 5; 1020*5256Slh155975 } 1021*5256Slh155975 1022*5256Slh155975 /* 1023*5256Slh155975 * Scan the whole array & update the start offset of the pattern in the 1024*5256Slh155975 * PMR and update the skip value. 1025*5256Slh155975 */ 1026*5256Slh155975 j = 0; 1027*5256Slh155975 i = 0; 1028*5256Slh155975 1029*5256Slh155975 PatternOffset = 1; 1030*5256Slh155975 Skip = 0; 1031*5256Slh155975 1032*5256Slh155975 while (j < (pMdl->PatternList_FreeIndex + ReqSize)) { 1033*5256Slh155975 1034*5256Slh155975 if (pMdl->PatternList[j] & 0x0f) { 1035*5256Slh155975 PatternOffset ++; 1036*5256Slh155975 if (SearchForStartOfPattern == 1) { 1037*5256Slh155975 SearchForStartOfPattern = 0; 1038*5256Slh155975 pMdl->tmpPtrArray[i++] = PatternOffset; 1039*5256Slh155975 } else if (pMdl->PatternList[j] & 0x80) { 1040*5256Slh155975 SearchForStartOfPattern = 1; 1041*5256Slh155975 } 1042*5256Slh155975 pMdl->PatternList[j] |= (Skip << 4); 1043*5256Slh155975 Skip = 0; 1044*5256Slh155975 } else { 1045*5256Slh155975 Skip++; 1046*5256Slh155975 } 1047*5256Slh155975 j += 5; 1048*5256Slh155975 } 1049*5256Slh155975 1050*5256Slh155975 /* valid pattern.. so update the house keeping info. */ 1051*5256Slh155975 pMdl->PatternList_FreeIndex += (unsigned short)ReqSize; 1052*5256Slh155975 pMdl->TotalPatterns++; 1053*5256Slh155975 1054*5256Slh155975 *retval = 0; 1055*5256Slh155975 } 1056*5256Slh155975 1057*5256Slh155975 /* 1058*5256Slh155975 * Purpose: 1059*5256Slh155975 * Removes the specified wakeup pattern. 1060*5256Slh155975 * 1061*5256Slh155975 * Arguments : 1062*5256Slh155975 * pLayerPointers 1063*5256Slh155975 * Pointer to the Adapter structure. 1064*5256Slh155975 * Pattern 1065*5256Slh155975 * The Pattern to be added. 1066*5256Slh155975 * PatternSize 1067*5256Slh155975 * The PatternSize as specified in the Information Buffer. 1068*5256Slh155975 */ 1069*5256Slh155975 static void 1070*5256Slh155975 mdlRemoveWakeUpPattern(struct LayerPointers *pLayerPointers, 1071*5256Slh155975 unsigned char *Pattern, unsigned long PatternSize, int *retval) 1072*5256Slh155975 { 1073*5256Slh155975 unsigned long ReqSize, MaskSize; 1074*5256Slh155975 unsigned char tmpData; 1075*5256Slh155975 unsigned long Data; 1076*5256Slh155975 unsigned short Data1, Data2, Data3, Data4, Data5, Data6, Data7, Data8; 1077*5256Slh155975 int PatternMismatch = 0; 1078*5256Slh155975 int count, StartIndex, index = 0; 1079*5256Slh155975 unsigned int i, j; 1080*5256Slh155975 unsigned char Skip = 0; 1081*5256Slh155975 struct mdl *pMdl = 0; 1082*5256Slh155975 int PatternOffset, SearchForStartOfPattern = 1; 1083*5256Slh155975 unsigned long tmpPtrArray[8]; 1084*5256Slh155975 int offset; 1085*5256Slh155975 1086*5256Slh155975 Data1 = Data2 = Data3 = Data4 = Data5 = Data6 = Data7 = Data8 = 0; 1087*5256Slh155975 1088*5256Slh155975 pMdl = (struct mdl *)(pLayerPointers->pMdl); 1089*5256Slh155975 1090*5256Slh155975 /* Find the pattern to be removed. */ 1091*5256Slh155975 if (pMdl->TotalPatterns == 0) { 1092*5256Slh155975 *retval = -1; 1093*5256Slh155975 return; 1094*5256Slh155975 } 1095*5256Slh155975 1096*5256Slh155975 MaskSize = PatternSize/4 + (PatternSize%4 ? 1 : 0); 1097*5256Slh155975 1098*5256Slh155975 ReqSize = PatternSize + MaskSize; 1099*5256Slh155975 if (((PatternSize+MaskSize)%5) != 0) 1100*5256Slh155975 ReqSize += 5 - ((PatternSize+MaskSize)%5); 1101*5256Slh155975 1102*5256Slh155975 count = pMdl->TotalPatterns; 1103*5256Slh155975 1104*5256Slh155975 while (count--) { 1105*5256Slh155975 PatternMismatch = 0; 1106*5256Slh155975 StartIndex = pMdl->PMR_PtrList[index]; 1107*5256Slh155975 1108*5256Slh155975 if (pMdl->PatternLength[index] != PatternSize) { 1109*5256Slh155975 index++; 1110*5256Slh155975 PatternMismatch = 1; 1111*5256Slh155975 continue; 1112*5256Slh155975 } 1113*5256Slh155975 1114*5256Slh155975 for (i = StartIndex; i < (StartIndex+ReqSize); i++) { 1115*5256Slh155975 if (!(i%5)) 1116*5256Slh155975 i++; 1117*5256Slh155975 1118*5256Slh155975 tmpData = *Pattern; 1119*5256Slh155975 if (pMdl->PatternList[i] != tmpData) { 1120*5256Slh155975 PatternMismatch = 1; 1121*5256Slh155975 break; 1122*5256Slh155975 } 1123*5256Slh155975 Pattern++; 1124*5256Slh155975 } 1125*5256Slh155975 1126*5256Slh155975 if (PatternMismatch == 0) { 1127*5256Slh155975 i = StartIndex + ReqSize; 1128*5256Slh155975 1129*5256Slh155975 /* Pattern found remove it from the arrays */ 1130*5256Slh155975 while (i < pMdl->PatternList_FreeIndex) { 1131*5256Slh155975 pMdl->PatternList[StartIndex] = 1132*5256Slh155975 pMdl->PatternList[i]; 1133*5256Slh155975 i++; 1134*5256Slh155975 StartIndex++; 1135*5256Slh155975 } 1136*5256Slh155975 1137*5256Slh155975 pMdl->PatternList_FreeIndex = 1138*5256Slh155975 (unsigned short)(StartIndex); 1139*5256Slh155975 1140*5256Slh155975 while (StartIndex < MAX_PATTERNS) 1141*5256Slh155975 pMdl->PatternList[StartIndex++] = 0; 1142*5256Slh155975 1143*5256Slh155975 while (index < (int)pMdl->TotalPatterns) { 1144*5256Slh155975 pMdl->PMR_PtrList[index] = 1145*5256Slh155975 pMdl->PMR_PtrList[index+1] - ReqSize; 1146*5256Slh155975 1147*5256Slh155975 pMdl->PatternLength[index] = 1148*5256Slh155975 pMdl->PatternLength[index+1]; 1149*5256Slh155975 1150*5256Slh155975 index ++; 1151*5256Slh155975 } 1152*5256Slh155975 1153*5256Slh155975 index--; 1154*5256Slh155975 while (index < MAX_ALLOWED_PATTERNS) { 1155*5256Slh155975 pMdl->PMR_PtrList[index+1] = 0; 1156*5256Slh155975 pMdl->PatternLength[index+1] = 0; 1157*5256Slh155975 index++; 1158*5256Slh155975 } 1159*5256Slh155975 1160*5256Slh155975 break; 1161*5256Slh155975 } 1162*5256Slh155975 index++; 1163*5256Slh155975 } 1164*5256Slh155975 1165*5256Slh155975 if (PatternMismatch) { 1166*5256Slh155975 *retval = -1; 1167*5256Slh155975 return; 1168*5256Slh155975 } 1169*5256Slh155975 1170*5256Slh155975 1171*5256Slh155975 for (j = 0; j < 8; j++) { 1172*5256Slh155975 tmpPtrArray[j] = 0; 1173*5256Slh155975 } 1174*5256Slh155975 1175*5256Slh155975 /* Zeroing the skip value of all the pattern masks */ 1176*5256Slh155975 j = 0; 1177*5256Slh155975 while (j < (pMdl->PatternList_FreeIndex)) { 1178*5256Slh155975 pMdl->PatternList[j] &= 0x8f; 1179*5256Slh155975 j += 5; 1180*5256Slh155975 } 1181*5256Slh155975 1182*5256Slh155975 /* 1183*5256Slh155975 * Scan the whole array & update the start offset of the pattern in the 1184*5256Slh155975 * PMR and update the skip value. 1185*5256Slh155975 */ 1186*5256Slh155975 j = 0; 1187*5256Slh155975 i = 0; 1188*5256Slh155975 Skip = 0; 1189*5256Slh155975 PatternOffset = 1; 1190*5256Slh155975 1191*5256Slh155975 while (j < (pMdl->PatternList_FreeIndex)) { 1192*5256Slh155975 if (pMdl->PatternList[j] & 0x0f) { 1193*5256Slh155975 1194*5256Slh155975 PatternOffset++; 1195*5256Slh155975 if (SearchForStartOfPattern == 1) { 1196*5256Slh155975 SearchForStartOfPattern = 0; 1197*5256Slh155975 tmpPtrArray[i++] = PatternOffset; 1198*5256Slh155975 } else if (pMdl->PatternList[j] & 0x80) { 1199*5256Slh155975 SearchForStartOfPattern = 1; 1200*5256Slh155975 } 1201*5256Slh155975 pMdl->PatternList[j] |= (Skip << 4); 1202*5256Slh155975 Skip = 0; 1203*5256Slh155975 } else { 1204*5256Slh155975 Skip++; 1205*5256Slh155975 } 1206*5256Slh155975 j += 5; 1207*5256Slh155975 } 1208*5256Slh155975 1209*5256Slh155975 1210*5256Slh155975 /* Write back the arrays to the PMR & lock the pmr */ 1211*5256Slh155975 WRITE_REG32(pLayerPointers, pMdl->Mem_Address+CMD7, PMAT_MODE); 1212*5256Slh155975 1213*5256Slh155975 /* Write the data & ctrl patterns from the array to the PMR */ 1214*5256Slh155975 i = 0; 1215*5256Slh155975 1216*5256Slh155975 offset = 2; 1217*5256Slh155975 1218*5256Slh155975 while (i < MAX_PATTERNS) { 1219*5256Slh155975 if (pMdl->PatternList[i] != 0) { 1220*5256Slh155975 Data = pMdl->PatternList[i+3] << 24 | 1221*5256Slh155975 pMdl->PatternList[i+2] << 16 | 1222*5256Slh155975 pMdl->PatternList[i+1] << 8 | 1223*5256Slh155975 pMdl->PatternList[i]; 1224*5256Slh155975 1225*5256Slh155975 WRITE_REG32(pLayerPointers, 1226*5256Slh155975 pMdl->Mem_Address+PMAT1, Data); 1227*5256Slh155975 1228*5256Slh155975 Data = (unsigned long) ((1<<30) | (offset << 16) | 1229*5256Slh155975 pMdl->PatternList[i+4]); 1230*5256Slh155975 1231*5256Slh155975 WRITE_REG32(pLayerPointers, 1232*5256Slh155975 pMdl->Mem_Address+PMAT0, Data); 1233*5256Slh155975 1234*5256Slh155975 offset++; 1235*5256Slh155975 1236*5256Slh155975 if (offset >= 64) { 1237*5256Slh155975 /* PMR is full !!!! */ 1238*5256Slh155975 *retval = -1; 1239*5256Slh155975 return; 1240*5256Slh155975 1241*5256Slh155975 } 1242*5256Slh155975 } 1243*5256Slh155975 i += 5; 1244*5256Slh155975 } 1245*5256Slh155975 1246*5256Slh155975 /* Valid pattern.. so update the house keeping info. */ 1247*5256Slh155975 pMdl->TotalPatterns--; 1248*5256Slh155975 1249*5256Slh155975 /* Update the pointer in the PMR */ 1250*5256Slh155975 pMdl->PatternEnableBit = 0; 1251*5256Slh155975 for (i = 0; i < pMdl->TotalPatterns; i++) { 1252*5256Slh155975 pMdl->PatternEnableBit |= (0x0001 << i); 1253*5256Slh155975 } 1254*5256Slh155975 1255*5256Slh155975 Data1 = Data2 = Data3 = Data4 = Data5 = Data6 = Data7 = Data8 = 0; 1256*5256Slh155975 1257*5256Slh155975 switch (pMdl->TotalPatterns) { 1258*5256Slh155975 case 8 : 1259*5256Slh155975 Data8 = (unsigned short)tmpPtrArray[7]; 1260*5256Slh155975 /* FALLTHROUGH */ 1261*5256Slh155975 case 7 : 1262*5256Slh155975 Data7 = (unsigned short)tmpPtrArray[6]; 1263*5256Slh155975 /* FALLTHROUGH */ 1264*5256Slh155975 case 6 : 1265*5256Slh155975 Data6 = (unsigned short)tmpPtrArray[5]; 1266*5256Slh155975 /* FALLTHROUGH */ 1267*5256Slh155975 case 5 : 1268*5256Slh155975 Data5 = (unsigned short)tmpPtrArray[4]; 1269*5256Slh155975 /* FALLTHROUGH */ 1270*5256Slh155975 case 4 : 1271*5256Slh155975 Data4 = (unsigned short)tmpPtrArray[3]; 1272*5256Slh155975 /* FALLTHROUGH */ 1273*5256Slh155975 case 3 : 1274*5256Slh155975 Data3 = (unsigned short)tmpPtrArray[2]; 1275*5256Slh155975 /* FALLTHROUGH */ 1276*5256Slh155975 case 2 : 1277*5256Slh155975 Data2 = (unsigned short)tmpPtrArray[1]; 1278*5256Slh155975 /* FALLTHROUGH */ 1279*5256Slh155975 case 1 : 1280*5256Slh155975 Data1 = (unsigned short)tmpPtrArray[0]; 1281*5256Slh155975 break; 1282*5256Slh155975 } 1283*5256Slh155975 1284*5256Slh155975 Data = pMdl->PatternEnableBit & 0x0f; 1285*5256Slh155975 1286*5256Slh155975 /* Updating the pointers 1,2,3 & 4 */ 1287*5256Slh155975 Data = (Data3 << 24 | Data2 << 16 | Data1 << 8 | Data); 1288*5256Slh155975 WRITE_REG32(pLayerPointers, pMdl->Mem_Address + PMAT1, Data); 1289*5256Slh155975 1290*5256Slh155975 Data = (unsigned long) ((1<<30) | Data4); 1291*5256Slh155975 WRITE_REG32(pLayerPointers, pMdl->Mem_Address + PMAT0, Data); 1292*5256Slh155975 1293*5256Slh155975 /* Updating the pointers 4,5,6 & 7 */ 1294*5256Slh155975 Data = (unsigned short)((unsigned)(pMdl->PatternEnableBit & 0xf0) >> 4); 1295*5256Slh155975 1296*5256Slh155975 Data = (Data7 << 24 | Data6 << 16 | Data5 << 8 | Data); 1297*5256Slh155975 WRITE_REG32(pLayerPointers, pMdl->Mem_Address + PMAT1, Data); 1298*5256Slh155975 1299*5256Slh155975 Data = (unsigned long) ((1<<30) | (1<<16) | Data8); 1300*5256Slh155975 WRITE_REG32(pLayerPointers, pMdl->Mem_Address + PMAT0, Data); 1301*5256Slh155975 1302*5256Slh155975 /* Unlock the PMR */ 1303*5256Slh155975 WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD7, VAL0 | PMAT_MODE); 1304*5256Slh155975 1305*5256Slh155975 *retval = 0; 1306*5256Slh155975 } 1307*5256Slh155975 1308*5256Slh155975 1309*5256Slh155975 /* 1310*5256Slh155975 * Checks the control register for the speed and the type of the 1311*5256Slh155975 * network connection. 1312*5256Slh155975 */ 1313*5256Slh155975 void 1314*5256Slh155975 mdlGetActiveMediaInfo(struct LayerPointers *pLayerPointers) 1315*5256Slh155975 { 1316*5256Slh155975 1317*5256Slh155975 unsigned long ulData; 1318*5256Slh155975 struct mdl *pMdl = 0; 1319*5256Slh155975 1320*5256Slh155975 pMdl = (struct mdl *)(pLayerPointers->pMdl); 1321*5256Slh155975 1322*5256Slh155975 ulData = READ_REG32(pLayerPointers, pMdl->Mem_Address + STAT0); 1323*5256Slh155975 1324*5256Slh155975 switch (ulData & SPEED_MASK) { 1325*5256Slh155975 case SPEED_100Mbps: 1326*5256Slh155975 pMdl->Speed = 100; 1327*5256Slh155975 break; 1328*5256Slh155975 case SPEED_10Mbps: 1329*5256Slh155975 pMdl->Speed = 10; 1330*5256Slh155975 break; 1331*5256Slh155975 default: 1332*5256Slh155975 pMdl->Speed = 100; 1333*5256Slh155975 break; 1334*5256Slh155975 } 1335*5256Slh155975 1336*5256Slh155975 if (ulData & FULL_DPLX) { 1337*5256Slh155975 pMdl->FullDuplex = B_TRUE; 1338*5256Slh155975 } else { 1339*5256Slh155975 pMdl->FullDuplex = B_FALSE; 1340*5256Slh155975 } 1341*5256Slh155975 } 1342*5256Slh155975 1343*5256Slh155975 void 1344*5256Slh155975 mdlChangeFilter(struct LayerPointers *pLayerPointers, unsigned long *ArrayPtr) 1345*5256Slh155975 { 1346*5256Slh155975 unsigned long *Ptr; 1347*5256Slh155975 unsigned char *MulticastArray; 1348*5256Slh155975 unsigned char *Pattern, *PatternMask; 1349*5256Slh155975 unsigned int InfoBuffer_MaskSize, PatternSize; 1350*5256Slh155975 int *retval; 1351*5256Slh155975 int NumberOfAddress, i; 1352*5256Slh155975 unsigned int j, CRCValue = 0; 1353*5256Slh155975 unsigned char HashCode = 0, FilterByte = 0; 1354*5256Slh155975 int BitMapIndex = 0; 1355*5256Slh155975 1356*5256Slh155975 Ptr = ArrayPtr; 1357*5256Slh155975 1358*5256Slh155975 while (*Ptr) { 1359*5256Slh155975 switch (*Ptr) { 1360*5256Slh155975 case DISABLE_BROADCAST: 1361*5256Slh155975 mdlDisableReceiveBroadCast(pLayerPointers); 1362*5256Slh155975 break; 1363*5256Slh155975 1364*5256Slh155975 case ENABLE_BROADCAST: 1365*5256Slh155975 mdlReceiveBroadCast(pLayerPointers); 1366*5256Slh155975 break; 1367*5256Slh155975 1368*5256Slh155975 case ENABLE_ALL_MULTICAST: 1369*5256Slh155975 for (i = 0; i < 8; i++) { 1370*5256Slh155975 pLayerPointers->pMdl->init_blk->LADRF[i] = 0xff; 1371*5256Slh155975 } 1372*5256Slh155975 WRITE_REG64(pLayerPointers, 1373*5256Slh155975 (unsigned long)pLayerPointers->pMdl 1374*5256Slh155975 ->Mem_Address + LADRF1, 1375*5256Slh155975 (char *)pLayerPointers->pMdl->init_blk->LADRF); 1376*5256Slh155975 break; 1377*5256Slh155975 1378*5256Slh155975 case DISABLE_ALL_MULTICAST: 1379*5256Slh155975 if (pLayerPointers->pMdl->EnableMulticast == 1) { 1380*5256Slh155975 for (i = 0; i < 8; i++) { 1381*5256Slh155975 pLayerPointers->pMdl->init_blk 1382*5256Slh155975 ->LADRF[i] = 1383*5256Slh155975 pLayerPointers->pMdl->TempLADRF[i]; 1384*5256Slh155975 } 1385*5256Slh155975 } 1386*5256Slh155975 1387*5256Slh155975 WRITE_REG64(pLayerPointers, 1388*5256Slh155975 (unsigned long)pLayerPointers->pMdl->Mem_Address 1389*5256Slh155975 + LADRF1, 1390*5256Slh155975 (char *)pLayerPointers->pMdl->init_blk->LADRF); 1391*5256Slh155975 break; 1392*5256Slh155975 1393*5256Slh155975 1394*5256Slh155975 case ADD_MULTICAST: 1395*5256Slh155975 NumberOfAddress = *(++Ptr); 1396*5256Slh155975 MulticastArray = (unsigned char *)(*(++Ptr)); 1397*5256Slh155975 mdlAddMulticastAddresses(pLayerPointers, 1398*5256Slh155975 NumberOfAddress, MulticastArray); 1399*5256Slh155975 break; 1400*5256Slh155975 1401*5256Slh155975 1402*5256Slh155975 case ENABLE_MULTICAST: 1403*5256Slh155975 for (i = 0; i < 8; i++) { 1404*5256Slh155975 pLayerPointers->pMdl->init_blk->LADRF[i] = 1405*5256Slh155975 pLayerPointers->pMdl->TempLADRF[i]; 1406*5256Slh155975 } 1407*5256Slh155975 pLayerPointers->pMdl->EnableMulticast = 1; 1408*5256Slh155975 1409*5256Slh155975 WRITE_REG64(pLayerPointers, 1410*5256Slh155975 (unsigned long)pLayerPointers->pMdl->Mem_Address 1411*5256Slh155975 + LADRF1, 1412*5256Slh155975 (char *)pLayerPointers->pMdl->init_blk->LADRF); 1413*5256Slh155975 break; 1414*5256Slh155975 1415*5256Slh155975 case DISABLE_MULTICAST: 1416*5256Slh155975 for (i = 0; i < 8; i++) { 1417*5256Slh155975 pLayerPointers->pMdl->init_blk->LADRF[i] = 0; 1418*5256Slh155975 } 1419*5256Slh155975 1420*5256Slh155975 pLayerPointers->pMdl->EnableMulticast = 0; 1421*5256Slh155975 1422*5256Slh155975 for (BitMapIndex = 0; BitMapIndex < 1423*5256Slh155975 MULTICAST_BITMAP_ARRAY_SIZE; BitMapIndex++) 1424*5256Slh155975 pLayerPointers->pMdl->MulticastBitMapArray 1425*5256Slh155975 [BitMapIndex] = 0; 1426*5256Slh155975 WRITE_REG64(pLayerPointers, 1427*5256Slh155975 (unsigned long)pLayerPointers->pMdl->Mem_Address 1428*5256Slh155975 + LADRF1, 1429*5256Slh155975 (char *)pLayerPointers->pMdl->init_blk->LADRF); 1430*5256Slh155975 break; 1431*5256Slh155975 1432*5256Slh155975 1433*5256Slh155975 case ADD_WAKE_UP_PATTERN: 1434*5256Slh155975 PatternMask = (unsigned char *)(*(++Ptr)); 1435*5256Slh155975 Pattern = (unsigned char *)(*(++Ptr)); 1436*5256Slh155975 InfoBuffer_MaskSize = (*(++Ptr)); 1437*5256Slh155975 PatternSize = (*(++Ptr)); 1438*5256Slh155975 retval = (int *)(*(++Ptr)); 1439*5256Slh155975 1440*5256Slh155975 mdlAddWakeUpPattern(pLayerPointers, 1441*5256Slh155975 PatternMask, 1442*5256Slh155975 Pattern, 1443*5256Slh155975 InfoBuffer_MaskSize, 1444*5256Slh155975 PatternSize, 1445*5256Slh155975 retval); 1446*5256Slh155975 break; 1447*5256Slh155975 1448*5256Slh155975 case REMOVE_WAKE_UP_PATTERN: 1449*5256Slh155975 Pattern = (unsigned char *)(*(++Ptr)); 1450*5256Slh155975 PatternSize = *(++Ptr); 1451*5256Slh155975 retval = (int *)(*(++Ptr)); 1452*5256Slh155975 mdlRemoveWakeUpPattern(pLayerPointers, 1453*5256Slh155975 Pattern, 1454*5256Slh155975 PatternSize, 1455*5256Slh155975 retval); 1456*5256Slh155975 break; 1457*5256Slh155975 1458*5256Slh155975 case ENABLE_MAGIC_PACKET_WAKE_UP: 1459*5256Slh155975 mdlEnableMagicPacketWakeUp(pLayerPointers); 1460*5256Slh155975 break; 1461*5256Slh155975 1462*5256Slh155975 case SET_SINGLE_MULTICAST: 1463*5256Slh155975 NumberOfAddress = *(++Ptr); 1464*5256Slh155975 MulticastArray = (unsigned char *)(*(++Ptr)); 1465*5256Slh155975 1466*5256Slh155975 for (i = 0; i < 8; i++) { 1467*5256Slh155975 pLayerPointers->pMdl->TempLADRF[i] = 1468*5256Slh155975 pLayerPointers->pMdl->init_blk->LADRF[i]; 1469*5256Slh155975 } 1470*5256Slh155975 CRCValue = mdlCalculateCRC(ETH_LENGTH_OF_ADDRESS, 1471*5256Slh155975 MulticastArray); 1472*5256Slh155975 for (j = 0; j < 6; j++) { 1473*5256Slh155975 HashCode = (HashCode << 1) + 1474*5256Slh155975 (((unsigned char)CRCValue >> j) & 0x01); 1475*5256Slh155975 } 1476*5256Slh155975 /* 1477*5256Slh155975 * Bits 3-5 of HashCode point to byte in address 1478*5256Slh155975 * filter. 1479*5256Slh155975 * Bits 0-2 point to bit within that byte. 1480*5256Slh155975 */ 1481*5256Slh155975 FilterByte = HashCode >> 3; 1482*5256Slh155975 pLayerPointers->pMdl->TempLADRF[FilterByte] |= 1483*5256Slh155975 (1 << (HashCode & 0x07)); 1484*5256Slh155975 break; 1485*5256Slh155975 1486*5256Slh155975 case UNSET_SINGLE_MULTICAST: 1487*5256Slh155975 NumberOfAddress = *(++Ptr); 1488*5256Slh155975 MulticastArray = (unsigned char *)(*(++Ptr)); 1489*5256Slh155975 for (i = 0; i < 8; i++) { 1490*5256Slh155975 pLayerPointers->pMdl->TempLADRF[i] = 1491*5256Slh155975 pLayerPointers->pMdl->init_blk->LADRF[i]; 1492*5256Slh155975 } 1493*5256Slh155975 CRCValue = mdlCalculateCRC(ETH_LENGTH_OF_ADDRESS, 1494*5256Slh155975 MulticastArray); 1495*5256Slh155975 for (j = 0; j < 6; j++) { 1496*5256Slh155975 HashCode = ((HashCode << 1) + 1497*5256Slh155975 (((unsigned char)CRCValue >> j) & 0x01)); 1498*5256Slh155975 } 1499*5256Slh155975 1500*5256Slh155975 /* 1501*5256Slh155975 * Bits 3-5 of HashCode point to byte in address 1502*5256Slh155975 * filter. 1503*5256Slh155975 * Bits 0-2 point to bit within that byte. 1504*5256Slh155975 */ 1505*5256Slh155975 FilterByte = HashCode >> 3; 1506*5256Slh155975 pLayerPointers->pMdl->TempLADRF[FilterByte] &= 1507*5256Slh155975 !(1 << (HashCode & 0x07)); 1508*5256Slh155975 break; 1509*5256Slh155975 1510*5256Slh155975 default: 1511*5256Slh155975 break; 1512*5256Slh155975 } 1513*5256Slh155975 Ptr++; 1514*5256Slh155975 } 1515*5256Slh155975 } 1516*5256Slh155975 1517*5256Slh155975 1518*5256Slh155975 void 1519*5256Slh155975 mdlAddMulticastAddresses(struct LayerPointers *pLayerPointers, 1520*5256Slh155975 int NumberOfAddress, unsigned char *MulticastAddresses) 1521*5256Slh155975 { 1522*5256Slh155975 unsigned int j, CRCValue; 1523*5256Slh155975 unsigned char HashCode, FilterByte; 1524*5256Slh155975 int i; 1525*5256Slh155975 1526*5256Slh155975 for (i = 0; i < 8; i++) { 1527*5256Slh155975 pLayerPointers->pMdl->TempLADRF[i] = 0x00; 1528*5256Slh155975 } 1529*5256Slh155975 1530*5256Slh155975 1531*5256Slh155975 for (i = 0; i < NumberOfAddress; i++) { 1532*5256Slh155975 HashCode = 0; 1533*5256Slh155975 1534*5256Slh155975 /* Calculate CRC value */ 1535*5256Slh155975 CRCValue = mdlCalculateCRC(ETH_LENGTH_OF_ADDRESS, 1536*5256Slh155975 MulticastAddresses); 1537*5256Slh155975 1538*5256Slh155975 for (j = 0; j < 6; j++) { 1539*5256Slh155975 HashCode = (HashCode << 1) + 1540*5256Slh155975 (((unsigned char)CRCValue >> j) & 0x01); 1541*5256Slh155975 } 1542*5256Slh155975 1543*5256Slh155975 /* Bits 3-5 of HashCode point to byte in address filter. */ 1544*5256Slh155975 /* Bits 0-2 point to bit within that byte. */ 1545*5256Slh155975 FilterByte = HashCode >> 3; 1546*5256Slh155975 pLayerPointers->pMdl->TempLADRF[FilterByte] |= 1547*5256Slh155975 (1 << (HashCode & 0x07)); 1548*5256Slh155975 MulticastAddresses += ETH_LENGTH_OF_ADDRESS; 1549*5256Slh155975 } 1550*5256Slh155975 } 1551*5256Slh155975 1552*5256Slh155975 /* Receive all packets */ 1553*5256Slh155975 void 1554*5256Slh155975 mdlSetPromiscuous(struct LayerPointers *pLayerPointers) 1555*5256Slh155975 { 1556*5256Slh155975 /* 1557*5256Slh155975 * Writable N == Can Be Written only when device is not running 1558*5256Slh155975 * (RUN == 0) 1559*5256Slh155975 */ 1560*5256Slh155975 WRITE_REG32(pLayerPointers, pLayerPointers->pMdl->Mem_Address + CMD2, 1561*5256Slh155975 VAL2 | PROM); 1562*5256Slh155975 pLayerPointers->pMdl->FLAGS |= PROM; /* B16_MASK */ 1563*5256Slh155975 } 1564*5256Slh155975 1565*5256Slh155975 /* Stop Receiving all packets */ 1566*5256Slh155975 void 1567*5256Slh155975 mdlDisablePromiscuous(struct LayerPointers *pLayerPointers) 1568*5256Slh155975 { 1569*5256Slh155975 /* 1570*5256Slh155975 * Writable N == Can Be Written only when device is not running 1571*5256Slh155975 * (RUN == 0) 1572*5256Slh155975 */ 1573*5256Slh155975 WRITE_REG32(pLayerPointers, pLayerPointers->pMdl->Mem_Address + CMD2, 1574*5256Slh155975 PROM); 1575*5256Slh155975 pLayerPointers->pMdl->FLAGS &= (~ PROM); /* B16_MASK */ 1576*5256Slh155975 } 1577*5256Slh155975 1578*5256Slh155975 /* 1579*5256Slh155975 * Disable Receive Broadcast. When set, disables the controller from receiving 1580*5256Slh155975 * broadcast messages. Used for protocols that do not support broadcast 1581*5256Slh155975 * addressing, except as a function of multicast. 1582*5256Slh155975 * DRCVBC is cleared by activation of H_RESET (broadcast messages will be 1583*5256Slh155975 * received) and is unaffected by the clearing of the RUN bit. 1584*5256Slh155975 */ 1585*5256Slh155975 static void 1586*5256Slh155975 mdlReceiveBroadCast(struct LayerPointers *pLayerPointers) 1587*5256Slh155975 { 1588*5256Slh155975 ULONG MappedMemBaseAddress; 1589*5256Slh155975 1590*5256Slh155975 MappedMemBaseAddress = pLayerPointers->pMdl->Mem_Address; 1591*5256Slh155975 WRITE_REG32(pLayerPointers, MappedMemBaseAddress + CMD2, DRCVBC); 1592*5256Slh155975 pLayerPointers->pMdl->FLAGS |= DRCVBC; 1593*5256Slh155975 } 1594*5256Slh155975 1595*5256Slh155975 static void 1596*5256Slh155975 mdlDisableReceiveBroadCast(struct LayerPointers *pLayerPointers) 1597*5256Slh155975 { 1598*5256Slh155975 ULONG MappedMemBaseAddress; 1599*5256Slh155975 1600*5256Slh155975 MappedMemBaseAddress = pLayerPointers->pMdl->Mem_Address; 1601*5256Slh155975 WRITE_REG32(pLayerPointers, MappedMemBaseAddress + CMD2, VAL2 | DRCVBC); 1602*5256Slh155975 pLayerPointers->pMdl->FLAGS &= (~DRCVBC); 1603*5256Slh155975 } 1604*5256Slh155975 1605*5256Slh155975 static void 1606*5256Slh155975 mdlEnableMagicPacketWakeUp(struct LayerPointers *pLayerPointers) 1607*5256Slh155975 { 1608*5256Slh155975 WRITE_REG32(pLayerPointers, pLayerPointers->pMdl->Mem_Address + CMD3, 1609*5256Slh155975 VAL1 | MPPLBA); 1610*5256Slh155975 WRITE_REG32(pLayerPointers, pLayerPointers->pMdl->Mem_Address + CMD7, 1611*5256Slh155975 VAL0 | MPEN_SW); 1612*5256Slh155975 } 1613*5256Slh155975 1614*5256Slh155975 /* 1615*5256Slh155975 * BitMap for add/del the Multicast address Since more than one M/C address 1616*5256Slh155975 * can map to same bit in the filter matrix, we should maintain the count for 1617*5256Slh155975 * # of M/C addresses associated with each bit. Only when the bit<->count 1618*5256Slh155975 * becomes zero, we should go ahead with changing/reseting the bit, else just 1619*5256Slh155975 * reduce the count associated with each bit and return. 1620*5256Slh155975 */ 1621*5256Slh155975 static int 1622*5256Slh155975 mdlMulticastBitMapping(struct LayerPointers *pLayerPointers, 1623*5256Slh155975 unsigned char *MulticastAddress, int FLAG) 1624*5256Slh155975 { 1625*5256Slh155975 unsigned char HashCode, FilterByte; 1626*5256Slh155975 int j = 0, BitMapIndex = 0; 1627*5256Slh155975 unsigned int CRCValue = 0; 1628*5256Slh155975 1629*5256Slh155975 HashCode = 0; 1630*5256Slh155975 /* Calculate the Bit Map location for the given Address */ 1631*5256Slh155975 CRCValue = mdlCalculateCRC(ETH_LENGTH_OF_ADDRESS, MulticastAddress); 1632*5256Slh155975 for (j = 0; j < 6; j++) { 1633*5256Slh155975 HashCode = (HashCode << 1) + 1634*5256Slh155975 (((unsigned char)CRCValue >> j) & 0x01); 1635*5256Slh155975 } 1636*5256Slh155975 1637*5256Slh155975 /* 1638*5256Slh155975 * Bits 3-5 of HashCode point to byte in address filter. 1639*5256Slh155975 * Bits 0-2 point to bit within that byte. 1640*5256Slh155975 */ 1641*5256Slh155975 FilterByte = HashCode & 0x38; 1642*5256Slh155975 FilterByte = FilterByte >> 3; 1643*5256Slh155975 BitMapIndex = (int)FilterByte * 8 + (HashCode & 0x7); 1644*5256Slh155975 1645*5256Slh155975 if (FLAG == DELETE_MULTICAST) { 1646*5256Slh155975 if ((pLayerPointers->pMdl->MulticastBitMapArray[BitMapIndex] 1647*5256Slh155975 == 0) || (--pLayerPointers->pMdl->MulticastBitMapArray 1648*5256Slh155975 [BitMapIndex] == 0)) { 1649*5256Slh155975 return (0); 1650*5256Slh155975 } else { 1651*5256Slh155975 return (-1); 1652*5256Slh155975 } 1653*5256Slh155975 } 1654*5256Slh155975 1655*5256Slh155975 if (FLAG == ADD_MULTICAST) { 1656*5256Slh155975 if (pLayerPointers->pMdl 1657*5256Slh155975 ->MulticastBitMapArray[BitMapIndex] > 0) { 1658*5256Slh155975 pLayerPointers->pMdl 1659*5256Slh155975 ->MulticastBitMapArray[BitMapIndex]++; 1660*5256Slh155975 return (-1); 1661*5256Slh155975 } else if (pLayerPointers->pMdl 1662*5256Slh155975 ->MulticastBitMapArray[BitMapIndex] == 0) { 1663*5256Slh155975 pLayerPointers->pMdl 1664*5256Slh155975 ->MulticastBitMapArray[BitMapIndex]++; 1665*5256Slh155975 return (0); 1666*5256Slh155975 } 1667*5256Slh155975 } 1668*5256Slh155975 return (0); 1669*5256Slh155975 } 1670*5256Slh155975 1671*5256Slh155975 /* 1672*5256Slh155975 * Set Interrupt Coalescing registers: 1673*5256Slh155975 * To reduce the host CPU interrupt service overhead the network 1674*5256Slh155975 * controller can be programmed to postpone the interrupt to the host 1675*5256Slh155975 * CPU until either a programmable number of receive or transmit 1676*5256Slh155975 * interrupt events have occurred or a programmable amount of time has 1677*5256Slh155975 * elapsed since the first interrupt event occurred. 1678*5256Slh155975 */ 1679*5256Slh155975 void 1680*5256Slh155975 SetIntrCoalesc(struct LayerPointers *pLayerPointers, boolean_t on) 1681*5256Slh155975 { 1682*5256Slh155975 long MemBaseAddress = pLayerPointers->pMdl->Mem_Address; 1683*5256Slh155975 struct mdl *pMdl = 0; 1684*5256Slh155975 unsigned int timeout, event_count; 1685*5256Slh155975 1686*5256Slh155975 pMdl = (struct mdl *)(pLayerPointers->pMdl); 1687*5256Slh155975 1688*5256Slh155975 if (on) { 1689*5256Slh155975 /* Set Rx Interrupt Coalescing */ 1690*5256Slh155975 timeout = pLayerPointers->pMdl->rx_intrcoalesc_time; 1691*5256Slh155975 event_count = 0; 1692*5256Slh155975 event_count |= pLayerPointers->pMdl->rx_intrcoalesc_events; 1693*5256Slh155975 if (timeout > 0x7ff) { 1694*5256Slh155975 timeout = 0x7ff; 1695*5256Slh155975 } 1696*5256Slh155975 if (event_count > 0x1f) { 1697*5256Slh155975 event_count = 0x1f; 1698*5256Slh155975 } 1699*5256Slh155975 1700*5256Slh155975 event_count = event_count << 16; 1701*5256Slh155975 WRITE_REG32(pLayerPointers, MemBaseAddress + DLY_INT_A, 1702*5256Slh155975 DLY_INT_A_R0 | event_count | timeout); 1703*5256Slh155975 1704*5256Slh155975 } else { 1705*5256Slh155975 /* Disable Software Timer Interrupt */ 1706*5256Slh155975 WRITE_REG32(pLayerPointers, MemBaseAddress + STVAL, 0); 1707*5256Slh155975 WRITE_REG32(pLayerPointers, pMdl->Mem_Address + INTEN0, 1708*5256Slh155975 STINTEN); 1709*5256Slh155975 1710*5256Slh155975 WRITE_REG32(pLayerPointers, MemBaseAddress + DLY_INT_A, 0); 1711*5256Slh155975 WRITE_REG32(pLayerPointers, MemBaseAddress + DLY_INT_B, 0); 1712*5256Slh155975 } 1713*5256Slh155975 } 1714*5256Slh155975 1715*5256Slh155975 void 1716*5256Slh155975 mdlSendPause(struct LayerPointers *pLayerPointers) 1717*5256Slh155975 { 1718*5256Slh155975 WRITE_REG32(pLayerPointers, pLayerPointers->pMdl->Mem_Address 1719*5256Slh155975 + FLOW_CONTROL, VAL2 | FIXP | FCCMD | 0x200); 1720*5256Slh155975 } 1721*5256Slh155975 1722*5256Slh155975 /* Reset all Tx descriptors and Tx buffers */ 1723*5256Slh155975 void 1724*5256Slh155975 milResetTxQ(struct LayerPointers *pLayerPointers) 1725*5256Slh155975 { 1726*5256Slh155975 struct nonphysical *pNonphysical = pLayerPointers->pMil->pNonphysical; 1727*5256Slh155975 int i; 1728*5256Slh155975 1729*5256Slh155975 pNonphysical->TxDescQRead = pNonphysical->TxDescQStart; 1730*5256Slh155975 pNonphysical->TxDescQWrite = pNonphysical->TxDescQStart; 1731*5256Slh155975 1732*5256Slh155975 /* Clean all Tx descriptors */ 1733*5256Slh155975 for (i = 0; i < TX_RING_SIZE; i++) { 1734*5256Slh155975 pNonphysical->TxDescQWrite->Tx_OWN = 0; 1735*5256Slh155975 pNonphysical->TxDescQWrite->Tx_SOP = 0; 1736*5256Slh155975 pNonphysical->TxDescQWrite->Tx_EOP = 0; 1737*5256Slh155975 pNonphysical->TxDescQWrite++; 1738*5256Slh155975 } 1739*5256Slh155975 pNonphysical->TxDescQWrite = pNonphysical->TxDescQStart; 1740*5256Slh155975 1741*5256Slh155975 /* Re-init Tx Buffers */ 1742*5256Slh155975 pLayerPointers->pOdl->tx_buf.free = 1743*5256Slh155975 pLayerPointers->pOdl->tx_buf.msg_buf; 1744*5256Slh155975 pLayerPointers->pOdl->tx_buf.next = 1745*5256Slh155975 pLayerPointers->pOdl->tx_buf.msg_buf; 1746*5256Slh155975 pLayerPointers->pOdl->tx_buf.curr = 1747*5256Slh155975 pLayerPointers->pOdl->tx_buf.msg_buf; 1748*5256Slh155975 } 1749*5256Slh155975 1750*5256Slh155975 /* 1751*5256Slh155975 * Initialises the data used in Mil. 1752*5256Slh155975 */ 1753*5256Slh155975 void 1754*5256Slh155975 milInitGlbds(struct LayerPointers *pLayerPointers) 1755*5256Slh155975 { 1756*5256Slh155975 pLayerPointers->pMil->name = DEVICE_CHIPNAME; 1757*5256Slh155975 1758*5256Slh155975 mdlInitGlbds(pLayerPointers); 1759*5256Slh155975 } 1760*5256Slh155975 1761*5256Slh155975 /* 1762*5256Slh155975 * Purpose : 1763*5256Slh155975 * Initialises the RxBufDescQ with the packet pointer and physical 1764*5256Slh155975 * address filled in the FreeQ. 1765*5256Slh155975 * 1766*5256Slh155975 * Arguments : 1767*5256Slh155975 * pLayerPointers 1768*5256Slh155975 * Pointer to the Adapter structure. 1769*5256Slh155975 */ 1770*5256Slh155975 void 1771*5256Slh155975 milInitRxQ(struct LayerPointers *pLayerPointers) 1772*5256Slh155975 { 1773*5256Slh155975 struct mil *pMil = pLayerPointers->pMil; 1774*5256Slh155975 struct nonphysical *pNonphysical = pMil->pNonphysical; 1775*5256Slh155975 int i; 1776*5256Slh155975 1777*5256Slh155975 pNonphysical->RxBufDescQRead->descriptor = pMil->Rx_desc; 1778*5256Slh155975 pNonphysical->RxBufDescQStart->descriptor = pMil->Rx_desc; 1779*5256Slh155975 pNonphysical->RxBufDescQEnd->descriptor = 1780*5256Slh155975 &(pMil->Rx_desc[pMil->RxRingSize - 1]); 1781*5256Slh155975 1782*5256Slh155975 pNonphysical->RxBufDescQRead->USpaceMap = pMil->USpaceMapArray; 1783*5256Slh155975 pNonphysical->RxBufDescQStart->USpaceMap = pMil->USpaceMapArray; 1784*5256Slh155975 pNonphysical->RxBufDescQEnd->USpaceMap = 1785*5256Slh155975 &(pMil->USpaceMapArray[pMil->RxRingSize - 1]); 1786*5256Slh155975 1787*5256Slh155975 /* Initialize the adapter rx descriptor Q and rx buffer Q */ 1788*5256Slh155975 for (i = 0; i < pMil->RxRingSize; i++) { 1789*5256Slh155975 pNonphysical->RxBufDescQRead->descriptor->Rx_BCNT 1790*5256Slh155975 = (unsigned)pMil->RxBufSize; 1791*5256Slh155975 1792*5256Slh155975 *(pNonphysical->RxBufDescQRead->USpaceMap) = 1793*5256Slh155975 (long)(pLayerPointers->pOdl->rx_buf.next->vir_addr); 1794*5256Slh155975 1795*5256Slh155975 pNonphysical->RxBufDescQRead->descriptor->Rx_Base_Addr 1796*5256Slh155975 = pLayerPointers->pOdl->rx_buf.next->phy_addr; 1797*5256Slh155975 1798*5256Slh155975 pNonphysical->RxBufDescQRead->descriptor->Rx_OWN = 1; 1799*5256Slh155975 pNonphysical->RxBufDescQRead->descriptor++; 1800*5256Slh155975 pNonphysical->RxBufDescQRead->USpaceMap++; 1801*5256Slh155975 pLayerPointers->pOdl->rx_buf.next = 1802*5256Slh155975 NEXT(pLayerPointers->pOdl->rx_buf, next); 1803*5256Slh155975 } 1804*5256Slh155975 1805*5256Slh155975 pNonphysical->RxBufDescQRead->descriptor = 1806*5256Slh155975 pNonphysical->RxBufDescQStart->descriptor; 1807*5256Slh155975 pNonphysical->RxBufDescQRead->USpaceMap = 1808*5256Slh155975 pNonphysical->RxBufDescQStart->USpaceMap; 1809*5256Slh155975 pLayerPointers->pOdl->rx_buf.next = 1810*5256Slh155975 pLayerPointers->pOdl->rx_buf.msg_buf; 1811*5256Slh155975 } 1812*5256Slh155975 1813*5256Slh155975 /* 1814*5256Slh155975 * Purpose : 1815*5256Slh155975 * This array is filled with the size of the structure & its 1816*5256Slh155975 * pointer for freeing purposes. 1817*5256Slh155975 * 1818*5256Slh155975 * Arguments : 1819*5256Slh155975 * pLayerPointers 1820*5256Slh155975 * Pointer to the adapter structure. 1821*5256Slh155975 * mem_free_array 1822*5256Slh155975 * Pointer to the array that holds the data required 1823*5256Slh155975 * for freeing. 1824*5256Slh155975 */ 1825*5256Slh155975 void 1826*5256Slh155975 milFreeResources(struct LayerPointers *pLayerPointers, ULONG *mem_free_array) 1827*5256Slh155975 { 1828*5256Slh155975 /* 1) For mil structure (pLayerPointers->pMil) */ 1829*5256Slh155975 /* Type */ 1830*5256Slh155975 *(mem_free_array) = VIRTUAL; 1831*5256Slh155975 /* Size */ 1832*5256Slh155975 *(++mem_free_array) = sizeof (struct mil); 1833*5256Slh155975 /* VA */ 1834*5256Slh155975 *(++mem_free_array) = (ULONG)pLayerPointers->pMil; 1835*5256Slh155975 1836*5256Slh155975 1837*5256Slh155975 /* 2) For USpaceMapArray queue */ 1838*5256Slh155975 /* Type */ 1839*5256Slh155975 *(++mem_free_array) = VIRTUAL; 1840*5256Slh155975 /* Size */ 1841*5256Slh155975 *(++mem_free_array) = pLayerPointers->pMil->RxRingSize * 1842*5256Slh155975 sizeof (unsigned long); 1843*5256Slh155975 /* VA */ 1844*5256Slh155975 *(++mem_free_array) = (ULONG)pLayerPointers->pMil->USpaceMapArray; 1845*5256Slh155975 1846*5256Slh155975 1847*5256Slh155975 /* 3) For non_physical structure */ 1848*5256Slh155975 /* Type */ 1849*5256Slh155975 *(++mem_free_array) = VIRTUAL; 1850*5256Slh155975 /* Size */ 1851*5256Slh155975 *(++mem_free_array) = sizeof (struct nonphysical); 1852*5256Slh155975 /* VA */ 1853*5256Slh155975 *(++mem_free_array) = (ULONG)pLayerPointers->pMil->pNonphysical; 1854*5256Slh155975 1855*5256Slh155975 /* 1856*5256Slh155975 * 4~6) For four allocation are for abstracting the Rx_Descritor ring 1857*5256Slh155975 */ 1858*5256Slh155975 1859*5256Slh155975 /* 4) Type */ 1860*5256Slh155975 *(++mem_free_array) = VIRTUAL; 1861*5256Slh155975 /* Size */ 1862*5256Slh155975 *(++mem_free_array) = sizeof (struct Rx_Buf_Desc); 1863*5256Slh155975 /* VA */ 1864*5256Slh155975 *(++mem_free_array) = 1865*5256Slh155975 (ULONG)pLayerPointers->pMil->pNonphysical->RxBufDescQRead; 1866*5256Slh155975 1867*5256Slh155975 /* 5) Type */ 1868*5256Slh155975 *(++mem_free_array) = VIRTUAL; 1869*5256Slh155975 /* Size */ 1870*5256Slh155975 *(++mem_free_array) = sizeof (struct Rx_Buf_Desc); 1871*5256Slh155975 /* VA */ 1872*5256Slh155975 *(++mem_free_array) = 1873*5256Slh155975 (ULONG)pLayerPointers->pMil->pNonphysical->RxBufDescQStart; 1874*5256Slh155975 1875*5256Slh155975 /* 6) Type */ 1876*5256Slh155975 *(++mem_free_array) = VIRTUAL; 1877*5256Slh155975 /* Size */ 1878*5256Slh155975 *(++mem_free_array) = sizeof (struct Rx_Buf_Desc); 1879*5256Slh155975 /* VA */ 1880*5256Slh155975 *(++mem_free_array) = 1881*5256Slh155975 (ULONG)pLayerPointers->pMil->pNonphysical->RxBufDescQEnd; 1882*5256Slh155975 1883*5256Slh155975 *(++mem_free_array) = 0; 1884*5256Slh155975 1885*5256Slh155975 mdlFreeResources(pLayerPointers, mem_free_array); 1886*5256Slh155975 } 1887*5256Slh155975 1888*5256Slh155975 1889*5256Slh155975 1890*5256Slh155975 /* 1891*5256Slh155975 * Purpose : 1892*5256Slh155975 * This array is filled with the size of the memory required for 1893*5256Slh155975 * allocating purposes. 1894*5256Slh155975 * 1895*5256Slh155975 * Arguments : 1896*5256Slh155975 * pLayerPointers 1897*5256Slh155975 * Pointer to the adapter structure. 1898*5256Slh155975 * mem_req_array 1899*5256Slh155975 * Pointer to the array that holds the data required for 1900*5256Slh155975 * allocating memory. 1901*5256Slh155975 */ 1902*5256Slh155975 void 1903*5256Slh155975 milRequestResources(ULONG *mem_req_array) 1904*5256Slh155975 { 1905*5256Slh155975 int RxRingSize; 1906*5256Slh155975 1907*5256Slh155975 RxRingSize = RX_RING_SIZE; /* 128 */ 1908*5256Slh155975 1909*5256Slh155975 /* 1) For mil structure (pLayerPointers->pMil) */ 1910*5256Slh155975 /* Type */ 1911*5256Slh155975 *mem_req_array = VIRTUAL; 1912*5256Slh155975 /* Size */ 1913*5256Slh155975 *(++mem_req_array) = sizeof (struct mil); 1914*5256Slh155975 1915*5256Slh155975 /* 2) For USpaceMapArray queue (pLayerPointers->pMil->USpaceMapArray) */ 1916*5256Slh155975 /* Type */ 1917*5256Slh155975 *(++mem_req_array) = VIRTUAL; 1918*5256Slh155975 /* Size */ 1919*5256Slh155975 *(++mem_req_array) = RxRingSize * sizeof (unsigned long); 1920*5256Slh155975 1921*5256Slh155975 1922*5256Slh155975 /* 3) For pNonphysical structure */ 1923*5256Slh155975 /* Type */ 1924*5256Slh155975 *(++mem_req_array) = VIRTUAL; 1925*5256Slh155975 /* Size */ 1926*5256Slh155975 *(++mem_req_array) = sizeof (struct nonphysical); 1927*5256Slh155975 1928*5256Slh155975 /* 1929*5256Slh155975 * 4~6) For four allocation are for abstracting the Rx_Descritor ring 1930*5256Slh155975 */ 1931*5256Slh155975 /* 4) Type */ 1932*5256Slh155975 *(++mem_req_array) = VIRTUAL; 1933*5256Slh155975 /* Size */ 1934*5256Slh155975 *(++mem_req_array) = sizeof (struct Rx_Buf_Desc); 1935*5256Slh155975 1936*5256Slh155975 /* 5) Type */ 1937*5256Slh155975 *(++mem_req_array) = VIRTUAL; 1938*5256Slh155975 /* Size */ 1939*5256Slh155975 *(++mem_req_array) = sizeof (struct Rx_Buf_Desc); 1940*5256Slh155975 1941*5256Slh155975 /* 6) Type */ 1942*5256Slh155975 *(++mem_req_array) = VIRTUAL; 1943*5256Slh155975 /* Size */ 1944*5256Slh155975 *(++mem_req_array) = sizeof (struct Rx_Buf_Desc); 1945*5256Slh155975 1946*5256Slh155975 *(++mem_req_array) = 0; 1947*5256Slh155975 1948*5256Slh155975 mdlRequestResources(mem_req_array); 1949*5256Slh155975 } 1950*5256Slh155975 1951*5256Slh155975 1952*5256Slh155975 1953*5256Slh155975 /* 1954*5256Slh155975 * Purpose : 1955*5256Slh155975 * This array contains the details of the allocated memory. The 1956*5256Slh155975 * pointers are taken from the respective locations in the array 1957*5256Slh155975 * & assigne appropriately to the respective structures. 1958*5256Slh155975 * 1959*5256Slh155975 * Arguments : 1960*5256Slh155975 * pLayerPointers 1961*5256Slh155975 * Pointer to the adapter structure. 1962*5256Slh155975 * pmem_set_array 1963*5256Slh155975 * Pointer to the array that holds the data after required 1964*5256Slh155975 * allocating memory. 1965*5256Slh155975 */ 1966*5256Slh155975 void 1967*5256Slh155975 milSetResources(struct LayerPointers *pLayerPointers, ULONG *pmem_set_array) 1968*5256Slh155975 { 1969*5256Slh155975 int RxRingSize, TxRingSize; 1970*5256Slh155975 int RxBufSize; 1971*5256Slh155975 struct mil *pMil; 1972*5256Slh155975 1973*5256Slh155975 RxRingSize = RX_RING_SIZE; 1974*5256Slh155975 TxRingSize = TX_RING_SIZE; 1975*5256Slh155975 RxBufSize = RX_BUF_SIZE; 1976*5256Slh155975 1977*5256Slh155975 /* 1) Set the pointers to the mil pointers */ 1978*5256Slh155975 /* Type */ 1979*5256Slh155975 pmem_set_array++; 1980*5256Slh155975 /* Size */ 1981*5256Slh155975 pmem_set_array++; 1982*5256Slh155975 pMil = (struct mil *)(*pmem_set_array); 1983*5256Slh155975 pLayerPointers->pMil = pMil; 1984*5256Slh155975 1985*5256Slh155975 pMil->RxRingSize = RxRingSize; 1986*5256Slh155975 pMil->TxRingSize = TxRingSize; 1987*5256Slh155975 pMil->RxBufSize = RxBufSize; 1988*5256Slh155975 1989*5256Slh155975 /* 2) Type */ 1990*5256Slh155975 pmem_set_array++; 1991*5256Slh155975 /* Size */ 1992*5256Slh155975 pmem_set_array++; 1993*5256Slh155975 pmem_set_array++; 1994*5256Slh155975 pMil->USpaceMapArray = (long *)(*pmem_set_array); 1995*5256Slh155975 1996*5256Slh155975 /* 3) Set the pointers to the NonPhysical part */ 1997*5256Slh155975 /* Type */ 1998*5256Slh155975 pmem_set_array++; 1999*5256Slh155975 /* Size */ 2000*5256Slh155975 pmem_set_array++; 2001*5256Slh155975 /* Virtual Addr of NonPhysical */ 2002*5256Slh155975 pmem_set_array++; 2003*5256Slh155975 pMil->pNonphysical = 2004*5256Slh155975 (struct nonphysical *)(*pmem_set_array); 2005*5256Slh155975 2006*5256Slh155975 /* 2007*5256Slh155975 * 4~6) Following four allocation are for abstracting the Rx_Descritor 2008*5256Slh155975 * Ring. 2009*5256Slh155975 */ 2010*5256Slh155975 /* 4) Type */ 2011*5256Slh155975 pmem_set_array++; 2012*5256Slh155975 /* Size */ 2013*5256Slh155975 pmem_set_array++; 2014*5256Slh155975 /* Virtual Addr of Abstracted RxDesc */ 2015*5256Slh155975 pmem_set_array++; 2016*5256Slh155975 pMil->pNonphysical->RxBufDescQRead = 2017*5256Slh155975 (struct Rx_Buf_Desc *)(*pmem_set_array); 2018*5256Slh155975 2019*5256Slh155975 /* 5) Type */ 2020*5256Slh155975 pmem_set_array++; 2021*5256Slh155975 /* Size */ 2022*5256Slh155975 pmem_set_array++; 2023*5256Slh155975 /* Virtual Addr of Abstracted RxDesc */ 2024*5256Slh155975 pmem_set_array++; 2025*5256Slh155975 pMil->pNonphysical->RxBufDescQStart = 2026*5256Slh155975 (struct Rx_Buf_Desc *)(*pmem_set_array); 2027*5256Slh155975 2028*5256Slh155975 /* 6) Type */ 2029*5256Slh155975 pmem_set_array++; 2030*5256Slh155975 /* Size */ 2031*5256Slh155975 pmem_set_array++; 2032*5256Slh155975 /* Virtual Addr of Abstracted RxDesc */ 2033*5256Slh155975 pmem_set_array++; 2034*5256Slh155975 pMil->pNonphysical->RxBufDescQEnd = 2035*5256Slh155975 (struct Rx_Buf_Desc *)(*pmem_set_array); 2036*5256Slh155975 2037*5256Slh155975 pmem_set_array++; 2038*5256Slh155975 2039*5256Slh155975 mdlSetResources(pLayerPointers, pmem_set_array); 2040*5256Slh155975 } 2041*5256Slh155975 2042*5256Slh155975 /* 2043*5256Slh155975 * Purpose : 2044*5256Slh155975 * This routine adds the Multicast addresses to the filter 2045*5256Slh155975 * 2046*5256Slh155975 * Arguments : 2047*5256Slh155975 * pLayerPointers 2048*5256Slh155975 * Pointer to Layer pointers structure. 2049*5256Slh155975 * pucMulticastAddress 2050*5256Slh155975 * Pointer to the array of multicast addresses 2051*5256Slh155975 */ 2052*5256Slh155975 void 2053*5256Slh155975 mdlAddMulticastAddress(struct LayerPointers *pLayerPointers, 2054*5256Slh155975 UCHAR *pucMulticastAddress) 2055*5256Slh155975 { 2056*5256Slh155975 unsigned long MODE[10]; 2057*5256Slh155975 unsigned long tmp1; 2058*5256Slh155975 unsigned long tmp2; 2059*5256Slh155975 2060*5256Slh155975 if (mdlMulticastBitMapping(pLayerPointers, pucMulticastAddress, 2061*5256Slh155975 ADD_MULTICAST) != 0) 2062*5256Slh155975 return; 2063*5256Slh155975 2064*5256Slh155975 tmp2 = SET_SINGLE_MULTICAST; 2065*5256Slh155975 MODE[0] = (unsigned long)tmp2; 2066*5256Slh155975 MODE[1] = 1; 2067*5256Slh155975 tmp1 = (unsigned long)pucMulticastAddress; 2068*5256Slh155975 MODE[2] = tmp1; 2069*5256Slh155975 MODE[3] = ENABLE_MULTICAST; 2070*5256Slh155975 MODE[4] = 0; 2071*5256Slh155975 mdlChangeFilter(pLayerPointers, (unsigned long *)MODE); 2072*5256Slh155975 } 2073*5256Slh155975 2074*5256Slh155975 2075*5256Slh155975 /* 2076*5256Slh155975 * Purpose : 2077*5256Slh155975 * This routine deletes the Multicast addresses requested by OS. 2078*5256Slh155975 * 2079*5256Slh155975 * Arguments : 2080*5256Slh155975 * pLayerPointers 2081*5256Slh155975 * Pointer to Layer pointers structure. 2082*5256Slh155975 * pucMulticastAddress 2083*5256Slh155975 * Pointer to the array of multicast addresses 2084*5256Slh155975 */ 2085*5256Slh155975 void 2086*5256Slh155975 mdlDeleteMulticastAddress(struct LayerPointers *pLayerPointers, 2087*5256Slh155975 UCHAR *pucMulticastAddress) 2088*5256Slh155975 { 2089*5256Slh155975 unsigned long MODE[10]; 2090*5256Slh155975 unsigned long tmp; 2091*5256Slh155975 2092*5256Slh155975 if (mdlMulticastBitMapping(pLayerPointers, pucMulticastAddress, 2093*5256Slh155975 DELETE_MULTICAST) != 0) 2094*5256Slh155975 return; 2095*5256Slh155975 2096*5256Slh155975 MODE[0] = UNSET_SINGLE_MULTICAST; 2097*5256Slh155975 MODE[1] = 1; 2098*5256Slh155975 tmp = (unsigned long)pucMulticastAddress; 2099*5256Slh155975 MODE[2] = tmp; 2100*5256Slh155975 MODE[3] = ENABLE_MULTICAST; 2101*5256Slh155975 MODE[4] = 0; 2102*5256Slh155975 mdlChangeFilter(pLayerPointers, (unsigned long *)MODE); 2103*5256Slh155975 } 2104*5256Slh155975 2105*5256Slh155975 /* 2106*5256Slh155975 * Purpose : 2107*5256Slh155975 * Calculates the CRC value over the input number of bytes. 2108*5256Slh155975 * 2109*5256Slh155975 * Arguments : 2110*5256Slh155975 * NumberOfBytes 2111*5256Slh155975 * The number of bytes in the input. 2112*5256Slh155975 * Input 2113*5256Slh155975 * An input "string" to calculate a CRC over. 2114*5256Slh155975 */ 2115*5256Slh155975 static unsigned int 2116*5256Slh155975 mdlCalculateCRC(unsigned int NumberOfBytes, unsigned char *Input) 2117*5256Slh155975 { 2118*5256Slh155975 const unsigned int POLY = 0x04c11db7; 2119*5256Slh155975 unsigned int CRCValue = 0xffffffff; 2120*5256Slh155975 unsigned int CurrentBit, CurrentCRCHigh; 2121*5256Slh155975 unsigned char CurrentByte; 2122*5256Slh155975 2123*5256Slh155975 for (; NumberOfBytes; NumberOfBytes--) { 2124*5256Slh155975 CurrentByte = *Input; 2125*5256Slh155975 Input++; 2126*5256Slh155975 2127*5256Slh155975 for (CurrentBit = 8; CurrentBit; CurrentBit--) { 2128*5256Slh155975 CurrentCRCHigh = CRCValue >> 31; 2129*5256Slh155975 CRCValue <<= 1; 2130*5256Slh155975 2131*5256Slh155975 if (CurrentCRCHigh ^ (CurrentByte & 0x01)) { 2132*5256Slh155975 CRCValue ^= POLY; 2133*5256Slh155975 CRCValue |= 0x00000001; 2134*5256Slh155975 } 2135*5256Slh155975 CurrentByte >>= 1; 2136*5256Slh155975 } 2137*5256Slh155975 } 2138*5256Slh155975 return (CRCValue); 2139*5256Slh155975 } 2140*5256Slh155975 2141*5256Slh155975 void 2142*5256Slh155975 mdlRxFastSuspend(struct LayerPointers *pLayerPointers) 2143*5256Slh155975 { 2144*5256Slh155975 WRITE_REG32(pLayerPointers, pLayerPointers->pMdl->Mem_Address + CMD0, 2145*5256Slh155975 VAL0 | RX_FAST_SPND); 2146*5256Slh155975 } 2147*5256Slh155975 2148*5256Slh155975 void 2149*5256Slh155975 mdlRxFastSuspendClear(struct LayerPointers *pLayerPointers) 2150*5256Slh155975 { 2151*5256Slh155975 WRITE_REG32(pLayerPointers, pLayerPointers->pMdl->Mem_Address + CMD0, 2152*5256Slh155975 RX_FAST_SPND); 2153*5256Slh155975 } 2154