NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/49789: wm driver, Bug in sgmii i2c write function



>Number:         49789
>Category:       kern
>Synopsis:       wm driver, Bug in sgmii i2c write function
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Mar 26 08:30:00 +0000 2015
>Originator:     Bernard Mérindol
>Release:        Netbsd 7  Beta
>Organization:
TelNowEdge
>Environment:
NetBSD tne 7.0_BETA NetBSD 7.0_BETA (BME) #21: Tue Mar 24 02:36:24 UTC 2015  root@test:/usr/src/sys/arch/i386/compile/BME i386

>Description:
When use Intel i210 chips (wm driver) with SFP SGMII connection, only works at
10 Mbit/s Half-Dupex.

After patch (send in Fix to the problem if known)

All works fine.
>How-To-Repeat:

>Fix:
The problem is in :
wm_sgmii_writereg(device_t self, int phy, int reg, int val) in /usr/src/sys/dev/pci/if_wm.c

In this function val is not used, the val is not write in I2C bus for SFP.

Old Code:
wm_sgmii_writereg(device_t self, int phy, int reg, int val)
{
	struct wm_softc *sc = device_private(self);
	uint32_t i2ccmd;
	int i;
	
	if (wm_get_swfw_semaphore(sc, swfwphysem[sc->sc_funcid])) {
		aprint_error_dev(sc->sc_dev, "%s: failed to get semaphore\n",
		    __func__);
		return;
	}
	
	i2ccmd = (reg << I2CCMD_REG_ADDR_SHIFT)
		  | (phy << I2CCMD_PHY_ADDR_SHIFT)
		  | I2CCMD_OPCODE_WRITE;
	CSR_WRITE(sc, WMREG_I2CCMD, i2ccmd);


New Code:
wm_sgmii_writereg(device_t self, int phy, int reg, int val)
{
	struct wm_softc *sc = device_private(self);
	uint32_t i2ccmd;
	int i;
	int val_swapped;
	
	if (wm_get_swfw_semaphore(sc, swfwphysem[sc->sc_funcid])) {
		aprint_error_dev(sc->sc_dev, "%s: failed to get semaphore\n",
		    __func__);
		return;
	}
	/* Swap the data bytes for the I2C interface */
	val_swapped = ((val >> 8) & 0x00FF) | ((val << 8) & 0xFF00);
	
	i2ccmd = ((reg << I2CCMD_REG_ADDR_SHIFT)
		  | (phy << I2CCMD_PHY_ADDR_SHIFT)
		  | I2CCMD_OPCODE_WRITE| val_swapped);
	CSR_WRITE(sc, WMREG_I2CCMD, i2ccmd);




Home | Main Index | Thread Index | Old Index