forked from luck/tmp_suning_uos_patched
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. Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
This commit is contained in:
parent
298e1a9ebe
commit
7fb7ac2411
@ -2403,32 +2403,31 @@ static int skge_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
|||||||
return err;
|
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;
|
u32 end;
|
||||||
|
|
||||||
start /= 8;
|
/* convert from K bytes to qwords used for hw register */
|
||||||
len /= 8;
|
start *= 1024/8;
|
||||||
end = start + len - 1;
|
space *= 1024/8;
|
||||||
|
end = start + space - 1;
|
||||||
|
|
||||||
skge_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR);
|
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_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_WP), start);
|
||||||
skge_write32(hw, RB_ADDR(q, RB_RP), 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) {
|
if (q == Q_R1 || q == Q_R2) {
|
||||||
|
u32 tp = space - space/4;
|
||||||
|
|
||||||
/* Set thresholds on receive queue's */
|
/* Set thresholds on receive queue's */
|
||||||
skge_write32(hw, RB_ADDR(q, RB_RX_UTPP),
|
skge_write32(hw, RB_ADDR(q, RB_RX_UTPP), tp);
|
||||||
start + (2*len)/3);
|
skge_write32(hw, RB_ADDR(q, RB_RX_LTPP), space/4);
|
||||||
skge_write32(hw, RB_ADDR(q, RB_RX_LTPP),
|
} else if (hw->chip_id != CHIP_ID_GENESIS)
|
||||||
start + (len/3));
|
/* Genesis Tx Fifo is too small for normal store/forward */
|
||||||
} else {
|
|
||||||
/* Enable store & forward on Tx queue's because
|
|
||||||
* Tx FIFO is only 4K on Genesis and 1K on Yukon
|
|
||||||
*/
|
|
||||||
skge_write8(hw, RB_ADDR(q, RB_CTRL), RB_ENA_STFWD);
|
skge_write8(hw, RB_ADDR(q, RB_CTRL), RB_ENA_STFWD);
|
||||||
}
|
|
||||||
|
|
||||||
skge_write8(hw, RB_ADDR(q, RB_CTRL), RB_ENA_OP_MD);
|
skge_write8(hw, RB_ADDR(q, RB_CTRL), RB_ENA_OP_MD);
|
||||||
}
|
}
|
||||||
@ -2456,7 +2455,7 @@ static int skge_up(struct net_device *dev)
|
|||||||
struct skge_port *skge = netdev_priv(dev);
|
struct skge_port *skge = netdev_priv(dev);
|
||||||
struct skge_hw *hw = skge->hw;
|
struct skge_hw *hw = skge->hw;
|
||||||
int port = skge->port;
|
int port = skge->port;
|
||||||
u32 chunk, ram_addr;
|
u32 ramaddr, ramsize, rxspace;
|
||||||
size_t rx_size, tx_size;
|
size_t rx_size, tx_size;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
@ -2511,14 +2510,15 @@ static int skge_up(struct net_device *dev)
|
|||||||
spin_unlock_bh(&hw->phy_lock);
|
spin_unlock_bh(&hw->phy_lock);
|
||||||
|
|
||||||
/* Configure RAMbuffers */
|
/* Configure RAMbuffers */
|
||||||
chunk = hw->ram_size / ((hw->ports + 1)*2);
|
ramsize = (hw->ram_size - hw->ram_offset) / hw->ports;
|
||||||
ram_addr = hw->ram_offset + 2 * chunk * port;
|
ramaddr = hw->ram_offset + port * ramsize;
|
||||||
|
rxspace = 8 + (2*(ramsize - 16))/3;
|
||||||
|
|
||||||
|
skge_ramset(hw, rxqaddr[port], ramaddr, rxspace);
|
||||||
|
skge_ramset(hw, txqaddr[port], ramaddr + rxspace, ramsize - rxspace);
|
||||||
|
|
||||||
skge_ramset(hw, rxqaddr[port], ram_addr, chunk);
|
|
||||||
skge_qset(skge, rxqaddr[port], skge->rx_ring.to_clean);
|
skge_qset(skge, rxqaddr[port], skge->rx_ring.to_clean);
|
||||||
|
|
||||||
BUG_ON(skge->tx_ring.to_use != skge->tx_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);
|
skge_qset(skge, txqaddr[port], skge->tx_ring.to_use);
|
||||||
|
|
||||||
/* Start receiver BMU */
|
/* Start receiver BMU */
|
||||||
@ -3450,15 +3450,12 @@ static int skge_reset(struct skge_hw *hw)
|
|||||||
if (hw->chip_id == CHIP_ID_GENESIS) {
|
if (hw->chip_id == CHIP_ID_GENESIS) {
|
||||||
if (t8 == 3) {
|
if (t8 == 3) {
|
||||||
/* special case: 4 x 64k x 36, offset = 0x80000 */
|
/* special case: 4 x 64k x 36, offset = 0x80000 */
|
||||||
hw->ram_size = 0x100000;
|
hw->ram_size = 1024;
|
||||||
hw->ram_offset = 0x80000;
|
hw->ram_offset = 512;
|
||||||
} else
|
} else
|
||||||
hw->ram_size = t8 * 512;
|
hw->ram_size = t8 * 512;
|
||||||
}
|
} else /* Yukon */
|
||||||
else if (t8 == 0)
|
hw->ram_size = t8 ? t8 * 4 : 128;
|
||||||
hw->ram_size = 0x20000;
|
|
||||||
else
|
|
||||||
hw->ram_size = t8 * 4096;
|
|
||||||
|
|
||||||
hw->intr_mask = IS_HW_ERR;
|
hw->intr_mask = IS_HW_ERR;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user