From 89114afd435a486deb8583e89f490fc274444d18 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sat, 8 Jul 2006 13:34:32 -0700 Subject: [NET] gso: Add skb_is_gso This patch adds the wrapper function skb_is_gso which can be used instead of directly testing skb_shinfo(skb)->gso_size. This makes things a little nicer and allows us to change the primary key for indicating whether an skb is GSO (if we ever want to do that). Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- drivers/net/sky2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/sky2.c') diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 418f169a6a31..31093760aa1e 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -1159,7 +1159,7 @@ static unsigned tx_le_req(const struct sk_buff *skb) count = sizeof(dma_addr_t) / sizeof(u32); count += skb_shinfo(skb)->nr_frags * count; - if (skb_shinfo(skb)->gso_size) + if (skb_is_gso(skb)) ++count; if (skb->ip_summed == CHECKSUM_HW) -- cgit v1.2.2 From 59139528c8e7880eee437e81647ade1b36af0d41 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 12 Jul 2006 15:23:45 -0700 Subject: [PATCH] sky2: sky2_reset section mismatch Since sky2_reset gets call from sky2_resume it shouldn't be tagged with devinit. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/sky2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/sky2.c') diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 31093760aa1e..4af3b86f62b8 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -2286,7 +2286,7 @@ static inline u32 sky2_clk2us(const struct sky2_hw *hw, u32 clk) } -static int __devinit sky2_reset(struct sky2_hw *hw) +static int sky2_reset(struct sky2_hw *hw) { u16 status; u8 t8, pmd_type; -- cgit v1.2.2 From 6a5706b99c98e3c974cf5b55324e4eed7f82e55a Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 12 Jul 2006 15:23:46 -0700 Subject: [PATCH] sky2: NAPI suspend/resume of dual port cards The changes to handle suspend/resume didn't handle the case where a dual port card has the first port down, but the second is running. In this driver, all NAPI polling is done on the primary port. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/sky2.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers/net/sky2.c') diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 4af3b86f62b8..5e8f9efd90a9 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -3437,17 +3437,14 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) return -EINVAL; del_timer_sync(&hw->idle_timer); + netif_poll_disable(hw->dev[0]); for (i = 0; i < hw->ports; i++) { struct net_device *dev = hw->dev[i]; - if (dev) { - if (!netif_running(dev)) - continue; - + if (netif_running(dev)) { sky2_down(dev); netif_device_detach(dev); - netif_poll_disable(dev); } } @@ -3474,9 +3471,8 @@ static int sky2_resume(struct pci_dev *pdev) for (i = 0; i < hw->ports; i++) { struct net_device *dev = hw->dev[i]; - if (dev && netif_running(dev)) { + if (netif_running(dev)) { netif_device_attach(dev); - netif_poll_enable(dev); err = sky2_up(dev); if (err) { @@ -3488,6 +3484,7 @@ static int sky2_resume(struct pci_dev *pdev) } } + netif_poll_enable(hw->dev[0]); sky2_idle_start(hw); out: return err; -- cgit v1.2.2 From afa195da458cb06f302c37f8d37b21b177060aed Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 12 Jul 2006 15:23:47 -0700 Subject: [PATCH] sky2: PHY power on delays The documentation says we need to wait after turning on the PHY. Also, don't enable WOL by default. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/sky2.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/net/sky2.c') diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 5e8f9efd90a9..e65689ebe147 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -234,7 +234,6 @@ static void sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) } if (hw->chip_id == CHIP_ID_YUKON_EC_U) { - sky2_write16(hw, B0_CTST, Y2_HW_WOL_ON); sky2_pci_write32(hw, PCI_DEV_REG3, 0); reg1 = sky2_pci_read32(hw, PCI_DEV_REG4); reg1 &= P_ASPM_CONTROL_MSK; @@ -243,6 +242,7 @@ static void sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) } sky2_pci_write32(hw, PCI_DEV_REG1, reg1); + udelay(100); break; @@ -255,6 +255,7 @@ static void sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) else reg1 |= (PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD); sky2_pci_write32(hw, PCI_DEV_REG1, reg1); + udelay(100); if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) sky2_write8(hw, B2_Y2_CLK_GATE, 0); -- cgit v1.2.2 From 22e1170310ec6afa41e0dc7ac9dfac735d82dcab Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 12 Jul 2006 15:23:48 -0700 Subject: [PATCH] sky2: optimize receive restart When the driver handles multiple packets per NAPI poll, it is better to reload the receive ring, then tell the hardware. Otherwise, under packet storm with flow control, the driver/hardware will degrade down to one packet getting through per pause-exchange. Likewise on transmit, don't wakeup until a little more than minimum ring space is available. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/sky2.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) (limited to 'drivers/net/sky2.c') diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index e65689ebe147..d98f28c34e5c 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -65,6 +65,7 @@ #define RX_MAX_PENDING (RX_LE_SIZE/2 - 2) #define RX_DEF_PENDING RX_MAX_PENDING #define RX_SKB_ALIGN 8 +#define RX_BUF_WRITE 16 #define TX_RING_SIZE 512 #define TX_DEF_PENDING (TX_RING_SIZE - 1) @@ -1390,7 +1391,7 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done) } sky2->tx_cons = put; - if (tx_avail(sky2) > MAX_SKB_TX_LE) + if (tx_avail(sky2) > MAX_SKB_TX_LE + 4) netif_wake_queue(dev); } @@ -1889,9 +1890,6 @@ resubmit: re->skb->ip_summed = CHECKSUM_NONE; sky2_rx_add(sky2, re->mapaddr); - /* Tell receiver about new buffers. */ - sky2_put_idx(sky2->hw, rxqaddr[sky2->port], sky2->rx_put); - return skb; oversize: @@ -1938,7 +1936,9 @@ static inline int sky2_more_work(const struct sky2_hw *hw) /* Process status response ring */ static int sky2_status_intr(struct sky2_hw *hw, int to_do) { + struct sky2_port *sky2; int work_done = 0; + unsigned buf_write[2] = { 0, 0 }; u16 hwidx = sky2_read16(hw, STAT_PUT_IDX); rmb(); @@ -1946,7 +1946,6 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) while (hw->st_idx != hwidx) { struct sky2_status_le *le = hw->st_le + hw->st_idx; struct net_device *dev; - struct sky2_port *sky2; struct sk_buff *skb; u32 status; u16 length; @@ -1979,6 +1978,14 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) #endif netif_receive_skb(skb); + /* Update receiver after 16 frames */ + if (++buf_write[le->link] == RX_BUF_WRITE) { + sky2_put_idx(hw, rxqaddr[le->link], + sky2->rx_put); + buf_write[le->link] = 0; + } + + /* Stop after net poll weight */ if (++work_done >= to_do) goto exit_loop; break; @@ -2017,6 +2024,16 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) } exit_loop: + if (buf_write[0]) { + sky2 = netdev_priv(hw->dev[0]); + sky2_put_idx(hw, Q_R1, sky2->rx_put); + } + + if (buf_write[1]) { + sky2 = netdev_priv(hw->dev[1]); + sky2_put_idx(hw, Q_R2, sky2->rx_put); + } + return work_done; } -- cgit v1.2.2