kern/101274: SysKonnect Yukon initialization bug on K8M800
motherboards
Kirill Stepanchuk
kirillstp at hotmail.com
Wed Aug 2 18:00:33 UTC 2006
>Number: 101274
>Category: kern
>Synopsis: SysKonnect Yukon initialization bug on K8M800 motherboards
>Confidential: no
>Severity: critical
>Priority: medium
>Responsible: freebsd-bugs
>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:
>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:
>Unformatted:
More information about the freebsd-bugs
mailing list