More sky2 patches for 2.6.21
Subsystems (2)
cover More sky2 patches for 2.6.21
These address issues found testing EC-U (88E8056 and 88E8055) chips.
--
Stephen Hemminger <[email protected]>
PATCH 1/6 sky2: disable support for 88E8056
This device is having all sorts of problems that lead to data corruption and system instability. It gets receive status and data out of order, it generates descriptor and TSO errors, etc.
Until the problems are resolved, it should not be used by anyone who cares about there system.
drivers/net/sky2.c +3 -0
@@ -123,7 +123,10 @@ static const struct pci_device_id sky2_i { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4361) }, /* 88E8050 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4362) }, /* 88E8053 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4363) }, /* 88E8055 */ +#ifdef broken + /* This device causes data corruption problems that are not resolved */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4364) }, /* 88E8056 */ +#endif { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4366) }, /* 88EC036 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4367) }, /* 88EC032 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4368) }, /* 88EC034 */
--
Stephen Hemminger <[email protected]>
Re: [PATCH 1/6] sky2: disable support for 88E8056
Quoted 8 lines · Stephen Hemminger
This device is having all sorts of problems that lead to data corruption and system instability. It gets receive status and data out of order, it generates descriptor and TSO errors, etc.
Until the problems are resolved, it should not be used by anyone who cares about there system.
Signed-off-by Stephen Hemminger <[email protected]>
applied 1-6
PATCH 2/6 sky2: handle descriptor errors
In reply to Stephen HemmingerThere should never be descriptor error unless hardware or driver is buggy. But if an error occurs, print useful information, clear irq, and recover.
--- drivers/net/sky2.c | 67 ++++++++++++++++++++++++++++------------------------ drivers/net/sky2.h | 3 ++ 2 files changed, 39 insertions(+), 31 deletions(-)
drivers/net/sky2.c +37 -32
@@ -2343,26 +2343,22 @@ static void sky2_mac_intr(struct sky2_hw } } -/* This should never happen it is a fatal situation */ -static void sky2_descriptor_error (struct sky2_hw *hw,unsigned port, -const char *rxtx,u32 mask) +/* This should never happen it is a bug. */ +static void sky2_le_error (struct sky2_hw *hw,unsigned port, +u16 q,unsigned ring_size) {struct net_device *dev = hw->dev[port];struct sky2_port *sky2 =netdev_priv (dev); -u32 imask; +unsigned idx; +const u64 *le = (q ==Q_R1 || q ==Q_R2 ) + ? (u64 *) sky2->rx_le : (u64 *) sky2->tx_le; + + idx =sky2_read16 (hw,Y2_QADDR (q,PREF_UNIT_GET_IDX )); + printk(KERN_ERR PFX "%s: descriptor error q=%#x get=%u [%llx] put=%u\n", + dev->name, (unsigned ) q, idx, (unsigned long long ) le[idx], + (unsigned) sky2_read16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX))); - printk(KERN_ERR PFX "%s: %s descriptor error (hardware problem)\n", - dev ? dev->name : "<not registered>", rxtx); - - imask =sky2_read32 (hw,B0_IMSK ); - imask &= ~mask; -sky2_write32 (hw,B0_IMSK , imask); - -if (dev) { -spin_lock (&sky2->phy_lock); -sky2_link_down (sky2); -spin_unlock (&sky2->phy_lock); - } +sky2_write32 (hw,Q_ADDR (q,Q_CSR ),BMU_CLR_IRQ_CHK ); }/* If idle then force a fake soft NAPI poll once a second
@@ -2386,23 +2382,15 @@ static void sky2_idle(unsigned long arg)mod_timer (&hw->idle_timer, jiffies +msecs_to_jiffies (idle_timeout)); } - -static int sky2_poll (struct net_device *dev0,int *budget) +/* Hardware/software error handling */ +static void sky2_err_intr (struct sky2_hw *hw,u32 status) { -struct sky2_hw *hw = ((struct sky2_port *)netdev_priv (dev0))->hw; -int work_limit =min (dev0->quota, *budget); -int work_done =0 ; -u32 status =sky2_read32 (hw,B0_Y2_SP_EISR ); +if (net_ratelimit ()) +dev_warn (&hw->pdev->dev,"error interrupt status=%#x\n" , status);if (status &Y2_IS_HW_ERR )sky2_hw_intr (hw); -if (status &Y2_IS_IRQ_PHY1 ) -sky2_phy_intr (hw,0 ); - -if (status &Y2_IS_IRQ_PHY2 ) -sky2_phy_intr (hw,1 ); -if (status &Y2_IS_IRQ_MAC1 )sky2_mac_intr (hw,0 );
@@ -2410,16 +2398,33 @@ static int sky2_poll(struct net_device *sky2_mac_intr (hw,1 );if (status &Y2_IS_CHK_RX1 ) -sky2_descriptor_error (hw,0 ,"receive" ,Y2_IS_CHK_RX1 ); +sky2_le_error (hw,0 ,Q_R1 ,RX_LE_SIZE );if (status &Y2_IS_CHK_RX2 ) -sky2_descriptor_error (hw,1 ,"receive" ,Y2_IS_CHK_RX2 ); +sky2_le_error (hw,1 ,Q_R2 ,RX_LE_SIZE );if (status &Y2_IS_CHK_TXA1 ) -sky2_descriptor_error (hw,0 ,"transmit" ,Y2_IS_CHK_TXA1 ); +sky2_le_error (hw,0 ,Q_XA1 ,TX_RING_SIZE );if (status &Y2_IS_CHK_TXA2 ) -sky2_descriptor_error (hw,1 ,"transmit" ,Y2_IS_CHK_TXA2 ); +sky2_le_error (hw,1 ,Q_XA2 ,TX_RING_SIZE ); +} + +static int sky2_poll (struct net_device *dev0,int *budget) +{ +struct sky2_hw *hw = ((struct sky2_port *)netdev_priv (dev0))->hw; +int work_limit =min (dev0->quota, *budget); +int work_done =0 ; +u32 status =sky2_read32 (hw,B0_Y2_SP_EISR ); + +if (unlikely (status &Y2_IS_ERROR )) +sky2_err_intr (hw, status); + +if (status &Y2_IS_IRQ_PHY1 ) +sky2_phy_intr (hw,0 ); + +if (status &Y2_IS_IRQ_PHY2 ) +sky2_phy_intr (hw,1 ); work_done =sky2_status_intr (hw, work_limit);if (work_done < work_limit) {
drivers/net/sky2.h +3 -0
@@ -288,6 +288,9 @@ enum { | Y2_IS_CHK_TXA1 | Y2_IS_CHK_RX1,Y2_IS_PORT_2 =Y2_IS_IRQ_PHY2 |Y2_IS_IRQ_MAC2 |Y2_IS_CHK_TXA2 |Y2_IS_CHK_RX2 , +Y2_IS_ERROR =Y2_IS_HW_ERR | +Y2_IS_IRQ_MAC1 |Y2_IS_CHK_TXA1 |Y2_IS_CHK_RX1 | + Y2_IS_IRQ_MAC2 | Y2_IS_CHK_TXA2 | Y2_IS_CHK_RX2, };/* B2_IRQM_HWE_MSK 32 bit IRQ Moderation HW Error Mask */
--
Stephen Hemminger <[email protected]>
PATCH 3/6 sky2: disable ASF on all chip types
In reply to Stephen HemmingerNeed to make sure and disable ASF on all chip types. Otherwise, there may be random reboots.
--- drivers/net/sky2.c | 18 ++++++++---------- 1 files changed, 8 insertions(+), 10 deletions(-)
drivers/net/sky2.c +8 -10
@@ -2542,16 +2542,14 @@ static void sky2_reset(struct sky2_hw *hint i;/* disable ASF */ -if (hw->chip_id <=CHIP_ID_YUKON_EC ) { -if (hw->chip_id ==CHIP_ID_YUKON_EX ) { - status =sky2_read16 (hw,HCU_CCSR ); - status &= ~(HCU_CCSR_AHB_RST |HCU_CCSR_CPU_RST_MODE | -HCU_CCSR_UC_STATE_MSK ); -sky2_write16 (hw,HCU_CCSR , status); - }else -sky2_write8 (hw,B28_Y2_ASF_STAT_CMD ,Y2_ASF_RESET ); -sky2_write16 (hw,B0_CTST ,Y2_ASF_DISABLE ); - } +if (hw->chip_id ==CHIP_ID_YUKON_EX ) { + status =sky2_read16 (hw,HCU_CCSR ); + status &= ~(HCU_CCSR_AHB_RST |HCU_CCSR_CPU_RST_MODE | +HCU_CCSR_UC_STATE_MSK ); +sky2_write16 (hw,HCU_CCSR , status); + }else +sky2_write8 (hw,B28_Y2_ASF_STAT_CMD ,Y2_ASF_RESET ); +sky2_write16 (hw,B0_CTST ,Y2_ASF_DISABLE );/* do a SW reset */ sky2_write8 (hw,B0_CTST ,CS_RST_SET );
--
Stephen Hemminger <[email protected]>
PATCH 4/6 sky2: EC-U performance and jumbo support
In reply to Stephen HemmingerThe Yukon EC Ultra chips have transmit settings for store and forward and PCI buffering. By setting these appropriately, normal performance goes from 750Mbytes/sec to 940Mbytes/sec (non-jumbo).
It is also possible to do Jumbo mode, but it means turning off TSO and checksum offload so the performance gets worse. There isn't enough buffering for checksum offload to work.
--- drivers/net/sky2.c | 85 +++++++++++++++++++++++++++++++++++++---------------- drivers/net/sky2.h | 8 ++++ 2 files changed, 68 insertions(+), 25 deletions(-)
drivers/net/sky2.c +60 -25
@@ -743,12 +743,17 @@ static void sky2_mac_init(struct sky2_hwif (hw->chip_id ==CHIP_ID_YUKON_EC_U || hw->chip_id ==CHIP_ID_YUKON_EX ) {sky2_write8 (hw,SK_REG (port,RX_GMF_LP_THR ),768 /8 );sky2_write8 (hw,SK_REG (port,RX_GMF_UP_THR ),1024 /8 ); -if (hw->dev[port]->mtu >ETH_DATA_LEN ) { -/* set Tx GMAC FIFO Almost Empty Threshold */ -sky2_write32 (hw,SK_REG (port,TX_GMF_AE_THR ),0x180 ); -/* Disable Store & Forward mode for TX */ -sky2_write32 (hw,SK_REG (port,TX_GMF_CTRL_T ),TX_STFW_DIS ); - } + +/* set Tx GMAC FIFO Almost Empty Threshold */ +sky2_write32 (hw,SK_REG (port,TX_GMF_AE_THR ), + (ECU_JUMBO_WM <<16 ) |ECU_AE_THR ); + +if (hw->dev[port]->mtu >ETH_DATA_LEN ) +sky2_write32 (hw,SK_REG (port,TX_GMF_CTRL_T ), +TX_JUMBO_ENA |TX_STFW_DIS ); +else +sky2_write32 (hw,SK_REG (port,TX_GMF_CTRL_T ), +TX_JUMBO_DIS |TX_STFW_ENA ); } }
@@ -1281,7 +1286,7 @@ static int sky2_up(struct net_device *de/* Set almost empty threshold */ if (hw->chip_id ==CHIP_ID_YUKON_EC_U && hw->chip_rev ==CHIP_REV_YU_EC_U_A0 ) -sky2_write16 (hw,Q_ADDR (txqaddr[port],Q_AL ),0x1a0 ); +sky2_write16 (hw,Q_ADDR (txqaddr[port],Q_AL ),ECU_TXFF_LEV );sky2_prefetch_init (hw, txqaddr[port], sky2->tx_le_map,TX_RING_SIZE -1 );
@@ -1587,13 +1592,6 @@ static int sky2_down(struct net_device *sky2_write32 (hw,RB_ADDR (txqaddr[port],RB_CTRL ),RB_RST_SET |RB_DIS_OP_MD ); -/* WA for dev. #4.209 */ -if (hw->chip_id ==CHIP_ID_YUKON_EC_U - && (hw->chip_rev ==CHIP_REV_YU_EC_U_A1 || hw->chip_rev ==CHIP_REV_YU_EC_U_B0 )) -sky2_write32 (hw,SK_REG (port,TX_GMF_CTRL_T ), - sky2->speed !=SPEED_1000 ? -TX_STFW_ENA :TX_STFW_DIS ); - ctrl =gma_read16 (hw, port,GM_GP_CTRL ); ctrl &= ~(GM_GPCR_TX_ENA |GM_GPCR_RX_ENA );gma_write16 (hw, port,GM_GP_CTRL , ctrl);
@@ -1893,6 +1891,7 @@ static int sky2_change_mtu(struct net_de {struct sky2_port *sky2 =netdev_priv (dev);struct sky2_hw *hw = sky2->hw; +unsigned port = sky2->port;int err;u16 ctl, mode;u32 imask;
@@ -1900,10 +1899,6 @@ static int sky2_change_mtu(struct net_deif (new_mtu <ETH_ZLEN || new_mtu >ETH_JUMBO_MTU )return -EINVAL ; -/* TSO on Yukon Ultra and MTU > 1500 not supported */ -if (hw->chip_id ==CHIP_ID_YUKON_EC_U && new_mtu >ETH_DATA_LEN ) - dev->features &= ~NETIF_F_TSO ; -if (!netif_running (dev)) { dev->mtu = new_mtu;return 0 ;
@@ -1918,8 +1913,18 @@ static int sky2_change_mtu(struct net_desynchronize_irq (hw->pdev->irq); - ctl =gma_read16 (hw, sky2->port,GM_GP_CTRL ); -gma_write16 (hw, sky2->port,GM_GP_CTRL , ctl & ~GM_GPCR_RX_ENA ); +if (hw->chip_id ==CHIP_ID_YUKON_EC_U || hw->chip_id ==CHIP_ID_YUKON_EX ) { +if (new_mtu >ETH_DATA_LEN ) { +sky2_write32 (hw,SK_REG (port,TX_GMF_CTRL_T ), +TX_JUMBO_ENA |TX_STFW_DIS ); + dev->features &=NETIF_F_TSO |NETIF_F_SG |NETIF_F_IP_CSUM ; + }else +sky2_write32 (hw,SK_REG (port,TX_GMF_CTRL_T ), +TX_JUMBO_DIS |TX_STFW_ENA ); + } + + ctl =gma_read16 (hw, port,GM_GP_CTRL ); +gma_write16 (hw, port,GM_GP_CTRL , ctl & ~GM_GPCR_RX_ENA );sky2_rx_stop (sky2);sky2_rx_clean (sky2);
@@ -1931,9 +1936,9 @@ static int sky2_change_mtu(struct net_deif (dev->mtu >ETH_DATA_LEN ) mode |=GM_SMOD_JUMBO_ENA ; -gma_write16 (hw, sky2->port,GM_SERIAL_MODE , mode); +gma_write16 (hw, port,GM_SERIAL_MODE , mode); -sky2_write8 (hw,RB_ADDR (rxqaddr[sky2->port],RB_CTRL ),RB_ENA_OP_MD ); +sky2_write8 (hw,RB_ADDR (rxqaddr[port],RB_CTRL ),RB_ENA_OP_MD ); err =sky2_rx_start (sky2);sky2_write32 (hw,B0_IMSK , imask);
@@ -1941,7 +1946,7 @@ static int sky2_change_mtu(struct net_deif (err)dev_close (dev);else { -gma_write16 (hw, sky2->port,GM_GP_CTRL , ctl); +gma_write16 (hw, port,GM_GP_CTRL , ctl);netif_poll_enable (hw->dev[0 ]);netif_wake_queue (dev);
@@ -3334,6 +3339,36 @@ static void sky2_get_regs(struct net_dev regs->len - B3_RI_WTO_R1); } +/* In order to do Jumbo packets on these chips, need to turn off the +* transmit store/forward. Therefore checksum offload won't work. +*/ +static int no_tx_offload (struct net_device *dev) +{ +const struct sky2_port *sky2 =netdev_priv (dev); +const struct sky2_hw *hw = sky2->hw; + +return dev->mtu >ETH_DATA_LEN && + (hw->chip_id ==CHIP_ID_YUKON_EX + || hw->chip_id ==CHIP_ID_YUKON_EC_U ); +} + +static int sky2_set_tx_csum (struct net_device *dev,u32 data) +{ +if (data &&no_tx_offload (dev)) +return -EINVAL ; + +return ethtool_op_set_tx_csum (dev, data); +} + + +static int sky2_set_tso (struct net_device *dev,u32 data) +{ +if (data &&no_tx_offload (dev)) +return -EINVAL ; + +return ethtool_op_set_tso (dev, data); +} +static const struct ethtool_ops sky2_ethtool_ops = { .get_settings = sky2_get_settings, .set_settings = sky2_set_settings,
@@ -3349,9 +3384,9 @@ static const struct ethtool_ops sky2_eth .get_sg = ethtool_op_get_sg, .set_sg = ethtool_op_set_sg, .get_tx_csum = ethtool_op_get_tx_csum, - .set_tx_csum = ethtool_op_set_tx_csum, + .set_tx_csum = sky2_set_tx_csum, .get_tso = ethtool_op_get_tso, - .set_tso = ethtool_op_set_tso, + .set_tso = sky2_set_tso, .get_rx_csum = sky2_get_rx_csum, .set_rx_csum = sky2_set_rx_csum, .get_strings = sky2_get_strings,
drivers/net/sky2.h +8 -0
@@ -741,6 +741,11 @@ enum {TX_GMF_RP =0x0d70 ,/* 32 bit Tx GMAC FIFO Read Pointer */ TX_GMF_RSTP =0x0d74 ,/* 32 bit Tx GMAC FIFO Restart Pointer */ TX_GMF_RLEV =0x0d78 ,/* 32 bit Tx GMAC FIFO Read Level */ + +/* Threshold values for Yukon-EC Ultra and Extreme */ +ECU_AE_THR =0x0070 ,/* Almost Empty Threshold */ +ECU_TXFF_LEV =0x01a0 ,/* Tx BMU FIFO Level */ + ECU_JUMBO_WM = 0x0080, /* Jumbo Mode Watermark */ };/* Descriptor Poll Timer Registers */
@@ -1634,6 +1639,9 @@ enum {TX_VLAN_TAG_ON =1 <<25 ,/* enable VLAN tagging */ TX_VLAN_TAG_OFF =1 <<24 ,/* disable VLAN tagging */ +TX_JUMBO_ENA =1 <<23 ,/* PCI Jumbo Mode enable (Yukon-EC Ultra) */ +TX_JUMBO_DIS =1 <<22 ,/* PCI Jumbo Mode enable (Yukon-EC Ultra) */ +GMF_WSP_TST_ON =1 <<18 ,/* Write Shadow Pointer Test On */ GMF_WSP_TST_OFF =1 <<17 ,/* Write Shadow Pointer Test Off */ GMF_WSP_STEP = 1<<16,/* Write Shadow Pointer Step/Increment */
--
Stephen Hemminger <[email protected]>
PATCH 5/6 sky2: no jumbo on Yukon FE
In reply to Stephen HemmingerThe Yukon FE (100mbit only) chips do not support large packets.
drivers/net/sky2.c +3 -0
@@ -1899,6 +1899,9 @@ static int sky2_change_mtu(struct net_deif (new_mtu <ETH_ZLEN || new_mtu >ETH_JUMBO_MTU )return -EINVAL ; +if (new_mtu >ETH_DATA_LEN && hw->chip_id ==CHIP_ID_YUKON_FE ) +return -EINVAL ; +if (!netif_running (dev)) { dev->mtu = new_mtu;return 0 ;
--
Stephen Hemminger <[email protected]>
PATCH 6/6 sky2: version 1.14
In reply to Stephen Hemmingerdrivers/net/sky2.c +1 -1
@@ -49,7 +49,7 @@#include "sky2.h" #define DRV_NAME "sky2" -#define DRV_VERSION "1.13" +#define DRV_VERSION "1.14"#define PFX DRV_NAME " "/*
--
Stephen Hemminger <[email protected]>