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