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