Skip to content

Commit

Permalink
skge: fix ram buffer size calculation
Browse files Browse the repository at this point in the history
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.

Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
  • Loading branch information
Stephen Hemminger authored and Jeff Garzik committed Oct 17, 2007
1 parent 298e1a9 commit 7fb7ac2
Showing 1 changed file with 24 additions and 27 deletions.
51 changes: 24 additions & 27 deletions drivers/net/skge.c
Original file line number Diff line number Diff line change
Expand Up @@ -2403,32 +2403,31 @@ static int skge_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return 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);
}
Expand Down Expand Up @@ -2456,7 +2455,7 @@ static int skge_up(struct net_device *dev)
struct 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;

Expand Down Expand Up @@ -2511,14 +2510,15 @@ static int skge_up(struct net_device *dev)
spin_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 */
Expand Down Expand Up @@ -3450,15 +3450,12 @@ static int skge_reset(struct skge_hw *hw)
if (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;

Expand Down

0 comments on commit 7fb7ac2

Please sign in to comment.