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