1 /*******************************************************************************
2
3
4 Copyright(c) 1999 - 2004 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
46 static void e100_config_long_rx(struct e100_private *bdp, unsigned char enable);
47
48 static 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 */
63 void
e100_config_init_82557(struct e100_private * bdp)64 e100_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
107 static void
e100_config_init_82558(struct e100_private * bdp)108 e100_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
139 static void
e100_config_init_82550(struct e100_private * bdp)140 e100_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 necessary
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 */
163 void
e100_config_init(struct e100_private * bdp)164 e100_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 */
187 unsigned char
e100_force_config(struct e100_private * bdp)188 e100_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 */
219 unsigned char
e100_config(struct e100_private * bdp)220 e100_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
254 exit:
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 */
270 void
e100_config_fc(struct e100_private * bdp)271 e100_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 */
324 void
e100_config_promisc(struct e100_private * bdp,unsigned char enable)325 e100_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 */
376 void
e100_config_mulcast_enbl(struct e100_private * bdp,unsigned char enable)377 e100_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 */
406 void
e100_config_ifs(struct e100_private * bdp)407 e100_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 */
434 void
e100_config_force_dplx(struct e100_private * bdp)435 e100_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 */
476 static void
e100_config_long_rx(struct e100_private * bdp,unsigned char enable)477 e100_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 PHY and Magic Packet WoL
498 */
499 void
e100_config_wol(struct e100_private * bdp)500 e100_config_wol(struct e100_private *bdp)
501 {
502 spin_lock_bh(&(bdp->config_lock));
503
504 if (bdp->wolopts & WAKE_PHY) {
505 bdp->config[9] |= CB_LINK_STATUS_WOL;
506 }
507 else {
508 /* Disable PHY WoL */
509 bdp->config[9] &= ~CB_LINK_STATUS_WOL;
510 }
511
512 if (bdp->wolopts & WAKE_MAGIC) {
513 bdp->config[19] &= ~CB_DISABLE_MAGPAK_WAKE;
514 }
515 else {
516 /* Disable Magic Packet WoL */
517 bdp->config[19] |= CB_DISABLE_MAGPAK_WAKE;
518 }
519
520 E100_CONFIG(bdp, 19);
521 spin_unlock_bh(&(bdp->config_lock));
522 }
523
524 void
e100_config_vlan_drop(struct e100_private * bdp,unsigned char enable)525 e100_config_vlan_drop(struct e100_private *bdp, unsigned char enable)
526 {
527 spin_lock_bh(&(bdp->config_lock));
528 if (enable) {
529 if (!(bdp->config[22] & CB_CFIG_VLAN_DROP_ENABLE)) {
530 bdp->config[22] |= CB_CFIG_VLAN_DROP_ENABLE;
531 E100_CONFIG(bdp, 22);
532 }
533
534 } else {
535 if ((bdp->config[22] & CB_CFIG_VLAN_DROP_ENABLE)) {
536 bdp->config[22] &= ~CB_CFIG_VLAN_DROP_ENABLE;
537 E100_CONFIG(bdp, 22);
538 }
539 }
540 spin_unlock_bh(&(bdp->config_lock));
541 }
542
543 /**
544 * e100_config_loopback_mode
545 * @bdp: atapter's private data struct
546 * @mode: loopback mode(phy/mac/none)
547 *
548 */
549 unsigned char
e100_config_loopback_mode(struct e100_private * bdp,u8 mode)550 e100_config_loopback_mode(struct e100_private *bdp, u8 mode)
551 {
552 unsigned char bc_changed = false;
553 u8 config_byte;
554
555 spin_lock_bh(&(bdp->config_lock));
556
557 switch (mode) {
558 case NO_LOOPBACK:
559 config_byte = CB_CFIG_LOOPBACK_NORMAL;
560 break;
561 case MAC_LOOPBACK:
562 config_byte = CB_CFIG_LOOPBACK_INTERNAL;
563 break;
564 case PHY_LOOPBACK:
565 config_byte = CB_CFIG_LOOPBACK_EXTERNAL;
566 break;
567 default:
568 printk(KERN_NOTICE "e100: e100_config_loopback_mode: "
569 "Invalid argument 'mode': %d\n", mode);
570 goto exit;
571 }
572
573 if ((bdp->config[10] & CB_CFIG_LOOPBACK_MODE) != config_byte) {
574
575 bdp->config[10] &= (~CB_CFIG_LOOPBACK_MODE);
576 bdp->config[10] |= config_byte;
577 E100_CONFIG(bdp, 10);
578 bc_changed = true;
579 }
580
581 exit:
582 spin_unlock_bh(&(bdp->config_lock));
583 return bc_changed;
584 }
585 unsigned char
e100_config_tcb_ext_enable(struct e100_private * bdp,unsigned char enable)586 e100_config_tcb_ext_enable(struct e100_private *bdp, unsigned char enable)
587 {
588 unsigned char bc_changed = false;
589
590 spin_lock_bh(&(bdp->config_lock));
591
592 if (enable) {
593 if (bdp->config[6] & CB_CFIG_EXT_TCB_DIS) {
594
595 bdp->config[6] &= (~CB_CFIG_EXT_TCB_DIS);
596 E100_CONFIG(bdp, 6);
597 bc_changed = true;
598 }
599
600 } else {
601 if (!(bdp->config[6] & CB_CFIG_EXT_TCB_DIS)) {
602
603 bdp->config[6] |= CB_CFIG_EXT_TCB_DIS;
604 E100_CONFIG(bdp, 6);
605 bc_changed = true;
606 }
607 }
608 spin_unlock_bh(&(bdp->config_lock));
609
610 return bc_changed;
611 }
612 unsigned char
e100_config_dynamic_tbd(struct e100_private * bdp,unsigned char enable)613 e100_config_dynamic_tbd(struct e100_private *bdp, unsigned char enable)
614 {
615 unsigned char bc_changed = false;
616
617 spin_lock_bh(&(bdp->config_lock));
618
619 if (enable) {
620 if (!(bdp->config[7] & CB_CFIG_DYNTBD_EN)) {
621
622 bdp->config[7] |= CB_CFIG_DYNTBD_EN;
623 E100_CONFIG(bdp, 7);
624 bc_changed = true;
625 }
626
627 } else {
628 if (bdp->config[7] & CB_CFIG_DYNTBD_EN) {
629
630 bdp->config[7] &= (~CB_CFIG_DYNTBD_EN);
631 E100_CONFIG(bdp, 7);
632 bc_changed = true;
633 }
634 }
635 spin_unlock_bh(&(bdp->config_lock));
636
637 return bc_changed;
638 }
639
640