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 #include "e100_phy.h"
29 #include "e100_config.h"
30
31 extern u16 e100_eeprom_read(struct e100_private *, u16);
32 extern int e100_wait_exec_cmplx(struct e100_private *, u32,u8, u8);
33 extern void e100_phy_reset(struct e100_private *bdp);
34 extern void e100_phy_autoneg(struct e100_private *bdp);
35 extern void e100_phy_set_loopback(struct e100_private *bdp);
36 extern void e100_force_speed_duplex(struct e100_private *bdp);
37
38 static u8 e100_diag_selftest(struct net_device *);
39 static u8 e100_diag_eeprom(struct net_device *);
40 static u8 e100_diag_loopback(struct net_device *);
41
42 static u8 e100_diag_one_loopback (struct net_device *, u8);
43 static u8 e100_diag_rcv_loopback_pkt(struct e100_private *);
44 static void e100_diag_config_loopback(struct e100_private *, u8, u8, u8 *,u8 *);
45 static u8 e100_diag_loopback_alloc(struct e100_private *);
46 static void e100_diag_loopback_cu_ru_exec(struct e100_private *);
47 static u8 e100_diag_check_pkt(u8 *);
48 static void e100_diag_loopback_free(struct e100_private *);
49 static int e100_cable_diag(struct e100_private *bdp);
50
51 #define LB_PACKET_SIZE 1500
52
53 /**
54 * e100_run_diag - main test execution handler - checks mask of requests and calls the diag routines
55 * @dev: atapter's net device data struct
56 * @test_info: array with test request mask also used to store test results
57 *
58 * RETURNS: updated flags field of struct ethtool_test
59 */
60 u32
e100_run_diag(struct net_device * dev,u64 * test_info,u32 flags)61 e100_run_diag(struct net_device *dev, u64 *test_info, u32 flags)
62 {
63 struct e100_private* bdp = dev->priv;
64 u8 test_result = 0;
65
66 if (!e100_get_link_state(bdp)) {
67 test_result = ETH_TEST_FL_FAILED;
68 test_info[test_link] = true;
69 }
70 if (!e100_diag_eeprom(dev)) {
71 test_result = ETH_TEST_FL_FAILED;
72 test_info[test_eeprom] = true;
73 }
74 if (flags & ETH_TEST_FL_OFFLINE) {
75 u8 fail_mask;
76 if (netif_running(dev)) {
77 spin_lock_bh(&dev->xmit_lock);
78 e100_close(dev);
79 spin_unlock_bh(&dev->xmit_lock);
80 }
81 if (e100_diag_selftest(dev)) {
82 test_result = ETH_TEST_FL_FAILED;
83 test_info[test_self_test] = true;
84 }
85
86 fail_mask = e100_diag_loopback(dev);
87 if (fail_mask) {
88 test_result = ETH_TEST_FL_FAILED;
89 if (fail_mask & PHY_LOOPBACK)
90 test_info[test_loopback_phy] = true;
91 if (fail_mask & MAC_LOOPBACK)
92 test_info[test_loopback_mac] = true;
93 }
94
95 test_info[cable_diag] = e100_cable_diag(bdp);
96 /* Need hw init regardless of netif_running */
97 e100_hw_init(bdp);
98 if (netif_running(dev)) {
99 e100_open(dev);
100 }
101 }
102 else {
103 test_info[test_self_test] = false;
104 test_info[test_loopback_phy] = false;
105 test_info[test_loopback_mac] = false;
106 test_info[cable_diag] = false;
107 }
108
109 return flags | test_result;
110 }
111
112 /**
113 * e100_diag_selftest - run hardware selftest
114 * @dev: atapter's net device data struct
115 */
116 static u8
e100_diag_selftest(struct net_device * dev)117 e100_diag_selftest(struct net_device *dev)
118 {
119 struct e100_private *bdp = dev->priv;
120 u32 st_timeout, st_result;
121 u8 retval = 0;
122
123 if (!e100_selftest(bdp, &st_timeout, &st_result)) {
124 if (!st_timeout) {
125 if (st_result & CB_SELFTEST_REGISTER_BIT)
126 retval |= REGISTER_TEST_FAIL;
127 if (st_result & CB_SELFTEST_DIAG_BIT)
128 retval |= SELF_TEST_FAIL;
129 if (st_result & CB_SELFTEST_ROM_BIT)
130 retval |= ROM_TEST_FAIL;
131 } else {
132 retval = TEST_TIMEOUT;
133 }
134 }
135
136 return retval;
137 }
138
139 /**
140 * e100_diag_eeprom - validate eeprom checksum correctness
141 * @dev: atapter's net device data struct
142 *
143 */
144 static u8
e100_diag_eeprom(struct net_device * dev)145 e100_diag_eeprom (struct net_device *dev)
146 {
147 struct e100_private *bdp = dev->priv;
148 u16 i, eeprom_sum, eeprom_actual_csm;
149
150 for (i = 0, eeprom_sum = 0; i < (bdp->eeprom_size - 1); i++) {
151 eeprom_sum += e100_eeprom_read(bdp, i);
152 }
153
154 eeprom_actual_csm = e100_eeprom_read(bdp, bdp->eeprom_size - 1);
155
156 if (eeprom_actual_csm == (u16)(EEPROM_SUM - eeprom_sum)) {
157 return true;
158 }
159
160 return false;
161 }
162
163 /**
164 * e100_diag_loopback - performs loopback test
165 * @dev: atapter's net device data struct
166 */
167 static u8
e100_diag_loopback(struct net_device * dev)168 e100_diag_loopback (struct net_device *dev)
169 {
170 u8 rc = 0;
171
172 printk(KERN_DEBUG "%s: PHY loopback test starts\n", dev->name);
173 e100_hw_init(dev->priv);
174 if (!e100_diag_one_loopback(dev, PHY_LOOPBACK)) {
175 rc |= PHY_LOOPBACK;
176 }
177 printk(KERN_DEBUG "%s: PHY loopback test ends\n", dev->name);
178
179 printk(KERN_DEBUG "%s: MAC loopback test starts\n", dev->name);
180 e100_hw_init(dev->priv);
181 if (!e100_diag_one_loopback(dev, MAC_LOOPBACK)) {
182 rc |= MAC_LOOPBACK;
183 }
184 printk(KERN_DEBUG "%s: MAC loopback test ends\n", dev->name);
185
186 return rc;
187 }
188
189 /**
190 * e100_diag_loopback - performs loopback test
191 * @dev: atapter's net device data struct
192 * @mode: lopback test type
193 */
194 static u8
e100_diag_one_loopback(struct net_device * dev,u8 mode)195 e100_diag_one_loopback (struct net_device *dev, u8 mode)
196 {
197 struct e100_private *bdp = dev->priv;
198 u8 res = false;
199 u8 saved_dynamic_tbd = false;
200 u8 saved_extended_tcb = false;
201
202 if (!e100_diag_loopback_alloc(bdp))
203 return false;
204
205 /* change the config block to standard tcb and the correct loopback */
206 e100_diag_config_loopback(bdp, true, mode,
207 &saved_extended_tcb, &saved_dynamic_tbd);
208
209 e100_diag_loopback_cu_ru_exec(bdp);
210
211 if (e100_diag_rcv_loopback_pkt(bdp)) {
212 res = true;
213 }
214
215 e100_diag_loopback_free(bdp);
216
217 /* change the config block to previous tcb mode and the no loopback */
218 e100_diag_config_loopback(bdp, false, mode,
219 &saved_extended_tcb, &saved_dynamic_tbd);
220 return res;
221 }
222
223 /**
224 * e100_diag_config_loopback - setup/clear loopback before/after lpbk test
225 * @bdp: atapter's private data struct
226 * @set_loopback: true if the function is called to set lb
227 * @loopback_mode: the loopback mode(MAC or PHY)
228 * @tcb_extended: true if need to set extended tcb mode after clean loopback
229 * @dynamic_tbd: true if needed to set dynamic tbd mode after clean loopback
230 *
231 */
232 void
e100_diag_config_loopback(struct e100_private * bdp,u8 set_loopback,u8 loopback_mode,u8 * tcb_extended,u8 * dynamic_tbd)233 e100_diag_config_loopback(struct e100_private* bdp,
234 u8 set_loopback,
235 u8 loopback_mode,
236 u8* tcb_extended,
237 u8* dynamic_tbd)
238 {
239 /* if set_loopback == true - we want to clear tcb_extended/dynamic_tbd.
240 * the previous values are saved in the params tcb_extended/dynamic_tbd
241 * if set_loopback == false - we want to restore previous value.
242 */
243 if (set_loopback || (*tcb_extended))
244 *tcb_extended = e100_config_tcb_ext_enable(bdp,*tcb_extended);
245
246 if (set_loopback || (*dynamic_tbd))
247 *dynamic_tbd = e100_config_dynamic_tbd(bdp,*dynamic_tbd);
248
249 if (set_loopback) {
250 /* ICH PHY loopback is broken */
251 if (bdp->flags & IS_ICH && loopback_mode == PHY_LOOPBACK)
252 loopback_mode = MAC_LOOPBACK;
253 /* Configure loopback on MAC */
254 e100_config_loopback_mode(bdp,loopback_mode);
255 } else {
256 e100_config_loopback_mode(bdp,NO_LOOPBACK);
257 }
258
259 e100_config(bdp);
260
261 if (loopback_mode == PHY_LOOPBACK) {
262 if (set_loopback)
263 /* Set PHY loopback mode */
264 e100_phy_set_loopback(bdp);
265 else
266 /* Reset PHY loopback mode */
267 e100_phy_reset(bdp);
268 /* Wait for PHY state change */
269 set_current_state(TASK_UNINTERRUPTIBLE);
270 schedule_timeout(HZ);
271 } else { /* For MAC loopback wait 500 msec to take effect */
272 set_current_state(TASK_UNINTERRUPTIBLE);
273 schedule_timeout(HZ / 2);
274 }
275 }
276
277 /**
278 * e100_diag_loopback_alloc - alloc & initate tcb and rfd for the loopback
279 * @bdp: atapter's private data struct
280 *
281 */
282 static u8
e100_diag_loopback_alloc(struct e100_private * bdp)283 e100_diag_loopback_alloc(struct e100_private *bdp)
284 {
285 dma_addr_t dma_handle;
286 tcb_t *tcb;
287 rfd_t *rfd;
288 tbd_t *tbd;
289
290 /* tcb, tbd and transmit buffer are allocated */
291 tcb = pci_alloc_consistent(bdp->pdev,
292 (sizeof (tcb_t) + sizeof (tbd_t) +
293 LB_PACKET_SIZE),
294 &dma_handle);
295 if (tcb == NULL)
296 return false;
297
298 memset(tcb, 0x00, sizeof (tcb_t) + sizeof (tbd_t) + LB_PACKET_SIZE);
299 tcb->tcb_phys = dma_handle;
300 tcb->tcb_hdr.cb_status = 0;
301 tcb->tcb_hdr.cb_cmd =
302 cpu_to_le16(CB_EL_BIT | CB_TRANSMIT | CB_TX_SF_BIT);
303 /* Next command is null */
304 tcb->tcb_hdr.cb_lnk_ptr = cpu_to_le32(0xffffffff);
305 tcb->tcb_cnt = 0;
306 tcb->tcb_thrshld = bdp->tx_thld;
307 tcb->tcb_tbd_num = 1;
308 /* Set up tcb tbd pointer */
309 tcb->tcb_tbd_ptr = cpu_to_le32(tcb->tcb_phys + sizeof (tcb_t));
310 tbd = (tbd_t *) ((u8 *) tcb + sizeof (tcb_t));
311 /* Set up tbd transmit buffer */
312 tbd->tbd_buf_addr =
313 cpu_to_le32(le32_to_cpu(tcb->tcb_tbd_ptr) + sizeof (tbd_t));
314 tbd->tbd_buf_cnt = __constant_cpu_to_le16(1024);
315 /* The value of first 512 bytes is FF */
316 memset((void *) ((u8 *) tbd + sizeof (tbd_t)), 0xFF, 512);
317 /* The value of second 512 bytes is BA */
318 memset((void *) ((u8 *) tbd + sizeof (tbd_t) + 512), 0xBA, 512);
319 wmb();
320 rfd = pci_alloc_consistent(bdp->pdev, sizeof (rfd_t), &dma_handle);
321
322 if (rfd == NULL) {
323 pci_free_consistent(bdp->pdev,
324 sizeof (tcb_t) + sizeof (tbd_t) +
325 LB_PACKET_SIZE, tcb, tcb->tcb_phys);
326 return false;
327 }
328
329 memset(rfd, 0x00, sizeof (rfd_t));
330
331 /* init all fields in rfd */
332 rfd->rfd_header.cb_cmd = cpu_to_le16(RFD_EL_BIT);
333 rfd->rfd_sz = cpu_to_le16(ETH_FRAME_LEN + CHKSUM_SIZE);
334 /* dma_handle is physical address of rfd */
335 bdp->loopback.dma_handle = dma_handle;
336 bdp->loopback.tcb = tcb;
337 bdp->loopback.rfd = rfd;
338 wmb();
339 return true;
340 }
341
342 /**
343 * e100_diag_loopback_cu_ru_exec - activates cu and ru to send & receive the pkt
344 * @bdp: atapter's private data struct
345 *
346 */
347 static void
e100_diag_loopback_cu_ru_exec(struct e100_private * bdp)348 e100_diag_loopback_cu_ru_exec(struct e100_private *bdp)
349 {
350 /*load CU & RU base */
351 if(!e100_wait_exec_cmplx(bdp, bdp->loopback.dma_handle, SCB_RUC_START, 0))
352 printk(KERN_ERR "e100: SCB_RUC_START failed!\n");
353
354 bdp->next_cu_cmd = START_WAIT;
355 e100_start_cu(bdp, bdp->loopback.tcb);
356 bdp->last_tcb = NULL;
357 rmb();
358 }
359 /**
360 * e100_diag_check_pkt - checks if a given packet is a loopback packet
361 * @bdp: atapter's private data struct
362 *
363 * Returns true if OK false otherwise.
364 */
365 static u8
e100_diag_check_pkt(u8 * datap)366 e100_diag_check_pkt(u8 *datap)
367 {
368 int i;
369 for (i = 0; i<512; i++) {
370 if( !((*datap)==0xFF && (*(datap + 512) == 0xBA)) ) {
371 printk (KERN_ERR "e100: check loopback packet failed at: %x\n", i);
372 return false;
373 }
374 }
375 printk (KERN_DEBUG "e100: Check received loopback packet OK\n");
376 return true;
377 }
378
379 /**
380 * e100_diag_rcv_loopback_pkt - waits for receive and checks lpbk packet
381 * @bdp: atapter's private data struct
382 *
383 * Returns true if OK false otherwise.
384 */
385 static u8
e100_diag_rcv_loopback_pkt(struct e100_private * bdp)386 e100_diag_rcv_loopback_pkt(struct e100_private* bdp)
387 {
388 rfd_t *rfdp;
389 u16 rfd_status;
390 unsigned long expires = jiffies + HZ * 2;
391
392 rfdp =bdp->loopback.rfd;
393
394 rfd_status = le16_to_cpu(rfdp->rfd_header.cb_status);
395
396 while (!(rfd_status & RFD_STATUS_COMPLETE)) {
397 if (time_before(jiffies, expires)) {
398 yield();
399 rmb();
400 rfd_status = le16_to_cpu(rfdp->rfd_header.cb_status);
401 } else {
402 break;
403 }
404 }
405
406 if (rfd_status & RFD_STATUS_COMPLETE) {
407 printk(KERN_DEBUG "e100: Loopback packet received\n");
408 return e100_diag_check_pkt(((u8 *)rfdp+bdp->rfd_size));
409 }
410 else {
411 printk(KERN_ERR "e100: Loopback packet not received\n");
412 return false;
413 }
414 }
415
416 /**
417 * e100_diag_loopback_free - free data allocated for loopback pkt send/receive
418 * @bdp: atapter's private data struct
419 *
420 */
421 static void
e100_diag_loopback_free(struct e100_private * bdp)422 e100_diag_loopback_free (struct e100_private *bdp)
423 {
424 pci_free_consistent(bdp->pdev,
425 sizeof(tcb_t) + sizeof(tbd_t) + LB_PACKET_SIZE,
426 bdp->loopback.tcb, bdp->loopback.tcb->tcb_phys);
427
428 pci_free_consistent(bdp->pdev, sizeof(rfd_t), bdp->loopback.rfd,
429 bdp->loopback.dma_handle);
430 }
431
432 static int
e100_cable_diag(struct e100_private * bdp)433 e100_cable_diag(struct e100_private *bdp)
434 {
435 int saved_open_circut = 0xffff;
436 int saved_short_circut = 0xffff;
437 int saved_distance = 0xffff;
438 int saved_same = 0;
439 int cable_status = E100_CABLE_UNKNOWN;
440 int i;
441
442 /* If we have link, */
443 if (e100_get_link_state(bdp))
444 return E100_CABLE_OK;
445
446 if (bdp->rev_id < D102_REV_ID)
447 return E100_CABLE_UNKNOWN;
448
449 /* Disable MDI/MDI-X auto switching */
450 e100_mdi_write(bdp, MII_NCONFIG, bdp->phy_addr,
451 MDI_MDIX_RESET_ALL_MASK);
452 /* Set to 100 Full as required by cable test */
453 e100_mdi_write(bdp, MII_BMCR, bdp->phy_addr,
454 BMCR_SPEED100 | BMCR_FULLDPLX);
455
456 /* Test up to 100 times */
457 for (i = 0; i < 100; i++) {
458 u16 ctrl_reg;
459 int distance, open_circut, short_circut, near_end;
460
461 /* Enable and execute cable test */
462 e100_mdi_write(bdp, HWI_CONTROL_REG, bdp->phy_addr,
463 (HWI_TEST_ENABLE | HWI_TEST_EXECUTE));
464 /* Wait for cable test finished */
465 set_current_state(TASK_UNINTERRUPTIBLE);
466 schedule_timeout(HZ/100 + 1);
467 /* Read results */
468 e100_mdi_read(bdp, HWI_CONTROL_REG, bdp->phy_addr, &ctrl_reg);
469 distance = ctrl_reg & HWI_TEST_DISTANCE;
470 open_circut = ctrl_reg & HWI_TEST_HIGHZ_PROBLEM;
471 short_circut = ctrl_reg & HWI_TEST_LOWZ_PROBLEM;
472
473 if ((distance == saved_distance) &&
474 (open_circut == saved_open_circut) &&
475 (short_circut == saved_short_circut))
476 saved_same++;
477 else {
478 saved_same = 0;
479 saved_distance = distance;
480 saved_open_circut = open_circut;
481 saved_short_circut = short_circut;
482 }
483 /* If results are the same 3 times */
484 if (saved_same == 3) {
485 near_end = ((distance * HWI_REGISTER_GRANULARITY) <
486 HWI_NEAR_END_BOUNDARY);
487 if (open_circut)
488 cable_status = (near_end) ?
489 E100_CABLE_OPEN_NEAR : E100_CABLE_OPEN_FAR;
490 if (short_circut)
491 cable_status = (near_end) ?
492 E100_CABLE_SHORT_NEAR : E100_CABLE_SHORT_FAR;
493 break;
494 }
495 }
496 /* Reset cable test */
497 e100_mdi_write(bdp, HWI_CONTROL_REG, bdp->phy_addr, HWI_RESET_ALL_MASK);
498 return cable_status;
499 }
500
501