1/******************************************************************************* 2 3 4 Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved. 5 6 This program is free software; you can redistribute it and/or modify it 7 under the terms of the GNU General Public License as published by the Free 8 Software Foundation; either version 2 of the License, or (at your option) 9 any later version. 10 11 This program is distributed in the hope that it will be useful, but WITHOUT 12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 more details. 15 16 You should have received a copy of the GNU General Public License along with 17 this program; if not, write to the Free Software Foundation, Inc., 59 18 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 20 The full GNU General Public License is included in this distribution in the 21 file called LICENSE. 22 23 Contact Information: 24 Linux NICS <linux.nics@intel.com> 25 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 26*******************************************************************************/ 27 28/********************************************************************** 29* * 30* INTEL CORPORATION * 31* * 32* This software is supplied under the terms of the license included * 33* above. All use of this driver must be in accordance with the terms * 34* of that license. * 35* * 36* Module Name: e100_config.c * 37* * 38* Abstract: Functions for configuring the network adapter. * 39* * 40* Environment: This file is intended to be specific to the Linux * 41* operating system. * 42* * 43**********************************************************************/ 44#include "e100_config.h" 45 46static void e100_config_long_rx(struct e100_private *bdp, unsigned char enable); 47 48static const u8 def_config[] = { 49 CB_CFIG_BYTE_COUNT, 50 0x08, 0x00, 0x00, 0x00, 0x00, 0x32, 0x07, 0x01, 51 0x00, 0x2e, 0x00, 0x60, 0x00, 0xf2, 0xc8, 0x00, 52 0x40, 0xf2, 0x80, 0x3f, 0x05 53}; 54 55/** 56 * e100_config_init_82557 - config the 82557 adapter 57 * @bdp: atapter's private data struct 58 * 59 * This routine will initialize the 82557 configure block. 60 * All other init functions will only set values that are 61 * different from the 82557 default. 62 */ 63static void __devinit 64e100_config_init_82557(struct e100_private *bdp) 65{ 66 /* initialize config block */ 67 memcpy(bdp->config, def_config, sizeof (def_config)); 68 bdp->config[0] = CB_CFIG_BYTE_COUNT; /* just in case */ 69 70 e100_config_ifs(bdp); 71 72 /* 73 * Enable extended statistical counters (82558 and up) and TCO counters 74 * (82559 and up) and set the statistical counters' mode in bdp 75 * 76 * stat. mode | TCO stat. bit (2) | Extended stat. bit (5) 77 * ------------------------------------------------------------------ 78 * Basic (557) | 0 | 1 79 * ------------------------------------------------------------------ 80 * Extended (558) | 0 | 0 81 * ------------------------------------------------------------------ 82 * TCO (559) | 1 | 1 83 * ------------------------------------------------------------------ 84 * Reserved | 1 | 0 85 * ------------------------------------------------------------------ 86 */ 87 bdp->config[6] &= ~CB_CFIG_TCO_STAT; 88 bdp->config[6] |= CB_CFIG_EXT_STAT_DIS; 89 bdp->stat_mode = E100_BASIC_STATS; 90 91 /* Setup for MII or 503 operation. The CRS+CDT bit should only be set */ 92 /* when operating in 503 mode. */ 93 if (bdp->phy_addr == 32) { 94 bdp->config[8] &= ~CB_CFIG_503_MII; 95 bdp->config[15] |= CB_CFIG_CRS_OR_CDT; 96 } else { 97 bdp->config[8] |= CB_CFIG_503_MII; 98 bdp->config[15] &= ~CB_CFIG_CRS_OR_CDT; 99 } 100 101 e100_config_fc(bdp); 102 e100_config_force_dplx(bdp); 103 e100_config_promisc(bdp, false); 104 e100_config_mulcast_enbl(bdp, false); 105} 106 107static void __devinit 108e100_config_init_82558(struct e100_private *bdp) 109{ 110 /* MWI enable. This should be turned on only if the adapter is a 82558/9 111 * and if the PCI command reg. has enabled the MWI bit. */ 112 bdp->config[3] |= CB_CFIG_MWI_EN; 113 114 bdp->config[6] &= ~CB_CFIG_EXT_TCB_DIS; 115 116 if (bdp->rev_id >= D101MA_REV_ID) { 117 /* this is 82559 and up - enable TCO counters */ 118 bdp->config[6] |= CB_CFIG_TCO_STAT; 119 bdp->config[6] |= CB_CFIG_EXT_STAT_DIS; 120 bdp->stat_mode = E100_TCO_STATS; 121 122 if ((bdp->rev_id < D102_REV_ID) && 123 (bdp->params.b_params & PRM_XSUMRX) && 124 (bdp->pdev->device != 0x1209)) { 125 126 bdp->flags |= DF_CSUM_OFFLOAD; 127 bdp->config[9] |= 1; 128 } 129 } else { 130 /* this is 82558 */ 131 bdp->config[6] &= ~CB_CFIG_TCO_STAT; 132 bdp->config[6] &= ~CB_CFIG_EXT_STAT_DIS; 133 bdp->stat_mode = E100_EXTENDED_STATS; 134 } 135 136 e100_config_long_rx(bdp, true); 137} 138 139static void __devinit 140e100_config_init_82550(struct e100_private *bdp) 141{ 142 /* The D102 chip allows for 32 config bytes. This value is 143 * supposed to be in Byte 0. Just add the extra bytes to 144 * what was already setup in the block. */ 145 bdp->config[0] += CB_CFIG_D102_BYTE_COUNT; 146 147 /* now we need to enable the extended RFD. When this is 148 * enabled, the immediated receive data buffer starts at offset 149 * 32 from the RFD base address, instead of at offset 16. */ 150 bdp->config[7] |= CB_CFIG_EXTENDED_RFD; 151 152 /* put the chip into D102 receive mode. This is neccessary 153 * for any parsing and offloading features. */ 154 bdp->config[22] = CB_CFIG_RECEIVE_GAMLA_MODE; 155 156 /* set the flag if checksum offloading was enabled */ 157 if (bdp->params.b_params & PRM_XSUMRX) { 158 bdp->flags |= DF_CSUM_OFFLOAD; 159 } 160} 161 162/* Initialize the adapter's configure block */ 163void __devinit 164e100_config_init(struct e100_private *bdp) 165{ 166 e100_config_init_82557(bdp); 167 168 if (bdp->flags & IS_BACHELOR) 169 e100_config_init_82558(bdp); 170 171 if (bdp->rev_id >= D102_REV_ID) 172 e100_config_init_82550(bdp); 173} 174 175/** 176 * e100_force_config - force a configure command 177 * @bdp: atapter's private data struct 178 * 179 * This routine will force a configure command to the adapter. 180 * The command will be executed in polled mode as interrupts 181 * are _disabled_ at this time. 182 * 183 * Returns: 184 * true: if the configure command was successfully issued and completed 185 * false: otherwise 186 */ 187unsigned char 188e100_force_config(struct e100_private *bdp) 189{ 190 spin_lock_bh(&(bdp->config_lock)); 191 192 bdp->config[0] = CB_CFIG_BYTE_COUNT; 193 if (bdp->rev_id >= D102_REV_ID) { 194 /* The D102 chip allows for 32 config bytes. This value is 195 supposed to be in Byte 0. Just add the extra bytes to 196 what was already setup in the block. */ 197 bdp->config[0] += CB_CFIG_D102_BYTE_COUNT; 198 } 199 200 spin_unlock_bh(&(bdp->config_lock)); 201 202 // although we call config outside the lock, there is no 203 // race condition because config byte count has maximum value 204 return e100_config(bdp); 205} 206 207/** 208 * e100_config - issue a configure command 209 * @bdp: atapter's private data struct 210 * 211 * This routine will issue a configure command to the 82557. 212 * This command will be executed in polled mode as interrupts 213 * are _disabled_ at this time. 214 * 215 * Returns: 216 * true: if the configure command was successfully issued and completed 217 * false: otherwise 218 */ 219unsigned char 220e100_config(struct e100_private *bdp) 221{ 222 cb_header_t *pntcb_hdr; 223 unsigned char res = true; 224 nxmit_cb_entry_t *cmd; 225 226 if (bdp->config[0] == 0) { 227 goto exit; 228 } 229 230 if ((cmd = e100_alloc_non_tx_cmd(bdp)) == NULL) { 231 res = false; 232 goto exit; 233 } 234 235 pntcb_hdr = (cb_header_t *) cmd->non_tx_cmd; 236 pntcb_hdr->cb_cmd = __constant_cpu_to_le16(CB_CONFIGURE); 237 238 spin_lock_bh(&bdp->config_lock); 239 240 if (bdp->config[0] < CB_CFIG_MIN_PARAMS) { 241 bdp->config[0] = CB_CFIG_MIN_PARAMS; 242 } 243 244 /* Copy the device's config block to the device's memory */ 245 memcpy(cmd->non_tx_cmd->ntcb.config.cfg_byte, bdp->config, 246 bdp->config[0]); 247 /* reset number of bytes to config next time */ 248 bdp->config[0] = 0; 249 250 spin_unlock_bh(&bdp->config_lock); 251 252 res = e100_exec_non_cu_cmd(bdp, cmd); 253 254exit: 255 if (netif_running(bdp->device)) 256 netif_wake_queue(bdp->device); 257 return res; 258} 259 260/** 261 * e100_config_fc - config flow-control state 262 * @bdp: adapter's private data struct 263 * 264 * This routine will enable or disable flow control support in the adapter's 265 * config block. Flow control will be enable only if requested using the command 266 * line option, and if the link is flow-contorl capable (both us and the link 267 * partner). But, if link partner is capable of autoneg, but not capable of 268 * flow control, received PAUSE frames are still honored. 269 */ 270void 271e100_config_fc(struct e100_private *bdp) 272{ 273 unsigned char enable = false; 274 /* 82557 doesn't support fc. Don't touch this option */ 275 if (!(bdp->flags & IS_BACHELOR)) 276 return; 277 278 /* Enable fc if requested and if the link supports it */ 279 if ((bdp->params.b_params & PRM_FC) && (bdp->flags & 280 (DF_LINK_FC_CAP | DF_LINK_FC_TX_ONLY))) { 281 enable = true; 282 } 283 284 spin_lock_bh(&(bdp->config_lock)); 285 286 if (enable) { 287 if (bdp->flags & DF_LINK_FC_TX_ONLY) { 288 /* If link partner is capable of autoneg, but */ 289 /* not capable of flow control, Received PAUSE */ 290 /* frames are still honored, i.e., */ 291 /* transmitted frames would be paused by */ 292 /* incoming PAUSE frames */ 293 bdp->config[16] = DFLT_NO_FC_DELAY_LSB; 294 bdp->config[17] = DFLT_NO_FC_DELAY_MSB; 295 bdp->config[19] &= ~(CB_CFIG_FC_RESTOP | CB_CFIG_FC_RESTART); 296 bdp->config[19] |= CB_CFIG_FC_REJECT; 297 bdp->config[19] &= ~CB_CFIG_TX_FC_DIS; 298 } else { 299 bdp->config[16] = DFLT_FC_DELAY_LSB; 300 bdp->config[17] = DFLT_FC_DELAY_MSB; 301 bdp->config[19] |= CB_CFIG_FC_OPTS; 302 bdp->config[19] &= ~CB_CFIG_TX_FC_DIS; 303 } 304 } else { 305 bdp->config[16] = DFLT_NO_FC_DELAY_LSB; 306 bdp->config[17] = DFLT_NO_FC_DELAY_MSB; 307 bdp->config[19] &= ~CB_CFIG_FC_OPTS; 308 bdp->config[19] |= CB_CFIG_TX_FC_DIS; 309 } 310 E100_CONFIG(bdp, 19); 311 spin_unlock_bh(&(bdp->config_lock)); 312 313 return; 314} 315 316/** 317 * e100_config_promisc - configure promiscuous mode 318 * @bdp: atapter's private data struct 319 * @enable: should we enable this option or not 320 * 321 * This routine will enable or disable promiscuous mode 322 * in the adapter's config block. 323 */ 324void 325e100_config_promisc(struct e100_private *bdp, unsigned char enable) 326{ 327 spin_lock_bh(&(bdp->config_lock)); 328 329 /* if in promiscuous mode, save bad frames */ 330 if (enable) { 331 332 if (!(bdp->config[6] & CB_CFIG_SAVE_BAD_FRAMES)) { 333 bdp->config[6] |= CB_CFIG_SAVE_BAD_FRAMES; 334 E100_CONFIG(bdp, 6); 335 } 336 337 if (bdp->config[7] & (u8) BIT_0) { 338 bdp->config[7] &= (u8) (~BIT_0); 339 E100_CONFIG(bdp, 7); 340 } 341 342 if (!(bdp->config[15] & CB_CFIG_PROMISCUOUS)) { 343 bdp->config[15] |= CB_CFIG_PROMISCUOUS; 344 E100_CONFIG(bdp, 15); 345 } 346 347 } else { /* not in promiscuous mode */ 348 349 if (bdp->config[6] & CB_CFIG_SAVE_BAD_FRAMES) { 350 bdp->config[6] &= ~CB_CFIG_SAVE_BAD_FRAMES; 351 E100_CONFIG(bdp, 6); 352 } 353 354 if (!(bdp->config[7] & (u8) BIT_0)) { 355 bdp->config[7] |= (u8) (BIT_0); 356 E100_CONFIG(bdp, 7); 357 } 358 359 if (bdp->config[15] & CB_CFIG_PROMISCUOUS) { 360 bdp->config[15] &= ~CB_CFIG_PROMISCUOUS; 361 E100_CONFIG(bdp, 15); 362 } 363 } 364 365 spin_unlock_bh(&(bdp->config_lock)); 366} 367 368/** 369 * e100_config_mulcast_enbl - configure allmulti mode 370 * @bdp: atapter's private data struct 371 * @enable: should we enable this option or not 372 * 373 * This routine will enable or disable reception of all multicast packets 374 * in the adapter's config block. 375 */ 376void 377e100_config_mulcast_enbl(struct e100_private *bdp, unsigned char enable) 378{ 379 spin_lock_bh(&(bdp->config_lock)); 380 381 /* this flag is used to enable receiving all multicast packet */ 382 if (enable) { 383 if (!(bdp->config[21] & CB_CFIG_MULTICAST_ALL)) { 384 bdp->config[21] |= CB_CFIG_MULTICAST_ALL; 385 E100_CONFIG(bdp, 21); 386 } 387 388 } else { 389 if (bdp->config[21] & CB_CFIG_MULTICAST_ALL) { 390 bdp->config[21] &= ~CB_CFIG_MULTICAST_ALL; 391 E100_CONFIG(bdp, 21); 392 } 393 } 394 395 spin_unlock_bh(&(bdp->config_lock)); 396} 397 398/** 399 * e100_config_ifs - configure the IFS parameter 400 * @bdp: atapter's private data struct 401 * 402 * This routine will configure the adaptive IFS value 403 * in the adapter's config block. IFS values are only 404 * relevant in half duplex, so set to 0 in full duplex. 405 */ 406void 407e100_config_ifs(struct e100_private *bdp) 408{ 409 u8 value = 0; 410 411 spin_lock_bh(&(bdp->config_lock)); 412 413 /* IFS value is only needed to be specified at half-duplex mode */ 414 if (bdp->cur_dplx_mode == HALF_DUPLEX) { 415 value = (u8) bdp->ifs_value; 416 } 417 418 if (bdp->config[2] != value) { 419 bdp->config[2] = value; 420 E100_CONFIG(bdp, 2); 421 } 422 423 spin_unlock_bh(&(bdp->config_lock)); 424} 425 426/** 427 * e100_config_force_dplx - configure the forced full duplex mode 428 * @bdp: atapter's private data struct 429 * 430 * This routine will enable or disable force full duplex 431 * in the adapter's config block. If the PHY is 503, and 432 * the duplex is full, consider the adapter forced. 433 */ 434void 435e100_config_force_dplx(struct e100_private *bdp) 436{ 437 spin_lock_bh(&(bdp->config_lock)); 438 439 /* We must force full duplex on if we are using PHY 0, and we are */ 440 /* supposed to run in FDX mode. We do this because the e100 has only */ 441 /* one FDX# input pin, and that pin will be connected to PHY 1. */ 442 /* Changed the 'if' condition below to fix performance problem * at 10 443 * full. The Phy was getting forced to full duplex while the MAC * was 444 * not, because the cur_dplx_mode was not being set to 2 by SetupPhy. * 445 * This is how the condition was, initially. * This has been changed so 446 * that the MAC gets forced to full duplex * simply if the user has 447 * forced full duplex. * * if (( bdp->phy_addr == 0 ) && ( 448 * bdp->cur_dplx_mode == 2 )) */ 449 /* The rest of the fix is in the PhyDetect code. */ 450 if ((bdp->params.e100_speed_duplex == E100_SPEED_10_FULL) || 451 (bdp->params.e100_speed_duplex == E100_SPEED_100_FULL) || 452 ((bdp->phy_addr == 32) && (bdp->cur_dplx_mode == FULL_DUPLEX))) { 453 if (!(bdp->config[19] & (u8) CB_CFIG_FORCE_FDX)) { 454 bdp->config[19] |= (u8) CB_CFIG_FORCE_FDX; 455 E100_CONFIG(bdp, 19); 456 } 457 458 } else { 459 if (bdp->config[19] & (u8) CB_CFIG_FORCE_FDX) { 460 bdp->config[19] &= (u8) (~CB_CFIG_FORCE_FDX); 461 E100_CONFIG(bdp, 19); 462 } 463 } 464 465 spin_unlock_bh(&(bdp->config_lock)); 466} 467 468/** 469 * e100_config_long_rx 470 * @bdp: atapter's private data struct 471 * @enable: should we enable this option or not 472 * 473 * This routine will enable or disable reception of larger packets. 474 * This is needed by VLAN implementations. 475 */ 476static void 477e100_config_long_rx(struct e100_private *bdp, unsigned char enable) 478{ 479 if (enable) { 480 if (!(bdp->config[18] & CB_CFIG_LONG_RX_OK)) { 481 bdp->config[18] |= CB_CFIG_LONG_RX_OK; 482 E100_CONFIG(bdp, 18); 483 } 484 485 } else { 486 if ((bdp->config[18] & CB_CFIG_LONG_RX_OK)) { 487 bdp->config[18] &= ~CB_CFIG_LONG_RX_OK; 488 E100_CONFIG(bdp, 18); 489 } 490 } 491} 492 493/** 494 * e100_config_wol 495 * @bdp: atapter's private data struct 496 * 497 * This sets configuration options for Wake On LAN functionality (WOL) in the 498 * config record. WOL options are retrieved from wolinfo_wolopts in @bdp 499 */ 500void 501e100_config_wol(struct e100_private *bdp) 502{ 503 spin_lock_bh(&(bdp->config_lock)); 504 505 if (bdp->wolopts & WAKE_PHY) { 506 bdp->config[9] |= CB_LINK_STATUS_WOL; 507 E100_CONFIG(bdp, 9); 508 } 509 510 if (!(bdp->wolopts & WAKE_MAGIC)) { 511 bdp->config[19] |= CB_DISABLE_MAGPAK_WAKE; 512 E100_CONFIG(bdp, 19); 513 } 514 515 spin_unlock_bh(&(bdp->config_lock)); 516} 517 518/** 519 * e100_config_loopback_mode 520 * @bdp: atapter's private data struct 521 * @mode: loopback mode(phy/mac/none) 522 * 523 */ 524unsigned char 525e100_config_loopback_mode(struct e100_private *bdp, u8 mode) 526{ 527 unsigned char bc_changed = false; 528 u8 config_byte; 529 530 spin_lock_bh(&(bdp->config_lock)); 531 532 switch (mode) { 533 case NO_LOOPBACK: 534 config_byte = CB_CFIG_LOOPBACK_NORMAL; 535 break; 536 case MAC_LOOPBACK: 537 config_byte = CB_CFIG_LOOPBACK_INTERNAL; 538 break; 539 case PHY_LOOPBACK: 540 config_byte = CB_CFIG_LOOPBACK_EXTERNAL; 541 break; 542 default: 543 printk(KERN_NOTICE "e100: e100_config_loopback_mode: " 544 "Invalid argument 'mode': %d\n", mode); 545 goto exit; 546 } 547 548 if ((bdp->config[10] & CB_CFIG_LOOPBACK_MODE) != config_byte) { 549 550 bdp->config[10] &= (~CB_CFIG_LOOPBACK_MODE); 551 bdp->config[10] |= config_byte; 552 E100_CONFIG(bdp, 10); 553 bc_changed = true; 554 } 555 556exit: 557 spin_unlock_bh(&(bdp->config_lock)); 558 return bc_changed; 559} 560unsigned char 561e100_config_tcb_ext_enable(struct e100_private *bdp, unsigned char enable) 562{ 563 unsigned char bc_changed = false; 564 565 spin_lock_bh(&(bdp->config_lock)); 566 567 if (enable) { 568 if (bdp->config[6] & CB_CFIG_EXT_TCB_DIS) { 569 570 bdp->config[6] &= (~CB_CFIG_EXT_TCB_DIS); 571 E100_CONFIG(bdp, 6); 572 bc_changed = true; 573 } 574 575 } else { 576 if (!(bdp->config[6] & CB_CFIG_EXT_TCB_DIS)) { 577 578 bdp->config[6] |= CB_CFIG_EXT_TCB_DIS; 579 E100_CONFIG(bdp, 6); 580 bc_changed = true; 581 } 582 } 583 spin_unlock_bh(&(bdp->config_lock)); 584 585 return bc_changed; 586} 587unsigned char 588e100_config_dynamic_tbd(struct e100_private *bdp, unsigned char enable) 589{ 590 unsigned char bc_changed = false; 591 592 spin_lock_bh(&(bdp->config_lock)); 593 594 if (enable) { 595 if (!(bdp->config[7] & CB_CFIG_DYNTBD_EN)) { 596 597 bdp->config[7] |= CB_CFIG_DYNTBD_EN; 598 E100_CONFIG(bdp, 7); 599 bc_changed = true; 600 } 601 602 } else { 603 if (bdp->config[7] & CB_CFIG_DYNTBD_EN) { 604 605 bdp->config[7] &= (~CB_CFIG_DYNTBD_EN); 606 E100_CONFIG(bdp, 7); 607 bc_changed = true; 608 } 609 } 610 spin_unlock_bh(&(bdp->config_lock)); 611 612 return bc_changed; 613} 614 615