From nobody@FreeBSD.org  Wed Aug  2 17:58:45 2006
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id C559916A4DA
	for <freebsd-gnats-submit@FreeBSD.org>; Wed,  2 Aug 2006 17:58:45 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [216.136.204.117])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 8888543D46
	for <freebsd-gnats-submit@FreeBSD.org>; Wed,  2 Aug 2006 17:58:45 +0000 (GMT)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.13.1/8.13.1) with ESMTP id k72Hwjx5008761
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 2 Aug 2006 17:58:45 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.13.1/8.13.1/Submit) id k72HwjGS008760;
	Wed, 2 Aug 2006 17:58:45 GMT
	(envelope-from nobody)
Message-Id: <200608021758.k72HwjGS008760@www.freebsd.org>
Date: Wed, 2 Aug 2006 17:58:45 GMT
From: Kirill Stepanchuk <kirillstp@hotmail.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: SysKonnect Yukon initialization bug on K8M800 motherboards
X-Send-Pr-Version: www-2.3

>Number:         101274
>Category:       kern
>Synopsis:       [sk] [patch] SysKonnect Yukon initialization bug on K8M800 motherboards
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    yongari
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Aug 02 18:00:31 GMT 2006
>Closed-Date:    
>Last-Modified:  Sun Mar 02 05:58:34 UTC 2008
>Originator:     Kirill Stepanchuk
>Release:        FreeBSD 5.4
>Organization:
Sandvine Inc
>Environment:
FreeBSD 5.4-STABLE FreeBSD 5.4-STABLE #3: Wed Oct 12 09:08:41 EDT 2005 i386

>Description:
The SysKonnect Yukon NICs have a problem with K8M800 motherboards.  On
reboots and power cycles, the NIC will come up in a bad state, which
prevents the driver from being attached.  The error message "sk0: unknown
media type 0x0" identifies that the NIC is in a bad state.
>How-To-Repeat:
A D-Link DGE-530T Gigabit Ethernet Adapter will exibit this behaviour on
K8M800 motherboards
>Fix:
--- if_sk.c@@/main/RELENG_5/sandvine_bsd_5_main/0	2006-07-25 10:59:39.000000000 -0400
+++ if_sk.c	2006-08-01 10:40:47.000000000 -0400
@@ -1564,12 +1564,82 @@
 	int			unit, error = 0, rid, *port;
 	uint8_t			skrs;
 	char			*pname, *revstr;
+        u_int32_t		iobase, membase, irq;
+        u_int32_t               command;
 
 	sc = device_get_softc(dev);
 	unit = device_get_unit(dev);
 
 	mtx_init(&sc->sk_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
 	    MTX_DEF | MTX_RECURSE);
