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