* [PATCH 7/9] sky2: lock less transmit completion
From: Stephen Hemminger @ 2009-08-14 15:15 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20090814151511.992669598@vyatta.com>
[-- Attachment #1: sky2-tx4b.patch --]
[-- Type: text/plain, Size: 2290 bytes --]
Transmit completion can safely run lockless against transmit start.
In the normal case, completion is done from NAPI and only looks
at elements that are at the tail of the ring. When doing shutdown
or reset, the transmiter should be completely block by NAPI disable
and blocking of transmit queue.
Based on earlier work by Mike McCormack.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
---
drivers/net/sky2.c | 120 +++++++++++++++++++++++++----------------------------
1 file changed, 57 insertions(+), 63 deletions(-)
--- a/drivers/net/sky2.c 2009-08-14 07:58:48.448220547 -0700
+++ b/drivers/net/sky2.c 2009-08-14 07:58:49.410251274 -0700
@@ -1734,8 +1734,12 @@ mapping_error:
/*
* Free ring elements from starting at tx_cons until "done"
*
- * NB: the hardware will tell us about partial completion of multi-part
+ * NB:
+ * 1. The hardware will tell us about partial completion of multi-part
* buffers so make sure not to free skb to early.
+ * 2. This may run in parallel start_xmit because the it only
+ * looks at the tail of the queue of FIFO (tx_cons), not
+ * the head (tx_prod)
*/
static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
{
@@ -1793,16 +1797,6 @@ static void sky2_tx_complete(struct sky2
netif_wake_queue(dev);
}
-/* Cleanup all untransmitted buffers, assume transmitter not running */
-static void sky2_tx_clean(struct net_device *dev)
-{
- struct sky2_port *sky2 = netdev_priv(dev);
-
- netif_tx_lock_bh(dev);
- sky2_tx_complete(sky2, sky2->tx_prod);
- netif_tx_unlock_bh(dev);
-}
-
static void sky2_tx_reset(struct sky2_hw *hw, unsigned port)
{
/* Disable Force Sync bit and Enable Alloc bit */
@@ -1890,7 +1884,9 @@ static int sky2_down(struct net_device *
sky2_tx_reset(hw, port);
- sky2_tx_clean(dev);
+ /* Free any pending frames stuck in HW queue */
+ sky2_tx_complete(sky2, sky2->tx_prod);
+
sky2_rx_clean(sky2);
pci_free_consistent(hw->pdev, RX_LE_BYTES,
@@ -2367,11 +2363,8 @@ static inline void sky2_tx_done(struct n
{
struct sky2_port *sky2 = netdev_priv(dev);
- if (netif_running(dev)) {
- netif_tx_lock(dev);
+ if (netif_running(dev))
sky2_tx_complete(sky2, last);
- netif_tx_unlock(dev);
- }
}
static inline void sky2_skb_rx(const struct sky2_port *sky2,
--
^ permalink raw reply
* [PATCH 6/9] sky2: cleanup restart operations
From: Stephen Hemminger @ 2009-08-14 15:15 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20090814151511.992669598@vyatta.com>
[-- Attachment #1: sky2-tx4a.patch --]
[-- Type: text/plain, Size: 4238 bytes --]
This unifies the places that bounce the device (suspend/resume
and restart). And makes the operations have the same semantics
as normal dev_open/dev_stop.
This also avoids setting the multicast addresses twice when
device is brought up.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
---
drivers/net/sky2.c | 120 +++++++++++++++++++++++++----------------------------
1 file changed, 57 insertions(+), 63 deletions(-)
--- a/drivers/net/sky2.c 2009-08-14 07:58:47.421479764 -0700
+++ b/drivers/net/sky2.c 2009-08-14 07:58:48.448220547 -0700
@@ -1498,10 +1498,9 @@ static int sky2_up(struct net_device *de
sky2_write32(hw, B0_IMSK, imask);
sky2_read32(hw, B0_IMSK);
- sky2_set_multicast(dev);
-
if (netif_msg_ifup(sky2))
printk(KERN_INFO PFX "%s: enabling interface\n", dev->name);
+
return 0;
err_out:
@@ -3076,18 +3075,46 @@ static void sky2_reset(struct sky2_hw *h
sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_START);
}
+/* Take device down (offline).
+ * Equivalent to doing dev_stop() but this does not
+ * inform upper layers of the transistion.
+ */
+static void sky2_detach(struct net_device *dev)
+{
+ if (netif_running(dev)) {
+ netif_device_detach(dev); /* stop txq */
+ sky2_down(dev);
+ }
+}
+
+/* Bring device back after doing sky2_detach */
+static int sky2_reattach(struct net_device *dev)
+{
+ int err = 0;
+
+ if (netif_running(dev)) {
+ err = sky2_up(dev);
+ if (err) {
+ printk(KERN_INFO PFX "%s: could not restart %d\n",
+ dev->name, err);
+ dev_close(dev);
+ } else {
+ netif_device_attach(dev);
+ sky2_set_multicast(dev);
+ }
+ }
+
+ return err;
+}
+
static void sky2_restart(struct work_struct *work)
{
struct sky2_hw *hw = container_of(work, struct sky2_hw, restart_work);
- struct net_device *dev;
- int i, err;
+ int i;
rtnl_lock();
- for (i = 0; i < hw->ports; i++) {
- dev = hw->dev[i];
- if (netif_running(dev))
- sky2_down(dev);
- }
+ for (i = 0; i < hw->ports; i++)
+ sky2_detach(hw->dev[i]);
napi_disable(&hw->napi);
sky2_write32(hw, B0_IMSK, 0);
@@ -3095,17 +3122,8 @@ static void sky2_restart(struct work_str
sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
napi_enable(&hw->napi);
- for (i = 0; i < hw->ports; i++) {
- dev = hw->dev[i];
- if (netif_running(dev)) {
- err = sky2_up(dev);
- if (err) {
- printk(KERN_INFO PFX "%s: could not restart %d\n",
- dev->name, err);
- dev_close(dev);
- }
- }
- }
+ for (i = 0; i < hw->ports; i++)
+ sky2_reattach(hw->dev[i]);
rtnl_unlock();
}
@@ -3694,7 +3712,6 @@ static int sky2_set_ringparam(struct net
struct ethtool_ringparam *ering)
{
struct sky2_port *sky2 = netdev_priv(dev);
- int err = 0;
if (ering->rx_pending > RX_MAX_PENDING ||
ering->rx_pending < 8 ||
@@ -3702,19 +3719,12 @@ static int sky2_set_ringparam(struct net
ering->tx_pending > TX_RING_SIZE - 1)
return -EINVAL;
- if (netif_running(dev))
- sky2_down(dev);
+ sky2_detach(dev);
sky2->rx_pending = ering->rx_pending;
sky2->tx_pending = ering->tx_pending;
- if (netif_running(dev)) {
- err = sky2_up(dev);
- if (err)
- dev_close(dev);
- }
-
- return err;
+ return sky2_reattach(dev);
}
static int sky2_get_regs_len(struct net_device *dev)
@@ -4636,9 +4646,7 @@ static int sky2_suspend(struct pci_dev *
struct net_device *dev = hw->dev[i];
struct sky2_port *sky2 = netdev_priv(dev);
- netif_device_detach(dev);
- if (netif_running(dev))
- sky2_down(dev);
+ sky2_detach(dev);
if (sky2->wol)
sky2_wol_init(sky2);
@@ -4686,25 +4694,18 @@ static int sky2_resume(struct pci_dev *p
sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
napi_enable(&hw->napi);
+ rtnl_lock();
for (i = 0; i < hw->ports; i++) {
- struct net_device *dev = hw->dev[i];
-
- netif_device_attach(dev);
- if (netif_running(dev)) {
- err = sky2_up(dev);
- if (err) {
- printk(KERN_ERR PFX "%s: could not up: %d\n",
- dev->name, err);
- rtnl_lock();
- dev_close(dev);
- rtnl_unlock();
- goto out;
- }
- }
+ err = sky2_reattach(hw->dev[i]);
+ if (err)
+ goto out;
}
+ rtnl_unlock();
return 0;
out:
+ rtnl_unlock();
+
dev_err(&pdev->dev, "resume failed (%d)\n", err);
pci_disable_device(pdev);
return err;
--
^ permalink raw reply
* [PATCH 8/9] sky2: fix pause negotiation
From: Stephen Hemminger @ 2009-08-14 15:15 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20090814151511.992669598@vyatta.com>
[-- Attachment #1: sky2-pause.patch --]
[-- Type: text/plain, Size: 9673 bytes --]
The sky2 driver combines auto speed negotiation with automatic negotiation
of pause parameters; but the ethtool interface expects them to be
split. This patch allows autonegotiation to be used for speed, but
manually disable flow control.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
--- a/drivers/net/sky2.c 2009-08-14 07:58:49.410251274 -0700
+++ b/drivers/net/sky2.c 2009-08-14 07:58:50.471356910 -0700
@@ -321,7 +321,7 @@ static void sky2_phy_init(struct sky2_hw
struct sky2_port *sky2 = netdev_priv(hw->dev[port]);
u16 ctrl, ct1000, adv, pg, ledctrl, ledover, reg;
- if (sky2->autoneg == AUTONEG_ENABLE &&
+ if ( (sky2->flags & SKY2_FLAG_AUTO_SPEED) &&
!(hw->flags & SKY2_HW_NEWER_PHY)) {
u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL);
@@ -363,7 +363,7 @@ static void sky2_phy_init(struct sky2_hw
ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO);
/* downshift on PHY 88E1112 and 88E1149 is changed */
- if (sky2->autoneg == AUTONEG_ENABLE
+ if ( (sky2->flags & SKY2_FLAG_AUTO_SPEED)
&& (hw->flags & SKY2_HW_NEWER_PHY)) {
/* set downshift counter to 3x and enable downshift */
ctrl &= ~PHY_M_PC_DSC_MSK;
@@ -408,7 +408,7 @@ static void sky2_phy_init(struct sky2_hw
adv = PHY_AN_CSMA;
reg = 0;
- if (sky2->autoneg == AUTONEG_ENABLE) {
+ if (sky2->flags & SKY2_FLAG_AUTO_SPEED) {
if (sky2_is_copper(hw)) {
if (sky2->advertising & ADVERTISED_1000baseT_Full)
ct1000 |= PHY_M_1000C_AFD;
@@ -423,14 +423,11 @@ static void sky2_phy_init(struct sky2_hw
if (sky2->advertising & ADVERTISED_10baseT_Half)
adv |= PHY_M_AN_10_HD;
- adv |= copper_fc_adv[sky2->flow_mode];
} else { /* special defines for FIBER (88E1040S only) */
if (sky2->advertising & ADVERTISED_1000baseT_Full)
adv |= PHY_M_AN_1000X_AFD;
if (sky2->advertising & ADVERTISED_1000baseT_Half)
adv |= PHY_M_AN_1000X_AHD;
-
- adv |= fiber_fc_adv[sky2->flow_mode];
}
/* Restart Auto-negotiation */
@@ -439,8 +436,8 @@ static void sky2_phy_init(struct sky2_hw
/* forced speed/duplex settings */
ct1000 = PHY_M_1000C_MSE;
- /* Disable auto update for duplex flow control and speed */
- reg |= GM_GPCR_AU_ALL_DIS;
+ /* Disable auto update for duplex flow control and duplex */
+ reg |= GM_GPCR_AU_DUP_DIS | GM_GPCR_AU_SPD_DIS;
switch (sky2->speed) {
case SPEED_1000:
@@ -458,8 +455,15 @@ static void sky2_phy_init(struct sky2_hw
ctrl |= PHY_CT_DUP_MD;
} else if (sky2->speed < SPEED_1000)
sky2->flow_mode = FC_NONE;
+ }
-
+ if (sky2->flags & SKY2_FLAG_AUTO_PAUSE) {
+ if (sky2_is_copper(hw))
+ adv |= copper_fc_adv[sky2->flow_mode];
+ else
+ adv |= fiber_fc_adv[sky2->flow_mode];
+ } else {
+ reg |= GM_GPCR_AU_FCT_DIS;
reg |= gm_fc_disable[sky2->flow_mode];
/* Forward pause packets to GMAC? */
@@ -594,7 +598,8 @@ static void sky2_phy_init(struct sky2_hw
/* no effect on Yukon-XL */
gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl);
- if (sky2->autoneg == AUTONEG_DISABLE || sky2->speed == SPEED_100) {
+ if ( !(sky2->flags & SKY2_FLAG_AUTO_SPEED)
+ || sky2->speed == SPEED_100) {
/* turn on 100 Mbps LED (LED_LINK100) */
ledover |= PHY_M_LED_MO_100(MO_LED_ON);
}
@@ -605,7 +610,7 @@ static void sky2_phy_init(struct sky2_hw
}
/* Enable phy interrupt on auto-negotiation complete (or link up) */
- if (sky2->autoneg == AUTONEG_ENABLE)
+ if (sky2->flags & SKY2_FLAG_AUTO_SPEED)
gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_AN_COMPL);
else
gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK);
@@ -661,7 +666,9 @@ static void sky2_phy_power_down(struct s
/* setup General Purpose Control Register */
gma_write16(hw, port, GM_GP_CTRL,
- GM_GPCR_FL_PASS | GM_GPCR_SPEED_100 | GM_GPCR_AU_ALL_DIS);
+ GM_GPCR_FL_PASS | GM_GPCR_SPEED_100 |
+ GM_GPCR_AU_DUP_DIS | GM_GPCR_AU_FCT_DIS |
+ GM_GPCR_AU_SPD_DIS);
if (hw->chip_id != CHIP_ID_YUKON_EC) {
if (hw->chip_id == CHIP_ID_YUKON_EC_U) {
@@ -1117,7 +1124,8 @@ static void rx_set_checksum(struct sky2_
sky2_write32(sky2->hw,
Q_ADDR(rxqaddr[sky2->port], Q_CSR),
- sky2->rx_csum ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
+ (sky2->flags & SKY2_FLAG_RX_CHECKSUM)
+ ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
}
/*
@@ -2076,7 +2084,7 @@ static void sky2_phy_intr(struct sky2_hw
printk(KERN_INFO PFX "%s: phy interrupt status 0x%x 0x%x\n",
sky2->netdev->name, istatus, phystat);
- if (sky2->autoneg == AUTONEG_ENABLE && (istatus & PHY_M_IS_AN_COMPL)) {
+ if (istatus & PHY_M_IS_AN_COMPL) {
if (sky2_autoneg_done(sky2, phystat) == 0)
sky2_link_up(sky2);
goto out;
@@ -2442,7 +2450,7 @@ static int sky2_status_intr(struct sky2_
/* This chip reports checksum status differently */
if (hw->flags & SKY2_HW_NEW_LE) {
- if (sky2->rx_csum &&
+ if ((sky2->flags & SKY2_FLAG_RX_CHECKSUM) &&
(le->css & (CSS_ISIPV4 | CSS_ISIPV6)) &&
(le->css & CSS_TCPUDPCSOK))
skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -2469,7 +2477,7 @@ static int sky2_status_intr(struct sky2_
/* fall through */
#endif
case OP_RXCHKS:
- if (!sky2->rx_csum)
+ if (!(sky2->flags & SKY2_FLAG_RX_CHECKSUM))
break;
/* If this happens then driver assuming wrong format */
@@ -2494,7 +2502,8 @@ static int sky2_status_intr(struct sky2_
printk(KERN_NOTICE PFX "%s: hardware receive "
"checksum problem (status = %#x)\n",
dev->name, status);
- sky2->rx_csum = 0;
+ sky2->flags &= ~SKY2_FLAG_RX_CHECKSUM;
+
sky2_write32(sky2->hw,
Q_ADDR(rxqaddr[port], Q_CSR),
BMU_DIS_RX_CHKSUM);
@@ -3195,7 +3204,8 @@ static int sky2_get_settings(struct net_
}
ecmd->advertising = sky2->advertising;
- ecmd->autoneg = sky2->autoneg;
+ ecmd->autoneg = (sky2->flags & SKY2_FLAG_AUTO_SPEED)
+ ? AUTONEG_ENABLE : AUTONEG_DISABLE;
ecmd->duplex = sky2->duplex;
return 0;
}
@@ -3207,6 +3217,7 @@ static int sky2_set_settings(struct net_
u32 supported = sky2_supported_modes(hw);
if (ecmd->autoneg == AUTONEG_ENABLE) {
+ sky2->flags |= SKY2_FLAG_AUTO_SPEED;
ecmd->advertising = supported;
sky2->duplex = -1;
sky2->speed = -1;
@@ -3248,9 +3259,9 @@ static int sky2_set_settings(struct net_
sky2->speed = ecmd->speed;
sky2->duplex = ecmd->duplex;
+ sky2->flags &= ~SKY2_FLAG_AUTO_SPEED;
}
- sky2->autoneg = ecmd->autoneg;
sky2->advertising = ecmd->advertising;
if (netif_running(dev)) {
@@ -3320,14 +3331,17 @@ static u32 sky2_get_rx_csum(struct net_d
{
struct sky2_port *sky2 = netdev_priv(dev);
- return sky2->rx_csum;
+ return !!(sky2->flags & SKY2_FLAG_RX_CHECKSUM);
}
static int sky2_set_rx_csum(struct net_device *dev, u32 data)
{
struct sky2_port *sky2 = netdev_priv(dev);
- sky2->rx_csum = data;
+ if (data)
+ sky2->flags |= SKY2_FLAG_RX_CHECKSUM;
+ else
+ sky2->flags &= ~SKY2_FLAG_RX_CHECKSUM;
sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR),
data ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
@@ -3345,7 +3359,7 @@ static int sky2_nway_reset(struct net_de
{
struct sky2_port *sky2 = netdev_priv(dev);
- if (!netif_running(dev) || sky2->autoneg != AUTONEG_ENABLE)
+ if (!netif_running(dev) || !(sky2->flags & SKY2_FLAG_AUTO_SPEED))
return -EINVAL;
sky2_phy_reinit(sky2);
@@ -3585,7 +3599,8 @@ static void sky2_get_pauseparam(struct n
ecmd->tx_pause = ecmd->rx_pause = 1;
}
- ecmd->autoneg = sky2->autoneg;
+ ecmd->autoneg = (sky2->flags & SKY2_FLAG_AUTO_PAUSE)
+ ? AUTONEG_ENABLE : AUTONEG_DISABLE;
}
static int sky2_set_pauseparam(struct net_device *dev,
@@ -3593,7 +3608,11 @@ static int sky2_set_pauseparam(struct ne
{
struct sky2_port *sky2 = netdev_priv(dev);
- sky2->autoneg = ecmd->autoneg;
+ if (ecmd->autoneg == AUTONEG_ENABLE)
+ sky2->flags |= SKY2_FLAG_AUTO_PAUSE;
+ else
+ sky2->flags &= ~SKY2_FLAG_AUTO_PAUSE;
+
sky2->flow_mode = sky2_flow(ecmd->rx_pause, ecmd->tx_pause);
if (netif_running(dev))
@@ -4283,13 +4302,15 @@ static __devinit struct net_device *sky2
sky2->msg_enable = netif_msg_init(debug, default_msg);
/* Auto speed and flow control */
- sky2->autoneg = AUTONEG_ENABLE;
+ sky2->flags = SKY2_FLAG_AUTO_SPEED | SKY2_FLAG_AUTO_PAUSE;
+ if (hw->chip_id != CHIP_ID_YUKON_XL)
+ sky2->flags |= SKY2_FLAG_RX_CHECKSUM;
+
sky2->flow_mode = FC_BOTH;
sky2->duplex = -1;
sky2->speed = -1;
sky2->advertising = sky2_supported_modes(hw);
- sky2->rx_csum = (hw->chip_id != CHIP_ID_YUKON_XL);
sky2->wol = wol;
spin_lock_init(&sky2->phy_lock);
--- a/drivers/net/sky2.h 2009-08-14 07:58:07.357063846 -0700
+++ b/drivers/net/sky2.h 2009-08-14 07:58:50.472100125 -0700
@@ -1583,7 +1583,6 @@ enum {
};
#define GM_GPCR_SPEED_1000 (GM_GPCR_GIGS_ENA | GM_GPCR_SPEED_100)
-#define GM_GPCR_AU_ALL_DIS (GM_GPCR_AU_DUP_DIS | GM_GPCR_AU_FCT_DIS|GM_GPCR_AU_SPD_DIS)
/* GM_TX_CTRL 16 bit r/w Transmit Control Register */
enum {
@@ -2042,15 +2041,18 @@ struct sky2_port {
u8 fifo_lev;
} check;
-
dma_addr_t rx_le_map;
dma_addr_t tx_le_map;
+
u16 advertising; /* ADVERTISED_ bits */
- u16 speed; /* SPEED_1000, SPEED_100, ... */
- u8 autoneg; /* AUTONEG_ENABLE, AUTONEG_DISABLE */
- u8 duplex; /* DUPLEX_HALF, DUPLEX_FULL */
- u8 rx_csum;
- u8 wol;
+ u16 speed; /* SPEED_1000, SPEED_100, ... */
+ u8 wol; /* WAKE_ bits */
+ u8 duplex; /* DUPLEX_HALF, DUPLEX_FULL */
+ u16 flags;
+#define SKY2_FLAG_RX_CHECKSUM 0x0001
+#define SKY2_FLAG_AUTO_SPEED 0x0002
+#define SKY2_FLAG_AUTO_PAUSE 0x0004
+
enum flow_control flow_mode;
enum flow_control flow_status;
--
^ permalink raw reply
* [PATCH 5/9] sky2: hold RTNL when doing suspend/shutdown operations
From: Stephen Hemminger @ 2009-08-14 15:15 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20090814151511.992669598@vyatta.com>
[-- Attachment #1: sky2-wol-rtnl.patch --]
[-- Type: text/plain, Size: 1197 bytes --]
The suspend and shutdown code plays with shared state. Use consistent
locking, for extra protection.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
--- a/drivers/net/sky2.c 2009-08-14 07:58:46.664005121 -0700
+++ b/drivers/net/sky2.c 2009-08-14 07:58:47.421479764 -0700
@@ -4631,6 +4631,7 @@ static int sky2_suspend(struct pci_dev *
del_timer_sync(&hw->watchdog_timer);
cancel_work_sync(&hw->restart_work);
+ rtnl_lock();
for (i = 0; i < hw->ports; i++) {
struct net_device *dev = hw->dev[i];
struct sky2_port *sky2 = netdev_priv(dev);
@@ -4648,6 +4649,7 @@ static int sky2_suspend(struct pci_dev *
sky2_write32(hw, B0_IMSK, 0);
napi_disable(&hw->napi);
sky2_power_aux(hw);
+ rtnl_unlock();
pci_save_state(pdev);
pci_enable_wake(pdev, pci_choose_state(pdev, state), wol);
@@ -4717,6 +4719,7 @@ static void sky2_shutdown(struct pci_dev
if (!hw)
return;
+ rtnl_lock();
del_timer_sync(&hw->watchdog_timer);
for (i = 0; i < hw->ports; i++) {
@@ -4731,6 +4734,7 @@ static void sky2_shutdown(struct pci_dev
if (wol)
sky2_power_aux(hw);
+ rtnl_unlock();
pci_enable_wake(pdev, PCI_D3hot, wol);
pci_enable_wake(pdev, PCI_D3cold, wol);
--
^ permalink raw reply
* [PATCH 0/9] sky2: version 1.24
From: Stephen Hemminger @ 2009-08-14 15:15 UTC (permalink / raw)
To: David Miller; +Cc: netdev
This is rework of some of Mike's patches, and additional
improvement in the restart logic. Patch against current
net-next-2.6.
--
^ permalink raw reply
* [PATCH 4/9] sky2: hold spinlock around phy_power_down
From: Stephen Hemminger @ 2009-08-14 15:15 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20090814151511.992669598@vyatta.com>
[-- Attachment #1: sky2-phy-lock.patch --]
[-- Type: text/plain, Size: 832 bytes --]
Avoid any possible problems with accessing PHY registers on shutdown.
This is a purely theoretical issue and is not related to any of the
outstanding bug reports. Since receiver and transmitter are already
shutdown and phy interrupts for this device are already disabled,
there should already be enough protection. Suggested by Mike McCormack.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
--- a/drivers/net/sky2.c 2009-08-14 07:58:45.736296852 -0700
+++ b/drivers/net/sky2.c 2009-08-14 07:58:46.664005121 -0700
@@ -1882,7 +1882,9 @@ static int sky2_down(struct net_device *
synchronize_irq(hw->pdev->irq);
napi_synchronize(&hw->napi);
+ spin_lock_bh(&sky2->phy_lock);
sky2_phy_power_down(hw, port);
+ spin_unlock_bh(&sky2->phy_lock);
/* turn off LED's */
sky2_write16(hw, B0_Y2LED, LED_STAT_OFF);
--
^ permalink raw reply
* [PATCH 9/9] sky2: version 1.24
From: Stephen Hemminger @ 2009-08-14 15:15 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20090814151511.992669598@vyatta.com>
[-- Attachment #1: sky2-v1.24.patch --]
[-- Type: text/plain, Size: 343 bytes --]
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
--- a/drivers/net/sky2.c 2009-08-14 07:58:50.471356910 -0700
+++ b/drivers/net/sky2.c 2009-08-14 07:58:51.564040271 -0700
@@ -50,7 +50,7 @@
#include "sky2.h"
#define DRV_NAME "sky2"
-#define DRV_VERSION "1.23"
+#define DRV_VERSION "1.24"
#define PFX DRV_NAME " "
/*
--
^ permalink raw reply
* pull request: wireless-next-2.6 2009-08-14
From: John W. Linville @ 2009-08-14 14:13 UTC (permalink / raw)
To: davem; +Cc: linux-wireless, netdev
Dave,
Yet another round of updates intended for 2.6.32...
-- sdio support fo wl1251
-- other wl1251 fixes
-- new driver for wl1271
-- some orinoco fixes
-- some work on LP-PHY support for b43 (finally...hooray!)
-- add new FIF_PSPOLL filter flag
-- mesh mode fixes
-- ath9k, ath5k, mac80211 updates, etc...
Please let me know if there are problems!
Thanks,
John
---
Individual patches are available here:
http://www.kernel.org/pub/linux/kernel/people/linville/wireless-next-2.6/
---
The following changes since commit c458bc50e31631f7e9333ea6f1832fc54d4e2c1e:
Eilon Greenstein (1):
bnx2x: update version to 1.52.1
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6.git master
Andrey Yurovsky (1):
mac80211: Use correct sign for mesh active path refresh.
Bob Copeland (8):
wl1251: separate bus i/o code into io.c
wl1251: use wiphy_dev instead of wl->spi->dev
wl1251: introduce wl1251_if_operations struct
wl1251: make wl1251_set_partition bus agnostic
wl1251: move module probe methods into spi.c
wl1251: split spi interface into separate module
wl1251: add sdio support
wl1251: make irq handling interface specific
Christian Lamparter (2):
p54: Write outside array bounds
p54: implement rfkill
Daniel Mack (1):
libertas: name the network device wlan%d
David Kilroy (6):
orinoco: prefer_port3 can be a single bit
orinoco: use local types for auth alg and sequence length
orinoco: pass orinoco_set_tkip_key the sequence lengths
orinoco: move disassociation to hw.c
orinoco: add function to retrieve current bssid
orinoco: consolidate storage of WEP and TKIP keys
David Woo (2):
mac80211: Mark a destination sequence number as valid when a PREQ is received.
mac80211: Fix invalid length passed to IE parser for PLINK CONFIRM frames
Gábor Stefanik (12):
b43: Add LP 2063 radio init
b43: Typo fixes & minor cleanup
b43: Fix fallout from the IEEE80211_IF_TYPE to NL80211_IFTYPE change.
b43: LP-PHY: Implement STX synchronization
b43: Implement LP-PHY baseband table initialization
b43: Update LP-PHY rev2+ baseband init to match the specs
ssb: Implement the remaining rev.8 SPROM vars needed for LP-PHY
b43: Fix a typo in the sync_stx routine
b43: LP-PHY: Implement reading band SPROM
b43: Implement RC calibration for rev.2+ LP PHYs
b43: LP-PHY: Refactor TX gain table I/O
b43: Implement RC calibration for rev.0/1 LP-PHYs
Igor Perminov (3):
rt2x00: Fix for race condition while update beacon
rt2x00: FIF_PSPOLL filter flag support
rt2x00: Fix beacon de-synchronization while update beacon
Ivo van Doorn (3):
rt2x00: Remove usage of deprecated radio_enabled & IEEE80211_CONF_CHANGE_RADIO_ENABLED
rt2x00: Use IEEE80211_TX_CTL_MORE_FRAMES flag
rt2x00: Align ieee80211 header to 4-byte boundary for PCI devices
Javier Cardona (7):
mac80211: Improve dequeing from mpath frame queue.
mac80211: Use 3-address format for mesh broadcast frames.
mac80211: Update the station failed frames average when minstrel is used.
mac80211: Early detection of broken mesh paths when using minstrel.
mac80211: Assign a default mesh beaconing interval.
mac80211: Move mpath and mpp growth to mesh workqueue.
mac80211: Fix unresolved mesh frames queued without valid control.vif
Joe Perches (1):
MAINTAINERS: NETWORKING [WIRELESS] additional patterns
Joerg Albert (1):
ath5k: fix missing output in monitor mode after ifconfig up
Johannes Berg (19):
mac80211: stay authenticated after disassoc
cfg80211: fix nl80211 disconnected events
cfg80211: fix SME association after disassociation
cfg80211: validate channel settings across interfaces
cfg80211: use reassociation when possible
nl80211: add generation number to all dumps
mac80211: explain TX retry and status
mac80211: document TX powersave filter requirements
mac80211: allow DMA optimisation
cfg80211: fix alignment problem in scan request
iwlwifi: refactor some thermal throttle code
iwlwifi: automatically adjust sleep level
cfg80211: fix locking for SIWFREQ
cfg80211: add missing device list locking
mac80211: take statistics before encryption
mac80211: sequence number micro-optimisation
mac80211: small tx code cleanup
cfg80211: check for and abort dangling scan requests
cfg80211: allow driver to override PS default
Julia Lawall (1):
drivers/net/wireless/ath/ath5k: Change constant name
Jussi Kivilinna (1):
usbnet: add rx queue pausing
Kalle Valo (18):
wl1251: remove fixed address support from spi commands
wl1251: remove wl1251_ops
wl1251: reorder wl1251_cmd_join() arguments
wl1251: use beacon interval and dtim period provided by mac80211
wl1251: remove wait parameter from wl1251_cmd_join()
wl1251: initialise default channel to zero
wl1251: add channel to wl1251_cmd_join() parameters
wl1251: create wl1251_join()
wl1251: fix channel setting in wl1251_op_config()
wl1251: move wl1251_acx_wake_up_conditions() to wl1251_ps_set_mode()
wl1251: use workqueue provided by mac80211
wl1251: rename reg.h to wl1251_reg.h
wl1251: remove Luciano as maintainer
wl1251: add hw scan completed debug message
wl1251: hack to disable filters for fixing association
iwl3945: fix compilation error in iwl3945_pass_packet_to_mac80211()
wl1251: remove wl1251_ops.c
wl1251: remove unused definitions from wl1251_reg.h
Lars Ericsson (2):
rt2x00: Fix quality houskeeping for software diversity
rt2x00: Fix rounding errors in RSSI average calculation
Luciano Coelho (4):
wl1271: add wl1271 driver files
wl1271: add wl1271 to Kconfig and the Makefile
MAINTAINERS: add information for wl1271 wireless driver
wl1271: fix compiler warnings on 64 bit archs
Luis R. Rodriguez (8):
ath9k: use new FIF_PSPOLL configure filter
zd1211rw: make it clear we don't use leds.h LED stuff
mac80211: fix compilation of mesh (although its disabled)
ath9k: Fix regression on receiving PS poll frames
ath: add common ath_rxbuf_alloc() and make ath9k use it
ath5k: use common ath.ko ath_rxbuf_alloc()
ath5k: use bit shift operators for cache line size
ath9k: update kconfig to indicate support for AR9002 family
Michael Buesch (2):
b43: Fix hardware key index handling
rtl818x: Add some documentation to the TX desc flags
Nick Kossifidis (5):
ath5k: Check EEPROM before tweaking SERDES
ath5k: Linear PCDAC code fixes
ath5k: Wakeup fixes
ath5k: Preserve pcicfg bits during attach
ath5k: Use SWI to trigger calibration
Pat Erley (1):
mac80211: remove max_bandwidth
Pavel Roskin (1):
cfg80211: fix disassociation warning due to misuse of wdev->current_bss
Reinette Chatre (3):
iwlwifi: re-introduce per device debugging
iwlwifi: revert uCode Alive notification with timeout
iwlwifi: fix missing EXPORT_SYMBOL
Samuel Ortiz (1):
cfg80211: Set WEP ciphers
Sujith (15):
ath9k: Remove unneeded assignment of protocol field
ath9k: Cleanup function return types
ath9k: Try to fix whitespace damage
ath9k: Remove a few DEBUG mesages
ath9k: Split eeprom.c into manageable pieces
ath9k: Cleanup ath9k_hw_4k_set_gain() interface
ath9k: Add macros for Antenna Diversity
ath9k: Clean antenna configuration for 4K EEPROM chips
ath9k: Cleanup TX power calculation for 4K chips
ath9k: Remove local chainmask variable
ath9k: Update beacon RSSI
ath9k: Remove has_hw_phycounters
ath9k: Remove duplicate variables
ath9k: Fix bug in PCI resume
ath9k: Set HW state properly
Thadeu Lima de Souza Cascardo (1):
trivial: remove duplicate "different" from comment
Wey-Yi Guy (10):
iwlwifi: name changed from "fat" to "ht40"
iwlwifi: new debugging feature for dumping data traffic
iwlwifi: Traffic type and counter for debugFs
iwlwifi: tx/rx queue pointer information
iwlwifi: uCode statistics notification counter
iwlwifi: Display sensitivity and chain noise information
iwlwifi: fix thermal throttling locking problem
iwlwifi: fix legacy thermal throttling power index
iwlwifi: handle the case when set power fail
iwlwifi: display correct critical temperature infomation
Zhu Yi (1):
wireless: display wext SSID when connected by cfg80211
gregor kowski (1):
b43: remove wrong probe_resp_plcp write
MAINTAINERS | 14 +-
drivers/net/usb/usbnet.c | 44 +-
drivers/net/wireless/ath/Kconfig | 4 +-
drivers/net/wireless/ath/ath.h | 30 +
drivers/net/wireless/ath/ath5k/ath5k.h | 17 +
drivers/net/wireless/ath/ath5k/attach.c | 60 +-
drivers/net/wireless/ath/ath5k/base.c | 138 +-
drivers/net/wireless/ath/ath5k/base.h | 6 +-
drivers/net/wireless/ath/ath5k/eeprom.c | 10 +
drivers/net/wireless/ath/ath5k/eeprom.h | 4 +
drivers/net/wireless/ath/ath5k/phy.c | 47 +-
drivers/net/wireless/ath/ath5k/qcu.c | 2 +-
drivers/net/wireless/ath/ath5k/reset.c | 155 +-
drivers/net/wireless/ath/ath9k/Kconfig | 8 +-
drivers/net/wireless/ath/ath9k/Makefile | 3 +
drivers/net/wireless/ath/ath9k/ani.c | 195 +-
drivers/net/wireless/ath/ath9k/ani.h | 1 -
drivers/net/wireless/ath/ath9k/ath9k.h | 4 +-
drivers/net/wireless/ath/ath9k/eeprom.c | 3870 +-------------------
drivers/net/wireless/ath/ath9k/eeprom.h | 245 +-
drivers/net/wireless/ath/ath9k/eeprom_4k.c | 1186 ++++++
drivers/net/wireless/ath/ath9k/eeprom_9287.c | 1183 ++++++
drivers/net/wireless/ath/ath9k/eeprom_def.c | 1385 +++++++
drivers/net/wireless/ath/ath9k/hw.c | 11 +-
drivers/net/wireless/ath/ath9k/hw.h | 19 +-
drivers/net/wireless/ath/ath9k/mac.c | 17 +-
drivers/net/wireless/ath/ath9k/mac.h | 8 +-
drivers/net/wireless/ath/ath9k/main.c | 7 +-
drivers/net/wireless/ath/ath9k/pci.c | 4 +-
drivers/net/wireless/ath/ath9k/phy.c | 12 +-
drivers/net/wireless/ath/ath9k/phy.h | 21 +-
drivers/net/wireless/ath/ath9k/recv.c | 48 +-
drivers/net/wireless/ath/main.c | 36 +
drivers/net/wireless/b43/b43.h | 11 +-
drivers/net/wireless/b43/main.c | 210 +-
drivers/net/wireless/b43/phy_lp.c | 768 ++++-
drivers/net/wireless/b43/phy_lp.h | 19 +
drivers/net/wireless/b43/tables_lpphy.c | 2151 +++++++++++-
drivers/net/wireless/b43/tables_lpphy.h | 13 +
drivers/net/wireless/b43/xmit.c | 4 +-
drivers/net/wireless/iwlwifi/iwl-1000.c | 4 +-
drivers/net/wireless/iwlwifi/iwl-3945-hw.h | 2 +-
drivers/net/wireless/iwlwifi/iwl-3945.c | 13 +-
drivers/net/wireless/iwlwifi/iwl-4965-hw.h | 6 +-
drivers/net/wireless/iwlwifi/iwl-4965.c | 72 +-
drivers/net/wireless/iwlwifi/iwl-5000.c | 10 +-
drivers/net/wireless/iwlwifi/iwl-6000.c | 4 +-
drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 81 +-
drivers/net/wireless/iwlwifi/iwl-agn.c | 129 +-
drivers/net/wireless/iwlwifi/iwl-calib.c | 2 +-
drivers/net/wireless/iwlwifi/iwl-commands.h | 29 +-
drivers/net/wireless/iwlwifi/iwl-core.c | 354 ++-
drivers/net/wireless/iwlwifi/iwl-core.h | 54 +-
drivers/net/wireless/iwlwifi/iwl-debug.h | 28 +-
drivers/net/wireless/iwlwifi/iwl-debugfs.c | 951 +++++-
drivers/net/wireless/iwlwifi/iwl-dev.h | 104 +-
drivers/net/wireless/iwlwifi/iwl-eeprom.c | 54 +-
drivers/net/wireless/iwlwifi/iwl-eeprom.h | 34 +-
drivers/net/wireless/iwlwifi/iwl-hcmd.c | 2 -
drivers/net/wireless/iwlwifi/iwl-led.c | 3 +-
drivers/net/wireless/iwlwifi/iwl-power.c | 496 ++--
drivers/net/wireless/iwlwifi/iwl-power.h | 80 +-
drivers/net/wireless/iwlwifi/iwl-rx.c | 21 +-
drivers/net/wireless/iwlwifi/iwl-sta.c | 8 +-
drivers/net/wireless/iwlwifi/iwl-tx.c | 16 +-
drivers/net/wireless/iwlwifi/iwl3945-base.c | 101 +-
drivers/net/wireless/libertas/main.c | 3 +-
drivers/net/wireless/orinoco/hw.c | 120 +-
drivers/net/wireless/orinoco/hw.h | 7 +-
drivers/net/wireless/orinoco/main.c | 35 +-
drivers/net/wireless/orinoco/orinoco.h | 16 +-
drivers/net/wireless/orinoco/wext.c | 173 +-
drivers/net/wireless/p54/fwio.c | 5 +-
drivers/net/wireless/p54/main.c | 7 +-
drivers/net/wireless/p54/txrx.c | 6 +
drivers/net/wireless/rndis_wlan.c | 13 +-
drivers/net/wireless/rt2x00/rt2400pci.c | 2 -
drivers/net/wireless/rt2x00/rt2500pci.c | 2 -
drivers/net/wireless/rt2x00/rt2500usb.c | 15 +-
drivers/net/wireless/rt2x00/rt2800usb.c | 11 +-
drivers/net/wireless/rt2x00/rt2x00.h | 33 +-
drivers/net/wireless/rt2x00/rt2x00config.c | 22 +-
drivers/net/wireless/rt2x00/rt2x00dev.c | 14 +-
drivers/net/wireless/rt2x00/rt2x00link.c | 154 +-
drivers/net/wireless/rt2x00/rt2x00mac.c | 72 +-
drivers/net/wireless/rt2x00/rt2x00queue.c | 30 +-
drivers/net/wireless/rt2x00/rt61pci.c | 10 +-
drivers/net/wireless/rt2x00/rt73usb.c | 10 +-
drivers/net/wireless/rtl818x/rtl818x.h | 14 +-
drivers/net/wireless/wl12xx/Kconfig | 38 +-
drivers/net/wireless/wl12xx/Makefile | 13 +-
drivers/net/wireless/wl12xx/wl1251.h | 78 +-
drivers/net/wireless/wl12xx/wl1251_acx.c | 84 +-
drivers/net/wireless/wl12xx/wl1251_acx.h | 146 +
drivers/net/wireless/wl12xx/wl1251_boot.c | 266 ++-
drivers/net/wireless/wl12xx/wl1251_boot.h | 1 +
drivers/net/wireless/wl12xx/wl1251_cmd.c | 62 +-
drivers/net/wireless/wl12xx/wl1251_cmd.h | 4 +-
drivers/net/wireless/wl12xx/wl1251_event.c | 7 +-
drivers/net/wireless/wl12xx/wl1251_init.c | 213 ++
drivers/net/wireless/wl12xx/wl1251_init.h | 2 +
drivers/net/wireless/wl12xx/wl1251_io.c | 196 +
drivers/net/wireless/wl12xx/wl1251_io.h | 64 +
drivers/net/wireless/wl12xx/wl1251_main.c | 375 ++-
drivers/net/wireless/wl12xx/wl1251_ops.c | 728 ----
drivers/net/wireless/wl12xx/wl1251_ops.h | 165 -
drivers/net/wireless/wl12xx/wl1251_ps.c | 18 +-
.../net/wireless/wl12xx/{reg.h => wl1251_reg.h} | 100 -
drivers/net/wireless/wl12xx/wl1251_rx.c | 9 +-
drivers/net/wireless/wl12xx/wl1251_sdio.c | 205 ++
drivers/net/wireless/wl12xx/wl1251_spi.c | 327 +-
drivers/net/wireless/wl12xx/wl1251_spi.h | 56 +-
drivers/net/wireless/wl12xx/wl1251_tx.c | 64 +-
drivers/net/wireless/wl12xx/wl1271.h | 407 ++
drivers/net/wireless/wl12xx/wl1271_acx.c | 961 +++++
drivers/net/wireless/wl12xx/wl1271_acx.h | 1221 ++++++
drivers/net/wireless/wl12xx/wl1271_boot.c | 541 +++
drivers/net/wireless/wl12xx/wl1271_boot.h | 72 +
drivers/net/wireless/wl12xx/wl1271_cmd.c | 813 ++++
drivers/net/wireless/wl12xx/wl1271_cmd.h | 464 +++
drivers/net/wireless/wl12xx/wl1271_debugfs.c | 518 +++
drivers/net/wireless/wl12xx/wl1271_debugfs.h | 33 +
drivers/net/wireless/wl12xx/wl1271_event.c | 125 +
drivers/net/wireless/wl12xx/wl1271_event.h | 110 +
drivers/net/wireless/wl12xx/wl1271_init.c | 397 ++
drivers/net/wireless/wl12xx/wl1271_init.h | 115 +
drivers/net/wireless/wl12xx/wl1271_main.c | 1397 +++++++
drivers/net/wireless/wl12xx/wl1271_ps.c | 142 +
drivers/net/wireless/wl12xx/wl1271_ps.h | 35 +
.../net/wireless/wl12xx/{reg.h => wl1271_reg.h} | 222 +-
drivers/net/wireless/wl12xx/wl1271_rx.c | 200 +
drivers/net/wireless/wl12xx/wl1271_rx.h | 121 +
drivers/net/wireless/wl12xx/wl1271_spi.c | 382 ++
drivers/net/wireless/wl12xx/wl1271_spi.h | 113 +
drivers/net/wireless/wl12xx/wl1271_tx.c | 378 ++
drivers/net/wireless/wl12xx/wl1271_tx.h | 130 +
drivers/net/wireless/zd1211rw/zd_chip.c | 6 +-
drivers/net/wireless/zd1211rw/zd_chip.h | 6 +-
drivers/net/wireless/zd1211rw/zd_mac.c | 4 +-
drivers/ssb/pci.c | 53 +-
include/linux/nl80211.h | 17 +-
include/linux/ssb/ssb.h | 44 +-
include/linux/ssb/ssb_regs.h | 66 +-
include/linux/usb/usbnet.h | 6 +
include/net/cfg80211.h | 26 +-
include/net/mac80211.h | 29 +-
net/mac80211/Kconfig | 8 +-
net/mac80211/cfg.c | 4 +
net/mac80211/ieee80211_i.h | 6 +-
net/mac80211/main.c | 16 +-
net/mac80211/mesh.c | 145 +-
net/mac80211/mesh.h | 30 +-
net/mac80211/mesh_hwmp.c | 17 +-
net/mac80211/mesh_pathtbl.c | 151 +-
net/mac80211/mesh_plink.c | 2 +-
net/mac80211/mlme.c | 31 +-
net/mac80211/rc80211_minstrel.c | 16 +-
net/mac80211/rx.c | 45 +-
net/mac80211/scan.c | 10 +-
net/mac80211/sta_info.c | 2 +
net/mac80211/tx.c | 158 +-
net/wireless/Makefile | 3 +-
net/wireless/chan.c | 89 +
net/wireless/core.c | 21 +-
net/wireless/core.h | 14 +-
net/wireless/ibss.c | 61 +-
net/wireless/mlme.c | 17 +-
net/wireless/nl80211.c | 88 +-
net/wireless/reg.c | 5 +-
net/wireless/scan.c | 31 +-
net/wireless/sme.c | 104 +-
net/wireless/util.c | 16 +-
net/wireless/wext-compat.c | 55 +-
net/wireless/wext-compat.h | 3 +-
net/wireless/wext-sme.c | 83 +-
175 files changed, 21316 insertions(+), 7692 deletions(-)
create mode 100644 drivers/net/wireless/ath/ath.h
create mode 100644 drivers/net/wireless/ath/ath9k/eeprom_4k.c
create mode 100644 drivers/net/wireless/ath/ath9k/eeprom_9287.c
create mode 100644 drivers/net/wireless/ath/ath9k/eeprom_def.c
create mode 100644 drivers/net/wireless/wl12xx/wl1251_io.c
create mode 100644 drivers/net/wireless/wl12xx/wl1251_io.h
delete mode 100644 drivers/net/wireless/wl12xx/wl1251_ops.c
delete mode 100644 drivers/net/wireless/wl12xx/wl1251_ops.h
copy drivers/net/wireless/wl12xx/{reg.h => wl1251_reg.h} (81%)
create mode 100644 drivers/net/wireless/wl12xx/wl1251_sdio.c
create mode 100644 drivers/net/wireless/wl12xx/wl1271.h
create mode 100644 drivers/net/wireless/wl12xx/wl1271_acx.c
create mode 100644 drivers/net/wireless/wl12xx/wl1271_acx.h
create mode 100644 drivers/net/wireless/wl12xx/wl1271_boot.c
create mode 100644 drivers/net/wireless/wl12xx/wl1271_boot.h
create mode 100644 drivers/net/wireless/wl12xx/wl1271_cmd.c
create mode 100644 drivers/net/wireless/wl12xx/wl1271_cmd.h
create mode 100644 drivers/net/wireless/wl12xx/wl1271_debugfs.c
create mode 100644 drivers/net/wireless/wl12xx/wl1271_debugfs.h
create mode 100644 drivers/net/wireless/wl12xx/wl1271_event.c
create mode 100644 drivers/net/wireless/wl12xx/wl1271_event.h
create mode 100644 drivers/net/wireless/wl12xx/wl1271_init.c
create mode 100644 drivers/net/wireless/wl12xx/wl1271_init.h
create mode 100644 drivers/net/wireless/wl12xx/wl1271_main.c
create mode 100644 drivers/net/wireless/wl12xx/wl1271_ps.c
create mode 100644 drivers/net/wireless/wl12xx/wl1271_ps.h
rename drivers/net/wireless/wl12xx/{reg.h => wl1271_reg.h} (93%)
create mode 100644 drivers/net/wireless/wl12xx/wl1271_rx.c
create mode 100644 drivers/net/wireless/wl12xx/wl1271_rx.h
create mode 100644 drivers/net/wireless/wl12xx/wl1271_spi.c
create mode 100644 drivers/net/wireless/wl12xx/wl1271_spi.h
create mode 100644 drivers/net/wireless/wl12xx/wl1271_tx.c
create mode 100644 drivers/net/wireless/wl12xx/wl1271_tx.h
create mode 100644 net/wireless/chan.c
Omnibus patch available here:
http://www.kernel.org/pub/linux/kernel/people/linville/wireless-next-2.6-2009-08-14.patch.bz2
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
^ permalink raw reply
* pull request: wireless-2.6 2009-08-14
From: John W. Linville @ 2009-08-14 14:12 UTC (permalink / raw)
To: davem; +Cc: linux-wireless, netdev
Dave,
A couple more squeakers for 2.6.31...one avoids a panic related to
802.11n, the other avoids some memory corruption with rt2x00 devices.
Please let me know if there are problems!
John
---
Individual patches are available here:
http://www.kernel.org/pub/linux/kernel/people/linville/wireless-2.6/
---
The following changes since commit 839d1624b9dcf31fdc02e47359043bb7bd71d6ca:
Francois Romieu (1):
8139cp: balance dma_map_single vs dma_unmap_single pair
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git master
Luis R. Rodriguez (1):
mac80211: fix panic when splicing unprepared TIDs
Pavel Roskin (1):
rt2x00: fix memory corruption in rf cache, add a sanity check
drivers/net/wireless/rt2x00/rt2x00.h | 6 ++++--
net/mac80211/agg-tx.c | 8 ++++++++
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index a498dde..49c9e2c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -849,13 +849,15 @@ struct rt2x00_dev {
static inline void rt2x00_rf_read(struct rt2x00_dev *rt2x00dev,
const unsigned int word, u32 *data)
{
- *data = rt2x00dev->rf[word];
+ BUG_ON(word < 1 || word > rt2x00dev->ops->rf_size / sizeof(u32));
+ *data = rt2x00dev->rf[word - 1];
}
static inline void rt2x00_rf_write(struct rt2x00_dev *rt2x00dev,
const unsigned int word, u32 data)
{
- rt2x00dev->rf[word] = data;
+ BUG_ON(word < 1 || word > rt2x00dev->ops->rf_size / sizeof(u32));
+ rt2x00dev->rf[word - 1] = data;
}
/*
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 9e5762a..a24e598 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -381,6 +381,14 @@ static void ieee80211_agg_splice_packets(struct ieee80211_local *local,
&local->hw, queue,
IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
+ if (!(sta->ampdu_mlme.tid_state_tx[tid] & HT_ADDBA_REQUESTED_MSK))
+ return;
+
+ if (WARN(!sta->ampdu_mlme.tid_tx[tid],
+ "TID %d gone but expected when splicing aggregates from"
+ "the pending queue\n", tid))
+ return;
+
if (!skb_queue_empty(&sta->ampdu_mlme.tid_tx[tid]->pending)) {
spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
/* mark queue as pending, it is stopped already */
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
^ permalink raw reply related
* [PATCH v2] Speed-up pfifo_fast lookup using a private bitmap
From: Krishna Kumar @ 2009-08-14 13:25 UTC (permalink / raw)
To: Jarek Poplawski; +Cc: netdev, davem, herbert, Krishna Kumar, kaber
In-Reply-To: <20090814132458.27518.65144.sendpatchset@localhost.localdomain>
Signed-off-by: Krishna Kumar <krkumar2@in.ibm.com>
---
net/sched/sch_generic.c | 70 ++++++++++++++++++++++++++------------
1 file changed, 48 insertions(+), 22 deletions(-)
diff -ruNp org/net/sched/sch_generic.c new/net/sched/sch_generic.c
--- org/net/sched/sch_generic.c 2009-08-07 12:05:43.000000000 +0530
+++ new/net/sched/sch_generic.c 2009-08-14 18:23:16.000000000 +0530
@@ -406,18 +406,38 @@ static const u8 prio2band[TC_PRIO_MAX+1]
#define PFIFO_FAST_BANDS 3
-static inline struct sk_buff_head *prio2list(struct sk_buff *skb,
- struct Qdisc *qdisc)
+/*
+ * Private data for a pfifo_fast scheduler containing:
+ * - the three band queues
+ * - bitmap indicating which of the bands contain skbs.
+ */
+struct pfifo_fast_priv {
+ u32 bitmap;
+ struct sk_buff_head q[PFIFO_FAST_BANDS];
+};
+
+/*
+ * Convert a bitmap to the first band number where an skb is queued, where:
+ * bitmap=0 means there are no skbs on any band.
+ * bitmap=1 means there is an skb on band 0.
+ * bitmap=7 means there are skbs on all 3 bands, etc.
+ */
+static const int bitmap2band[] = {-1, 0, 1, 0, 2, 0, 1, 0};
+
+static inline struct sk_buff_head *band2list(struct pfifo_fast_priv *priv,
+ int band)
{
- struct sk_buff_head *list = qdisc_priv(qdisc);
- return list + prio2band[skb->priority & TC_PRIO_MAX];
+ return priv->q + band;
}
static int pfifo_fast_enqueue(struct sk_buff *skb, struct Qdisc* qdisc)
{
- struct sk_buff_head *list = prio2list(skb, qdisc);
+ int band = prio2band[skb->priority & TC_PRIO_MAX];
+ struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
+ struct sk_buff_head *list = band2list(priv, band);
if (skb_queue_len(list) < qdisc_dev(qdisc)->tx_queue_len) {
+ priv->bitmap |= (1 << band);
qdisc->q.qlen++;
return __qdisc_enqueue_tail(skb, qdisc, list);
}
@@ -427,14 +447,18 @@ static int pfifo_fast_enqueue(struct sk_
static struct sk_buff *pfifo_fast_dequeue(struct Qdisc* qdisc)
{
- int prio;
- struct sk_buff_head *list = qdisc_priv(qdisc);
+ struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
+ int band = bitmap2band[priv->bitmap];
- for (prio = 0; prio < PFIFO_FAST_BANDS; prio++) {
- if (!skb_queue_empty(list + prio)) {
- qdisc->q.qlen--;
- return __qdisc_dequeue_head(qdisc, list + prio);
- }
+ if (likely(band >= 0)) {
+ struct sk_buff_head *list = band2list(priv, band);
+ struct sk_buff *skb = __qdisc_dequeue_head(qdisc, list);
+
+ qdisc->q.qlen--;
+ if (skb_queue_empty(list))
+ priv->bitmap &= ~(1 << band);
+
+ return skb;
}
return NULL;
@@ -442,12 +466,13 @@ static struct sk_buff *pfifo_fast_dequeu
static struct sk_buff *pfifo_fast_peek(struct Qdisc* qdisc)
{
- int prio;
- struct sk_buff_head *list = qdisc_priv(qdisc);
+ struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
+ int band = bitmap2band[priv->bitmap];
+
+ if (band >= 0) {
+ struct sk_buff_head *list = band2list(priv, band);
- for (prio = 0; prio < PFIFO_FAST_BANDS; prio++) {
- if (!skb_queue_empty(list + prio))
- return skb_peek(list + prio);
+ return skb_peek(list);
}
return NULL;
@@ -456,11 +481,12 @@ static struct sk_buff *pfifo_fast_peek(s
static void pfifo_fast_reset(struct Qdisc* qdisc)
{
int prio;
- struct sk_buff_head *list = qdisc_priv(qdisc);
+ struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
for (prio = 0; prio < PFIFO_FAST_BANDS; prio++)
- __qdisc_reset_queue(qdisc, list + prio);
+ __qdisc_reset_queue(qdisc, band2list(priv, prio));
+ priv->bitmap = 0;
qdisc->qstats.backlog = 0;
qdisc->q.qlen = 0;
}
@@ -480,17 +506,17 @@ nla_put_failure:
static int pfifo_fast_init(struct Qdisc *qdisc, struct nlattr *opt)
{
int prio;
- struct sk_buff_head *list = qdisc_priv(qdisc);
+ struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
for (prio = 0; prio < PFIFO_FAST_BANDS; prio++)
- skb_queue_head_init(list + prio);
+ skb_queue_head_init(band2list(priv, prio));
return 0;
}
static struct Qdisc_ops pfifo_fast_ops __read_mostly = {
.id = "pfifo_fast",
- .priv_size = PFIFO_FAST_BANDS * sizeof(struct sk_buff_head),
+ .priv_size = sizeof(struct pfifo_fast_priv),
.enqueue = pfifo_fast_enqueue,
.dequeue = pfifo_fast_dequeue,
.peek = pfifo_fast_peek,
^ permalink raw reply
* [PATCH v1] Speed-up pfifo_fast lookup using a public bitmap
From: Krishna Kumar @ 2009-08-14 13:25 UTC (permalink / raw)
To: Jarek Poplawski; +Cc: netdev, herbert, kaber, Krishna Kumar, davem
In-Reply-To: <20090814132458.27518.65144.sendpatchset@localhost.localdomain>
Signed-off-by: Krishna Kumar <krkumar2@in.ibm.com>
---
include/net/sch_generic.h | 1
net/sched/sch_generic.c | 46 +++++++++++++++++++++++-------------
2 files changed, 31 insertions(+), 16 deletions(-)
diff -ruNp org/include/net/sch_generic.h new/include/net/sch_generic.h
--- org/include/net/sch_generic.h 2009-08-07 12:05:43.000000000 +0530
+++ new/include/net/sch_generic.h 2009-08-13 16:55:32.000000000 +0530
@@ -72,6 +72,7 @@ struct Qdisc
* For performance sake on SMP, we put highly modified fields at the end
*/
unsigned long state;
+ u32 bitmap;
struct sk_buff_head q;
struct gnet_stats_basic bstats;
struct gnet_stats_queue qstats;
diff -ruNp org/net/sched/sch_generic.c new/net/sched/sch_generic.c
--- org/net/sched/sch_generic.c 2009-08-07 12:05:43.000000000 +0530
+++ new/net/sched/sch_generic.c 2009-08-14 18:23:01.000000000 +0530
@@ -406,18 +406,28 @@ static const u8 prio2band[TC_PRIO_MAX+1]
#define PFIFO_FAST_BANDS 3
-static inline struct sk_buff_head *prio2list(struct sk_buff *skb,
- struct Qdisc *qdisc)
+/*
+ * Convert a bitmap to the first band number where an skb is queued, where:
+ * bitmap=0 means there are no skbs on any band.
+ * bitmap=1 means there is an skb on band 0.
+ * bitmap=7 means there are skbs on all 3 bands, etc.
+ */
+static const int bitmap2band[] = {-1, 0, 1, 0, 2, 0, 1, 0};
+
+static inline struct sk_buff_head *band2list(struct Qdisc *qdisc, int band)
{
struct sk_buff_head *list = qdisc_priv(qdisc);
- return list + prio2band[skb->priority & TC_PRIO_MAX];
+
+ return list + band;
}
static int pfifo_fast_enqueue(struct sk_buff *skb, struct Qdisc* qdisc)
{
- struct sk_buff_head *list = prio2list(skb, qdisc);
+ int band = prio2band[skb->priority & TC_PRIO_MAX];
+ struct sk_buff_head *list = band2list(qdisc, band);
if (skb_queue_len(list) < qdisc_dev(qdisc)->tx_queue_len) {
+ qdisc->bitmap |= (1 << band);
qdisc->q.qlen++;
return __qdisc_enqueue_tail(skb, qdisc, list);
}
@@ -427,14 +437,17 @@ static int pfifo_fast_enqueue(struct sk_
static struct sk_buff *pfifo_fast_dequeue(struct Qdisc* qdisc)
{
- int prio;
- struct sk_buff_head *list = qdisc_priv(qdisc);
+ int band = bitmap2band[qdisc->bitmap];
- for (prio = 0; prio < PFIFO_FAST_BANDS; prio++) {
- if (!skb_queue_empty(list + prio)) {
- qdisc->q.qlen--;
- return __qdisc_dequeue_head(qdisc, list + prio);
- }
+ if (likely(band >= 0)) {
+ struct sk_buff_head *list = qdisc_priv(qdisc);
+ struct sk_buff *skb = __qdisc_dequeue_head(qdisc, list + band);
+
+ qdisc->q.qlen--;
+ if (skb_queue_empty(list + band))
+ qdisc->bitmap &= ~(1 << band);
+
+ return skb;
}
return NULL;
@@ -442,12 +455,12 @@ static struct sk_buff *pfifo_fast_dequeu
static struct sk_buff *pfifo_fast_peek(struct Qdisc* qdisc)
{
- int prio;
- struct sk_buff_head *list = qdisc_priv(qdisc);
+ int band = bitmap2band[qdisc->bitmap];
+
+ if (band >= 0) {
+ struct sk_buff_head *list = qdisc_priv(qdisc);
- for (prio = 0; prio < PFIFO_FAST_BANDS; prio++) {
- if (!skb_queue_empty(list + prio))
- return skb_peek(list + prio);
+ return skb_peek(list + band);
}
return NULL;
@@ -461,6 +474,7 @@ static void pfifo_fast_reset(struct Qdis
for (prio = 0; prio < PFIFO_FAST_BANDS; prio++)
__qdisc_reset_queue(qdisc, list + prio);
+ qdisc->bitmap = 0;
qdisc->qstats.backlog = 0;
qdisc->q.qlen = 0;
}
^ permalink raw reply
* Re: [PATCH] Speed-up pfifo_fast lookup using a bitmap
From: Krishna Kumar @ 2009-08-14 13:24 UTC (permalink / raw)
To: Jarek Poplawski; +Cc: kaber, netdev, davem, Krishna Kumar, herbert
Hi Jarek,
Jarek Poplawski <jarkao2@gmail.com> wrote on 08/14/2009 04:31:27 PM:
> Alas, private or public, these values are lower on average than
> before, so I'm not sure the complexity (especially in reading) added
> by this patch is worth it. So, I can only say it looks formally OK,
> except the changelog and maybe 2 cosmetical suggestions below.
Maybe the different test parameters result in smaller improvements.
I agree with you - the first approach is very readable and probably
preferable, while the second introduces a new structure and more
complexity.
I am sending both these versions a last time, after fixing your
comments in case someone can help decide if one or the other is
better (sorry I forgot to run checkpatch couple of times, will try
to remember next time).
Thanks,
- KK
^ permalink raw reply
* [PATCH] WAN: bit and/or confusion
From: Roel Kluin @ 2009-08-14 12:51 UTC (permalink / raw)
To: Francois Romieu, netdev, Andrew Morton, David S. Miller
Fix the tests that check whether Frame* bits are not set
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
---
// vi drivers/net/wan/dscc4.c +307
#define FrameVfr 0x80
#define FrameRdo 0x40
#define FrameCrc 0x20
#define FrameRab 0x10
diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c
index 8face5d..dd3c64a 100644
--- a/drivers/net/wan/dscc4.c
+++ b/drivers/net/wan/dscc4.c
@@ -663,9 +663,9 @@ static inline void dscc4_rx_skb(struct dscc4_dev_priv *dpriv,
} else {
if (skb->data[pkt_len] & FrameRdo)
dev->stats.rx_fifo_errors++;
- else if (!(skb->data[pkt_len] | ~FrameCrc))
+ else if (!(skb->data[pkt_len] & ~FrameCrc))
dev->stats.rx_crc_errors++;
- else if (!(skb->data[pkt_len] | ~(FrameVfr | FrameRab)))
+ else if (!(skb->data[pkt_len] & ~(FrameVfr | FrameRab)))
dev->stats.rx_length_errors++;
else
dev->stats.rx_errors++;
^ permalink raw reply related
* Re: [PATCH] revert TCP retransmission backoff on ICMP destination unreachable
From: Damian Lukowski @ 2009-08-14 12:08 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20090813.160839.127192632.davem@davemloft.net>
[-- Attachment #1: Type: text/plain, Size: 445 bytes --]
> Longer than 80 columns, and use an inline function instead
> of a macro in order to get proper type checking.
> [...]
> Do not break up the function local variables with spurious new lines
> like this, please.
> [...]
> The indentation and tabbing is messed up in all of the code you are
> adding, please fix it up to be consistent with the surrounding code
> and the rest of the TCP stack.
>
> Do not use C++ style // comments.
Better?
--
[-- Attachment #2: TCP_ICMP_2.6.30.4.patch --]
[-- Type: text/plain, Size: 4105 bytes --]
Signed-off-by: Damian Lukowski <damian@tvk.rwth-aachen.de>
diff -Naur linux-2.6.30.4/include/net/tcp.h linux-2.6.30.4-tcp-icmp/include/net/tcp.h
--- linux-2.6.30.4/include/net/tcp.h 2009-07-31 00:34:47.000000000 +0200
+++ linux-2.6.30.4-tcp-icmp/include/net/tcp.h 2009-08-14 12:18:30.846060685 +0200
@@ -1220,6 +1220,14 @@
#define tcp_for_write_queue_from_safe(skb, tmp, sk) \
skb_queue_walk_from_safe(&(sk)->sk_write_queue, skb, tmp)
+static inline bool retrans_overstepped(const struct sock *sk,
+ unsigned int boundary)
+{
+ return inet_csk(sk)->icsk_retransmits &&
+ (tcp_time_stamp - tcp_sk(sk)->retrans_stamp) >=
+ TCP_RTO_MIN*(2 << boundary);
+}
+
static inline struct sk_buff *tcp_send_head(struct sock *sk)
{
return sk->sk_send_head;
diff -Naur linux-2.6.30.4/net/ipv4/tcp_ipv4.c linux-2.6.30.4-tcp-icmp/net/ipv4/tcp_ipv4.c
--- linux-2.6.30.4/net/ipv4/tcp_ipv4.c 2009-07-31 00:34:47.000000000 +0200
+++ linux-2.6.30.4-tcp-icmp/net/ipv4/tcp_ipv4.c 2009-08-14 13:19:48.841598908 +0200
@@ -332,11 +332,13 @@
{
struct iphdr *iph = (struct iphdr *)skb->data;
struct tcphdr *th = (struct tcphdr *)(skb->data + (iph->ihl << 2));
+ struct inet_connection_sock *icsk;
struct tcp_sock *tp;
struct inet_sock *inet;
const int type = icmp_hdr(skb)->type;
const int code = icmp_hdr(skb)->code;
struct sock *sk;
+ struct sk_buff *skb_r;
__u32 seq;
int err;
struct net *net = dev_net(skb->dev);
@@ -367,6 +369,7 @@
if (sk->sk_state == TCP_CLOSE)
goto out;
+ icsk = inet_csk(sk);
tp = tcp_sk(sk);
seq = ntohl(th->seq);
if (sk->sk_state != TCP_LISTEN &&
@@ -393,6 +396,41 @@
}
err = icmp_err_convert[code].errno;
+ /* check if ICMP unreachable messages allow revert of backoff */
+ if ((code != ICMP_NET_UNREACH && code != ICMP_HOST_UNREACH) ||
+ seq != tp->snd_una || !icsk->icsk_retransmits ||
+ !icsk->icsk_backoff)
+ break;
+
+ icsk->icsk_backoff--;
+ icsk->icsk_rto >>= 1;
+
+ skb_r = skb_peek(&sk->sk_write_queue);
+ BUG_ON(!skb_r);
+
+ if (sock_owned_by_user(sk)) {
+ /* Deferring retransmission clocked by ICMP
+ * due to locked socket. */
+ inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
+ min(icsk->icsk_rto, TCP_RESOURCE_PROBE_INTERVAL),
+ TCP_RTO_MAX);
+ }
+
+ if (tcp_time_stamp - TCP_SKB_CB(skb_r)->when >
+ inet_csk(sk)->icsk_rto) {
+ /* RTO revert clocked out retransmission. */
+ tcp_retransmit_skb(sk, skb_r);
+ inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
+ icsk->icsk_rto, TCP_RTO_MAX);
+ } else {
+ /* RTO revert shortened timer. */
+ inet_csk_reset_xmit_timer(
+ sk, ICSK_TIME_RETRANS,
+ icsk->icsk_rto-
+ (tcp_time_stamp-TCP_SKB_CB(skb_r)->when),
+ TCP_RTO_MAX);
+ }
+
break;
case ICMP_TIME_EXCEEDED:
err = EHOSTUNREACH;
diff -Naur linux-2.6.30.4/net/ipv4/tcp_timer.c linux-2.6.30.4-tcp-icmp/net/ipv4/tcp_timer.c
--- linux-2.6.30.4/net/ipv4/tcp_timer.c 2009-07-31 00:34:47.000000000 +0200
+++ linux-2.6.30.4-tcp-icmp/net/ipv4/tcp_timer.c 2009-08-14 13:22:18.068666329 +0200
@@ -143,7 +143,7 @@
dst_negative_advice(&sk->sk_dst_cache);
retry_until = icsk->icsk_syn_retries ? : sysctl_tcp_syn_retries;
} else {
- if (icsk->icsk_retransmits >= sysctl_tcp_retries1) {
+ if (retrans_overstepped(sk, sysctl_tcp_retries1)) {
/* Black hole detection */
tcp_mtu_probing(icsk, sk);
@@ -156,12 +156,14 @@
retry_until = tcp_orphan_retries(sk, alive);
- if (tcp_out_of_resources(sk, alive || icsk->icsk_retransmits < retry_until))
+ if (tcp_out_of_resources(
+ sk, alive ||
+ !retrans_overstepped(sk, retry_until)))
return 1;
}
}
- if (icsk->icsk_retransmits >= retry_until) {
+ if (retrans_overstepped(sk, retry_until)) {
/* Has it gone just too far? */
tcp_write_err(sk);
return 1;
@@ -385,7 +387,7 @@
out_reset_timer:
icsk->icsk_rto = min(icsk->icsk_rto << 1, TCP_RTO_MAX);
inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto, TCP_RTO_MAX);
- if (icsk->icsk_retransmits > sysctl_tcp_retries1)
+ if (retrans_overstepped(sk, sysctl_tcp_retries1))
__sk_dst_reset(sk);
out:;
^ permalink raw reply
* [PATCH] via-velocity: Fix test of mii_status bit VELOCITY_DUPLEX_FULL
From: Roel Kluin @ 2009-08-14 12:09 UTC (permalink / raw)
To: netdev, Andrew Morton, Francois Romieu, David S. Miller
Test whether VELOCITY_DUPLEX_FULL bit is set in mii_status.
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
---
// vi drivers/net/via-velocity.h +1448
#define VELOCITY_DUPLEX_FULL 0x00000010UL
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index 3ba3595..cee08a1 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -1778,7 +1778,7 @@ static void velocity_error(struct velocity_info *vptr, int status)
* mode
*/
if (vptr->rev_id < REV_ID_VT3216_A0) {
- if (vptr->mii_status | VELOCITY_DUPLEX_FULL)
+ if (vptr->mii_status & VELOCITY_DUPLEX_FULL)
BYTE_REG_BITS_ON(TCR_TB2BDIS, ®s->TCR);
else
BYTE_REG_BITS_OFF(TCR_TB2BDIS, ®s->TCR);
^ permalink raw reply related
* Re: [PATCH] net/ipv4, linux-2.6.30.4
From: Daniel Slot @ 2009-08-14 11:52 UTC (permalink / raw)
To: David Miller; +Cc: hannemann, netdev
In-Reply-To: <20090813.131506.187121582.davem@davemloft.net>
> Why not just fix up for the deficiencies you're aware of?
Because it never was our intention to replace/improve the already
existing reordering mechanisms.
We just wanted to provide the possibility to switch to another
reordering-robust algorithm.
It could be similar to the large amount of congestion control
algorithms, which are also part of the kernel but rarely used.
A sophistcated congestion control algorithm is standardly used by the
kernel, but other ones are available too.
With our tcp-ncr patch, researchers would have the possibility to make
measurements with an IETF approved algorithm.
^ permalink raw reply
* Re: [PATCHv3 2/2] vhost_net: a kernel-level virtio server
From: Arnd Bergmann @ 2009-08-14 11:40 UTC (permalink / raw)
To: virtualization
Cc: Michael S. Tsirkin, netdev, kvm, linux-kernel, mingo, linux-mm,
akpm, hpa, gregory.haskins
In-Reply-To: <20090813182931.GC6585@redhat.com>
On Thursday 13 August 2009, Michael S. Tsirkin wrote:
> What it is: vhost net is a character device that can be used to reduce
> the number of system calls involved in virtio networking.
> Existing virtio net code is used in the guest without modification.
AFAICT, you have addressed all my comments, mostly by convincing me
that you got it right anyway ;-).
I hope this gets into 2.6.32, good work!
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
One idea though:
> + /* Parameter checking */
> + if (sock->sk->sk_type != SOCK_RAW) {
> + r = -ESOCKTNOSUPPORT;
> + goto done;
> + }
> +
> + r = sock->ops->getname(sock, (struct sockaddr *)&uaddr.sa,
> + &uaddr_len, 0);
> + if (r)
> + goto done;
> +
> + if (uaddr.sa.sll_family != AF_PACKET) {
> + r = -EPFNOSUPPORT;
> + goto done;
> + }
You currently limit the scope of the driver by only allowing raw packet
sockets to be passed into the network driver. In qemu, we currently support
some very similar transports:
* raw packet (not in a release yet)
* tcp connection
* UDP multicast
* tap character device
* VDE with Unix local sockets
My primary interest right now is the tap support, but I think it would
be interesting in general to allow different file descriptor types
in vhost_net_set_socket. AFAICT, there are two major differences
that we need to handle for this:
* most of the transports are sockets, tap uses a character device.
This could be dealt with by having both a struct socket * in
struct vhost_net *and* a struct file *, or by always keeping the
struct file and calling vfs_readv/vfs_writev for the data transport
in both cases.
* Each transport has a slightly different header, we have
- raw ethernet frames (raw, udp multicast, tap)
- 32-bit length + raw frames, possibly fragmented (tcp)
- 80-bit header + raw frames, possibly fragmented (tap with vnet_hdr)
To handle these three cases, we need either different ioctl numbers
so that vhost_net can choose the right one, or a flags field in
VHOST_NET_SET_SOCKET, like
#define VHOST_NET_RAW 1
#define VHOST_NET_LEN_HDR 2
#define VHOST_NET_VNET_HDR 4
struct vhost_net_socket {
unsigned int flags;
int fd;
};
#define VHOST_NET_SET_SOCKET _IOW(VHOST_VIRTIO, 0x30, struct vhost_net_socket)
If both of those are addressed, we can treat vhost_net as a generic
way to do network handling in the kernel independent of the qemu
model (raw, tap, ...) for it.
Your qemu patch would have to work differently, so instead of
qemu -net nic,vhost=eth0
you would do the same as today with the raw packet socket extension
qemu -net nic -net raw,ifname=eth0
Qemu could then automatically try to use vhost_net, if it's available
in the kernel, or just fall back on software vlan otherwise.
Does that make sense?
Arnd <>
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: [PATCH] Speed-up pfifo_fast lookup using a bitmap
From: Jarek Poplawski @ 2009-08-14 11:01 UTC (permalink / raw)
To: Krishna Kumar; +Cc: kaber, netdev, davem, herbert
In-Reply-To: <20090814081907.18169.10600.sendpatchset@localhost.localdomain>
On Fri, Aug 14, 2009 at 01:49:07PM +0530, Krishna Kumar wrote:
> Jarek Poplawski <jarkao2@gmail.com> wrote on 08/13/2009 04:57:16 PM:
>
> > > Sounds reasonable. To quantify that, I will test again for a longer
> > > run and report the difference.
> >
> > Yes, more numbers would be appreciated.
>
> I did a longer 7-hour testing of original code, public bitmap (the
> code submitted earlier) and a private bitmap (patch below). Each
> result line is aggregate of 5 iterations of individual 1, 2, 4, 8,
> 32 netperf sessions, each running for 55 seconds:
>
> -------------------------------------------------------
> IO Size Org Public Private
> -------------------------------------------------------
> 4K 122571 126821 125913
> 16K 135715 135642 135530
> 128K 131324 131862 131668
> 256K 130060 130107 130378
> -------------------------------------------------------
> Total: 519670 524433 (0.92%) 523491 (0.74%)
> -------------------------------------------------------
>
> The difference between keeping the bitmap private and public is
> not much.
Alas, private or public, these values are lower on average than
before, so I'm not sure the complexity (especially in reading) added
by this patch is worth it. So, I can only say it looks formally OK,
except the changelog and maybe 2 cosmetical suggestions below.
> > > The tests are on the latest tree which contains CAN_BYPASS. So a
> > > single netperf process running this change will get no advantage
> > > since this enqueue/dequeue never happens unless the NIC is slow.
> > > But for multiple processes, it should help.
> >
> > I mean: since the previous patch saved ~2% on omitting enqueue/dequeue,
> > and now enqueue/dequeue is ~2% faster, is it still worth to omit this?
>
> I haven't tested the bitmap patch without the bypass code.
> Theoretically I assume that patch should help as we still save
> an enqueue/dequeue.
>
> Thanks,
>
> - KK
>
> Signed-off-by: Krishna Kumar <krkumar2@in.ibm.com>
> ---
>
> net/sched/sch_generic.c | 70 ++++++++++++++++++++++++++------------
> 1 file changed, 48 insertions(+), 22 deletions(-)
>
> diff -ruNp org/net/sched/sch_generic.c new2/net/sched/sch_generic.c
> --- org/net/sched/sch_generic.c 2009-08-07 12:05:43.000000000 +0530
> +++ new2/net/sched/sch_generic.c 2009-08-14 12:48:37.000000000 +0530
> @@ -406,18 +406,38 @@ static const u8 prio2band[TC_PRIO_MAX+1]
...
> +static inline struct sk_buff_head *band2list(struct pfifo_fast_priv *priv,
> + int band)
> {
> - struct sk_buff_head *list = qdisc_priv(qdisc);
> - return list + prio2band[skb->priority & TC_PRIO_MAX];
> + return &priv->q[0] + band;
return priv->q + band;
seems more readable.
...
> static struct Qdisc_ops pfifo_fast_ops __read_mostly = {
> .id = "pfifo_fast",
> - .priv_size = PFIFO_FAST_BANDS * sizeof(struct sk_buff_head),
> + .priv_size = sizeof (struct pfifo_fast_priv),
checkpatch warns here, and it seems consistent with Documentation/
CodingStyle.
Thanks,
Jarek P.
^ permalink raw reply
* Re: [Bonding-devel] [PATCH net-next-2.6] bonding: introduce primary_lazy option
From: Jiri Pirko @ 2009-08-14 10:59 UTC (permalink / raw)
To: Nicolas de Pesloüan; +Cc: davem, netdev, fubar, bonding-devel
In-Reply-To: <4A846C4E.8030509@free.fr>
Thu, Aug 13, 2009 at 09:41:02PM CEST, nicolas.2p.debian@free.fr wrote:
> Jiri Pirko wrote:
>> In some cases there is not desirable to switch back to primary interface when
>> it's link recovers and rather stay wiith currently active one. We need to avoid
>> packetloss as much as we can in some cases. This is solved by introducing
>> primary_lazy option. Note that enslaved primary slave is set as current
>> active no matter what.
>
> May I suggest that instead of creating a new option to better define how
> the "primary" option is expected to behave for active-backup mode, we
> try the "weight" slave option I proposed in the thread "alternative to
> primary" earlier this year ?
>
> http://sourceforge.net/mailarchive/forum.php?thread_name=49D5357E.4020201%40free.fr&forum_name=bonding-devel
This link does not work for me :(
>
> Giving the same "weight" to two different slaves means "chose at random
> on startup and keep the active one until it fails". And if the "at
> random" behavior is not appropriate, one can force the active slave
> using what Jay suggested (/sys/class/net/bond0/bonding/active).
>
> The proposed "weight" slave's option is able to prevent the slaves from
> flip-flopping, by stating the fact that two slaves share the same
> "primary" level, and may provide several other enhancements as described
> in the thread.
>
Although I cannot reach the thread, this looks interesting. But I'm not sure it
has real benefits over primary_lazy option (and it doesn't solve initial curr
active slave setup)
Jirka
> Hence, it is a more general configuration interface than what you
> proposed. I must admit that despite the fact that I suggested this in
> april, I didn't posted any patch for it until now. Unfortunately,
> I'didn't had time for it and probably not the proper skills anyway :-).
>
> Nicolas.
>
>
>
^ permalink raw reply
* Re: [PATCH net-next-2.6] bonding: introduce primary_lazy option
From: Jiri Pirko @ 2009-08-14 10:52 UTC (permalink / raw)
To: Jay Vosburgh; +Cc: davem, bonding-devel, netdev
In-Reply-To: <19189.1250178295@death.nxdomain.ibm.com>
Thu, Aug 13, 2009 at 05:44:55PM CEST, fubar@us.ibm.com wrote:
>Jiri Pirko <jpirko@redhat.com> wrote:
>
>>In some cases there is not desirable to switch back to primary interface when
>>it's link recovers and rather stay wiith currently active one. We need to avoid
>>packetloss as much as we can in some cases. This is solved by introducing
>>primary_lazy option. Note that enslaved primary slave is set as current
>>active no matter what.
>
> Are you just looking for a way to insure that, when the bond
>first comes up (is configured at boot, for example), a particular slave
>is the active slave? In that case, why can't an explicit selection be
>made via either ifenslave -c or /sys/class/net/bond0/bonding/active ?
Indeed this can be done this way and I'm aware of it. I'm leaving aside that you
must put this somewhere into init scripts which brings downsides.
But imagine you have bond with 3 slaves:
eth0 eth1 eth2
UP(curr) UP UP
DOWN UP(curr) UP
UP UP(curr) UP
UP DOWN UP(curr)
eth2 ends up being current active but we prefer eth0 (as primary interface).
This is not desirable and is solved by primary_lazy option.
Jirka
>
> -J
>
>>Signed-off-by: Jiri Pirko <jpirko@redhat.com>
>>
>>diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt
>>index d5181ce..f1b82af 100644
>>--- a/Documentation/networking/bonding.txt
>>+++ b/Documentation/networking/bonding.txt
>>@@ -614,6 +614,15 @@ primary
>>
>> The primary option is only valid for active-backup mode.
>>
>>+primary_lazy
>>+
>>+ Specifies the behaviour of the primary slave in case of
>>+ it's link recovery has been detected. By default (value 0) the
>>+ primary slave is set as active slave immediately after the link
>>+ recovery. If the value is 1 then current active slave doesn't
>>+ change as long as it's link status doesn't change. This prevents
>>+ the bonding device from flip-flopping.
>>+
>> updelay
>>
>> Specifies the time, in milliseconds, to wait before enabling a
>>diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
>>index 3bf0cc6..00fbb9d 100644
>>--- a/drivers/net/bonding/bond_main.c
>>+++ b/drivers/net/bonding/bond_main.c
>>@@ -94,6 +94,7 @@ static int downdelay;
>> static int use_carrier = 1;
>> static char *mode;
>> static char *primary;
>>+static int primary_lazy;
>> static char *lacp_rate;
>> static char *ad_select;
>> static char *xmit_hash_policy;
>>@@ -126,6 +127,9 @@ MODULE_PARM_DESC(mode, "Mode of operation : 0 for balance-rr, "
>> "6 for balance-alb");
>> module_param(primary, charp, 0);
>> MODULE_PARM_DESC(primary, "Primary network device to use");
>>+module_param(primary_lazy, int, 0);
>>+MODULE_PARM_DESC(primary_lazy, "Do not set primary slave active once it comes up; "
>>+ "0 for off (default), 1 for on");
>> module_param(lacp_rate, charp, 0);
>> MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner "
>> "(slow/fast)");
>>@@ -1067,7 +1071,6 @@ out:
>>
>> }
>>
>>-
>> /**
>> * find_best_interface - select the best available slave to be the active one
>> * @bond: our bonding struct
>>@@ -1097,9 +1100,11 @@ static struct slave *bond_find_best_slave(struct bonding *bond)
>> * and primary_slave that may be up and able to arp
>> */
>> if ((bond->primary_slave) &&
>>- (!bond->params.arp_interval) &&
>>- (IS_UP(bond->primary_slave->dev))) {
>>+ (IS_UP(bond->primary_slave->dev)) &&
>>+ (!(bond->params.primary_lazy && old_active &&
>>+ (IS_UP(old_active->dev))) || bond->force_primary)) {
>> new_active = bond->primary_slave;
>>+ bond->force_primary = false;
>> }
>>
>> /* remember where to stop iterating over the slaves */
>>@@ -1674,8 +1679,10 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
>>
>> if (USES_PRIMARY(bond->params.mode) && bond->params.primary[0]) {
>> /* if there is a primary slave, remember it */
>>- if (strcmp(bond->params.primary, new_slave->dev->name) == 0)
>>+ if (strcmp(bond->params.primary, new_slave->dev->name) == 0) {
>> bond->primary_slave = new_slave;
>>+ bond->force_primary = true;
>>+ }
>> }
>>
>> write_lock_bh(&bond->curr_slave_lock);
>>@@ -2929,7 +2936,9 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks)
>> */
>> if (bond->primary_slave &&
>> (bond->primary_slave != bond->curr_active_slave) &&
>>- (bond->primary_slave->link == BOND_LINK_UP))
>>+ (bond->primary_slave->link == BOND_LINK_UP) &&
>>+ !(bond->params.primary_lazy && bond->curr_active_slave &&
>>+ bond->curr_active_slave->link == BOND_LINK_UP))
>> commit++;
>>
>> read_unlock(&bond->curr_slave_lock);
>>@@ -3035,7 +3044,9 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks)
>> */
>> if (bond->primary_slave &&
>> (bond->primary_slave != bond->curr_active_slave) &&
>>- (bond->primary_slave->link == BOND_LINK_UP)) {
>>+ (bond->primary_slave->link == BOND_LINK_UP) &&
>>+ !(bond->params.primary_lazy && bond->curr_active_slave &&
>>+ bond->curr_active_slave->link == BOND_LINK_UP)) {
>> write_lock_bh(&bond->curr_slave_lock);
>> bond_change_active_slave(bond, bond->primary_slave);
>> write_unlock_bh(&bond->curr_slave_lock);
>>@@ -4987,6 +4998,17 @@ static int bond_check_params(struct bond_params *params)
>> primary = NULL;
>> }
>>
>>+ if (primary) {
>>+ if ((primary_lazy != 0) && (primary_lazy != 1)) {
>>+ pr_warning(DRV_NAME
>>+ ": Warning: primary_lazy module parameter "
>>+ "(%d), not of valid value (0/1), so it was "
>>+ "set to 0\n",
>>+ primary_lazy);
>>+ primary_lazy = 1;
>>+ }
>>+ }
>>+
>> if (fail_over_mac) {
>> fail_over_mac_value = bond_parse_parm(fail_over_mac,
>> fail_over_mac_tbl);
>>@@ -5018,6 +5040,7 @@ static int bond_check_params(struct bond_params *params)
>> params->use_carrier = use_carrier;
>> params->lacp_fast = lacp_fast;
>> params->primary[0] = 0;
>>+ params->primary_lazy = primary_lazy;
>> params->fail_over_mac = fail_over_mac_value;
>>
>> if (primary) {
>>diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
>>index 55bf34f..573fe82 100644
>>--- a/drivers/net/bonding/bond_sysfs.c
>>+++ b/drivers/net/bonding/bond_sysfs.c
>>@@ -1209,6 +1209,59 @@ static DEVICE_ATTR(primary, S_IRUGO | S_IWUSR,
>> bonding_show_primary, bonding_store_primary);
>>
>> /*
>>+ * Show and set the primary_lazy flag.
>>+ */
>>+static ssize_t bonding_show_primary_lazy(struct device *d,
>>+ struct device_attribute *attr,
>>+ char *buf)
>>+{
>>+ struct bonding *bond = to_bond(d);
>>+
>>+ return sprintf(buf, "%d\n", bond->params.primary_lazy);
>>+}
>>+
>>+static ssize_t bonding_store_primary_lazy(struct device *d,
>>+ struct device_attribute *attr,
>>+ const char *buf, size_t count)
>>+{
>>+ int new_value, ret = count;
>>+ struct bonding *bond = to_bond(d);
>>+
>>+ if (!rtnl_trylock())
>>+ return restart_syscall();
>>+
>>+ if (sscanf(buf, "%d", &new_value) != 1) {
>>+ pr_err(DRV_NAME
>>+ ": %s: no primary_lazy value specified.\n",
>>+ bond->dev->name);
>>+ ret = -EINVAL;
>>+ goto out;
>>+ }
>>+ if ((new_value == 0) || (new_value == 1)) {
>>+ bond->params.primary_lazy = new_value;
>>+ pr_info(DRV_NAME ": %s: Setting primary_lazy to %d.\n",
>>+ bond->dev->name, new_value);
>>+ if (!bond->params.primary_lazy) {
>>+ bond->force_primary = true;
>>+ read_lock(&bond->lock);
>>+ write_lock_bh(&bond->curr_slave_lock);
>>+ bond_select_active_slave(bond);
>>+ write_unlock_bh(&bond->curr_slave_lock);
>>+ read_unlock(&bond->lock);
>>+ }
>>+ } else {
>>+ pr_info(DRV_NAME
>>+ ": %s: Ignoring invalid primary_lazy value %d.\n",
>>+ bond->dev->name, new_value);
>>+ }
>>+out:
>>+ rtnl_unlock();
>>+ return count;
>>+}
>>+static DEVICE_ATTR(primary_lazy, S_IRUGO | S_IWUSR,
>>+ bonding_show_primary_lazy, bonding_store_primary_lazy);
>>+
>>+/*
>> * Show and set the use_carrier flag.
>> */
>> static ssize_t bonding_show_carrier(struct device *d,
>>@@ -1497,6 +1550,7 @@ static struct attribute *per_bond_attrs[] = {
>> &dev_attr_num_unsol_na.attr,
>> &dev_attr_miimon.attr,
>> &dev_attr_primary.attr,
>>+ &dev_attr_primary_lazy.attr,
>> &dev_attr_use_carrier.attr,
>> &dev_attr_active_slave.attr,
>> &dev_attr_mii_status.attr,
>>diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
>>index 6290a50..ac35c6c 100644
>>--- a/drivers/net/bonding/bonding.h
>>+++ b/drivers/net/bonding/bonding.h
>>@@ -131,6 +131,7 @@ struct bond_params {
>> int lacp_fast;
>> int ad_select;
>> char primary[IFNAMSIZ];
>>+ int primary_lazy;
>> __be32 arp_targets[BOND_MAX_ARP_TARGETS];
>> };
>>
>>@@ -190,6 +191,7 @@ struct bonding {
>> struct slave *curr_active_slave;
>> struct slave *current_arp_slave;
>> struct slave *primary_slave;
>>+ bool force_primary;
>> s32 slave_cnt; /* never change this value outside the attach/detach wrappers */
>> rwlock_t lock;
>> rwlock_t curr_slave_lock;
>
>---
> -Jay Vosburgh, IBM Linux Technology Center, fubar@us.ibm.com
^ permalink raw reply
* Re: ifb and gso problem
From: Herbert Xu @ 2009-08-14 10:28 UTC (permalink / raw)
To: avl; +Cc: netdev
In-Reply-To: <200908141250.11876.avl@strace.net>
Dmitry Labutcky <avl@strace.net> wrote:
>
> When downloading from 192.168.1.1, speed not exceeds 256-300kbit/s on 100mbit link.
> After disabling gso - speed becomes 100mbit/s.
>
> Patch below fixed this problem.
It's already fixed:
commit 82c49a352e0fd7af7e79a922b863f33f619f3209
Author: Herbert Xu <herbert@gondor.apana.org.au>
Date: Fri May 22 22:11:37 2009 +0000
skbuff: Move new code into __copy_skb_header
Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* ifb and gso problem
From: Dmitry Labutcky @ 2009-08-14 9:50 UTC (permalink / raw)
To: netdev
Hello,
I found the problem when redirect egress traffic from ethernet device to ifb when gso is enabled
on ethernet device.
Scenario like this:
eth0: 192.168.1.1/24
# modprobe ifb
# ifconfig ifb0 up
# tc qdisc del dev eth0 root 2>/dev/null
# tc qdisc add dev eth0 root handle 1: htb
# tc qdisc add dev ifb0 root handle 1: prio
# tc filter add dev eth0 parent 1: protocol ip u32 match ip src 192.168.1.1/32 action mirred egress redirect dev ifb0
# ethtool -k eth0
Offload parameters for eth0:
Cannot get device flags: Operation not supported
rx-checksumming: on
tx-checksumming: on
scatter-gather: on
tcp-segmentation-offload: off
udp-fragmentation-offload: off
generic-segmentation-offload: on
generic-receive-offload: off
large-receive-offload: off
When downloading from 192.168.1.1, speed not exceeds 256-300kbit/s on 100mbit link.
After disabling gso - speed becomes 100mbit/s.
Patch below fixed this problem.
# diff -u work/linux-source-2.6.30/net/core/skbuff.c linux-source-2.6.30/net/core/skbuff.c
--- work/linux-source-2.6.30/net/core/skbuff.c 2009-06-10 06:05:27.000000000 +0300
+++ linux-source-2.6.30/net/core/skbuff.c 2009-08-14 08:54:21.000000000 +0300
@@ -518,6 +518,7 @@
{
new->tstamp = old->tstamp;
new->dev = old->dev;
+ new->iif = old->iif;
new->transport_header = old->transport_header;
new->network_header = old->network_header;
new->mac_header = old->mac_header;
@@ -569,7 +570,6 @@
n->cloned = 1;
n->nohdr = 0;
n->destructor = NULL;
- C(iif);
C(tail);
C(end);
C(head);
^ permalink raw reply
* Re: [PATCH] yellowfin: Fix buffer underrun after dev_alloc_skb() failure
From: Roel Kluin @ 2009-08-14 9:59 UTC (permalink / raw)
To: David Miller; +Cc: netdev, akpm
In-Reply-To: <20090812.210845.84504668.davem@davemloft.net>
When dev_alloc_skb fails in the first iteration, a buffer underrun occurs.
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
---
> I think this is a case where this code is going to need to
> be majorly reworked so that you can pass error status up
> to the caller when this allocation failure happens, and
> the caller can properly act upon it.
>
> Just silently returning when no RX ring has been allocated,
> and the TX ring hasn't been setup at all, is going to be
> worse than the array overrun you're supposedly fixing.
I think it should be something like this. Should yellowfin_open()
do more than just passing the yellowfin_init_ring() error?
diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c
index a075801..ee35b11 100644
--- a/drivers/net/yellowfin.c
+++ b/drivers/net/yellowfin.c
@@ -346,7 +346,7 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
static int yellowfin_open(struct net_device *dev);
static void yellowfin_timer(unsigned long data);
static void yellowfin_tx_timeout(struct net_device *dev);
-static void yellowfin_init_ring(struct net_device *dev);
+static int yellowfin_init_ring(struct net_device *dev);
static int yellowfin_start_xmit(struct sk_buff *skb, struct net_device *dev);
static irqreturn_t yellowfin_interrupt(int irq, void *dev_instance);
static int yellowfin_rx(struct net_device *dev);
@@ -573,19 +573,22 @@ static int yellowfin_open(struct net_device *dev)
{
struct yellowfin_private *yp = netdev_priv(dev);
void __iomem *ioaddr = yp->base;
- int i;
+ int i, ret;
/* Reset the chip. */
iowrite32(0x80000000, ioaddr + DMACtrl);
- i = request_irq(dev->irq, &yellowfin_interrupt, IRQF_SHARED, dev->name, dev);
- if (i) return i;
+ ret = request_irq(dev->irq, &yellowfin_interrupt, IRQF_SHARED, dev->name, dev);
+ if (ret)
+ return ret;
if (yellowfin_debug > 1)
printk(KERN_DEBUG "%s: yellowfin_open() irq %d.\n",
dev->name, dev->irq);
- yellowfin_init_ring(dev);
+ ret = yellowfin_init_ring(dev);
+ if (ret)
+ return ret;
iowrite32(yp->rx_ring_dma, ioaddr + RxPtr);
iowrite32(yp->tx_ring_dma, ioaddr + TxPtr);
@@ -725,10 +728,10 @@ static void yellowfin_tx_timeout(struct net_device *dev)
}
/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
-static void yellowfin_init_ring(struct net_device *dev)
+static int yellowfin_init_ring(struct net_device *dev)
{
struct yellowfin_private *yp = netdev_priv(dev);
- int i;
+ int i, j;
yp->tx_full = 0;
yp->cur_rx = yp->cur_tx = 0;
@@ -753,6 +756,11 @@ static void yellowfin_init_ring(struct net_device *dev)
yp->rx_ring[i].addr = cpu_to_le32(pci_map_single(yp->pci_dev,
skb->data, yp->rx_buf_sz, PCI_DMA_FROMDEVICE));
}
+ if (i != RX_RING_SIZE) {
+ for (j = 0; j < i; j++)
+ dev_kfree_skb(yp->rx_skbuff[j]);
+ return -ENOMEM;
+ }
yp->rx_ring[i-1].dbdma_cmd = cpu_to_le32(CMD_STOP);
yp->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
@@ -769,8 +777,6 @@ static void yellowfin_init_ring(struct net_device *dev)
yp->tx_ring[--i].dbdma_cmd = cpu_to_le32(CMD_STOP | BRANCH_ALWAYS);
#else
{
- int j;
-
/* Tx ring needs a pair of descriptors, the second for the status. */
for (i = 0; i < TX_RING_SIZE; i++) {
j = 2*i;
@@ -805,7 +811,7 @@ static void yellowfin_init_ring(struct net_device *dev)
}
#endif
yp->tx_tail_desc = &yp->tx_status[0];
- return;
+ return 0;
}
static int yellowfin_start_xmit(struct sk_buff *skb, struct net_device *dev)
^ permalink raw reply related
* [PATCH net-next-2.6] can: Use WARN_ONCE() instead of BUG_ON() for sanity check in receive path
From: Oliver Hartkopp @ 2009-08-14 8:54 UTC (permalink / raw)
To: David Miller; +Cc: Urs Thuermann, Luotao Fu, Michael Olbrich, Linux Netdev List
[-- Attachment #1: Type: text/plain, Size: 612 bytes --]
To ensure a proper handling of CAN frames transported in skbuffs some checks
need to be performed at receive time.
As stated by Michael Olbrich and Luotao Fu BUG_ON() might be to restrictive.
This is right as we can just drop the non conform skbuff and the Kernel can
continue working.
This patch replaces the BUG_ON() with a WARN_ONCE() so that the system remains
healthy but we made the problem visible (once).
Signed-off-by: Oliver Hartkopp <oliver@hartkopp.net>
Signed-off-by: Urs Thuermann <urs@isnogud.escape.de>
CC: Michael Olbrich <m.olbrich@pengutronix.de>
CC: Luotao Fu <l.fu@pengutronix.de>
---
[-- Attachment #2: af_can_convert_bug_to_warn.patch --]
[-- Type: text/x-patch, Size: 985 bytes --]
diff --git a/net/can/af_can.c b/net/can/af_can.c
index e733725..f9c027b 100644
--- a/net/can/af_can.c
+++ b/net/can/af_can.c
@@ -651,12 +651,16 @@ static int can_rcv(struct sk_buff *skb, struct net_device *dev,
struct can_frame *cf = (struct can_frame *)skb->data;
int matches;
- if (dev->type != ARPHRD_CAN || !net_eq(dev_net(dev), &init_net)) {
- kfree_skb(skb);
- return 0;
- }
+ if (!net_eq(dev_net(dev), &init_net))
+ goto drop;
- BUG_ON(skb->len != sizeof(struct can_frame) || cf->can_dlc > 8);
+ if (WARN_ONCE(dev->type != ARPHRD_CAN ||
+ skb->len != sizeof(struct can_frame) ||
+ cf->can_dlc > 8,
+ "PF_CAN: dropped non conform skbuf: "
+ "dev type %d, len %d, can_dlc %d\n",
+ dev->type, skb->len, cf->can_dlc))
+ goto drop;
/* update statistics */
can_stats.rx_frames++;
@@ -683,6 +687,10 @@ static int can_rcv(struct sk_buff *skb, struct net_device *dev,
}
return 0;
+
+drop:
+ kfree_skb(skb);
+ return 0;
}
/*
^ permalink raw reply related
* Re: [PATCH] Speed-up pfifo_fast lookup using a bitmap
From: Krishna Kumar @ 2009-08-14 8:19 UTC (permalink / raw)
To: Jarek Poplawski; +Cc: kaber, netdev, davem, Krishna Kumar, herbert
Jarek Poplawski <jarkao2@gmail.com> wrote on 08/13/2009 04:57:16 PM:
> > Sounds reasonable. To quantify that, I will test again for a longer
> > run and report the difference.
>
> Yes, more numbers would be appreciated.
I did a longer 7-hour testing of original code, public bitmap (the
code submitted earlier) and a private bitmap (patch below). Each
result line is aggregate of 5 iterations of individual 1, 2, 4, 8,
32 netperf sessions, each running for 55 seconds:
-------------------------------------------------------
IO Size Org Public Private
-------------------------------------------------------
4K 122571 126821 125913
16K 135715 135642 135530
128K 131324 131862 131668
256K 130060 130107 130378
-------------------------------------------------------
Total: 519670 524433 (0.92%) 523491 (0.74%)
-------------------------------------------------------
The difference between keeping the bitmap private and public is
not much.
> > The tests are on the latest tree which contains CAN_BYPASS. So a
> > single netperf process running this change will get no advantage
> > since this enqueue/dequeue never happens unless the NIC is slow.
> > But for multiple processes, it should help.
>
> I mean: since the previous patch saved ~2% on omitting enqueue/dequeue,
> and now enqueue/dequeue is ~2% faster, is it still worth to omit this?
I haven't tested the bitmap patch without the bypass code.
Theoretically I assume that patch should help as we still save
an enqueue/dequeue.
Thanks,
- KK
Signed-off-by: Krishna Kumar <krkumar2@in.ibm.com>
---
net/sched/sch_generic.c | 70 ++++++++++++++++++++++++++------------
1 file changed, 48 insertions(+), 22 deletions(-)
diff -ruNp org/net/sched/sch_generic.c new2/net/sched/sch_generic.c
--- org/net/sched/sch_generic.c 2009-08-07 12:05:43.000000000 +0530
+++ new2/net/sched/sch_generic.c 2009-08-14 12:48:37.000000000 +0530
@@ -406,18 +406,38 @@ static const u8 prio2band[TC_PRIO_MAX+1]
#define PFIFO_FAST_BANDS 3
-static inline struct sk_buff_head *prio2list(struct sk_buff *skb,
- struct Qdisc *qdisc)
+/*
+ * Private data for a pfifo_fast scheduler containing:
+ * - the three band queues
+ * - bitmap indicating which of the bands contain skbs.
+ */
+struct pfifo_fast_priv {
+ u32 bitmap;
+ struct sk_buff_head q[PFIFO_FAST_BANDS];
+};
+
+/*
+ * Convert a bitmap to the first band number where an skb is queued, where:
+ * bitmap=0 means there are no skbs on any bands.
+ * bitmap=1 means there is an skb on band 0.
+ * bitmap=7 means there are skbs on all 3 bands, etc.
+ */
+static const int bitmap2band[] = {-1, 0, 1, 0, 2, 0, 1, 0};
+
+static inline struct sk_buff_head *band2list(struct pfifo_fast_priv *priv,
+ int band)
{
- struct sk_buff_head *list = qdisc_priv(qdisc);
- return list + prio2band[skb->priority & TC_PRIO_MAX];
+ return &priv->q[0] + band;
}
static int pfifo_fast_enqueue(struct sk_buff *skb, struct Qdisc* qdisc)
{
- struct sk_buff_head *list = prio2list(skb, qdisc);
+ int band = prio2band[skb->priority & TC_PRIO_MAX];
+ struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
+ struct sk_buff_head *list = band2list(priv, band);
if (skb_queue_len(list) < qdisc_dev(qdisc)->tx_queue_len) {
+ priv->bitmap |= (1 << band);
qdisc->q.qlen++;
return __qdisc_enqueue_tail(skb, qdisc, list);
}
@@ -427,14 +447,18 @@ static int pfifo_fast_enqueue(struct sk_
static struct sk_buff *pfifo_fast_dequeue(struct Qdisc* qdisc)
{
- int prio;
- struct sk_buff_head *list = qdisc_priv(qdisc);
+ struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
+ int band = bitmap2band[priv->bitmap];
- for (prio = 0; prio < PFIFO_FAST_BANDS; prio++) {
- if (!skb_queue_empty(list + prio)) {
- qdisc->q.qlen--;
- return __qdisc_dequeue_head(qdisc, list + prio);
- }
+ if (likely(band >= 0)) {
+ struct sk_buff_head *list = band2list(priv, band);
+ struct sk_buff *skb = __qdisc_dequeue_head(qdisc, list);
+
+ qdisc->q.qlen--;
+ if (skb_queue_empty(list))
+ priv->bitmap &= ~(1 << band);
+
+ return skb;
}
return NULL;
@@ -442,12 +466,13 @@ static struct sk_buff *pfifo_fast_dequeu
static struct sk_buff *pfifo_fast_peek(struct Qdisc* qdisc)
{
- int prio;
- struct sk_buff_head *list = qdisc_priv(qdisc);
+ struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
+ int band = bitmap2band[priv->bitmap];
+
+ if (band >= 0) {
+ struct sk_buff_head *list = band2list(priv, band);
- for (prio = 0; prio < PFIFO_FAST_BANDS; prio++) {
- if (!skb_queue_empty(list + prio))
- return skb_peek(list + prio);
+ return skb_peek(list);
}
return NULL;
@@ -456,11 +481,12 @@ static struct sk_buff *pfifo_fast_peek(s
static void pfifo_fast_reset(struct Qdisc* qdisc)
{
int prio;
- struct sk_buff_head *list = qdisc_priv(qdisc);
+ struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
for (prio = 0; prio < PFIFO_FAST_BANDS; prio++)
- __qdisc_reset_queue(qdisc, list + prio);
+ __qdisc_reset_queue(qdisc, band2list(priv, prio));
+ priv->bitmap = 0;
qdisc->qstats.backlog = 0;
qdisc->q.qlen = 0;
}
@@ -480,17 +506,17 @@ nla_put_failure:
static int pfifo_fast_init(struct Qdisc *qdisc, struct nlattr *opt)
{
int prio;
- struct sk_buff_head *list = qdisc_priv(qdisc);
+ struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
for (prio = 0; prio < PFIFO_FAST_BANDS; prio++)
- skb_queue_head_init(list + prio);
+ skb_queue_head_init(band2list(priv, prio));
return 0;
}
static struct Qdisc_ops pfifo_fast_ops __read_mostly = {
.id = "pfifo_fast",
- .priv_size = PFIFO_FAST_BANDS * sizeof(struct sk_buff_head),
+ .priv_size = sizeof (struct pfifo_fast_priv),
.enqueue = pfifo_fast_enqueue,
.dequeue = pfifo_fast_dequeue,
.peek = pfifo_fast_peek,
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox