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