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