skge: patches for 2.6.24
Subsystems (2)
cover skge: patches for 2.6.24
The first three are bug fixes, followed by cleanup and addition of new eeprom and debug interface.
Patches are against current linux-2.6 git tree which is at pre 2.6.24 state.
Signature · 1 line
Stephen Hemminger <[email protected]>
PATCH 1/7 skge: fix ram buffer size calculation
This fixes problems with transmit hangs on older fiber based SysKonnect boards.
Adjust ram buffer sizing calculation to make it correct on all boards and make it like the code in sky2 driver.
drivers/net/skge.c +24 -27
@@ -2403,32 +2403,31 @@ static int skge_ioctl(struct net_devicereturn err; } -static void skge_ramset (struct skge_hw *hw,u16 q,u32 start,size_t len) +/* Assign Ram Buffer allocation to queue */ +static void skge_ramset (struct skge_hw *hw,u16 q,u32 start,u32 space) {u32 end; - start /=8 ; - len /=8 ; - end = start + len -1 ; +/* convert from K bytes to qwords used for hw register */ + start *=1024 /8 ; + space *=1024 /8 ; + end = start + space -1 ;skge_write8 (hw,RB_ADDR (q,RB_CTRL ),RB_RST_CLR );skge_write32 (hw,RB_ADDR (q,RB_START ), start); +skge_write32 (hw,RB_ADDR (q,RB_END ), end);skge_write32 (hw,RB_ADDR (q,RB_WP ), start);skge_write32 (hw,RB_ADDR (q,RB_RP ), start); -skge_write32 (hw,RB_ADDR (q,RB_END ), end);if (q ==Q_R1 || q ==Q_R2 ) { +u32 tp = space - space/4 ; +/* Set thresholds on receive queue's */ -skge_write32 (hw,RB_ADDR (q,RB_RX_UTPP ), - start + (2 *len)/3 ); -skge_write32 (hw,RB_ADDR (q,RB_RX_LTPP ), - start + (len/3 )); - }else { -/* Enable store & forward on Tx queue's because -* Tx FIFO is only 4K on Genesis and 1K on Yukon -*/ +skge_write32 (hw,RB_ADDR (q,RB_RX_UTPP ), tp); +skge_write32 (hw,RB_ADDR (q,RB_RX_LTPP ), space/4 ); + }else if (hw->chip_id !=CHIP_ID_GENESIS ) +/* Genesis Tx Fifo is too small for normal store/forward */ skge_write8 (hw,RB_ADDR (q,RB_CTRL ),RB_ENA_STFWD ); - }skge_write8 (hw,RB_ADDR (q,RB_CTRL ),RB_ENA_OP_MD ); }
@@ -2456,7 +2455,7 @@ static int skge_up(struct net_device *destruct skge_port *skge =netdev_priv (dev);struct skge_hw *hw = skge->hw;int port = skge->port; -u32 chunk, ram_addr; +u32 ramaddr, ramsize, rxspace;size_t rx_size, tx_size;int err;
@@ -2511,14 +2510,15 @@ static int skge_up(struct net_device *despin_unlock_bh (&hw->phy_lock);/* Configure RAMbuffers */ - chunk = hw->ram_size / ((hw->ports +1 )*2 ); - ram_addr = hw->ram_offset +2 * chunk * port; + ramsize = (hw->ram_size - hw->ram_offset) / hw->ports; + ramaddr = hw->ram_offset + port * ramsize; + rxspace =8 + (2 *(ramsize -16 ))/3 ; -skge_ramset (hw, rxqaddr[port], ram_addr, chunk); -skge_qset (skge, rxqaddr[port], skge->rx_ring.to_clean); +skge_ramset (hw, rxqaddr[port], ramaddr, rxspace); +skge_ramset (hw, txqaddr[port], ramaddr + rxspace, ramsize - rxspace); +skge_qset (skge, rxqaddr[port], skge->rx_ring.to_clean);BUG_ON (skge->tx_ring.to_use != skge->tx_ring.to_clean); -skge_ramset (hw, txqaddr[port], ram_addr+chunk, chunk);skge_qset (skge, txqaddr[port], skge->tx_ring.to_use);/* Start receiver BMU */
@@ -3450,15 +3450,12 @@ static int skge_reset(struct skge_hw *hwif (hw->chip_id ==CHIP_ID_GENESIS ) {if (t8 ==3 ) {/* special case: 4 x 64k x 36, offset = 0x80000 */ - hw->ram_size =0x100000 ; - hw->ram_offset =0x80000 ; + hw->ram_size =1024 ; + hw->ram_offset =512 ; }else hw->ram_size = t8 *512 ; - } -else if (t8 ==0 ) - hw->ram_size =0x20000 ; -else - hw->ram_size = t8 *4096 ; + }else /* Yukon */ + hw->ram_size = t8 ? t8 *4 :128 ; hw->intr_mask =IS_HW_ERR ;
Signature · 1 line
Stephen Hemminger <[email protected]>
Re: [PATCH 1/7] skge: fix ram buffer size calculation
applied 1-7
PATCH 2/7 skge: changing MTU while running causes problems
In reply to Stephen HemmingerRather than bring network down/up when changing MTU, only need to impact receiver.
drivers/net/skge.c +44 -7
@@ -2544,6 +2544,15 @@ static int skge_up(struct net_device *dereturn err; } +/* stop receiver */ +static void skge_rx_stop (struct skge_hw *hw,int port) +{ +skge_write8 (hw,Q_ADDR (rxqaddr[port],Q_CSR ),CSR_STOP ); +skge_write32 (hw,RB_ADDR (port ?Q_R2 :Q_R1 ,RB_CTRL ), +RB_RST_SET |RB_DIS_OP_MD ); +skge_write32 (hw,Q_ADDR (rxqaddr[port],Q_CSR ),CSR_SET_RESET ); +} +static int skge_down (struct net_device *dev) {struct skge_port *skge =netdev_priv (dev);
@@ -2595,11 +2604,8 @@ static int skge_down(struct net_device */* Reset the RAM Buffer async Tx queue */ skge_write8 (hw,RB_ADDR (port ==0 ?Q_XA1 :Q_XA2 ,RB_CTRL ),RB_RST_SET ); -/* stop receiver */ -skge_write8 (hw,Q_ADDR (rxqaddr[port],Q_CSR ),CSR_STOP ); -skge_write32 (hw,RB_ADDR (port ?Q_R2 :Q_R1 ,RB_CTRL ), -RB_RST_SET |RB_DIS_OP_MD ); -skge_write32 (hw,Q_ADDR (rxqaddr[port],Q_CSR ),CSR_SET_RESET ); + +skge_rx_stop (hw, port);if (hw->chip_id ==CHIP_ID_GENESIS ) {skge_write8 (hw,SK_REG (port,TX_MFF_CTRL2 ),MFF_RST_SET );
@@ -2782,7 +2788,11 @@ static void skge_tx_timeout(struct net_dstatic int skge_change_mtu (struct net_device *dev,int new_mtu) { +struct skge_port *skge =netdev_priv (dev); +struct skge_hw *hw = skge->hw; +int port = skge->port;int err; +u16 ctl, reg;if (new_mtu <ETH_ZLEN || new_mtu >ETH_JUMBO_MTU )return -EINVAL ;
@@ -2792,13 +2802,40 @@ static int skge_change_mtu(struct net_dereturn 0 ; } -skge_down (dev); +skge_write32 (hw,B0_IMSK ,0 ); + dev->trans_start = jiffies;/* prevent tx timeout */ +netif_stop_queue (dev); +napi_disable (&skge->napi); + + ctl =gma_read16 (hw, port,GM_GP_CTRL ); +gma_write16 (hw, port,GM_GP_CTRL , ctl & ~GM_GPCR_RX_ENA ); + +skge_rx_clean (skge); +skge_rx_stop (hw, port); dev->mtu = new_mtu; - err =skge_up (dev); + reg =GM_SMOD_VLAN_ENA |IPG_DATA_VAL (IPG_DATA_DEF ); +if (new_mtu >1500 ) + reg |=GM_SMOD_JUMBO_ENA ; +gma_write16 (hw, port,GM_SERIAL_MODE , reg); + +skge_write8 (hw,RB_ADDR (rxqaddr[port],RB_CTRL ),RB_ENA_OP_MD ); + + err =skge_rx_fill (dev); +wmb (); +if (!err) +skge_write8 (hw,Q_ADDR (rxqaddr[port],Q_CSR ),CSR_START |CSR_IRQ_CL_F ); +skge_write32 (hw,B0_IMSK , hw->intr_mask); +if (err)dev_close (dev); +else { +gma_write16 (hw, port,GM_GP_CTRL , ctl); + +napi_enable (&skge->napi); +netif_wake_queue (dev); + }return err; }
Signature · 1 line
Stephen Hemminger <[email protected]>
PATCH 3/7 skge: XM PHY handling fixes
In reply to Stephen HemmingerChange how PHY is managed on SysKonnect fibre based boards. Poll for PHY coming up 1 per second, but use interrupt to detect loss.
drivers/net/skge.c +48 -40
@@ -57,7 +57,7 @@#define TX_WATCHDOG (5 * HZ)#define NAPI_WEIGHT 64#define BLINK_MS 250 -#define LINK_HZ (HZ/2) +#define LINK_HZ HZMODULE_DESCRIPTION ("SysKonnect Gigabit Ethernet driver" );MODULE_AUTHOR ("Stephen Hemminger <[email protected]>" );
@@ -995,19 +995,15 @@ static void xm_link_down(struct skge_hw {struct net_device *dev = hw->dev[port];struct skge_port *skge =netdev_priv (dev); -u16 cmd, msk; +u16 cmd =xm_read16 (hw, port,XM_MMU_CMD ); -if (hw->phy_type ==SK_PHY_XMAC ) { - msk =xm_read16 (hw, port,XM_IMSK ); - msk |=XM_IS_INP_ASS |XM_IS_LIPA_RC |XM_IS_RX_PAGE |XM_IS_AND ; -xm_write16 (hw, port,XM_IMSK , msk); - } +xm_write16 (hw, port,XM_IMSK ,XM_IMSK_DISABLE ); - cmd =xm_read16 (hw, port,XM_MMU_CMD ); cmd &= ~(XM_MMU_ENA_RX |XM_MMU_ENA_TX );xm_write16 (hw, port,XM_MMU_CMD , cmd); +/* dummy read to ensure writing */ - (void )xm_read16 (hw, port,XM_MMU_CMD ); +xm_read16 (hw, port,XM_MMU_CMD );if (netif_carrier_ok (dev))skge_link_down (skge);
@@ -1103,7 +1099,7 @@ static void genesis_reset(struct skge_hw/* reset the statistics module */ xm_write32 (hw, port,XM_GP_PORT ,XM_GP_RES_STAT ); -xm_write16 (hw, port,XM_IMSK ,0xffff );/* disable XMAC IRQs */ +xm_write16 (hw, port,XM_IMSK ,XM_IMSK_DISABLE );xm_write32 (hw, port,XM_MODE ,0 );/* clear Mode Reg */ xm_write16 (hw, port,XM_TX_CMD ,0 );/* reset TX CMD Reg */ xm_write16 (hw, port,XM_RX_CMD ,0 );/* reset RX CMD Reg */
@@ -1141,7 +1137,7 @@ static void bcom_check_link(struct skge_u16 status;/* read twice because of latch */ - (void )xm_phy_read (hw, port,PHY_BCOM_STAT ); +xm_phy_read (hw, port,PHY_BCOM_STAT ); status =xm_phy_read (hw, port,PHY_BCOM_STAT );if ((status &PHY_ST_LSYNC ) ==0 ) {
@@ -1342,7 +1338,7 @@ static void xm_phy_init(struct skge_portmod_timer (&skge->link_timer, jiffies +LINK_HZ ); } -static void xm_check_link (struct net_device *dev) +static int xm_check_link (struct net_device *dev) {struct skge_port *skge =netdev_priv (dev);struct skge_hw *hw = skge->hw;
@@ -1350,25 +1346,25 @@ static void xm_check_link(struct net_devu16 status;/* read twice because of latch */ - (void )xm_phy_read (hw, port,PHY_XMAC_STAT ); +xm_phy_read (hw, port,PHY_XMAC_STAT ); status =xm_phy_read (hw, port,PHY_XMAC_STAT );if ((status &PHY_ST_LSYNC ) ==0 ) {xm_link_down (hw, port); -return ; +return 0 ; }if (skge->autoneg ==AUTONEG_ENABLE ) {u16 lpa, res;if (!(status &PHY_ST_AN_OVER )) -return ; +return 0 ; lpa =xm_phy_read (hw, port,PHY_XMAC_AUNE_LP );if (lpa &PHY_B_AN_RF ) { printk(KERN_NOTICE PFX "%s: remote fault\n", dev->name); -return ; +return 0 ; } res =xm_phy_read (hw, port,PHY_XMAC_RES_ABI );
@@ -1384,7 +1380,7 @@ static void xm_check_link(struct net_devdefault : printk(KERN_NOTICE PFX "%s: duplex mismatch\n", dev->name); -return ; +return 0 ; }/* We are using IEEE 802.3z/D5.0 Table 37-4 */
@@ -1408,11 +1404,14 @@ static void xm_check_link(struct net_devif (!netif_carrier_ok (dev))genesis_link_up (skge); +return 1 ; }/* Poll to check for link coming up. +* * Since internal PHY is wired to a level triggered pin, can't -* get an interrupt when carrier is detected. +* get an interrupt when carrier is detected, need to poll for +* link coming up. */ static void xm_link_timer (unsigned long arg) {
@@ -1420,29 +1419,35 @@ static void xm_link_timer(unsigned longstruct net_device *dev = skge->netdev;struct skge_hw *hw = skge->hw;int port = skge->port; +int i; +unsigned long flags;if (!netif_running (dev))return ; -if (netif_carrier_ok (dev)) { +spin_lock_irqsave (&hw->phy_lock, flags); + +/* +* Verify that the link by checking GPIO register three times. +* This pin has the signal from the link_sync pin connected to it. +*/ +for (i =0 ; i <3 ; i++) { +if (xm_read16 (hw, port,XM_GP_PORT ) &XM_GP_INP_ASS ) + goto link_down; + } + +/* Re-enable interrupt to detect link down */ +if (xm_check_link (dev)) { +u16 msk =xm_read16 (hw, port,XM_IMSK ); + msk &= ~XM_IS_INP_ASS ; +xm_write16 (hw, port,XM_IMSK , msk);xm_read16 (hw, port,XM_ISRC ); -if (!(xm_read16 (hw, port,XM_ISRC ) &XM_IS_INP_ASS )) - goto nochange; }else { -if (xm_read32 (hw, port,XM_GP_PORT ) &XM_GP_INP_ASS ) - goto nochange; -xm_read16 (hw, port,XM_ISRC ); -if (xm_read16 (hw, port,XM_ISRC ) &XM_IS_INP_ASS ) - goto nochange; +link_down: +mod_timer (&skge->link_timer, +round_jiffies (jiffies +LINK_HZ )); } - -spin_lock (&hw->phy_lock); -xm_check_link (dev); -spin_unlock (&hw->phy_lock); - -nochange: -if (netif_running (dev)) -mod_timer (&skge->link_timer, jiffies +LINK_HZ ); +spin_unlock_irqrestore (&hw->phy_lock, flags); }static void genesis_mac_init (struct skge_hw *hw,int port)
@@ -1686,14 +1691,16 @@ static void genesis_mac_intr(struct skge printk(KERN_DEBUG PFX "%s: mac interrupt status 0x%x\n", skge->netdev->name, status); -if (hw->phy_type ==SK_PHY_XMAC && - (status & (XM_IS_INP_ASS |XM_IS_LIPA_RC ))) -xm_link_down (hw, port); +if (hw->phy_type ==SK_PHY_XMAC && (status &XM_IS_INP_ASS )) { +xm_link_down (hw, port); +mod_timer (&skge->link_timer, jiffies +1 ); + }if (status &XM_IS_TXF_UR ) {xm_write32 (hw, port,XM_MODE ,XM_MD_FTF ); ++skge->net_stats.tx_fifo_errors; } +if (status &XM_IS_RXF_OV ) {xm_write32 (hw, port,XM_MODE ,XM_MD_FRF ); ++skge->net_stats.rx_fifo_errors;
@@ -1753,11 +1760,12 @@ static void genesis_link_up(struct skge_ }xm_write32 (hw, port,XM_MODE , mode); - msk =XM_DEF_MSK ; -if (hw->phy_type !=SK_PHY_XMAC ) - msk |=XM_IS_INP_ASS ;/* disable GP0 interrupt bit */ +/* Turn on detection of Tx underrun, Rx overrun */ + msk =xm_read16 (hw, port,XM_IMSK ); + msk &= ~(XM_IS_RXF_OV |XM_IS_TXF_UR );xm_write16 (hw, port,XM_IMSK , msk); +xm_read16 (hw, port,XM_ISRC );/* get MMU Command Reg. */
drivers/net/skge.h +2 -4
@@ -2191,11 +2191,9 @@ enum {XM_IS_TXF_UR =1 <<2 ,/* Bit 2: Transmit FIFO Underrun */ XM_IS_TX_COMP =1 <<1 ,/* Bit 1: Frame Tx Complete */ XM_IS_RX_COMP =1 <<0 ,/* Bit 0: Frame Rx Complete */ -}; - -#define XM_DEF_MSK (~(XM_IS_INP_ASS | XM_IS_LIPA_RC | \ - XM_IS_RXF_OV | XM_IS_TXF_UR)) + XM_IMSK_DISABLE = 0xffff, +};/* XM_HW_CFG 16 bit r/w Hardware Config Register */ enum {
Signature · 1 line
Stephen Hemminger <[email protected]>
PATCH 4/7 skge: internal stats
In reply to Stephen HemmingerUse internal stats structure
drivers/net/skge.c +24 -28
@@ -445,15 +445,15 @@ static struct net_device_stats *skge_getelse yukon_get_stats (skge, data); - skge->net_stats.tx_bytes = data[0 ]; - skge->net_stats.rx_bytes = data[1 ]; - skge->net_stats.tx_packets = data[2 ] + data[4 ] + data[6 ]; - skge->net_stats.rx_packets = data[3 ] + data[5 ] + data[7 ]; - skge->net_stats.multicast = data[3 ] + data[5 ]; - skge->net_stats.collisions = data[10 ]; - skge->net_stats.tx_aborted_errors = data[12 ]; + dev->stats.tx_bytes = data[0 ]; + dev->stats.rx_bytes = data[1 ]; + dev->stats.tx_packets = data[2 ] + data[4 ] + data[6 ]; + dev->stats.rx_packets = data[3 ] + data[5 ] + data[7 ]; + dev->stats.multicast = data[3 ] + data[5 ]; + dev->stats.collisions = data[10 ]; + dev->stats.tx_aborted_errors = data[12 ]; -return &skge->net_stats; +return &dev->stats; }static void skge_get_strings (struct net_device *dev,u32 stringset,u8 *data)
@@ -1684,12 +1684,13 @@ static void genesis_get_stats(struct skgstatic void genesis_mac_intr (struct skge_hw *hw,int port) { -struct skge_port *skge =netdev_priv (hw->dev[port]); +struct net_device *dev = hw->dev[port]; +struct skge_port *skge =netdev_priv (dev);u16 status =xm_read16 (hw, port,XM_ISRC );if (netif_msg_intr (skge)) printk(KERN_DEBUG PFX "%s: mac interrupt status 0x%x\n", - skge->netdev->name, status); + dev->name, status);if (hw->phy_type ==SK_PHY_XMAC && (status &XM_IS_INP_ASS )) {xm_link_down (hw, port);
@@ -1698,12 +1699,12 @@ static void genesis_mac_intr(struct skgeif (status &XM_IS_TXF_UR ) {xm_write32 (hw, port,XM_MODE ,XM_MD_FTF ); - ++skge->net_stats.tx_fifo_errors; + ++dev->stats.tx_fifo_errors; }if (status &XM_IS_RXF_OV ) {xm_write32 (hw, port,XM_MODE ,XM_MD_FRF ); - ++skge->net_stats.rx_fifo_errors; + ++dev->stats.rx_fifo_errors; } }
@@ -2200,12 +2201,12 @@ static void yukon_mac_intr(struct skge_h dev->name, status);if (status &GM_IS_RX_FF_OR ) { - ++skge->net_stats.rx_fifo_errors; + ++dev->stats.rx_fifo_errors;skge_write8 (hw,SK_REG (port,RX_GMF_CTRL_T ),GMF_CLI_RX_FO ); }if (status &GM_IS_TX_FF_UR ) { - ++skge->net_stats.tx_fifo_errors; + ++dev->stats.tx_fifo_errors;skge_write8 (hw,SK_REG (port,TX_GMF_CTRL_T ),GMF_CLI_TX_FU ); }
@@ -3039,18 +3040,18 @@ error:if (skge->hw->chip_id ==CHIP_ID_GENESIS ) {if (status & (XMR_FS_RUNT |XMR_FS_LNG_ERR )) - skge->net_stats.rx_length_errors++; + dev->stats.rx_length_errors++;if (status &XMR_FS_FRA_ERR ) - skge->net_stats.rx_frame_errors++; + dev->stats.rx_frame_errors++;if (status &XMR_FS_FCS_ERR ) - skge->net_stats.rx_crc_errors++; + dev->stats.rx_crc_errors++; }else {if (status & (GMR_FS_LONG_ERR |GMR_FS_UN_SIZE )) - skge->net_stats.rx_length_errors++; + dev->stats.rx_length_errors++;if (status &GMR_FS_FRAGMENT ) - skge->net_stats.rx_frame_errors++; + dev->stats.rx_frame_errors++;if (status &GMR_FS_CRC_ERR ) - skge->net_stats.rx_crc_errors++; + dev->stats.rx_crc_errors++; } resubmit:
@@ -3148,10 +3149,7 @@ static void skge_mac_parity(struct skge_ {struct net_device *dev = hw->dev[port]; -if (dev) { -struct skge_port *skge =netdev_priv (dev); - ++skge->net_stats.tx_heartbeat_errors; - } + ++dev->stats.tx_heartbeat_errors;if (hw->chip_id ==CHIP_ID_GENESIS ) skge_write16(hw, SK_REG(port, TX_MFF_CTRL1),
@@ -3304,9 +3302,7 @@ static irqreturn_t skge_intr(int irq, voskge_write16 (hw,B3_PA_CTRL ,PA_CLR_TO_TX1 );if (status &IS_PA_TO_RX1 ) { -struct skge_port *skge =netdev_priv (hw->dev[0 ]); - - ++skge->net_stats.rx_over_errors; + ++hw->dev[0 ]->stats.rx_over_errors;skge_write16 (hw,B3_PA_CTRL ,PA_CLR_TO_RX1 ); }
@@ -3323,7 +3319,7 @@ static irqreturn_t skge_intr(int irq, vo }if (status &IS_PA_TO_RX2 ) { - ++skge->net_stats.rx_over_errors; + ++hw->dev[1 ]->stats.rx_over_errors;skge_write16 (hw,B3_PA_CTRL ,PA_CLR_TO_RX2 ); }
drivers/net/skge.h +0 -2
@@ -2467,8 +2467,6 @@ struct skge_port {void *mem;/* PCI memory for rings */ dma_addr_t dma;unsigned long mem_size; - -struct net_device_stats net_stats; };
Signature · 1 line
Stephen Hemminger <[email protected]>
PATCH 5/7 skge: eeprom support
In reply to Stephen HemmingerAdd ability to read/write EEPROM
--- drivers/net/skge.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++ drivers/net/skge.h | 6 ++- 2 files changed, 102 insertions(+), 2 deletions(-)
drivers/net/skge.c +98 -0
@@ -59,6 +59,9 @@#define BLINK_MS 250#define LINK_HZ HZ +#define SKGE_EEPROM_MAGIC 0x9933aabb + +MODULE_DESCRIPTION ("SysKonnect Gigabit Ethernet driver" );MODULE_AUTHOR ("Stephen Hemminger <[email protected]>" );MODULE_LICENSE ("GPL" );
@@ -798,6 +801,98 @@ static int skge_phys_id(struct net_devicreturn 0 ; } +static int skge_get_eeprom_len (struct net_device *dev) +{ +struct skge_port *skge =netdev_priv (dev); +u32 reg2; + +pci_read_config_dword (skge->hw->pdev,PCI_DEV_REG2 , ®2); +return 1 << ( ((reg2 &PCI_VPD_ROM_SZ ) >>14 ) +8 ); +} + +static u32 skge_vpd_read (struct pci_dev *pdev,int cap,u16 offset) +{ +u32 val; + +pci_write_config_word (pdev, cap +PCI_VPD_ADDR , offset); + +do { +pci_read_config_word (pdev, cap +PCI_VPD_ADDR , &offset); + }while (!(offset &PCI_VPD_ADDR_F )); + +pci_read_config_dword (pdev, cap +PCI_VPD_DATA , &val); +return val; +} + +static void skge_vpd_write (struct pci_dev *pdev,int cap,u16 offset,u32 val) +{ +pci_write_config_dword (pdev, cap +PCI_VPD_DATA , val); +pci_write_config_word (pdev, cap +PCI_VPD_ADDR , + offset |PCI_VPD_ADDR_F ); + +do { +pci_read_config_word (pdev, cap +PCI_VPD_ADDR , &offset); + }while (offset &PCI_VPD_ADDR_F ); +} + +static int skge_get_eeprom (struct net_device *dev,struct ethtool_eeprom *eeprom, +u8 *data) +{ +struct skge_port *skge =netdev_priv (dev); +struct pci_dev *pdev = skge->hw->pdev; +int cap =pci_find_capability (pdev,PCI_CAP_ID_VPD ); +int length = eeprom->len; +u16 offset = eeprom->offset; + +if (!cap) +return -EINVAL ; + + eeprom->magic =SKGE_EEPROM_MAGIC ; + +while (length >0 ) { +u32 val =skge_vpd_read (pdev, cap, offset); +int n =min_t (int, length,sizeof (val)); + +memcpy (data, &val, n); + length -= n; + data += n; + offset += n; + } +return 0 ; +} + +static int skge_set_eeprom (struct net_device *dev,struct ethtool_eeprom *eeprom, +u8 *data) +{ +struct skge_port *skge =netdev_priv (dev); +struct pci_dev *pdev = skge->hw->pdev; +int cap =pci_find_capability (pdev,PCI_CAP_ID_VPD ); +int length = eeprom->len; +u16 offset = eeprom->offset; + +if (!cap) +return -EINVAL ; + +if (eeprom->magic !=SKGE_EEPROM_MAGIC ) +return -EINVAL ; + +while (length >0 ) { +u32 val; +int n =min_t (int, length,sizeof (val)); + +if (n <sizeof (val)) + val =skge_vpd_read (pdev, cap, offset); +memcpy (&val, data, n); + +skge_vpd_write (pdev, cap, offset, val); + + length -= n; + data += n; + offset += n; + } +return 0 ; +} +static const struct ethtool_ops skge_ethtool_ops = { .get_settings = skge_get_settings, .set_settings = skge_set_settings,
@@ -810,6 +905,9 @@ static const struct ethtool_ops skge_eth .set_msglevel = skge_set_msglevel, .nway_reset = skge_nway_reset, .get_link = ethtool_op_get_link, + .get_eeprom_len = skge_get_eeprom_len, + .get_eeprom = skge_get_eeprom, + .set_eeprom = skge_set_eeprom, .get_ringparam = skge_get_ring_param, .set_ringparam = skge_set_ring_param, .get_pauseparam = skge_get_pauseparam,
drivers/net/skge.h +4 -2
@@ -1,5 +1,5 @@/* -* Definitions for the new Marvell Yukon / SysKonenct driver. +* Definitions for the new Marvell Yukon / SysKonnect driver. */ #ifndef _SKGE_H#define _SKGE_H
@@ -8,8 +8,10 @@#define PCI_DEV_REG1 0x40#define PCI_PHY_COMA 0x8000000#define PCI_VIO 0x2000000 +#define PCI_DEV_REG2 0x44 -#define PCI_REV_DESC 0x4 +#define PCI_VPD_ROM_SZ 7L<<14/* VPD ROM size 0=256, 1=512, ... */ +#define PCI_REV_DESC 1<<2/* Reverse Descriptor bytes */ #define PCI_STATUS_ERROR_BITS (PCI_STATUS_DETECTED_PARITY | \ PCI_STATUS_SIG_SYSTEM_ERROR | \
Signature · 1 line
Stephen Hemminger <[email protected]>
PATCH 6/7 skge: add a debug interface
In reply to Stephen HemmingerAdd a debugfs interface to look at internal ring state.
--- drivers/net/Kconfig | 10 +++ drivers/net/skge.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++++ drivers/net/skge.h | 3 + 3 files changed, 156 insertions(+)
drivers/net/Kconfig +10 -0
@@ -2173,6 +2173,16 @@ config SKGE To compile this driver as a module, choose M here: the module will be called skge. This is recommended. +config SKGE_DEBUG + bool "Debugging interface" + depends on SKGE && DEBUG_FS + help + This option adds the ability to dump driver state for debugging. + The file debugfs/skge/ethX displays the state of the internal + transmit and receive rings. + + If unsure, say N. + config SKY2 tristate "SysKonnect Yukon2 support" depends on PCI
drivers/net/skge.c +143 -0
167 lines not on this page · raw message
drivers/net/skge.h +3 -0
@@ -2469,6 +2469,9 @@ struct skge_port {void *mem;/* PCI memory for rings */ dma_addr_t dma;unsigned long mem_size; +#ifdef CONFIG_SKGE_DEBUG +struct dentry *debugfs; +#endif };
Signature · 1 line
Stephen Hemminger <[email protected]>
PATCH 7/7 skge 1.12
In reply to Stephen Hemmingerversion update
drivers/net/skge.c +1 -1
@@ -44,7 +44,7 @@#include "skge.h" #define DRV_NAME "skge" -#define DRV_VERSION "1.11" +#define DRV_VERSION "1.12"#define PFX DRV_NAME " "#define DEFAULT_TX_RING_SIZE 128
Signature · 1 line
Stephen Hemminger <[email protected]>