+
+
+
+	/*
+	 * Handle power management nonsense.
+	 */
+	command = pci_read_config(dev, SK_PCI_CAPID, 4) & 0x000000FF;
+	if (command == 0x01) {
+		command = pci_read_config(dev, SK_PCI_PWRMGMTCTRL, 4);
+		if (command & SK_PSTATE_MASK) {
+
+
+			/* Save important PCI config data. */
+			iobase = pci_read_config(dev, SK_PCI_LOIO, 4);
+			membase = pci_read_config(dev, SK_PCI_LOMEM, 4);
+			irq = pci_read_config(dev, SK_PCI_INTLINE, 4);
+
+			/* Reset the power state. */
+			printf("skc%d: chip is in D%d power mode "
+			"-- setting to D0\n", unit, command & SK_PSTATE_MASK);
+			command &= 0xFFFFFFFC;
+			pci_write_config(dev, SK_PCI_PWRMGMTCTRL, command, 4);
+
+			/* Restore PCI config data. */
+			pci_write_config(dev, SK_PCI_LOIO, iobase, 4);
+			pci_write_config(dev, SK_PCI_LOMEM, membase, 4);
+			pci_write_config(dev, SK_PCI_INTLINE, irq, 4);
+		}
+	}
+
+	/* Perform a PCI Reset using the chip's own power management functions:
+	1. Save Config
+	2. Set to D3 power mode
+	3. Set to D0 power mode
+	4. Restore Config
+	*/
+
+	/* Save important PCI config data. */
+	iobase = pci_read_config(dev, SK_PCI_LOIO, 4);
+	membase = pci_read_config(dev, SK_PCI_LOMEM, 4);
+	irq = pci_read_config(dev, SK_PCI_INTLINE, 4);
+
+	if(bootverbose){
+		command = pci_read_config(dev, SK_PCI_PWRMGMTCTRL, 4);
+		printf("skc%d: chip is in D%d power mode "
+		"-- setting to D3\n", unit, command & SK_PSTATE_MASK);
+	}
+	command =SK_PSTATE_D3;
+	pci_write_config(dev, SK_PCI_PWRMGMTCTRL, command, 4);
+	if(bootverbose) {
+		command = pci_read_config(dev, SK_PCI_PWRMGMTCTRL, 4);
+		printf("skc%d: chip is in D%d power mode "
+		"-- setting to D0\n", unit, command & SK_PSTATE_MASK);
+	}
+	command =SK_PSTATE_D0;
+	pci_write_config(dev, SK_PCI_PWRMGMTCTRL, command, 4);
+	if(bootverbose){
+		command = pci_read_config(dev, SK_PCI_PWRMGMTCTRL, 4);
+		printf("skc%d: chip is in D%d power mode ", unit, command & SK_PSTATE_MASK);
+	}
+
+	/* Restore PCI config data. */
+	pci_write_config(dev, SK_PCI_LOIO, iobase, 4);
+	pci_write_config(dev, SK_PCI_LOMEM, membase, 4);
+	pci_write_config(dev, SK_PCI_INTLINE, irq, 4);
+
+
+
 	/*
 	 * Map control/status registers.
 	 */

>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->yongari 
Responsible-Changed-By: yongari 
Responsible-Changed-When: Fri Aug 4 03:46:02 UTC 2006 
Responsible-Changed-Why:  
I'll handle this. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=101274 
State-Changed-From-To: open->feedback 
State-Changed-By: yongari 
State-Changed-When: Fri Aug 4 03:54:59 UTC 2006 
State-Changed-Why:  
Power management _is_ handled by BUS layer. And I think driver 
should not program its PCI configuration space directly without 
compelling reason. I guess the issues comes from PHY COMA mode. 
sk(4) in CURRENT handles the case better than before. 
Does the same issue shows on CURRENT too? 

http://www.freebsd.org/cgi/query-pr.cgi?pr=101274 

From: "k s" <kirillstp@hotmail.com>
To: bug-followup@FreeBSD.org, kirillstp@hotmail.com
Cc:  
Subject: Re: kern/101274: [sk] [patch] SysKonnect Yukon initialization bug on K8M800 moth
Date: Fri, 04 Aug 2006 10:53:55 -0400

 I have not tested it with FreeBSD 6 or FreeBSD7.
 This code is not power management, but a fix for the bug in the NIC.
 The NIC in question must be reset in order to work with the K8M800 
 motherboard. The manufacturer (SysKonnect) recommends resetting the NIC by 
 following the D0->D3->D0 transition, which is how it was done in the 
 official 2.4 Linux driver (removed from 2.6, with a hairy mess of new 
 drivers introduced).
 
 On K8M800 motherboards, the NIC gets in a bad state almost every other 
 reboot. If the NIC is not reset with D0->D3->D0, there is no way to get it 
 out of the bad state.
 
 
State-Changed-From-To: feedback->open 
State-Changed-By: linimon 
State-Changed-When: Sun Mar 2 05:58:03 UTC 2008 
State-Changed-Why:  
Note that feedback was received quite some time ago. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=101274 
>Unformatted:
