Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-next-2.6
authorDavid S. Miller <davem@davemloft.net>
Tue, 11 May 2010 06:03:26 +0000 (23:03 -0700)
committerDavid S. Miller <davem@davemloft.net>
Tue, 11 May 2010 06:03:26 +0000 (23:03 -0700)
181 files changed:
drivers/bluetooth/btmrvl_drv.h
drivers/bluetooth/btmrvl_main.c
drivers/bluetooth/btmrvl_sdio.c
drivers/bluetooth/hci_h4.c
drivers/bluetooth/hci_ll.c
drivers/bluetooth/hci_vhci.c
drivers/net/3c501.c
drivers/net/3c505.c
drivers/net/3c507.c
drivers/net/3c509.c
drivers/net/3c515.c
drivers/net/3c523.c
drivers/net/3c59x.c
drivers/net/7990.c
drivers/net/8139cp.c
drivers/net/8139too.c
drivers/net/82596.c
drivers/net/a2065.c
drivers/net/amd8111e.c
drivers/net/appletalk/cops.c
drivers/net/arcnet/arcnet.c
drivers/net/ariadne.c
drivers/net/arm/am79c961a.c
drivers/net/arm/at91_ether.c
drivers/net/arm/ep93xx_eth.c
drivers/net/arm/ether1.c
drivers/net/arm/ether3.c
drivers/net/arm/ixp4xx_eth.c
drivers/net/arm/ks8695net.c
drivers/net/arm/w90p910_ether.c
drivers/net/at1700.c
drivers/net/atarilance.c
drivers/net/atlx/atl2.c
drivers/net/atp.c
drivers/net/au1000_eth.c
drivers/net/b44.c
drivers/net/bcm63xx_enet.c
drivers/net/bfin_mac.c
drivers/net/can/at91_can.c
drivers/net/can/bfin_can.c
drivers/net/can/mcp251x.c
drivers/net/can/sja1000/sja1000.c
drivers/net/cassini.c
drivers/net/cpmac.c
drivers/net/cris/eth_v10.c
drivers/net/cs89x0.c
drivers/net/davinci_emac.c
drivers/net/de600.c
drivers/net/de620.c
drivers/net/declance.c
drivers/net/depca.c
drivers/net/dm9000.c
drivers/net/dnet.c
drivers/net/e100.c
drivers/net/eepro.c
drivers/net/eexpress.c
drivers/net/ehea/ehea_main.c
drivers/net/enc28j60.c
drivers/net/epic100.c
drivers/net/eth16i.c
drivers/net/ethoc.c
drivers/net/ewrk3.c
drivers/net/fealnx.c
drivers/net/fec.c
drivers/net/fec_mpc52xx.c
drivers/net/forcedeth.c
drivers/net/fs_enet/fs_enet-main.c
drivers/net/gianfar.c
drivers/net/hp100.c
drivers/net/ibmveth.c
drivers/net/ifb.c
drivers/net/ioc3-eth.c
drivers/net/irda/au1k_ir.c
drivers/net/irda/donauboe.c
drivers/net/irda/pxaficp_ir.c
drivers/net/irda/sa1100_ir.c
drivers/net/irda/sir_dev.c
drivers/net/irda/smsc-ircc2.c
drivers/net/irda/vlsi_ir.c
drivers/net/irda/w83977af_ir.c
drivers/net/ixgbevf/ixgbevf_main.c
drivers/net/ixp2000/ixpdev.c
drivers/net/lance.c
drivers/net/lib82596.c
drivers/net/lib8390.c
drivers/net/ll_temac_main.c
drivers/net/lp486e.c
drivers/net/mac89x0.c
drivers/net/macb.c
drivers/net/macmace.c
drivers/net/meth.c
drivers/net/mv643xx_eth.c
drivers/net/natsemi.c
drivers/net/netx-eth.c
drivers/net/ni5010.c
drivers/net/ni52.c
drivers/net/ni65.c
drivers/net/octeon/octeon_mgmt.c
drivers/net/pci-skeleton.c
drivers/net/pcmcia/3c574_cs.c
drivers/net/pcmcia/3c589_cs.c
drivers/net/pcmcia/axnet_cs.c
drivers/net/pcmcia/fmvj18x_cs.c
drivers/net/pcmcia/nmclan_cs.c
drivers/net/pcmcia/smc91c92_cs.c
drivers/net/pcmcia/xirc2ps_cs.c
drivers/net/pcnet32.c
drivers/net/plip.c
drivers/net/ps3_gelic_net.c
drivers/net/r6040.c
drivers/net/rrunner.c
drivers/net/s6gmac.c
drivers/net/sb1250-mac.c
drivers/net/sc92031.c
drivers/net/seeq8005.c
drivers/net/sgiseeq.c
drivers/net/sh_eth.c
drivers/net/sis900.c
drivers/net/skfp/skfddi.c
drivers/net/slip.c
drivers/net/smc911x.c
drivers/net/smc9194.c
drivers/net/smc91x.c
drivers/net/smsc911x.c
drivers/net/smsc9420.c
drivers/net/sonic.c
drivers/net/starfire.c
drivers/net/sun3_82586.c
drivers/net/sun3lance.c
drivers/net/sunbmac.c
drivers/net/sundance.c
drivers/net/sungem.c
drivers/net/sunhme.c
drivers/net/sunlance.c
drivers/net/sunqe.c
drivers/net/sunvnet.c
drivers/net/tc35815.c
drivers/net/tlan.c
drivers/net/tokenring/ibmtr.c
drivers/net/tokenring/smctr.c
drivers/net/tokenring/tms380tr.c
drivers/net/tulip/de2104x.c
drivers/net/tulip/de4x5.c
drivers/net/tulip/dmfe.c
drivers/net/tulip/pnic.c
drivers/net/tulip/tulip_core.c
drivers/net/tulip/uli526x.c
drivers/net/tulip/winbond-840.c
drivers/net/tun.c
drivers/net/typhoon.c
drivers/net/ucc_geth.c
drivers/net/usb/hso.c
drivers/net/usb/kaweth.c
drivers/net/usb/pegasus.c
drivers/net/via-rhine.c
drivers/net/via-velocity.c
drivers/net/vmxnet3/vmxnet3_drv.c
drivers/net/wan/dscc4.c
drivers/net/wan/hd64570.c
drivers/net/wan/hd64572.c
drivers/net/wan/ixp4xx_hss.c
drivers/net/wan/lmc/lmc_main.c
drivers/net/wan/pc300_drv.c
drivers/net/wan/wanxl.c
drivers/net/wireless/atmel.c
drivers/net/wireless/libertas/main.c
drivers/net/wireless/libertas/tx.c
drivers/net/wireless/orinoco/main.c
drivers/net/wireless/prism54/islpci_eth.c
drivers/net/wireless/ray_cs.c
drivers/net/wireless/wl3501_cs.c
drivers/net/wireless/zd1201.c
drivers/net/xilinx_emaclite.c
drivers/net/znet.c
include/net/bluetooth/hci_core.h
include/net/bluetooth/l2cap.h
net/bluetooth/Kconfig
net/bluetooth/hci_core.c
net/bluetooth/hci_sysfs.c
net/bluetooth/l2cap.c
net/bluetooth/sco.c

index 2047275..bed0ba6 100644 (file)
@@ -42,6 +42,8 @@ struct btmrvl_device {
        void *card;
        struct hci_dev *hcidev;
 
+       u8 dev_type;
+
        u8 tx_dnld_rdy;
 
        u8 psmode;
@@ -88,8 +90,11 @@ struct btmrvl_private {
 #define BT_CMD_HOST_SLEEP_ENABLE       0x5A
 #define BT_CMD_MODULE_CFG_REQ          0x5B
 
-/* Sub-commands: Module Bringup/Shutdown Request */
+/* Sub-commands: Module Bringup/Shutdown Request/Response */
 #define MODULE_BRINGUP_REQ             0xF1
+#define MODULE_BROUGHT_UP              0x00
+#define MODULE_ALREADY_UP              0x0C
+
 #define MODULE_SHUTDOWN_REQ            0xF2
 
 #define BT_EVENT_POWER_STATE           0x20
@@ -123,6 +128,7 @@ struct btmrvl_event {
 
 /* Prototype of global function */
 
+int btmrvl_register_hdev(struct btmrvl_private *priv);
 struct btmrvl_private *btmrvl_add_card(void *card);
 int btmrvl_remove_card(struct btmrvl_private *priv);
 
index 53a43ad..ee37ef0 100644 (file)
@@ -66,7 +66,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb)
 {
        struct btmrvl_adapter *adapter = priv->adapter;
        struct btmrvl_event *event;
-       u8 ret = 0;
+       int ret = 0;
 
        event = (struct btmrvl_event *) skb->data;
        if (event->ec != 0xff) {
@@ -112,8 +112,17 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb)
        case BT_CMD_MODULE_CFG_REQ:
                if (priv->btmrvl_dev.sendcmdflag &&
                                event->data[1] == MODULE_BRINGUP_REQ) {
-                       BT_DBG("EVENT:%s", (event->data[2]) ?
-                               "Bring-up failed" : "Bring-up succeed");
+                       BT_DBG("EVENT:%s",
+                               ((event->data[2] == MODULE_BROUGHT_UP) ||
+                               (event->data[2] == MODULE_ALREADY_UP)) ?
+                               "Bring-up succeed" : "Bring-up failed");
+
+                       if (event->length > 3)
+                               priv->btmrvl_dev.dev_type = event->data[3];
+                       else
+                               priv->btmrvl_dev.dev_type = HCI_BREDR;
+
+                       BT_DBG("dev_type: %d", priv->btmrvl_dev.dev_type);
                } else if (priv->btmrvl_dev.sendcmdflag &&
                                event->data[1] == MODULE_SHUTDOWN_REQ) {
                        BT_DBG("EVENT:%s", (event->data[2]) ?
@@ -522,47 +531,20 @@ static int btmrvl_service_main_thread(void *data)
        return 0;
 }
 
-struct btmrvl_private *btmrvl_add_card(void *card)
+int btmrvl_register_hdev(struct btmrvl_private *priv)
 {
        struct hci_dev *hdev = NULL;
-       struct btmrvl_private *priv;
        int ret;
 
-       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-       if (!priv) {
-               BT_ERR("Can not allocate priv");
-               goto err_priv;
-       }
-
-       priv->adapter = kzalloc(sizeof(*priv->adapter), GFP_KERNEL);
-       if (!priv->adapter) {
-               BT_ERR("Allocate buffer for btmrvl_adapter failed!");
-               goto err_adapter;
-       }
-
-       btmrvl_init_adapter(priv);
-
        hdev = hci_alloc_dev();
        if (!hdev) {
                BT_ERR("Can not allocate HCI device");
                goto err_hdev;
        }
 
-       BT_DBG("Starting kthread...");
-       priv->main_thread.priv = priv;
-       spin_lock_init(&priv->driver_lock);
-
-       init_waitqueue_head(&priv->main_thread.wait_q);
-       priv->main_thread.task = kthread_run(btmrvl_service_main_thread,
-                               &priv->main_thread, "btmrvl_main_service");
-
        priv->btmrvl_dev.hcidev = hdev;
-       priv->btmrvl_dev.card = card;
-
        hdev->driver_data = priv;
 
-       priv->btmrvl_dev.tx_dnld_rdy = true;
-
        hdev->bus = HCI_SDIO;
        hdev->open = btmrvl_open;
        hdev->close = btmrvl_close;
@@ -572,6 +554,10 @@ struct btmrvl_private *btmrvl_add_card(void *card)
        hdev->ioctl = btmrvl_ioctl;
        hdev->owner = THIS_MODULE;
 
+       btmrvl_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ);
+
+       hdev->dev_type = priv->btmrvl_dev.dev_type;
+
        ret = hci_register_dev(hdev);
        if (ret < 0) {
                BT_ERR("Can not register HCI device");
@@ -582,16 +568,52 @@ struct btmrvl_private *btmrvl_add_card(void *card)
        btmrvl_debugfs_init(hdev);
 #endif
 
-       return priv;
+       return 0;
 
 err_hci_register_dev:
-       /* Stop the thread servicing the interrupts */
-       kthread_stop(priv->main_thread.task);
-
        hci_free_dev(hdev);
 
 err_hdev:
+       /* Stop the thread servicing the interrupts */
+       kthread_stop(priv->main_thread.task);
+
        btmrvl_free_adapter(priv);
+       kfree(priv);
+
+       return -ENOMEM;
+}
+EXPORT_SYMBOL_GPL(btmrvl_register_hdev);
+
+struct btmrvl_private *btmrvl_add_card(void *card)
+{
+       struct btmrvl_private *priv;
+
+       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+       if (!priv) {
+               BT_ERR("Can not allocate priv");
+               goto err_priv;
+       }
+
+       priv->adapter = kzalloc(sizeof(*priv->adapter), GFP_KERNEL);
+       if (!priv->adapter) {
+               BT_ERR("Allocate buffer for btmrvl_adapter failed!");
+               goto err_adapter;
+       }
+
+       btmrvl_init_adapter(priv);
+
+       BT_DBG("Starting kthread...");
+       priv->main_thread.priv = priv;
+       spin_lock_init(&priv->driver_lock);
+
+       init_waitqueue_head(&priv->main_thread.wait_q);
+       priv->main_thread.task = kthread_run(btmrvl_service_main_thread,
+                               &priv->main_thread, "btmrvl_main_service");
+
+       priv->btmrvl_dev.card = card;
+       priv->btmrvl_dev.tx_dnld_rdy = true;
+
+       return priv;
 
 err_adapter:
        kfree(priv);
index 0dba76a..df0773e 100644 (file)
@@ -931,7 +931,12 @@ static int btmrvl_sdio_probe(struct sdio_func *func,
        priv->hw_host_to_card = btmrvl_sdio_host_to_card;
        priv->hw_wakeup_firmware = btmrvl_sdio_wakeup_fw;
 
-       btmrvl_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ);
+       if (btmrvl_register_hdev(priv)) {
+               BT_ERR("Register hdev failed!");
+               ret = -ENODEV;
+               goto disable_host_int;
+       }
+
        priv->btmrvl_dev.psmode = 1;
        btmrvl_enable_ps(priv);
 
index c0ce813..3f038f5 100644 (file)
@@ -246,7 +246,7 @@ static int h4_recv(struct hci_uart *hu, void *data, int count)
                        BT_ERR("Can't allocate mem for new packet");
                        h4->rx_state = H4_W4_PACKET_TYPE;
                        h4->rx_count = 0;
-                       return 0;
+                       return -ENOMEM;
                }
 
                h4->rx_skb->dev = (void *) hu->hdev;
index 5c65014..fb8445c 100644 (file)
@@ -402,7 +402,7 @@ static int ll_recv(struct hci_uart *hu, void *data, int count)
                                continue;
 
                        case HCILL_W4_EVENT_HDR:
-                               eh = (struct hci_event_hdr *) ll->rx_skb->data;
+                               eh = hci_event_hdr(ll->rx_skb);
 
                                BT_DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen);
 
@@ -410,7 +410,7 @@ static int ll_recv(struct hci_uart *hu, void *data, int count)
                                continue;
 
                        case HCILL_W4_ACL_HDR:
-                               ah = (struct hci_acl_hdr *) ll->rx_skb->data;
+                               ah = hci_acl_hdr(ll->rx_skb);
                                dlen = __le16_to_cpu(ah->dlen);
 
                                BT_DBG("ACL header: dlen %d", dlen);
@@ -419,7 +419,7 @@ static int ll_recv(struct hci_uart *hu, void *data, int count)
                                continue;
 
                        case HCILL_W4_SCO_HDR:
-                               sh = (struct hci_sco_hdr *) ll->rx_skb->data;
+                               sh = hci_sco_hdr(ll->rx_skb);
 
                                BT_DBG("SCO header: dlen %d", sh->dlen);
 
@@ -491,7 +491,7 @@ static int ll_recv(struct hci_uart *hu, void *data, int count)
                        BT_ERR("Can't allocate mem for new packet");
                        ll->rx_state = HCILL_W4_PACKET_TYPE;
                        ll->rx_count = 0;
-                       return 0;
+                       return -ENOMEM;
                }
 
                ll->rx_skb->dev = (void *) hu->hdev;
index bb0aefd..3aa7b2a 100644 (file)
@@ -157,7 +157,7 @@ static inline ssize_t vhci_put_user(struct vhci_data *data,
                break;
 
        case HCI_SCODATA_PKT:
-               data->hdev->stat.cmd_tx++;
+               data->hdev->stat.sco_tx++;
                break;
        };
 
index 3ea42ff..4fed2a8 100644 (file)
@@ -480,7 +480,6 @@ static netdev_tx_t el_start_xmit(struct sk_buff *skb, struct net_device *dev)
                        /* fire ... Trigger xmit.  */
                        outb(AX_XMIT, AX_CMD);
                        lp->loading = 0;
-                       dev->trans_start = jiffies;
                        if (el_debug > 2)
                                pr_debug(" queued xmit.\n");
                        dev_kfree_skb(skb);
index 8d584f5..88d766e 100644 (file)
@@ -1055,7 +1055,7 @@ static void elp_timeout(struct net_device *dev)
                   (stat & ACRF) ? "interrupt" : "command");
        if (elp_debug >= 1)
                pr_debug("%s: status %#02x\n", dev->name, stat);
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        dev->stats.tx_dropped++;
        netif_wake_queue(dev);
 }
@@ -1093,11 +1093,6 @@ static netdev_tx_t elp_start_xmit(struct sk_buff *skb, struct net_device *dev)
        if (elp_debug >= 3)
                pr_debug("%s: packet of length %d sent\n", dev->name, (int) skb->len);
 
-       /*
-        * start the transmit timeout
-        */
-       dev->trans_start = jiffies;
-
        prime_rx(dev);
        spin_unlock_irqrestore(&adapter->lock, flags);
        netif_start_queue(dev);
index 9e95afa..c4e272f 100644 (file)
@@ -504,7 +504,7 @@ static void el16_tx_timeout (struct net_device *dev)
                outb (0, ioaddr + SIGNAL_CA);   /* Issue channel-attn. */
                lp->last_restart = dev->stats.tx_packets;
        }
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        netif_wake_queue (dev);
 }
 
@@ -528,7 +528,6 @@ static netdev_tx_t el16_send_packet (struct sk_buff *skb,
 
        hardware_send_packet (dev, buf, skb->len, length - skb->len);
 
-       dev->trans_start = jiffies;
        /* Enable the 82586 interrupt input. */
        outb (0x84, ioaddr + MISC_CTRL);
 
index ab9bb3c..54deaa9 100644 (file)
@@ -807,7 +807,7 @@ el3_tx_timeout (struct net_device *dev)
                   dev->name, inb(ioaddr + TX_STATUS), inw(ioaddr + EL3_STATUS),
                   inw(ioaddr + TX_FREE));
        dev->stats.tx_errors++;
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        /* Issue TX_RESET and TX_START commands. */
        outw(TxReset, ioaddr + EL3_CMD);
        outw(TxEnable, ioaddr + EL3_CMD);
@@ -868,7 +868,6 @@ el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
        /* ... and the packet rounded to a doubleword. */
        outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
 
-       dev->trans_start = jiffies;
        if (inw(ioaddr + TX_FREE) > 1536)
                netif_start_queue(dev);
        else
index 2e17837..569e269 100644 (file)
@@ -992,7 +992,7 @@ static void corkscrew_timeout(struct net_device *dev)
                if (!(inw(ioaddr + EL3_STATUS) & CmdInProgress))
                        break;
        outw(TxEnable, ioaddr + EL3_CMD);
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        dev->stats.tx_errors++;
        dev->stats.tx_dropped++;
        netif_wake_queue(dev);
@@ -1055,7 +1055,6 @@ static netdev_tx_t corkscrew_start_xmit(struct sk_buff *skb,
                                prev_entry->status &= ~0x80000000;
                        netif_wake_queue(dev);
                }
-               dev->trans_start = jiffies;
                return NETDEV_TX_OK;
        }
        /* Put out the doubleword header... */
@@ -1091,7 +1090,6 @@ static netdev_tx_t corkscrew_start_xmit(struct sk_buff *skb,
                outw(SetTxThreshold + (1536 >> 2), ioaddr + EL3_CMD);
 #endif                         /* bus master */
 
-       dev->trans_start = jiffies;
 
        /* Clear the Tx status stack. */
        {
index 55d219e..a7b0e5e 100644 (file)
@@ -1152,7 +1152,6 @@ static netdev_tx_t elmc_send_packet(struct sk_buff *skb, struct net_device *dev)
                p->scb->cmd = CUC_START;
                p->xmit_cmds[0]->cmd_status = 0;
                        elmc_attn586();
-               dev->trans_start = jiffies;
                if (!i) {
                        dev_kfree_skb(skb);
                }
@@ -1176,7 +1175,6 @@ static netdev_tx_t elmc_send_packet(struct sk_buff *skb, struct net_device *dev)
        p->xmit_cmds[0]->cmd_status = p->nop_cmds[next_nop]->cmd_status = 0;
 
        p->nop_cmds[p->nop_point]->cmd_link = make16((p->xmit_cmds[0]));
-       dev->trans_start = jiffies;
        p->nop_point = next_nop;
        dev_kfree_skb(skb);
 #endif
@@ -1190,7 +1188,6 @@ static netdev_tx_t elmc_send_packet(struct sk_buff *skb, struct net_device *dev)
            = make16((p->nop_cmds[next_nop]));
        p->nop_cmds[next_nop]->cmd_status = 0;
                p->nop_cmds[p->xmit_count]->cmd_link = make16((p->xmit_cmds[p->xmit_count]));
-       dev->trans_start = jiffies;
        p->xmit_count = next_nop;
        if (p->xmit_count != p->xmit_last)
                netif_wake_queue(dev);
index 9752530..dab2afa 100644 (file)
@@ -1917,7 +1917,7 @@ static void vortex_tx_timeout(struct net_device *dev)
 
        /* Issue Tx Enable */
        iowrite16(TxEnable, ioaddr + EL3_CMD);
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
 
        /* Switch to register set 7 for normal use. */
        EL3WINDOW(7);
@@ -2063,7 +2063,6 @@ vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
                }
        }
 
-       dev->trans_start = jiffies;
 
        /* Clear the Tx status stack. */
        {
@@ -2174,7 +2173,6 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
        }
        iowrite16(DownUnstall, ioaddr + EL3_CMD);
        spin_unlock_irqrestore(&vp->lock, flags);
-       dev->trans_start = jiffies;
        return NETDEV_TX_OK;
 }
 
index f09e594..561d3d5 100644 (file)
@@ -262,7 +262,7 @@ static int lance_reset (struct net_device *dev)
 
         load_csrs (lp);
         lance_init_ring (dev);
-        dev->trans_start = jiffies;
+        dev->trans_start = jiffies; /* prevent tx timeout */
         status = init_restart_lance (lp);
 #ifdef DEBUG_DRIVER
         printk ("Lance restart=%d\n", status);
@@ -526,7 +526,7 @@ void lance_tx_timeout(struct net_device *dev)
 {
        printk("lance_tx_timeout\n");
        lance_reset(dev);
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        netif_wake_queue (dev);
 }
 EXPORT_SYMBOL_GPL(lance_tx_timeout);
@@ -574,7 +574,6 @@ int lance_start_xmit (struct sk_buff *skb, struct net_device *dev)
         outs++;
         /* Kick the lance: transmit now */
         WRITERDP(lp, LE_C0_INEA | LE_C0_TDMD);
-        dev->trans_start = jiffies;
         dev_kfree_skb (skb);
 
        spin_lock_irqsave (&lp->devlock, flags);
index 4e8d11c..cd63b97 100644 (file)
@@ -882,7 +882,6 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb,
        spin_unlock_irqrestore(&cp->lock, intr_flags);
 
        cpw8(TxPoll, NormalTxPoll);
-       dev->trans_start = jiffies;
 
        return NETDEV_TX_OK;
 }
index d0cb372..4ba7293 100644 (file)
@@ -1716,8 +1716,6 @@ static netdev_tx_t rtl8139_start_xmit (struct sk_buff *skb,
        RTL_W32_F (TxStatus0 + (entry * sizeof (u32)),
                   tp->tx_flag | max(len, (unsigned int)ETH_ZLEN));
 
-       dev->trans_start = jiffies;
-
        tp->cur_tx++;
 
        if ((tp->cur_tx - NUM_TX_DESC) == tp->dirty_tx)
index 97c5fc0..dd8dc15 100644 (file)
@@ -1050,7 +1050,7 @@ static void i596_tx_timeout (struct net_device *dev)
                lp->last_restart = dev->stats.tx_packets;
        }
 
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        netif_wake_queue (dev);
 }
 
@@ -1060,7 +1060,6 @@ static netdev_tx_t i596_start_xmit(struct sk_buff *skb, struct net_device *dev)
        struct tx_cmd *tx_cmd;
        struct i596_tbd *tbd;
        short length = skb->len;
-       dev->trans_start = jiffies;
 
        DEB(DEB_STARTTX,printk(KERN_DEBUG "%s: i596_start_xmit(%x,%p) called\n",
                                dev->name, skb->len, skb->data));
index ce0a0b8..ecaa28c 100644 (file)
@@ -525,7 +525,7 @@ static inline int lance_reset (struct net_device *dev)
        load_csrs (lp);
 
        lance_init_ring (dev);
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        netif_start_queue(dev);
 
        status = init_restart_lance (lp);
@@ -588,7 +588,6 @@ static netdev_tx_t lance_start_xmit (struct sk_buff *skb,
 
        /* Kick the lance: transmit now */
        ll->rdp = LE_C0_INEA | LE_C0_TDMD;
-       dev->trans_start = jiffies;
        dev_kfree_skb (skb);
 
        local_irq_restore(flags);
index 97d71a9..585c25f 100644 (file)
@@ -1339,8 +1339,6 @@ static netdev_tx_t amd8111e_start_xmit(struct sk_buff *skb,
        writel( VAL1 | TDMD0, lp->mmio + CMD0);
        writel( VAL2 | RDMD0,lp->mmio + CMD0);
 
-       dev->trans_start = jiffies;
-
        if(amd8111e_tx_queue_avail(lp) < 0){
                netif_stop_queue(dev);
        }
index 6f8d620..14e1d95 100644 (file)
@@ -866,7 +866,7 @@ static void cops_timeout(struct net_device *dev)
        }
        printk(KERN_WARNING "%s: Transmit timed out.\n", dev->name);
        cops_jumpstart(dev);    /* Restart the card. */
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        netif_wake_queue(dev);
 }
 
@@ -919,9 +919,8 @@ static netdev_tx_t cops_send_packet(struct sk_buff *skb,
        /* Done sending packet, update counters and cleanup. */
        dev->stats.tx_packets++;
        dev->stats.tx_bytes += skb->len;
-       dev->trans_start = jiffies;
        dev_kfree_skb (skb);
-        return NETDEV_TX_OK;
+       return NETDEV_TX_OK;
 }
 
 /*
index d8f0293..a746ba2 100644 (file)
@@ -654,7 +654,6 @@ netdev_tx_t arcnet_send_packet(struct sk_buff *skb,
                        }
                }
                retval = NETDEV_TX_OK;
-               dev->trans_start = jiffies;
                lp->next_tx = txbuf;
        } else {
                retval = NETDEV_TX_BUSY;
index fa1a235..705373a 100644 (file)
@@ -676,8 +676,6 @@ static netdev_tx_t ariadne_start_xmit(struct sk_buff *skb,
     lance->RAP = CSR0;         /* PCnet-ISA Controller Status */
     lance->RDP = INEA|TDMD;
 
-    dev->trans_start = jiffies;
-
     if (lowb(priv->tx_ring[(entry+1) % TX_RING_SIZE]->TMD1) != 0) {
        netif_stop_queue(dev);
        priv->tx_full = 1;
index a4b5b08..8c496fb 100644 (file)
@@ -469,7 +469,6 @@ am79c961_sendpacket(struct sk_buff *skb, struct net_device *dev)
 
        spin_lock_irqsave(&priv->chip_lock, flags);
        write_rreg (dev->base_addr, CSR0, CSR0_TDMD|CSR0_IENA);
-       dev->trans_start = jiffies;
        spin_unlock_irqrestore(&priv->chip_lock, flags);
 
        /*
index 0adab30..e07b314 100644 (file)
@@ -824,7 +824,6 @@ static int at91ether_start_xmit(struct sk_buff *skb, struct net_device *dev)
                /* Set length of the packet in the Transmit Control register */
                at91_emac_write(AT91_EMAC_TCR, skb->len);
 
-               dev->trans_start = jiffies;
        } else {
                printk(KERN_ERR "at91_ether.c: at91ether_start_xmit() called, but device is busy!\n");
                return NETDEV_TX_BUSY;  /* if we return anything but zero, dev.c:1055 calls kfree_skb(skb)
index 6995169..c5f6736 100644 (file)
@@ -374,8 +374,6 @@ static int ep93xx_xmit(struct sk_buff *skb, struct net_device *dev)
                                skb->len, DMA_TO_DEVICE);
        dev_kfree_skb(skb);
 
-       dev->trans_start = jiffies;
-
        spin_lock_irq(&ep->tx_pending_lock);
        ep->tx_pending++;
        if (ep->tx_pending == TX_QUEUE_ENTRIES)
index e47c0d9..b17ab51 100644 (file)
@@ -736,7 +736,6 @@ ether1_sendpacket (struct sk_buff *skb, struct net_device *dev)
        local_irq_restore(flags);
 
        /* handle transmit */
-       dev->trans_start = jiffies;
 
        /* check to see if we have room for a full sized ether frame */
        tmp = priv(dev)->tx_head;
index d9de9bc..1361b73 100644 (file)
@@ -529,7 +529,6 @@ ether3_sendpacket(struct sk_buff *skb, struct net_device *dev)
                return NETDEV_TX_BUSY;  /* unable to queue */
        }
 
-       dev->trans_start = jiffies;
        ptr              = 0x600 * priv(dev)->tx_head;
        priv(dev)->tx_head = next_ptr;
        next_ptr        *= 0x600;
index 7800d7d..24df032 100644 (file)
@@ -708,7 +708,6 @@ static int eth_xmit(struct sk_buff *skb, struct net_device *dev)
        /* NPE firmware pads short frames with zeros internally */
        wmb();
        queue_put_desc(TX_QUEUE(port->id), tx_desc_phys(port, n), desc);
-       dev->trans_start = jiffies;
 
        if (qmgr_stat_below_low_watermark(txreadyq)) { /* empty */
 #if DEBUG_TX
index 6404704..54c6d84 100644 (file)
@@ -1302,8 +1302,6 @@ ks8695_start_xmit(struct sk_buff *skb, struct net_device *ndev)
        if (++ksp->tx_ring_used == MAX_TX_DESC)
                netif_stop_queue(ndev);
 
-       ndev->trans_start = jiffies;
-
        /* Kick the TX DMA in case it decided to go IDLE */
        ks8695_writereg(ksp, KS8695_DTSC, 0);
 
index 2491934..2e85246 100644 (file)
@@ -483,7 +483,7 @@ static void w90p910_reset_mac(struct net_device *dev)
 
        w90p910_init_desc(dev);
 
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        ether->cur_tx = 0x0;
        ether->finish_tx = 0x0;
        ether->cur_rx = 0x0;
@@ -497,7 +497,7 @@ static void w90p910_reset_mac(struct net_device *dev)
        w90p910_trigger_tx(dev);
        w90p910_trigger_rx(dev);
 
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
 
        if (netif_queue_stopped(dev))
                netif_wake_queue(dev);
@@ -634,8 +634,6 @@ static int w90p910_send_frame(struct net_device *dev,
 
        txbd = &ether->tdesc->desclist[ether->cur_tx];
 
-       dev->trans_start = jiffies;
-
        if (txbd->mode & TX_OWEN_DMA)
                netif_stop_queue(dev);
 
index 332f980..861f07a 100644 (file)
@@ -583,7 +583,7 @@ static void net_tx_timeout (struct net_device *dev)
        outb (0x00, ioaddr + TX_START);
        outb (0x03, ioaddr + COL16CNTL);
 
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
 
        lp->tx_started = 0;
        lp->tx_queue_ready = 1;
@@ -636,7 +636,6 @@ static netdev_tx_t net_send_packet (struct sk_buff *skb,
                outb (0x80 | lp->tx_queue, ioaddr + TX_START);
                lp->tx_queue = 0;
                lp->tx_queue_len = 0;
-               dev->trans_start = jiffies;
                lp->tx_started = 1;
                netif_start_queue (dev);
        } else if (lp->tx_queue_len < 4096 - 1502)
index a8686bf..b57d7de 100644 (file)
@@ -767,8 +767,8 @@ static void lance_tx_timeout (struct net_device *dev)
        /* lance_restart, essentially */
        lance_init_ring(dev);
        REGA( CSR0 ) = CSR0_INEA | CSR0_INIT | CSR0_STRT;
-       dev->trans_start = jiffies;
-       netif_wake_queue (dev);
+       dev->trans_start = jiffies; /* prevent tx timeout */
+       netif_wake_queue(dev);
 }
 
 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
@@ -836,7 +836,6 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
 
        /* Trigger an immediate send poll. */
        DREG = CSR0_INEA | CSR0_TDMD;
-       dev->trans_start = jiffies;
 
        if ((MEM->tx_head[(entry+1) & TX_RING_MOD_MASK].flag & TMD1_OWN) ==
                TMD1_OWN_HOST)
index fee9cf6..8da8738 100644 (file)
@@ -892,7 +892,6 @@ static netdev_tx_t atl2_xmit_frame(struct sk_buff *skb,
                (adapter->txd_write_ptr >> 2));
 
        mmiowb();
-       netdev->trans_start = jiffies;
        dev_kfree_skb_any(skb);
        return NETDEV_TX_OK;
 }
index 2bd1a5c..75ff0c5 100644 (file)
@@ -547,7 +547,7 @@ static void tx_timeout(struct net_device *dev)
        dev->stats.tx_errors++;
        /* Try to restart the adapter. */
        hardware_init(dev);
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        netif_wake_queue(dev);
        dev->stats.tx_errors++;
 }
@@ -586,7 +586,6 @@ static netdev_tx_t atp_send_packet(struct sk_buff *skb,
        write_reg(ioaddr, IMR, ISR_RxOK | ISR_TxErr | ISR_TxOK);
        write_reg_high(ioaddr, IMR, ISRh_RxErr);
 
-       dev->trans_start = jiffies;
        dev_kfree_skb (skb);
        return NETDEV_TX_OK;
 }
index 7abb2c8..ece6128 100644 (file)
@@ -924,7 +924,6 @@ static netdev_tx_t au1000_tx(struct sk_buff *skb, struct net_device *dev)
        au_sync();
        dev_kfree_skb(skb);
        aup->tx_head = (aup->tx_head + 1) & (NUM_TX_DMA - 1);
-       dev->trans_start = jiffies;
        return NETDEV_TX_OK;
 }
 
@@ -937,7 +936,7 @@ static void au1000_tx_timeout(struct net_device *dev)
        netdev_err(dev, "au1000_tx_timeout: dev=%p\n", dev);
        au1000_reset_mac(dev);
        au1000_init(dev);
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        netif_wake_queue(dev);
 }
 
index 4582721..293f9c1 100644 (file)
@@ -1014,8 +1014,6 @@ static netdev_tx_t b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
        if (TX_BUFFS_AVAIL(bp) < 1)
                netif_stop_queue(dev);
 
-       dev->trans_start = jiffies;
-
 out_unlock:
        spin_unlock_irqrestore(&bp->lock, flags);
 
index f48ba80..faf5add 100644 (file)
@@ -565,7 +565,6 @@ static int bcm_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        priv->stats.tx_bytes += skb->len;
        priv->stats.tx_packets++;
-       dev->trans_start = jiffies;
        ret = NETDEV_TX_OK;
 
 out_unlock:
index c488cea..b0207f0 100644 (file)
@@ -654,7 +654,6 @@ static int bfin_mac_hard_start_xmit(struct sk_buff *skb,
 out:
        adjust_tx_list();
        current_tx_ptr = current_tx_ptr->next;
-       dev->trans_start = jiffies;
        dev->stats.tx_packets++;
        dev->stats.tx_bytes += (skb->len);
        return NETDEV_TX_OK;
@@ -805,7 +804,7 @@ static void bfin_mac_timeout(struct net_device *dev)
        bfin_mac_enable();
 
        /* We can accept TX packets again */
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        netif_wake_queue(dev);
 }
 
index 5f98348..2d8bd86 100644 (file)
@@ -375,7 +375,6 @@ static netdev_tx_t at91_start_xmit(struct sk_buff *skb, struct net_device *dev)
        at91_write(priv, AT91_MCR(mb), reg_mcr);
 
        stats->tx_bytes += cf->can_dlc;
-       dev->trans_start = jiffies;
 
        /* _NOTE_: substract AT91_MB_TX_FIRST offset from mb! */
        can_put_echo_skb(skb, dev, mb - AT91_MB_TX_FIRST);
index d77264a..b6e890d 100644 (file)
@@ -269,8 +269,6 @@ static int bfin_can_start_xmit(struct sk_buff *skb, struct net_device *dev)
        /* fill data length code */
        bfin_write16(&reg->chl[TRANSMIT_CHL].dlc, dlc);
 
-       dev->trans_start = jiffies;
-
        can_put_echo_skb(skb, dev, 0);
 
        /* set transmit request */
index 8431eb0..b11a0cb 100644 (file)
@@ -475,7 +475,6 @@ static netdev_tx_t mcp251x_hard_start_xmit(struct sk_buff *skb,
 
        netif_stop_queue(net);
        priv->tx_skb = skb;
-       net->trans_start = jiffies;
        queue_work(priv->wq, &priv->tx_work);
 
        return NETDEV_TX_OK;
index 618c112..24b5861 100644 (file)
@@ -292,8 +292,6 @@ static netdev_tx_t sja1000_start_xmit(struct sk_buff *skb,
        for (i = 0; i < dlc; i++)
                priv->write_reg(priv, dreg++, cf->data[i]);
 
-       dev->trans_start = jiffies;
-
        can_put_echo_skb(skb, dev, 0);
 
        priv->write_reg(priv, REG_CMR, CMD_TR);
index bd857a2..6d76236 100644 (file)
@@ -2889,7 +2889,6 @@ static netdev_tx_t cas_start_xmit(struct sk_buff *skb, struct net_device *dev)
         */
        if (cas_xmit_tx_ringN(cp, ring++ & N_TX_RINGS_MASK, skb))
                return NETDEV_TX_BUSY;
-       dev->trans_start = jiffies;
        return NETDEV_TX_OK;
 }
 
index bdfff78..3c58db5 100644 (file)
@@ -579,7 +579,6 @@ static int cpmac_start_xmit(struct sk_buff *skb, struct net_device *dev)
        }
 
        spin_lock(&priv->lock);
-       dev->trans_start = jiffies;
        spin_unlock(&priv->lock);
        desc->dataflags = CPMAC_SOP | CPMAC_EOP | CPMAC_OWN;
        desc->skb = skb;
index f49ad8e..7e00027 100644 (file)
@@ -1108,7 +1108,7 @@ e100_send_packet(struct sk_buff *skb, struct net_device *dev)
 
        myNextTxDesc->skb = skb;
 
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */
 
        e100_hardware_send_packet(np, buf, skb->len);
 
index 4c38491..2281ebc 100644 (file)
@@ -1554,7 +1554,6 @@ static netdev_tx_t net_send_packet(struct sk_buff *skb,struct net_device *dev)
        writewords(dev->base_addr, TX_FRAME_PORT,skb->data,(skb->len+1) >>1);
        spin_unlock_irqrestore(&lp->lock, flags);
        lp->stats.tx_bytes += skb->len;
-       dev->trans_start = jiffies;
        dev_kfree_skb (skb);
 
        /*
index 1f9df5c..08e82b1 100644 (file)
@@ -1468,7 +1468,6 @@ static int emac_dev_xmit(struct sk_buff *skb, struct net_device *ndev)
        tx_buf.length = skb->len;
        tx_buf.buf_token = (void *)skb;
        tx_buf.data_ptr = skb->data;
-       ndev->trans_start = jiffies;
        ret_code = emac_send(priv, &tx_packet, EMAC_DEF_TX_CH);
        if (unlikely(ret_code != 0)) {
                if (ret_code == EMAC_ERR_TX_OUT_OF_BD) {
index 6b13f4f..23a6539 100644 (file)
@@ -166,8 +166,8 @@ static int de600_start_xmit(struct sk_buff *skb, struct net_device *dev)
        int     i;
 
        if (free_tx_pages <= 0) {       /* Do timeouts, to avoid hangs. */
-               tickssofar = jiffies - dev->trans_start;
-               if (tickssofar < 5)
+               tickssofar = jiffies - dev_trans_start(dev);
+               if (tickssofar < HZ/20)
                        return NETDEV_TX_BUSY;
                /* else */
                printk(KERN_WARNING "%s: transmit timed out (%d), %s?\n", dev->name, tickssofar, "network cable problem");
index a0a6830..f3650fd 100644 (file)
@@ -535,7 +535,6 @@ static int de620_start_xmit(struct sk_buff *skb, struct net_device *dev)
        }
        de620_write_block(dev, buffer, skb->len, len-skb->len);
 
-       dev->trans_start = jiffies;
        if(!(using_txbuf == (TXBF0 | TXBF1)))
                netif_wake_queue(dev);
 
index fb3f098..74abe19 100644 (file)
@@ -874,7 +874,7 @@ static inline int lance_reset(struct net_device *dev)
 
        lance_init_ring(dev);
        load_csrs(lp);
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        status = init_restart_lance(lp);
        return status;
 }
@@ -930,7 +930,6 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        spin_unlock_irqrestore(&lp->lock, flags);
 
-       dev->trans_start = jiffies;
        dev_kfree_skb(skb);
 
        return NETDEV_TX_OK;
index a88300a..38d4d9e 100644 (file)
@@ -921,7 +921,7 @@ static void depca_tx_timeout(struct net_device *dev)
        STOP_DEPCA;
        depca_init_ring(dev);
        LoadCSRs(dev);
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        netif_wake_queue(dev);
        InitRestartDepca(dev);
 }
@@ -954,7 +954,6 @@ static netdev_tx_t depca_start_xmit(struct sk_buff *skb,
                        outw(CSR0, DEPCA_ADDR);
                        outw(INEA | TDMD, DEPCA_DATA);
 
-                       dev->trans_start = jiffies;
                        dev_kfree_skb(skb);
                }
                if (TX_BUFFS_AVAIL)
index a818ea9..254b6f7 100644 (file)
@@ -769,7 +769,7 @@ dm9000_hash_table(struct net_device *dev)
 }
 
 /*
- * Initilize dm9000 board
+ * Initialize dm9000 board
  */
 static void
 dm9000_init_dm9000(struct net_device *dev)
@@ -825,7 +825,7 @@ dm9000_init_dm9000(struct net_device *dev)
        /* Init Driver variable */
        db->tx_pkt_cnt = 0;
        db->queue_pkt_len = 0;
-       dev->trans_start = 0;
+       dev->trans_start = jiffies;
 }
 
 /* Our watchdog timed out. Called by the networking layer */
@@ -843,7 +843,7 @@ static void dm9000_timeout(struct net_device *dev)
        dm9000_reset(db);
        dm9000_init_dm9000(dev);
        /* We can accept TX packets again */
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        netif_wake_queue(dev);
 
        /* Restore previous register address */
index d51a83e..8b0f50b 100644 (file)
@@ -594,8 +594,6 @@ static netdev_tx_t dnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        spin_unlock_irqrestore(&bp->lock, flags);
 
-       dev->trans_start = jiffies;
-
        return NETDEV_TX_OK;
 }
 
index ef97bfc..b194bad 100644 (file)
@@ -1764,7 +1764,6 @@ static netdev_tx_t e100_xmit_frame(struct sk_buff *skb,
                return NETDEV_TX_BUSY;
        }
 
-       netdev->trans_start = jiffies;
        return NETDEV_TX_OK;
 }
 
index eed65d8..8d97f16 100644 (file)
@@ -1161,8 +1161,7 @@ static netdev_tx_t eepro_send_packet(struct sk_buff *skb,
                        /* we won't wake queue here because we're out of space */
                        dev->stats.tx_dropped++;
                else {
-               dev->stats.tx_bytes+=skb->len;
-               dev->trans_start = jiffies;
+                       dev->stats.tx_bytes+=skb->len;
                        netif_wake_queue(dev);
                }
 
index c31dd06..43c9c9c 100644 (file)
@@ -543,7 +543,7 @@ static void unstick_cu(struct net_device *dev)
 
        if (lp->started)
        {
-               if (time_after(jiffies, dev->trans_start + 50))
+               if (time_after(jiffies, dev_trans_start(dev) + HZ/2))
                {
                        if (lp->tx_link==lp->last_tx_restart)
                        {
@@ -1018,7 +1018,7 @@ static void eexp_hw_tx_pio(struct net_device *dev, unsigned short *buf,
        outw(lp->tx_head+0x16, ioaddr + DATAPORT);
        outw(0, ioaddr + DATAPORT);
 
-        outsw(ioaddr + DATAPORT, buf, (len+1)>>1);
+       outsw(ioaddr + DATAPORT, buf, (len+1)>>1);
 
        outw(lp->tx_tail+0xc, ioaddr + WRITE_PTR);
        outw(lp->tx_head, ioaddr + DATAPORT);
index 3977481..33a41e2 100644 (file)
@@ -2241,7 +2241,7 @@ static int ehea_start_xmit(struct sk_buff *skb, struct net_device *dev)
                }
                spin_unlock_irqrestore(&pr->netif_queue, flags);
        }
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */
        spin_unlock(&pr->xmit_lock);
 
        return NETDEV_TX_OK;
index ff27f72..112c5aa 100644 (file)
@@ -1293,8 +1293,6 @@ static netdev_tx_t enc28j60_send_packet(struct sk_buff *skb,
         */
        netif_stop_queue(dev);
 
-       /* save the timestamp */
-       priv->netdev->trans_start = jiffies;
        /* Remember the skb for deferred processing */
        priv->tx_skb = skb;
        schedule_work(&priv->tx_work);
index 8b5a203..a48da2d 100644 (file)
@@ -908,7 +908,7 @@ static void epic_tx_timeout(struct net_device *dev)
                outl(TxQueued, dev->base_addr + COMMAND);
        }
 
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        ep->stats.tx_errors++;
        if (!ep->tx_full)
                netif_wake_queue(dev);
@@ -1006,7 +1006,6 @@ static netdev_tx_t epic_start_xmit(struct sk_buff *skb, struct net_device *dev)
        /* Trigger an immediate transmit demand. */
        outl(TxQueued, dev->base_addr + COMMAND);
 
-       dev->trans_start = jiffies;
        if (debug > 4)
                printk(KERN_DEBUG "%s: Queued Tx packet size %d to slot %d, "
                           "flag %2.2x Tx status %8.8x.\n",
index d4e24f0..874973f 100644 (file)
@@ -1027,7 +1027,7 @@ static void eth16i_timeout(struct net_device *dev)
        inw(ioaddr + TX_STATUS_REG),  (inb(ioaddr + TX_STATUS_REG) & TX_DONE) ?
                       "IRQ conflict" : "network cable problem");
 
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
 
        /* Let's dump all registers */
        if(eth16i_debug > 0) {
@@ -1047,7 +1047,7 @@ static void eth16i_timeout(struct net_device *dev)
        }
        dev->stats.tx_errors++;
        eth16i_reset(dev);
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
        netif_wake_queue(dev);
 }
@@ -1109,7 +1109,6 @@ static netdev_tx_t eth16i_tx(struct sk_buff *skb, struct net_device *dev)
                outb(TX_START | lp->tx_queue, ioaddr + TRANSMIT_START_REG);
                lp->tx_queue = 0;
                lp->tx_queue_len = 0;
-               dev->trans_start = jiffies;
                lp->tx_started = 1;
                netif_wake_queue(dev);
        }
index ad1bc73..14cbde5 100644 (file)
@@ -851,7 +851,6 @@ static netdev_tx_t ethoc_start_xmit(struct sk_buff *skb, struct net_device *dev)
                netif_stop_queue(dev);
        }
 
-       dev->trans_start = jiffies;
        spin_unlock_irq(&priv->lock);
 out:
        dev_kfree_skb(skb);
index 11ba70f..99eb56b 100644 (file)
@@ -757,7 +757,7 @@ static void ewrk3_timeout(struct net_device *dev)
                 */
                ENABLE_IRQs;
 
-               dev->trans_start = jiffies;
+               dev->trans_start = jiffies; /* prevent tx timeout */
                netif_wake_queue(dev);
        }
 }
@@ -862,7 +862,6 @@ static netdev_tx_t ewrk3_queue_pkt(struct sk_buff *skb, struct net_device *dev)
        spin_unlock_irq (&lp->hw_lock);
 
        dev->stats.tx_bytes += skb->len;
-       dev->trans_start = jiffies;
        dev_kfree_skb (skb);
 
        /* Check for free resources: stop Tx queue if there are none */
index 51b738d..15f4f8d 100644 (file)
@@ -1233,7 +1233,7 @@ static void fealnx_tx_timeout(struct net_device *dev)
 
        spin_unlock_irqrestore(&np->lock, flags);
 
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        np->stats.tx_errors++;
        netif_wake_queue(dev); /* or .._start_.. ?? */
 }
@@ -1374,7 +1374,6 @@ static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev)
                netif_stop_queue(dev);
        ++np->really_tx_count;
        iowrite32(0, np->mem + TXPDR);
-       dev->trans_start = jiffies;
 
        spin_unlock_irqrestore(&np->lock, flags);
        return NETDEV_TX_OK;
index 2b1651a..47da519 100644 (file)
@@ -275,8 +275,6 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
                        | BD_ENET_TX_LAST | BD_ENET_TX_TC);
        bdp->cbd_sc = status;
 
-       dev->trans_start = jiffies;
-
        /* Trigger transmission start */
        writel(0, fep->hwp + FEC_X_DES_ACTIVE);
 
index 0376c3e..221f440 100644 (file)
@@ -327,7 +327,6 @@ static int mpc52xx_fec_start_xmit(struct sk_buff *skb, struct net_device *dev)
        }
 
        spin_lock_irqsave(&priv->lock, flags);
-       dev->trans_start = jiffies;
 
        bd = (struct bcom_fec_bd *)
                bcom_prepare_next_buffer(priv->tx_dmatsk);
index e282d0a..268ea4d 100644 (file)
@@ -2214,7 +2214,6 @@ static netdev_tx_t nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
                dprintk("\n");
        }
 
-       dev->trans_start = jiffies;
        writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl);
        return NETDEV_TX_OK;
 }
@@ -2369,7 +2368,6 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb,
                dprintk("\n");
        }
 
-       dev->trans_start = jiffies;
        writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl);
        return NETDEV_TX_OK;
 }
index 0770e2f..0fb0fef 100644 (file)
@@ -674,8 +674,6 @@ static int fs_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
                                skb->data, skb->len, DMA_TO_DEVICE));
        CBDW_DATLEN(bdp, skb->len);
 
-       dev->trans_start = jiffies;
-
        /*
         * If this was the last BD in the ring, start at the beginning again.
         */
index 5267c27..11d8cae 100644 (file)
@@ -1738,7 +1738,7 @@ void gfar_start(struct net_device *dev)
                gfar_write(&regs->imask, IMASK_DEFAULT);
        }
 
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
 }
 
 void gfar_configure_coalescing(struct gfar_private *priv,
@@ -2161,8 +2161,6 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
        /* reduce TxBD free count */
        tx_queue->num_txbdfree -= (nr_txbds);
 
-       dev->trans_start = jiffies;
-
        /* If the next BD still needs to be cleaned up, then the bds
           are full.  We need to tell the kernel to stop sending us stuff. */
        if (!tx_queue->num_txbdfree) {
index 0f3f6c2..68e5ac8 100644 (file)
@@ -1102,7 +1102,7 @@ static int hp100_open(struct net_device *dev)
                return -EAGAIN;
        }
 
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        netif_start_queue(dev);
 
        lp->lan_type = hp100_sense_lan(dev);
@@ -1510,7 +1510,7 @@ static netdev_tx_t hp100_start_xmit_bm(struct sk_buff *skb,
                printk("hp100: %s: start_xmit_bm: No TX PDL available.\n", dev->name);
 #endif
                /* not waited long enough since last tx? */
-               if (time_before(jiffies, dev->trans_start + HZ))
+               if (time_before(jiffies, dev_trans_start(dev) + HZ))
                        goto drop;
 
                if (hp100_check_lan(dev))
@@ -1547,7 +1547,6 @@ static netdev_tx_t hp100_start_xmit_bm(struct sk_buff *skb,
                        }
                }
 
-               dev->trans_start = jiffies;
                goto drop;
        }
 
@@ -1585,7 +1584,6 @@ static netdev_tx_t hp100_start_xmit_bm(struct sk_buff *skb,
        /* Update statistics */
        lp->stats.tx_packets++;
        lp->stats.tx_bytes += skb->len;
-       dev->trans_start = jiffies;
 
        return NETDEV_TX_OK;
 
@@ -1663,7 +1661,7 @@ static netdev_tx_t hp100_start_xmit(struct sk_buff *skb,
                printk("hp100: %s: start_xmit: tx free mem = 0x%x\n", dev->name, i);
 #endif
                /* not waited long enough since last failed tx try? */
-               if (time_before(jiffies, dev->trans_start + HZ)) {
+               if (time_before(jiffies, dev_trans_start(dev) + HZ)) {
 #ifdef HP100_DEBUG
                        printk("hp100: %s: trans_start timing problem\n",
                               dev->name);
@@ -1701,7 +1699,6 @@ static netdev_tx_t hp100_start_xmit(struct sk_buff *skb,
                                mdelay(1);
                        }
                }
-               dev->trans_start = jiffies;
                goto drop;
        }
 
@@ -1745,7 +1742,6 @@ static netdev_tx_t hp100_start_xmit(struct sk_buff *skb,
 
        lp->stats.tx_packets++;
        lp->stats.tx_bytes += skb->len;
-       dev->trans_start = jiffies;
        hp100_ints_on();
        spin_unlock_irqrestore(&lp->lock, flags);
 
index 0d2c3ac..092fb9d 100644 (file)
@@ -957,7 +957,7 @@ static netdev_tx_t ibmveth_start_xmit(struct sk_buff *skb,
        } else {
                tx_packets++;
                tx_bytes += skb->len;
-               netdev->trans_start = jiffies;
+               netdev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */
        }
 
        if (!used_bounce)
index f4081c0..ab9f675 100644 (file)
@@ -182,7 +182,6 @@ static netdev_tx_t ifb_xmit(struct sk_buff *skb, struct net_device *dev)
                netif_stop_queue(dev);
        }
 
-       dev->trans_start = jiffies;
        skb_queue_tail(&dp->rq, skb);
        if (!dp->tasklet_pending) {
                dp->tasklet_pending = 1;
index 091ea33..e3b5e94 100644 (file)
@@ -1503,7 +1503,6 @@ static int ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        BARRIER();
 
-       dev->trans_start = jiffies;
        ip->tx_skbs[produce] = skb;                     /* Remember skb */
        produce = (produce + 1) & 127;
        ip->tx_pi = produce;
index b5cbd39..a3d696a 100644 (file)
@@ -546,7 +546,6 @@ static int au1k_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
 
        dev_kfree_skb(skb);
        aup->tx_head = (aup->tx_head + 1) & (NUM_IR_DESC - 1);
-       dev->trans_start = jiffies;
        return NETDEV_TX_OK;
 }
 
index b7e6625..48bd5ec 100644 (file)
@@ -1002,8 +1002,6 @@ toshoboe_hard_xmit (struct sk_buff *skb, struct net_device *dev)
 
   toshoboe_checkstuck (self);
 
-  dev->trans_start = jiffies;
-
  /* Check if we need to change the speed */
   /* But not now. Wait after transmission if mtt not required */
   speed=irda_get_next_speed(skb);
index 1a54f6b..c192c31 100644 (file)
@@ -556,7 +556,6 @@ static int pxa_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
        }
 
        dev_kfree_skb(skb);
-       dev->trans_start = jiffies;
        return NETDEV_TX_OK;
 }
 
index 1dcdce0..da27050 100644 (file)
@@ -715,8 +715,6 @@ static int sa1100_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
                Ser2HSCR0 = si->hscr0 | HSCR0_HSSP | HSCR0_TXE;
        }
 
-       dev->trans_start = jiffies;
-
        return NETDEV_TX_OK;
 }
 
index de91cd1..1b051da 100644 (file)
@@ -655,7 +655,6 @@ static netdev_tx_t sirdev_hard_xmit(struct sk_buff *skb,
 
        if (likely(actual > 0)) {
                dev->tx_skb = skb;
-               ndev->trans_start = jiffies;
                dev->tx_buff.data += actual;
                dev->tx_buff.len -= actual;
        }
index 6af84d8..35e4e44 100644 (file)
@@ -868,7 +868,7 @@ static void smsc_ircc_timeout(struct net_device *dev)
        spin_lock_irqsave(&self->lock, flags);
        smsc_ircc_sir_start(self);
        smsc_ircc_change_speed(self, self->io.speed);
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        netif_wake_queue(dev);
        spin_unlock_irqrestore(&self->lock, flags);
 }
index e145052..c3d0738 100644 (file)
@@ -1037,7 +1037,6 @@ static netdev_tx_t vlsi_hard_start_xmit(struct sk_buff *skb,
                wmb();
                outw(0, iobase+VLSI_PIO_PROMPT);
        }
-       ndev->trans_start = jiffies;
 
        if (ring_put(r) == NULL) {
                netif_stop_queue(ndev);
index cb0cb75..1f9c3f0 100644 (file)
@@ -515,7 +515,6 @@ static netdev_tx_t w83977af_hard_xmit(struct sk_buff *skb,
                /* Check for empty frame */
                if (!skb->len) {
                        w83977af_change_speed(self, speed); 
-                       dev->trans_start = jiffies;
                        dev_kfree_skb(skb);
                        return NETDEV_TX_OK;
                } else
@@ -549,7 +548,6 @@ static netdev_tx_t w83977af_hard_xmit(struct sk_buff *skb,
                switch_bank(iobase, SET0);
                outb(ICR_ETXTHI, iobase+ICR);
        }
-       dev->trans_start = jiffies;
        dev_kfree_skb(skb);
 
        /* Restore set register */
index 460c37f..40f47b8 100644 (file)
@@ -3184,8 +3184,6 @@ static int ixgbevf_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
                         ixgbevf_tx_map(adapter, tx_ring, skb, tx_flags, first),
                         skb->len, hdr_len);
 
-       netdev->trans_start = jiffies;
-
        ixgbevf_maybe_stop_tx(netdev, tx_ring, DESC_NEEDED);
 
        return NETDEV_TX_OK;
index d5932ca..78ddd8b 100644 (file)
@@ -64,8 +64,6 @@ static int ixpdev_xmit(struct sk_buff *skb, struct net_device *dev)
        ixp2000_reg_write(RING_TX_PENDING,
                TX_BUF_DESC_BASE + (entry * sizeof(struct ixpdev_tx_desc)));
 
-       dev->trans_start = jiffies;
-
        local_irq_save(flags);
        ip->tx_queue_entries++;
        if (ip->tx_queue_entries == TX_BUF_COUNT_PER_CHAN)
index 7b94476..21f8ada 100644 (file)
@@ -945,7 +945,7 @@ static void lance_tx_timeout (struct net_device *dev)
 #endif
        lance_restart (dev, 0x0043, 1);
 
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        netif_wake_queue (dev);
 }
 
@@ -1011,8 +1011,6 @@ static netdev_tx_t lance_start_xmit(struct sk_buff *skb,
        outw(0x0000, ioaddr+LANCE_ADDR);
        outw(0x0048, ioaddr+LANCE_DATA);
 
-       dev->trans_start = jiffies;
-
        if ((lp->cur_tx - lp->dirty_tx) >= TX_RING_SIZE)
                netif_stop_queue(dev);
 
index 61c38ab..de856d8 100644 (file)
@@ -963,7 +963,7 @@ static void i596_tx_timeout (struct net_device *dev)
                lp->last_restart = dev->stats.tx_packets;
        }
 
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        netif_wake_queue (dev);
 }
 
@@ -974,7 +974,6 @@ static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev)
        struct tx_cmd *tx_cmd;
        struct i596_tbd *tbd;
        short length = skb->len;
-       dev->trans_start = jiffies;
 
        DEB(DEB_STARTTX, printk(KERN_DEBUG
                                "%s: i596_start_xmit(%x,%p) called\n",
index 770b606..64d51d6 100644 (file)
@@ -257,7 +257,7 @@ static void __ei_tx_timeout(struct net_device *dev)
 {
        unsigned long e8390_base = dev->base_addr;
        struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
-       int txsr, isr, tickssofar = jiffies - dev->trans_start;
+       int txsr, isr, tickssofar = jiffies - dev_trans_start(dev);
        unsigned long flags;
 
        dev->stats.tx_errors++;
@@ -386,7 +386,6 @@ static netdev_tx_t __ei_start_xmit(struct sk_buff *skb,
        {
                ei_local->txing = 1;
                NS8390_trigger_send(dev, send_length, output_page);
-               dev->trans_start = jiffies;
                if (output_page == ei_local->tx_start_page)
                {
                        ei_local->tx1 = -1;
index 78c9a2e..b59b24d 100644 (file)
@@ -527,7 +527,7 @@ static void temac_device_reset(struct net_device *ndev)
                dev_err(&ndev->dev, "Error setting TEMAC options\n");
 
        /* Init Driver variable */
-       ndev->trans_start = 0;
+       ndev->trans_start = jiffies; /* prevent tx timeout */
 }
 
 void temac_adjust_link(struct net_device *ndev)
index 72379c5..3df046a 100644 (file)
@@ -875,8 +875,6 @@ static netdev_tx_t i596_start_xmit (struct sk_buff *skb, struct net_device *dev)
                length = ETH_ZLEN;
        }
 
-       dev->trans_start = jiffies;
-
        tx_cmd = kmalloc((sizeof (struct tx_cmd) + sizeof (struct i596_tbd)), GFP_ATOMIC);
        if (tx_cmd == NULL) {
                printk(KERN_WARNING "%s: i596_xmit Memory squeeze, dropping packet.\n", dev->name);
index c0876e9..69fa4ef 100644 (file)
@@ -408,7 +408,6 @@ net_send_packet(struct sk_buff *skb, struct net_device *dev)
                                  skb->len+1);
 
        local_irq_restore(flags);
-       dev->trans_start = jiffies;
        dev_kfree_skb (skb);
 
        return NETDEV_TX_OK;
index cf7debc..40797fb 100644 (file)
@@ -666,8 +666,6 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        spin_unlock_irqrestore(&bp->lock, flags);
 
-       dev->trans_start = jiffies;
-
        return NETDEV_TX_OK;
 }
 
index a6e19fc..c685a46 100644 (file)
@@ -488,7 +488,6 @@ static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev)
 
        dev_kfree_skb(skb);
 
-       dev->trans_start = jiffies;
        return NETDEV_TX_OK;
 }
 
index 9f72cb4..16a3594 100644 (file)
@@ -746,7 +746,7 @@ static void meth_tx_timeout(struct net_device *dev)
        /* Enable interrupt */
        spin_unlock_irqrestore(&priv->meth_lock, flags);
 
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        netif_wake_queue(dev);
 
        return;
index 4ee9d04..1f724e5 100644 (file)
@@ -882,7 +882,6 @@ static netdev_tx_t mv643xx_eth_xmit(struct sk_buff *skb, struct net_device *dev)
 
                txq->tx_bytes += skb->len;
                txq->tx_packets++;
-               dev->trans_start = jiffies;
 
                entries_left = txq->tx_ring_size - txq->tx_desc_count;
                if (entries_left < MAX_SKB_FRAGS + 1)
index 9250bf6..2a17b50 100644 (file)
@@ -1905,7 +1905,7 @@ static void ns_tx_timeout(struct net_device *dev)
        spin_unlock_irq(&np->lock);
        enable_irq(dev->irq);
 
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        np->stats.tx_errors++;
        netif_wake_queue(dev);
 }
@@ -2119,8 +2119,6 @@ static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev)
        }
        spin_unlock_irqrestore(&np->lock, flags);
 
-       dev->trans_start = jiffies;
-
        if (netif_msg_tx_queued(np)) {
                printk(KERN_DEBUG "%s: Transmit frame #%d queued in slot %d.\n",
                        dev->name, np->cur_tx, entry);
index 6477029..2e4b421 100644 (file)
@@ -126,7 +126,6 @@ netx_eth_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev)
                   FIFO_PTR_FRAMENO(1) |
                   FIFO_PTR_FRAMELEN(len));
 
-       ndev->trans_start = jiffies;
        ndev->stats.tx_packets++;
        ndev->stats.tx_bytes += skb->len;
 
index 3892330..f80b501 100644 (file)
@@ -444,7 +444,7 @@ static void ni5010_timeout(struct net_device *dev)
        /* Try to restart the adaptor. */
        /* FIXME: Give it a real kick here */
        chipset_init(dev, 1);
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        netif_wake_queue(dev);
 }
 
@@ -460,7 +460,6 @@ static int ni5010_send_packet(struct sk_buff *skb, struct net_device *dev)
 
        netif_stop_queue(dev);
        hardware_send_packet(dev, (unsigned char *)skb->data, skb->len, length-skb->len);
-       dev->trans_start = jiffies;
        dev_kfree_skb (skb);
        return NETDEV_TX_OK;
 }
index b7837eb..9bddb5f 100644 (file)
@@ -1147,7 +1147,7 @@ static void ni52_timeout(struct net_device *dev)
                writeb(CUC_START, &p->scb->cmd_cuc);
                ni_attn586();
                wait_for_scb_cmd(dev);
-               dev->trans_start = jiffies;
+               dev->trans_start = jiffies; /* prevent tx timeout */
                return 0;
        }
 #endif
@@ -1165,7 +1165,7 @@ static void ni52_timeout(struct net_device *dev)
                ni52_close(dev);
                ni52_open(dev);
        }
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
 }
 
 /******************************************************
@@ -1218,7 +1218,6 @@ static netdev_tx_t ni52_send_packet(struct sk_buff *skb,
                        writeb(CUC_START, &p->scb->cmd_cuc);
                }
                ni_attn586();
-               dev->trans_start = jiffies;
                if (!i)
                        dev_kfree_skb(skb);
                wait_for_scb_cmd(dev);
@@ -1240,7 +1239,6 @@ static netdev_tx_t ni52_send_packet(struct sk_buff *skb,
        writew(0, &p->nop_cmds[next_nop]->cmd_status);
 
        writew(make16(p->xmit_cmds[0]), &p->nop_cmds[p->nop_point]->cmd_link);
-       dev->trans_start = jiffies;
        p->nop_point = next_nop;
        dev_kfree_skb(skb);
 #      endif
@@ -1256,7 +1254,6 @@ static netdev_tx_t ni52_send_packet(struct sk_buff *skb,
        writew(0, &p->nop_cmds[next_nop]->cmd_status);
        writew(make16(p->xmit_cmds[p->xmit_count]),
                                &p->nop_cmds[p->xmit_count]->cmd_link);
-       dev->trans_start = jiffies;
        p->xmit_count = next_nop;
        {
                unsigned long flags;
index 9225c76..da228a0 100644 (file)
@@ -784,7 +784,7 @@ static void ni65_stop_start(struct net_device *dev,struct priv *p)
                if(!p->lock)
                        if (p->tmdnum || !p->xmit_queued)
                                netif_wake_queue(dev);
-               dev->trans_start = jiffies;
+               dev->trans_start = jiffies; /* prevent tx timeout */
        }
        else
                writedatareg(CSR0_STRT | csr0);
@@ -1150,7 +1150,7 @@ static void ni65_timeout(struct net_device *dev)
                printk("%02x ",p->tmdhead[i].u.s.status);
        printk("\n");
        ni65_lance_reinit(dev);
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        netif_wake_queue(dev);
 }
 
@@ -1213,7 +1213,6 @@ static netdev_tx_t ni65_send_packet(struct sk_buff *skb,
                        netif_wake_queue(dev);
 
                p->lock = 0;
-               dev->trans_start = jiffies;
 
                spin_unlock_irqrestore(&p->ring_lock, flags);
        }
index 3924703..43bf26f 100644 (file)
@@ -992,7 +992,6 @@ static int octeon_mgmt_xmit(struct sk_buff *skb, struct net_device *netdev)
        /* Ring the bell.  */
        cvmx_write_csr(CVMX_MIXX_ORING2(port), 1);
 
-       netdev->trans_start = jiffies;
        rv = NETDEV_TX_OK;
 out:
        octeon_mgmt_update_tx_stats(netdev);
index dc3b4c7..56f3fc4 100644 (file)
@@ -1354,7 +1354,6 @@ static int netdrv_start_xmit(struct sk_buff *skb, struct net_device *dev)
        NETDRV_W32(TxStatus0 + (entry * sizeof(u32)),
                   tp->tx_flag | (skb->len >= ETH_ZLEN ? skb->len : ETH_ZLEN));
 
-       dev->trans_start = jiffies;
        atomic_inc(&tp->cur_tx);
        if ((atomic_read(&tp->cur_tx) - atomic_read(&tp->dirty_tx)) >= NUM_TX_DESC)
                netif_stop_queue(dev);
index 757f87b..b6d9313 100644 (file)
@@ -739,7 +739,7 @@ static void el3_tx_timeout(struct net_device *dev)
        printk(KERN_NOTICE "%s: Transmit timed out!\n", dev->name);
        dump_status(dev);
        dev->stats.tx_errors++;
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        /* Issue TX_RESET and TX_START commands. */
        tc574_wait_for_completion(dev, TxReset);
        outw(TxEnable, ioaddr + EL3_CMD);
@@ -790,8 +790,6 @@ static netdev_tx_t el3_start_xmit(struct sk_buff *skb,
        /* ... and the packet rounded to a doubleword. */
        outsl(ioaddr + TX_FIFO, skb->data, (skb->len+3)>>2);
 
-       dev->trans_start = jiffies;
-
        /* TxFree appears only in Window 1, not offset 0x1c. */
        if (inw(ioaddr + TxFree) <= 1536) {
                netif_stop_queue(dev);
index 580977f..d6a459d 100644 (file)
@@ -563,7 +563,7 @@ static void el3_tx_timeout(struct net_device *dev)
     netdev_warn(dev, "Transmit timed out!\n");
     dump_status(dev);
     dev->stats.tx_errors++;
-    dev->trans_start = jiffies;
+    dev->trans_start = jiffies; /* prevent tx timeout */
     /* Issue TX_RESET and TX_START commands. */
     tc589_wait_for_completion(dev, TxReset);
     outw(TxEnable, ioaddr + EL3_CMD);
@@ -611,7 +611,6 @@ static netdev_tx_t el3_start_xmit(struct sk_buff *skb,
     /* ... and the packet rounded to a doubleword. */
     outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
 
-    dev->trans_start = jiffies;
     if (inw(ioaddr + TX_FREE) <= 1536) {
        netif_stop_queue(dev);
        /* Interrupt us when the FIFO has room for max-sized packet. */
index 70fc959..a1a6b08 100644 (file)
@@ -1005,7 +1005,7 @@ static void axnet_tx_timeout(struct net_device *dev)
 {
        long e8390_base = dev->base_addr;
        struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
-       int txsr, isr, tickssofar = jiffies - dev->trans_start;
+       int txsr, isr, tickssofar = jiffies - dev_trans_start(dev);
        unsigned long flags;
 
        dev->stats.tx_errors++;
index 6734f7d..16fc3e5 100644 (file)
@@ -890,7 +890,6 @@ static netdev_tx_t fjn_start_xmit(struct sk_buff *skb,
            lp->sent = lp->tx_queue ;
            lp->tx_queue = 0;
            lp->tx_queue_len = 0;
-           dev->trans_start = jiffies;
            lp->tx_started = 1;
            netif_start_queue(dev);
        } else {
index c516c19..ca4efd2 100644 (file)
@@ -903,7 +903,7 @@ static void mace_tx_timeout(struct net_device *dev)
 #else /* #if RESET_ON_TIMEOUT */
   printk("NOT resetting card\n");
 #endif /* #if RESET_ON_TIMEOUT */
-  dev->trans_start = jiffies;
+  dev->trans_start = jiffies; /* prevent tx timeout */
   netif_wake_queue(dev);
 }
 
@@ -945,8 +945,6 @@ static netdev_tx_t mace_start_xmit(struct sk_buff *skb,
       outb(skb->data[skb->len-1], ioaddr + AM2150_XMT);
     }
 
-    dev->trans_start = jiffies;
-
 #if MULTI_TX
     if (lp->tx_free_frames > 0)
       netif_start_queue(dev);
index 949ac1a..b5c62db 100644 (file)
@@ -1254,7 +1254,7 @@ static void smc_tx_timeout(struct net_device *dev)
           dev->name, inw(ioaddr)&0xff, inw(ioaddr + 2));
     dev->stats.tx_errors++;
     smc_reset(dev);
-    dev->trans_start = jiffies;
+    dev->trans_start = jiffies; /* prevent tx timeout */
     smc->saved_skb = NULL;
     netif_wake_queue(dev);
 }
index 656be93..6622f04 100644 (file)
@@ -1295,7 +1295,7 @@ xirc2ps_tx_timeout_task(struct work_struct *work)
        struct net_device *dev = local->dev;
     /* reset the card */
     do_reset(dev,1);
-    dev->trans_start = jiffies;
+    dev->trans_start = jiffies; /* prevent tx timeout */
     netif_wake_queue(dev);
 }
 
@@ -1358,7 +1358,6 @@ do_start_xmit(struct sk_buff *skb, struct net_device *dev)
        PutByte(XIRCREG_CR, TransmitPacket|EnableIntr);
 
     dev_kfree_skb (skb);
-    dev->trans_start = jiffies;
     dev->stats.tx_bytes += pktlen;
     netif_start_queue(dev);
     return NETDEV_TX_OK;
index a2254f7..566fd89 100644 (file)
@@ -448,7 +448,7 @@ static void pcnet32_netif_stop(struct net_device *dev)
 {
        struct pcnet32_private *lp = netdev_priv(dev);
 
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        napi_disable(&lp->napi);
        netif_tx_disable(dev);
 }
@@ -2398,7 +2398,7 @@ static void pcnet32_tx_timeout(struct net_device *dev)
        }
        pcnet32_restart(dev, CSR0_NORMAL);
 
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        netif_wake_queue(dev);
 
        spin_unlock_irqrestore(&lp->lock, flags);
@@ -2449,8 +2449,6 @@ static netdev_tx_t pcnet32_start_xmit(struct sk_buff *skb,
        /* Trigger an immediate send poll. */
        lp->a.write_csr(ioaddr, CSR0, CSR0_INTEN | CSR0_TXPOLL);
 
-       dev->trans_start = jiffies;
-
        if (lp->tx_ring[(entry + 1) & lp->tx_mod_mask].base != 0) {
                lp->tx_full = 1;
                netif_stop_queue(dev);
index 9a2103a..f4e1f9a 100644 (file)
@@ -979,7 +979,6 @@ plip_tx_packet(struct sk_buff *skb, struct net_device *dev)
                printk(KERN_DEBUG "%s: send request\n", dev->name);
 
        spin_lock_irq(&nl->lock);
-       dev->trans_start = jiffies;
        snd->skb = skb;
        snd->length.h = skb->len;
        snd->state = PLIP_PK_TRIGGER;
index 022317d..87d6b8f 100644 (file)
@@ -903,9 +903,6 @@ int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
                gelic_descr_release_tx(card, descr->next);
                card->tx_chain.tail = descr->next->next;
                dev_info(ctodev(card), "%s: kick failure\n", __func__);
-       } else {
-               /* OK, DMA started/reserved */
-               netdev->trans_start = jiffies;
        }
 
        spin_unlock_irqrestore(&card->tx_lock, flags);
index 4122916..3cc7bef 100644 (file)
@@ -924,7 +924,6 @@ static netdev_tx_t r6040_start_xmit(struct sk_buff *skb,
        if (!lp->tx_free_desc)
                netif_stop_queue(dev);
 
-       dev->trans_start = jiffies;
        spin_unlock_irqrestore(&lp->lock, flags);
 
        return NETDEV_TX_OK;
index f2e335f..e26e107 100644 (file)
@@ -1467,7 +1467,6 @@ static netdev_tx_t rr_start_xmit(struct sk_buff *skb,
 
        spin_unlock_irqrestore(&rrpriv->lock, flags);
 
-       dev->trans_start = jiffies;
        return NETDEV_TX_OK;
 }
 
index 6b12524..a7ff8ea 100644 (file)
@@ -852,8 +852,8 @@ static int s6gmac_tx(struct sk_buff *skb, struct net_device *dev)
 {
        struct s6gmac *pd = netdev_priv(dev);
        unsigned long flags;
+
        spin_lock_irqsave(&pd->lock, flags);
-       dev->trans_start = jiffies;
        writel(skb->len << S6_GMAC_BURST_PREWR_LEN |
                0 << S6_GMAC_BURST_PREWR_CFE |
                1 << S6_GMAC_BURST_PREWR_PPE |
index fec3c29..1f3acc3 100644 (file)
@@ -2068,8 +2068,6 @@ static int sbmac_start_tx(struct sk_buff *skb, struct net_device *dev)
                return NETDEV_TX_BUSY;
        }
 
-       dev->trans_start = jiffies;
-
        spin_unlock_irqrestore(&sc->sbm_lock, flags);
 
        return NETDEV_TX_OK;
@@ -2488,7 +2486,7 @@ static void sbmac_tx_timeout (struct net_device *dev)
        spin_lock_irqsave(&sc->sbm_lock, flags);
 
 
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        dev->stats.tx_errors++;
 
        spin_unlock_irqrestore(&sc->sbm_lock, flags);
index 1b32605..8c4067a 100644 (file)
@@ -987,8 +987,6 @@ static netdev_tx_t sc92031_start_xmit(struct sk_buff *skb,
        iowrite32(tx_status, port_base + TxStatus0 + entry * 4);
        mmiowb();
 
-       dev->trans_start = jiffies;
-
        if (priv->tx_head - priv->tx_tail >= NUM_TX_DESC)
                netif_stop_queue(dev);
 
index 374832c..11ab32e 100644 (file)
@@ -390,7 +390,7 @@ static void seeq8005_timeout(struct net_device *dev)
                   tx_done(dev) ? "IRQ conflict" : "network cable problem");
        /* Try to restart the adaptor. */
        seeq8005_init(dev, 1);
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        netif_wake_queue(dev);
 }
 
@@ -411,7 +411,6 @@ static netdev_tx_t seeq8005_send_packet(struct sk_buff *skb,
        netif_stop_queue(dev);
 
        hardware_send_packet(dev, buf, length);
-       dev->trans_start = jiffies;
        dev->stats.tx_bytes += length;
        dev_kfree_skb (skb);
        /* You might need to clean up and record Tx statistics here. */
index c8fc896..cc4bd8c 100644 (file)
@@ -574,7 +574,7 @@ static inline int sgiseeq_reset(struct net_device *dev)
        if (err)
                return err;
 
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        netif_wake_queue(dev);
 
        return 0;
@@ -638,8 +638,6 @@ static int sgiseeq_start_xmit(struct sk_buff *skb, struct net_device *dev)
        if (!(hregs->tx_ctrl & HPC3_ETXCTRL_ACTIVE))
                kick_tx(dev, sp, hregs);
 
-       dev->trans_start = jiffies;
-
        if (!TX_BUFFS_AVAIL(sp))
                netif_stop_queue(dev);
        spin_unlock_irqrestore(&sp->tx_lock, flags);
@@ -652,7 +650,7 @@ static void timeout(struct net_device *dev)
        printk(KERN_NOTICE "%s: transmit timed out, resetting\n", dev->name);
        sgiseeq_reset(dev);
 
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        netif_wake_queue(dev);
 }
 
index 6242b85..586ed09 100644 (file)
@@ -1148,8 +1148,6 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
        if (!(ctrl_inl(ndev->base_addr + EDTRR) & EDTRR_TRNS))
                ctrl_outl(EDTRR_TRNS, ndev->base_addr + EDTRR);
 
-       ndev->trans_start = jiffies;
-
        return NETDEV_TX_OK;
 }
 
index 6293592..11f7ebe 100644 (file)
@@ -1553,7 +1553,7 @@ static void sis900_tx_timeout(struct net_device *net_dev)
 
        spin_unlock_irqrestore(&sis_priv->lock, flags);
 
-       net_dev->trans_start = jiffies;
+       net_dev->trans_start = jiffies; /* prevent tx timeout */
 
        /* load Transmit Descriptor Register */
        outl(sis_priv->tx_ring_dma, ioaddr + txdp);
@@ -1623,8 +1623,6 @@ sis900_start_xmit(struct sk_buff *skb, struct net_device *net_dev)
 
        spin_unlock_irqrestore(&sis_priv->lock, flags);
 
-       net_dev->trans_start = jiffies;
-
        if (netif_msg_tx_queued(sis_priv))
                printk(KERN_DEBUG "%s: Queued Tx packet at %p size %d "
                       "to slot %d.\n",
index 7912606..91adc38 100644 (file)
@@ -1076,7 +1076,6 @@ static netdev_tx_t skfp_send_pkt(struct sk_buff *skb,
        if (bp->QueueSkb == 0) {
                netif_stop_queue(dev);
        }
-       dev->trans_start = jiffies;
        return NETDEV_TX_OK;
 
 }                              // skfp_send_pkt
index 8969615..d92772e 100644 (file)
@@ -458,7 +458,7 @@ static void sl_tx_timeout(struct net_device *dev)
                 *      14 Oct 1994 Dmitry Gorodchanin.
                 */
 #ifdef SL_CHECK_TRANSMIT
-               if (time_before(jiffies, dev->trans_start + 20 * HZ))  {
+               if (time_before(jiffies, dev_trans_start(dev) + 20 * HZ))  {
                        /* 20 sec timeout not reached */
                        goto out;
                }
index 1e49fcf..66831f3 100644 (file)
@@ -1289,7 +1289,7 @@ static void smc911x_timeout(struct net_device *dev)
                schedule_work(&lp->phy_configure);
 
        /* We can accept TX packets again */
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        netif_wake_queue(dev);
 }
 
index d76c815..acb81a8 100644 (file)
@@ -1164,7 +1164,7 @@ static void smc_timeout(struct net_device *dev)
        /* "kick" the adaptor */
        smc_reset( dev->base_addr );
        smc_enable( dev->base_addr );
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        /* clear anything saved */
        ((struct smc_local *)netdev_priv(dev))->saved_skb = NULL;
        netif_wake_queue(dev);
index 682bc4f..10cf0cb 100644 (file)
@@ -1360,7 +1360,7 @@ static void smc_timeout(struct net_device *dev)
                schedule_work(&lp->phy_configure);
 
        /* We can accept TX packets again */
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        netif_wake_queue(dev);
 }
 
index 746fb91..89f35f9 100644 (file)
@@ -1335,7 +1335,6 @@ static int smsc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
        smsc911x_tx_writefifo(pdata, (unsigned int *)bufp, wrsz);
        freespace -= (skb->len + 32);
        dev_kfree_skb(skb);
-       dev->trans_start = jiffies;
 
        if (unlikely(smsc911x_tx_get_txstatcount(pdata) >= 30))
                smsc911x_tx_update_txcounters(dev);
index ada05c4..6cdee6a 100644 (file)
@@ -1034,8 +1034,6 @@ static netdev_tx_t smsc9420_hard_start_xmit(struct sk_buff *skb,
        smsc9420_reg_write(pd, TX_POLL_DEMAND, 1);
        smsc9420_pci_flush_write(pd);
 
-       dev->trans_start = jiffies;
-
        return NETDEV_TX_OK;
 }
 
index e5d6732..26e25d7 100644 (file)
@@ -174,7 +174,7 @@ static void sonic_tx_timeout(struct net_device *dev)
        /* Try to restart the adaptor. */
        sonic_init(dev);
        lp->stats.tx_errors++;
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        netif_wake_queue(dev);
 }
 
@@ -263,8 +263,6 @@ static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev)
 
        SONIC_WRITE(SONIC_CMD, SONIC_CR_TXP);
 
-       dev->trans_start = jiffies;
-
        return NETDEV_TX_OK;
 }
 
index 8a6d27c..e19b5a1 100644 (file)
@@ -1173,7 +1173,7 @@ static void tx_timeout(struct net_device *dev)
 
        /* Trigger an immediate transmit demand. */
 
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        np->stats.tx_errors++;
        netif_wake_queue(dev);
 }
@@ -1312,8 +1312,6 @@ static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev)
        if ((np->cur_tx - np->dirty_tx) + 4 > TX_RING_SIZE)
                netif_stop_queue(dev);
 
-       dev->trans_start = jiffies;
-
        return NETDEV_TX_OK;
 }
 
index 31ab4ab..1513123 100644 (file)
@@ -985,7 +985,7 @@ static void sun3_82586_timeout(struct net_device *dev)
                p->scb->cmd_cuc = CUC_START;
                sun3_attn586();
                WAIT_4_SCB_CMD();
-               dev->trans_start = jiffies;
+               dev->trans_start = jiffies; /* prevent tx timeout */
                return 0;
        }
 #endif
@@ -998,7 +998,7 @@ static void sun3_82586_timeout(struct net_device *dev)
                sun3_82586_close(dev);
                sun3_82586_open(dev);
        }
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
 }
 
 /******************************************************
@@ -1062,7 +1062,6 @@ static int sun3_82586_send_packet(struct sk_buff *skb, struct net_device *dev)
                        }
 
                        sun3_attn586();
-                       dev->trans_start = jiffies;
                        if(!i)
                                dev_kfree_skb(skb);
                        WAIT_4_SCB_CMD();
@@ -1082,7 +1081,6 @@ static int sun3_82586_send_packet(struct sk_buff *skb, struct net_device *dev)
                p->xmit_cmds[0]->cmd_status = p->nop_cmds[next_nop]->cmd_status = 0;
 
                p->nop_cmds[p->nop_point]->cmd_link = make16((p->xmit_cmds[0]));
-               dev->trans_start = jiffies;
                p->nop_point = next_nop;
                dev_kfree_skb(skb);
 #      endif
@@ -1097,7 +1095,6 @@ static int sun3_82586_send_packet(struct sk_buff *skb, struct net_device *dev)
                p->nop_cmds[next_nop]->cmd_status = 0;
 
                p->nop_cmds[p->xmit_count]->cmd_link = make16((p->xmit_cmds[p->xmit_count]));
-               dev->trans_start = jiffies;
                p->xmit_count = next_nop;
 
                {
index 1694ca5..358c22f 100644 (file)
@@ -523,8 +523,8 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
 
        /* Transmitter timeout, serious problems. */
        if (netif_queue_stopped(dev)) {
-               int tickssofar = jiffies - dev->trans_start;
-               if (tickssofar < 20)
+               int tickssofar = jiffies - dev_trans_start(dev);
+               if (tickssofar < HZ/5)
                        return NETDEV_TX_BUSY;
 
                DPRINTK( 1, ( "%s: transmit timed out, status %04x, resetting.\n",
@@ -559,7 +559,6 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
                REGA( CSR0 ) = CSR0_INEA | CSR0_INIT | CSR0_STRT;
 
                netif_start_queue(dev);
-               dev->trans_start = jiffies;
 
                return NETDEV_TX_OK;
        }
@@ -637,8 +636,7 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
        AREG = CSR0;
        DPRINTK( 2, ( "%s: lance_start_xmit() exiting, csr0 %4.4x.\n",
                                  dev->name, DREG ));
-       dev->trans_start = jiffies;
-       dev_kfree_skb( skb );
+       dev_kfree_skb(skb);
 
        lp->lock = 0;
        if ((MEM->tx_head[(entry+1) & TX_RING_MOD_MASK].flag & TMD1_OWN) ==
index 5291315..34446b6 100644 (file)
@@ -982,8 +982,6 @@ static int bigmac_start_xmit(struct sk_buff *skb, struct net_device *dev)
        sbus_writel(CREG_CTRL_TWAKEUP, bp->creg + CREG_CTRL);
 
 
-       dev->trans_start = jiffies;
-
        return NETDEV_TX_OK;
 }
 
index da45f01..1680325 100644 (file)
@@ -972,7 +972,7 @@ static void tx_timeout(struct net_device *dev)
 
        dev->if_port = 0;
 
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        dev->stats.tx_errors++;
        if (np->cur_tx - np->dirty_tx < TX_QUEUE_LEN - 4) {
                netif_wake_queue(dev);
@@ -1084,7 +1084,6 @@ start_tx (struct sk_buff *skb, struct net_device *dev)
        } else {
                netif_stop_queue (dev);
        }
-       dev->trans_start = jiffies;
        if (netif_msg_tx_queued(np)) {
                printk (KERN_DEBUG
                        "%s: Transmit frame #%d queued in slot %d.\n",
index 2b78e97..5bc786f 100644 (file)
@@ -1136,7 +1136,7 @@ static netdev_tx_t gem_start_xmit(struct sk_buff *skb,
        writel(gp->tx_new, gp->regs + TXDMA_KICK);
        spin_unlock_irqrestore(&gp->tx_lock, flags);
 
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */
 
        return NETDEV_TX_OK;
 }
index 982ff12..377c0b5 100644 (file)
@@ -2341,8 +2341,6 @@ static netdev_tx_t happy_meal_start_xmit(struct sk_buff *skb,
 
        spin_unlock_irq(&hp->happy_lock);
 
-       dev->trans_start = jiffies;
-
        tx_add_log(hp, TXLOG_ACTION_TXMIT, 0);
        return NETDEV_TX_OK;
 }
index c7748b7..f88a60f 100644 (file)
@@ -1003,7 +1003,7 @@ static int lance_reset(struct net_device *dev)
        }
        lp->init_ring(dev);
        load_csrs(lp);
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        status = init_restart_lance(lp);
        return status;
 }
@@ -1160,7 +1160,6 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        spin_unlock_irq(&lp->lock);
 
-       dev->trans_start = jiffies;
        dev_kfree_skb(skb);
 
        return NETDEV_TX_OK;
index 239f097..a7542d2 100644 (file)
@@ -602,7 +602,6 @@ static int qe_start_xmit(struct sk_buff *skb, struct net_device *dev)
        qep->tx_new = NEXT_TX(entry);
 
        /* Get it going. */
-       dev->trans_start = jiffies;
        sbus_writel(CREG_CTRL_TWAKEUP, qep->qcregs + CREG_CTRL);
 
        dev->stats.tx_packets++;
index 6cf8b06..d281a7b 100644 (file)
@@ -717,7 +717,6 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        dev_kfree_skb(skb);
 
-       dev->trans_start = jiffies;
        return NETDEV_TX_OK;
 
 out_dropped_unlock:
index 36149dd..be08b75 100644 (file)
@@ -1357,8 +1357,6 @@ static int tc35815_send_packet(struct sk_buff *skb, struct net_device *dev)
        }
        lp->tfd_start = (lp->tfd_start + 1) % TX_FD_NUM;
 
-       dev->trans_start = jiffies;
-
        /* If we just used up the very last entry in the
         * TX ring on this device, tell the queueing
         * layer to send no more.
index 8ffec22..ccee3ed 100644 (file)
@@ -1034,7 +1034,7 @@ static void TLan_tx_timeout(struct net_device *dev)
        TLan_ResetLists( dev );
        TLan_ReadAndClearStats( dev, TLAN_IGNORE );
        TLan_ResetAdapter( dev );
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        netif_wake_queue( dev );
 
 }
@@ -1147,7 +1147,6 @@ static netdev_tx_t TLan_StartTx( struct sk_buff *skb, struct net_device *dev )
 
        CIRC_INC( priv->txTail, TLAN_NUM_TX_LISTS );
 
-       dev->trans_start = jiffies;
        return NETDEV_TX_OK;
 
 } /* TLan_StartTx */
index eebdaae..91e6c78 100644 (file)
@@ -1041,7 +1041,6 @@ static netdev_tx_t tok_send_packet(struct sk_buff *skb,
        writew(ti->exsap_station_id, ti->srb + STATION_ID_OFST);
        writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
        spin_unlock_irqrestore(&(ti->lock), flags);
-       dev->trans_start = jiffies;
        return NETDEV_TX_OK;
 }
 
index e405601..213b9af 100644 (file)
@@ -4562,7 +4562,7 @@ static void smctr_timeout(struct net_device *dev)
          * fake transmission time and go on trying. Our own timeout
          * routine is in sktr_timer_chk()
          */
-        dev->trans_start = jiffies;
+        dev->trans_start = jiffies; /* prevent tx timeout */
         netif_wake_queue(dev);
 }
 
index c169fd0..8cb126a 100644 (file)
@@ -592,7 +592,7 @@ static void tms380tr_timeout(struct net_device *dev)
         * fake transmission time and go on trying. Our own timeout
         * routine is in tms380tr_timer_chk()
         */
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        netif_wake_queue(dev);
 }
 
index 9c0f29c..c0e7000 100644 (file)
@@ -654,7 +654,6 @@ static netdev_tx_t de_start_xmit (struct sk_buff *skb,
 
        /* Trigger an immediate transmit demand. */
        dw32(TxPoll, NormalTxPoll);
-       dev->trans_start = jiffies;
 
        return NETDEV_TX_OK;
 }
index d818456..9522baf 100644 (file)
@@ -1337,7 +1337,7 @@ de4x5_open(struct net_device *dev)
     }
 
     lp->interrupt = UNMASK_INTERRUPTS;
-    dev->trans_start = jiffies;
+    dev->trans_start = jiffies; /* prevent tx timeout */
 
     START_DE4X5;
 
@@ -1507,7 +1507,6 @@ de4x5_queue_pkt(struct sk_buff *skb, struct net_device *dev)
            outl(POLL_DEMAND, DE4X5_TPD);/* Start the TX */
 
            lp->tx_new = (++lp->tx_new) % lp->txRingSize;
-           dev->trans_start = jiffies;
 
            if (TX_BUFFS_AVAIL) {
                netif_start_queue(dev);         /* Another pkt may be queued */
@@ -1937,7 +1936,7 @@ set_multicast_list(struct net_device *dev)
 
            lp->tx_new = (++lp->tx_new) % lp->txRingSize;
            outl(POLL_DEMAND, DE4X5_TPD);       /* Start the TX */
-           dev->trans_start = jiffies;
+           dev->trans_start = jiffies; /* prevent tx timeout */
        }
     }
 }
index 7278ecb..bdb25b8 100644 (file)
@@ -1180,11 +1180,11 @@ static void dmfe_timer(unsigned long data)
 
        /* TX polling kick monitor */
        if ( db->tx_packet_cnt &&
-            time_after(jiffies, dev->trans_start + DMFE_TX_KICK) ) {
+            time_after(jiffies, dev_trans_start(dev) + DMFE_TX_KICK) ) {
                outl(0x1, dev->base_addr + DCR1);   /* Tx polling again */
 
                /* TX Timeout */
-               if ( time_after(jiffies, dev->trans_start + DMFE_TX_TIMEOUT) ) {
+               if (time_after(jiffies, dev_trans_start(dev) + DMFE_TX_TIMEOUT) ) {
                        db->reset_TXtimeout++;
                        db->wait_reset = 1;
                        dev_warn(&dev->dev, "Tx timeout - resetting\n");
index 966efa1..a63e64b 100644 (file)
@@ -67,7 +67,7 @@ void pnic_lnk_change(struct net_device *dev, int csr5)
                 */
                if (tulip_media_cap[dev->if_port] & MediaIsMII)
                        return;
-               if (! tp->nwayset  ||  time_after(jiffies, dev->trans_start + 1*HZ)) {
+               if (! tp->nwayset || time_after(jiffies, dev_trans_start(dev) + 1*HZ)) {
                        tp->csr6 = 0x00420000 | (tp->csr6 & 0x0000fdff);
                        iowrite32(tp->csr6, ioaddr + CSR6);
                        iowrite32(0x30, ioaddr + CSR12);
index 22e766e..254643e 100644 (file)
@@ -605,7 +605,7 @@ static void tulip_tx_timeout(struct net_device *dev)
 
 out_unlock:
        spin_unlock_irqrestore (&tp->lock, flags);
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        netif_wake_queue (dev);
 }
 
@@ -707,8 +707,6 @@ tulip_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        spin_unlock_irqrestore(&tp->lock, flags);
 
-       dev->trans_start = jiffies;
-
        return NETDEV_TX_OK;
 }
 
index c7f9728..96de582 100644 (file)
@@ -1040,11 +1040,11 @@ static void uli526x_timer(unsigned long data)
 
        /* TX polling kick monitor */
        if ( db->tx_packet_cnt &&
-            time_after(jiffies, dev->trans_start + ULI526X_TX_KICK) ) {
+            time_after(jiffies, dev_trans_start(dev) + ULI526X_TX_KICK) ) {
                outl(0x1, dev->base_addr + DCR1);   // Tx polling again
 
                // TX Timeout
-               if ( time_after(jiffies, dev->trans_start + ULI526X_TX_TIMEOUT) ) {
+               if ( time_after(jiffies, dev_trans_start(dev) + ULI526X_TX_TIMEOUT) ) {
                        db->reset_TXtimeout++;
                        db->wait_reset = 1;
                        printk( "%s: Tx timeout - resetting\n",
index 18c8ced..60a8754 100644 (file)
@@ -969,7 +969,7 @@ static void tx_timeout(struct net_device *dev)
        enable_irq(dev->irq);
 
        netif_wake_queue(dev);
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        np->stats.tx_errors++;
        return;
 }
@@ -1055,8 +1055,6 @@ static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev)
        }
        spin_unlock_irq(&np->lock);
 
-       dev->trans_start = jiffies;
-
        if (debug > 4) {
                printk(KERN_DEBUG "%s: Transmit frame #%d queued in slot %d\n",
                       dev->name, np->cur_tx, entry);
index 6b150c0..dbdfb1f 100644 (file)
@@ -396,7 +396,6 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
 
        /* Enqueue packet */
        skb_queue_tail(&tun->socket.sk->sk_receive_queue, skb);
-       dev->trans_start = jiffies;
 
        /* Notify and wake up reader process */
        if (tun->flags & TUN_FASYNC)
index b94c4cc..22bde49 100644 (file)
@@ -881,8 +881,6 @@ typhoon_start_tx(struct sk_buff *skb, struct net_device *dev)
        wmb();
        iowrite32(txRing->lastWrite, tp->tx_ioaddr + txRing->writeRegister);
 
-       dev->trans_start = jiffies;
-
        /* If we don't have room to put the worst case packet on the
         * queue, then we must stop the queue. We need 2 extra
         * descriptors -- one to prevent ring wrap, and one for the
index 081f76b..932602d 100644 (file)
@@ -3148,8 +3148,6 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
        /* set bd status and length */
        out_be32((u32 __iomem *)bd, bd_status);
 
-       dev->trans_start = jiffies;
-
        /* Move to next BD in the ring */
        if (!(bd_status & T_W))
                bd += sizeof(struct qe_bd);
index be0cc99..a6227f8 100644 (file)
@@ -834,8 +834,6 @@ static netdev_tx_t hso_net_start_xmit(struct sk_buff *skb,
        } else {
                net->stats.tx_packets++;
                net->stats.tx_bytes += skb->len;
-               /* And tell the kernel when the last transmit started. */
-               net->trans_start = jiffies;
        }
        dev_kfree_skb(skb);
        /* we're done */
index c4c334d..46890dc 100644 (file)
@@ -856,7 +856,6 @@ skip:
        {
                kaweth->stats.tx_packets++;
                kaweth->stats.tx_bytes += skb->len;
-               net->trans_start = jiffies;
        }
 
        spin_unlock_irq(&kaweth->device_lock);
index 4183877..1cd17d2 100644 (file)
@@ -808,7 +808,7 @@ static void write_bulk_callback(struct urb *urb)
                break;
        }
 
-       net->trans_start = jiffies;
+       net->trans_start = jiffies; /* prevent tx timeout */
        netif_wake_queue(net);
 }
 
@@ -909,7 +909,6 @@ static netdev_tx_t pegasus_start_xmit(struct sk_buff *skb,
        } else {
                pegasus->stats.tx_packets++;
                pegasus->stats.tx_bytes += skb->len;
-               net->trans_start = jiffies;
        }
        dev_kfree_skb(skb);
 
index 467bcff..4930f9d 100644 (file)
@@ -1209,7 +1209,7 @@ static void rhine_reset_task(struct work_struct *work)
        spin_unlock_bh(&rp->lock);
        enable_irq(rp->pdev->irq);
 
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        dev->stats.tx_errors++;
        netif_wake_queue(dev);
 }
@@ -1294,8 +1294,6 @@ static netdev_tx_t rhine_start_tx(struct sk_buff *skb,
        if (rp->cur_tx == rp->dirty_tx + TX_QUEUE_LEN)
                netif_stop_queue(dev);
 
-       dev->trans_start = jiffies;
-
        spin_unlock_irqrestore(&rp->lock, flags);
 
        if (debug > 4) {
index 616f8c9..42dffd3 100644 (file)
@@ -2606,7 +2606,6 @@ static netdev_tx_t velocity_xmit(struct sk_buff *skb,
        td_ptr->td_buf[0].size |= TD_QUEUE;
        mac_tx_queue_wake(vptr->mac_regs, qnum);
 
-       dev->trans_start = jiffies;
        spin_unlock_irqrestore(&vptr->lock, flags);
 out:
        return NETDEV_TX_OK;
index 90e783a..3946232 100644 (file)
@@ -992,7 +992,6 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
                VMXNET3_WRITE_BAR0_REG(adapter, VMXNET3_REG_TXPROD,
                                       tq->tx_ring.next2fill);
        }
-       netdev->trans_start = jiffies;
 
        return NETDEV_TX_OK;
 
index a4859f7..d45b08d 100644 (file)
@@ -1175,8 +1175,6 @@ static netdev_tx_t dscc4_start_xmit(struct sk_buff *skb,
        spin_unlock(&dpriv->lock);
 #endif
 
-       dev->trans_start = jiffies;
-
        if (debug > 2)
                dscc4_tx_print(dev, dpriv, "Xmit");
        /* To be cleaned(unsigned int)/optimized. Later, ok ? */
index 4dde2ea..a3ea27c 100644 (file)
@@ -658,7 +658,6 @@ static netdev_tx_t sca_xmit(struct sk_buff *skb, struct net_device *dev)
 #endif
        writew(len, &desc->len);
        writeb(ST_TX_EOM, &desc->stat);
-       dev->trans_start = jiffies;
 
        port->txin = next_desc(port, port->txin, 1);
        sca_outw(desc_offset(port, port->txin, 1),
index aad9ed4..ea476cb 100644 (file)
@@ -585,7 +585,6 @@ static netdev_tx_t sca_xmit(struct sk_buff *skb, struct net_device *dev)
 
        writew(len, &desc->len);
        writeb(ST_TX_EOM, &desc->stat);
-       dev->trans_start = jiffies;
 
        port->txin = (port->txin + 1) % card->tx_ring_buffers;
        sca_outl(desc_offset(port, port->txin, 1),
index 0c2cdde..88e3630 100644 (file)
@@ -891,7 +891,6 @@ static int hss_hdlc_xmit(struct sk_buff *skb, struct net_device *dev)
 
        wmb();
        queue_put_desc(queue_ids[port->id].tx, tx_desc_phys(port, n), desc);
-       dev->trans_start = jiffies;
 
        if (qmgr_stat_below_low_watermark(txreadyq)) { /* empty */
 #if DEBUG_TX
index b278503..e2c6f7f 100644 (file)
@@ -1506,8 +1506,6 @@ static netdev_tx_t lmc_start_xmit(struct sk_buff *skb,
     /* send now! */
     LMC_CSR_WRITE (sc, csr_txpoll, 0);
 
-    dev->trans_start = jiffies;
-
     spin_unlock_irqrestore(&sc->lmc_lock, flags);
 
     lmc_trace(dev, "lmc_start_xmit_out");
@@ -2103,7 +2101,7 @@ static void lmc_driver_timeout(struct net_device *dev)
     printk("%s: Xmitter busy|\n", dev->name);
 
     sc->extra_stats.tx_tbusy_calls++;
-    if (jiffies - dev->trans_start < TX_TIMEOUT)
+    if (jiffies - dev_trans_start(dev) < TX_TIMEOUT)
            goto bug_out;
 
     /*
@@ -2135,7 +2133,7 @@ static void lmc_driver_timeout(struct net_device *dev)
     sc->lmc_device->stats.tx_errors++;
     sc->extra_stats.tx_ProcTimeout++; /* -baz */
 
-    dev->trans_start = jiffies;
+    dev->trans_start = jiffies; /* prevent tx timeout */
 
 bug_out:
 
index 17502d8..c6aa66e 100644 (file)
@@ -1790,7 +1790,7 @@ static void cpc_tx_timeout(struct net_device *dev)
                           cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) &
                           ~(CPLD_REG2_FALC_LED1 << (2 * ch)));
        }
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        CPC_UNLOCK(card, flags);
        netif_wake_queue(dev);
 }
@@ -1849,7 +1849,6 @@ static int cpc_queue_xmit(struct sk_buff *skb, struct net_device *dev)
        if (d->trace_on) {
                cpc_trace(dev, skb, 'T');
        }
-       dev->trans_start = jiffies;
 
        /* Start transmission */
        CPC_LOCK(card, flags);
index 541c700..db73a7b 100644 (file)
@@ -298,7 +298,6 @@ static netdev_tx_t wanxl_xmit(struct sk_buff *skb, struct net_device *dev)
        desc->stat = PACKET_FULL;
        writel(1 << (DOORBELL_TO_CARD_TX_0 + port->node),
               port->card->plx + PLX_DOORBELL_TO_CARD);
-       dev->trans_start = jiffies;
 
        port->tx_out = (port->tx_out + 1) % TX_BUFFERS;
 
index 3edbbcf..c8f7090 100644 (file)
@@ -865,7 +865,6 @@ static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev)
 
        /* low bit of first byte of destination tells us if broadcast */
        tx_update_descriptor(priv, *(skb->data) & 0x01, len + 18, buff, TX_PACKET_TYPE_DATA);
-       dev->trans_start = jiffies;
        dev->stats.tx_bytes += len;
 
        spin_unlock_irqrestore(&priv->irqlock, flags);
index 38edad6..d9b8ee1 100644 (file)
@@ -229,7 +229,7 @@ static void lbs_tx_timeout(struct net_device *dev)
 
        lbs_pr_err("tx watch dog timeout\n");
 
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
 
        if (priv->currenttxskb)
                lbs_send_tx_feedback(priv, 0);
index 52d244e..a9bf658 100644 (file)
@@ -147,8 +147,6 @@ netdev_tx_t lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
        dev->stats.tx_packets++;
        dev->stats.tx_bytes += skb->len;
 
-       dev->trans_start = jiffies;
-
        if (priv->monitormode) {
                /* Keep the skb to echo it back once Tx feedback is
                   received from FW */
index 1d60c7e..884a777 100644 (file)
@@ -517,7 +517,6 @@ static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
                goto busy;
        }
 
-       dev->trans_start = jiffies;
        stats->tx_bytes += HERMES_802_3_OFFSET + skb->len;
        goto ok;
 
index 64585da..2fc52bc 100644 (file)
@@ -224,8 +224,6 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
                priv->data_low_tx_full = 1;
        }
 
-       /* set the transmission time */
-       ndev->trans_start = jiffies;
        ndev->stats.tx_packets++;
        ndev->stats.tx_bytes += skb->len;
 
index d9c45bf..73972ee 100644 (file)
@@ -941,7 +941,6 @@ static netdev_tx_t ray_dev_start_xmit(struct sk_buff *skb,
        case XMIT_MSG_BAD:
        case XMIT_OK:
        default:
-               dev->trans_start = jiffies;
                dev_kfree_skb(skb);
        }
 
index 65dd502..1e61e6c 100644 (file)
@@ -1307,7 +1307,7 @@ static void wl3501_tx_timeout(struct net_device *dev)
                printk(KERN_ERR "%s: Error %d resetting card on Tx timeout!\n",
                       dev->name, rc);
        else {
-               dev->trans_start = jiffies;
+               dev->trans_start = jiffies; /* prevent tx timeout */
                netif_wake_queue(dev);
        }
 }
@@ -1326,7 +1326,6 @@ static netdev_tx_t wl3501_hard_start_xmit(struct sk_buff *skb,
 
        spin_lock_irqsave(&this->lock, flags);
        enabled = wl3501_block_interrupt(this);
-       dev->trans_start = jiffies;
        rc = wl3501_send_pkt(this, skb->data, skb->len);
        if (enabled)
                wl3501_unblock_interrupt(this);
index 1e2b684..ece86a5 100644 (file)
@@ -827,7 +827,6 @@ static netdev_tx_t zd1201_hard_start_xmit(struct sk_buff *skb,
        } else {
                dev->stats.tx_packets++;
                dev->stats.tx_bytes += skb->len;
-               dev->trans_start = jiffies;
        }
        kfree_skb(skb);
 
@@ -845,7 +844,7 @@ static void zd1201_tx_timeout(struct net_device *dev)
        usb_unlink_urb(zd->tx_urb);
        dev->stats.tx_errors++;
        /* Restart the timeout to quiet the watchdog: */
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
 }
 
 static int zd1201_set_mac_address(struct net_device *dev, void *p)
index 93828d5..a7db68d 100644 (file)
@@ -558,7 +558,7 @@ static void xemaclite_tx_timeout(struct net_device *dev)
        }
 
        /* To exclude tx timeout */
-       dev->trans_start = 0xffffffff - TX_TIMEOUT - TX_TIMEOUT;
+       dev->trans_start = jiffies; /* prevent tx timeout */
 
        /* We're all ready to go. Start the queue */
        netif_wake_queue(dev);
@@ -590,7 +590,7 @@ static void xemaclite_tx_handler(struct net_device *dev)
                        dev->stats.tx_bytes += lp->deferred_skb->len;
                        dev_kfree_skb_irq(lp->deferred_skb);
                        lp->deferred_skb = NULL;
-                       dev->trans_start = jiffies;
+                       dev->trans_start = jiffies; /* prevent tx timeout */
                        netif_wake_queue(dev);
                }
        }
@@ -1054,7 +1054,6 @@ static int xemaclite_send(struct sk_buff *orig_skb, struct net_device *dev)
 
        dev->stats.tx_bytes += len;
        dev_kfree_skb(new_skb);
-       dev->trans_start = jiffies;
 
        return 0;
 }
index dbfef8d..b9fd2f0 100644 (file)
@@ -587,7 +587,6 @@ static netdev_tx_t znet_send_packet(struct sk_buff *skb, struct net_device *dev)
                }
                spin_unlock_irqrestore (&znet->lock, flags);
 
-               dev->trans_start = jiffies;
                netif_start_queue (dev);
 
                if (znet_debug > 4)
index ce3c99e..e42f6ed 100644 (file)
@@ -107,6 +107,8 @@ struct hci_dev {
        unsigned long   acl_last_tx;
        unsigned long   sco_last_tx;
 
+       struct workqueue_struct *workqueue;
+
        struct tasklet_struct   cmd_task;
        struct tasklet_struct   rx_task;
        struct tasklet_struct   tx_task;
@@ -636,8 +638,8 @@ int hci_register_notifier(struct notifier_block *nb);
 int hci_unregister_notifier(struct notifier_block *nb);
 
 int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param);
-int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
-int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb);
+void hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
+void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb);
 
 void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode);
 
index 17a689f..7c695bf 100644 (file)
 #define L2CAP_DEFAULT_MIN_MTU          48
 #define L2CAP_DEFAULT_FLUSH_TO         0xffff
 #define L2CAP_DEFAULT_TX_WINDOW                63
-#define L2CAP_DEFAULT_NUM_TO_ACK        (L2CAP_DEFAULT_TX_WINDOW/5)
 #define L2CAP_DEFAULT_MAX_TX           3
 #define L2CAP_DEFAULT_RETRANS_TO       1000    /* 1 second */
 #define L2CAP_DEFAULT_MONITOR_TO       12000   /* 12 seconds */
 #define L2CAP_DEFAULT_MAX_PDU_SIZE     672
+#define L2CAP_DEFAULT_ACK_TO           200
+#define L2CAP_LOCAL_BUSY_TRIES         12
 
 #define L2CAP_CONN_TIMEOUT     (40000) /* 40 seconds */
 #define L2CAP_INFO_TIMEOUT     (4000)  /*  4 seconds */
@@ -55,6 +56,8 @@ struct l2cap_options {
        __u16 flush_to;
        __u8  mode;
        __u8  fcs;
+       __u8  max_tx;
+       __u16 txwin_size;
 };
 
 #define L2CAP_CONNINFO 0x02
@@ -292,6 +295,7 @@ struct l2cap_conn {
 #define l2cap_pi(sk) ((struct l2cap_pinfo *) sk)
 #define TX_QUEUE(sk) (&l2cap_pi(sk)->tx_queue)
 #define SREJ_QUEUE(sk) (&l2cap_pi(sk)->srej_queue)
+#define BUSY_QUEUE(sk) (&l2cap_pi(sk)->busy_queue)
 #define SREJ_LIST(sk) (&l2cap_pi(sk)->srej_l.list)
 
 struct srej_list {
@@ -320,7 +324,7 @@ struct l2cap_pinfo {
        __u8            conf_req[64];
        __u8            conf_len;
        __u8            conf_state;
-       __u           conn_state;
+       __u16           conn_state;
 
        __u8            next_tx_seq;
        __u8            expected_ack_seq;
@@ -328,27 +332,35 @@ struct l2cap_pinfo {
        __u8            buffer_seq;
        __u8            buffer_seq_srej;
        __u8            srej_save_reqseq;
+       __u8            frames_sent;
        __u8            unacked_frames;
        __u8            retry_count;
-       __u8            num_to_ack;
+       __u8            num_acked;
        __u16           sdu_len;
        __u16           partial_sdu_len;
        struct sk_buff  *sdu;
 
        __u8            ident;
 
+       __u8            tx_win;
+       __u8            max_tx;
        __u8            remote_tx_win;
        __u8            remote_max_tx;
        __u16           retrans_timeout;
        __u16           monitor_timeout;
-       __u16           max_pdu_size;
+       __u16           remote_mps;
+       __u16           mps;
 
        __le16          sport;
 
+       spinlock_t              send_lock;
        struct timer_list       retrans_timer;
        struct timer_list       monitor_timer;
+       struct timer_list       ack_timer;
        struct sk_buff_head     tx_queue;
        struct sk_buff_head     srej_queue;
+       struct sk_buff_head     busy_queue;
+       struct work_struct      busy_work;
        struct srej_list        srej_l;
        struct l2cap_conn       *conn;
        struct sock             *next_c;
@@ -367,19 +379,24 @@ struct l2cap_pinfo {
 #define L2CAP_CONF_MAX_CONF_REQ 2
 #define L2CAP_CONF_MAX_CONF_RSP 2
 
-#define L2CAP_CONN_SAR_SDU         0x01
-#define L2CAP_CONN_SREJ_SENT       0x02
-#define L2CAP_CONN_WAIT_F          0x04
-#define L2CAP_CONN_SREJ_ACT        0x08
-#define L2CAP_CONN_SEND_PBIT       0x10
-#define L2CAP_CONN_REMOTE_BUSY     0x20
-#define L2CAP_CONN_LOCAL_BUSY      0x40
-#define L2CAP_CONN_REJ_ACT         0x80
+#define L2CAP_CONN_SAR_SDU         0x0001
+#define L2CAP_CONN_SREJ_SENT       0x0002
+#define L2CAP_CONN_WAIT_F          0x0004
+#define L2CAP_CONN_SREJ_ACT        0x0008
+#define L2CAP_CONN_SEND_PBIT       0x0010
+#define L2CAP_CONN_REMOTE_BUSY     0x0020
+#define L2CAP_CONN_LOCAL_BUSY      0x0040
+#define L2CAP_CONN_REJ_ACT         0x0080
+#define L2CAP_CONN_SEND_FBIT       0x0100
+#define L2CAP_CONN_RNR_SENT        0x0200
+#define L2CAP_CONN_SAR_RETRY       0x0400
 
 #define __mod_retrans_timer() mod_timer(&l2cap_pi(sk)->retrans_timer, \
                jiffies +  msecs_to_jiffies(L2CAP_DEFAULT_RETRANS_TO));
 #define __mod_monitor_timer() mod_timer(&l2cap_pi(sk)->monitor_timer, \
                jiffies + msecs_to_jiffies(L2CAP_DEFAULT_MONITOR_TO));
+#define __mod_ack_timer() mod_timer(&l2cap_pi(sk)->ack_timer, \
+               jiffies + msecs_to_jiffies(L2CAP_DEFAULT_ACK_TO));
 
 static inline int l2cap_tx_window_full(struct sock *sk)
 {
index ed37168..ee3b304 100644 (file)
@@ -43,6 +43,19 @@ config BT_L2CAP
          Say Y here to compile L2CAP support into the kernel or say M to
          compile it as module (l2cap).
 
+config BT_L2CAP_EXT_FEATURES
+       bool "L2CAP Extended Features support (EXPERIMENTAL)"
+       depends on BT_L2CAP && EXPERIMENTAL
+       help
+         This option enables the L2CAP Extended Features support. These
+         new features include the Enhanced Retransmission and Streaming
+         Modes, the Frame Check Sequence (FCS), and Segmentation and
+         Reassembly (SAR) for L2CAP packets. They are a required for the
+         new Alternate MAC/PHY and the Bluetooth Medical Profile.
+
+         You should say N unless you know what you are doing. Note that
+         this is in an experimental state yet.
+
 config BT_SCO
        tristate "SCO links support"
        depends on BT
index 4ad2319..5e83f8e 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/fcntl.h>
 #include <linux/init.h>
 #include <linux/skbuff.h>
+#include <linux/workqueue.h>
 #include <linux/interrupt.h>
 #include <linux/notifier.h>
 #include <linux/rfkill.h>
@@ -928,6 +929,10 @@ int hci_register_dev(struct hci_dev *hdev)
 
        write_unlock_bh(&hci_dev_list_lock);
 
+       hdev->workqueue = create_singlethread_workqueue(hdev->name);
+       if (!hdev->workqueue)
+               goto nomem;
+
        hci_register_sysfs(hdev);
 
        hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
@@ -942,6 +947,13 @@ int hci_register_dev(struct hci_dev *hdev)
        hci_notify(hdev, HCI_DEV_REG);
 
        return id;
+
+nomem:
+       write_lock_bh(&hci_dev_list_lock);
+       list_del(&hdev->list);
+       write_unlock_bh(&hci_dev_list_lock);
+
+       return -ENOMEM;
 }
 EXPORT_SYMBOL(hci_register_dev);
 
@@ -970,6 +982,8 @@ int hci_unregister_dev(struct hci_dev *hdev)
 
        hci_unregister_sysfs(hdev);
 
+       destroy_workqueue(hdev->workqueue);
+
        __hci_dev_put(hdev);
 
        return 0;
@@ -1260,7 +1274,7 @@ static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
        hdr->dlen   = cpu_to_le16(len);
 }
 
-int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags)
+void hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags)
 {
        struct hci_dev *hdev = conn->hdev;
        struct sk_buff *list;
@@ -1303,23 +1317,18 @@ int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags)
 
        tasklet_schedule(&hdev->tx_task);
 
-       return 0;
+       return;
 }
 EXPORT_SYMBOL(hci_send_acl);
 
 /* Send SCO data */
-int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
+void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
 {
        struct hci_dev *hdev = conn->hdev;
        struct hci_sco_hdr hdr;
 
        BT_DBG("%s len %d", hdev->name, skb->len);
 
-       if (skb->len > hdev->sco_mtu) {
-               kfree_skb(skb);
-               return -EINVAL;
-       }
-
        hdr.handle = cpu_to_le16(conn->handle);
        hdr.dlen   = skb->len;
 
@@ -1332,8 +1341,6 @@ int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
 
        skb_queue_tail(&conn->data_q, skb);
        tasklet_schedule(&hdev->tx_task);
-
-       return 0;
 }
 EXPORT_SYMBOL(hci_send_sco);
 
index 0e8e1a5..463ffa4 100644 (file)
@@ -14,8 +14,6 @@ static struct class *bt_class;
 struct dentry *bt_debugfs = NULL;
 EXPORT_SYMBOL_GPL(bt_debugfs);
 
-static struct workqueue_struct *bt_workq;
-
 static inline char *link_typetostr(int type)
 {
        switch (type) {
@@ -161,14 +159,14 @@ void hci_conn_add_sysfs(struct hci_conn *conn)
 {
        BT_DBG("conn %p", conn);
 
-       queue_work(bt_workq, &conn->work_add);
+       queue_work(conn->hdev->workqueue, &conn->work_add);
 }
 
 void hci_conn_del_sysfs(struct hci_conn *conn)
 {
        BT_DBG("conn %p", conn);
 
-       queue_work(bt_workq, &conn->work_del);
+       queue_work(conn->hdev->workqueue, &conn->work_del);
 }
 
 static inline char *host_bustostr(int bus)
@@ -283,11 +281,9 @@ static ssize_t show_idle_timeout(struct device *dev, struct device_attribute *at
 static ssize_t store_idle_timeout(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
        struct hci_dev *hdev = dev_get_drvdata(dev);
-       char *ptr;
-       __u32 val;
+       unsigned long val;
 
-       val = simple_strtoul(buf, &ptr, 10);
-       if (ptr == buf)
+       if (strict_strtoul(buf, 0, &val) < 0)
                return -EINVAL;
 
        if (val != 0 && (val < 500 || val > 3600000))
@@ -307,11 +303,9 @@ static ssize_t show_sniff_max_interval(struct device *dev, struct device_attribu
 static ssize_t store_sniff_max_interval(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
        struct hci_dev *hdev = dev_get_drvdata(dev);
-       char *ptr;
-       __u16 val;
+       unsigned long val;
 
-       val = simple_strtoul(buf, &ptr, 10);
-       if (ptr == buf)
+       if (strict_strtoul(buf, 0, &val) < 0)
                return -EINVAL;
 
        if (val < 0x0002 || val > 0xFFFE || val % 2)
@@ -334,11 +328,9 @@ static ssize_t show_sniff_min_interval(struct device *dev, struct device_attribu
 static ssize_t store_sniff_min_interval(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
        struct hci_dev *hdev = dev_get_drvdata(dev);
-       char *ptr;
-       __u16 val;
+       unsigned long val;
 
-       val = simple_strtoul(buf, &ptr, 10);
-       if (ptr == buf)
+       if (strict_strtoul(buf, 0, &val) < 0)
                return -EINVAL;
 
        if (val < 0x0002 || val > 0xFFFE || val % 2)
@@ -487,17 +479,11 @@ void hci_unregister_sysfs(struct hci_dev *hdev)
 
 int __init bt_sysfs_init(void)
 {
-       bt_workq = create_singlethread_workqueue("bluetooth");
-       if (!bt_workq)
-               return -ENOMEM;
-
        bt_debugfs = debugfs_create_dir("bluetooth", NULL);
 
        bt_class = class_create(THIS_MODULE, "bluetooth");
-       if (IS_ERR(bt_class)) {
-               destroy_workqueue(bt_workq);
+       if (IS_ERR(bt_class))
                return PTR_ERR(bt_class);
-       }
 
        return 0;
 }
@@ -507,6 +493,4 @@ void bt_sysfs_cleanup(void)
        class_destroy(bt_class);
 
        debugfs_remove_recursive(bt_debugfs);
-
-       destroy_workqueue(bt_workq);
 }
index 864c76f..673a368 100644 (file)
 
 #define VERSION "2.14"
 
+#ifdef CONFIG_BT_L2CAP_EXT_FEATURES
+static int enable_ertm = 1;
+#else
 static int enable_ertm = 0;
+#endif
 static int max_transmit = L2CAP_DEFAULT_MAX_TX;
+static int tx_window = L2CAP_DEFAULT_TX_WINDOW;
 
 static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
 static u8 l2cap_fixed_chan[8] = { 0x02, };
 
 static const struct proto_ops l2cap_sock_ops;
 
+static struct workqueue_struct *_busy_wq;
+
 static struct bt_sock_list l2cap_sk_list = {
        .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock)
 };
 
+static void l2cap_busy_work(struct work_struct *work);
+
 static void __l2cap_sock_close(struct sock *sk, int reason);
 static void l2cap_sock_close(struct sock *sk);
 static void l2cap_sock_kill(struct sock *sk);
@@ -219,7 +228,7 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct so
 
        l2cap_pi(sk)->conn = conn;
 
-       if (sk->sk_type == SOCK_SEQPACKET) {
+       if (sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM) {
                /* Alloc CID for connection-oriented socket */
                l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
        } else if (sk->sk_type == SOCK_DGRAM) {
@@ -325,19 +334,19 @@ static inline u8 l2cap_get_ident(struct l2cap_conn *conn)
        return id;
 }
 
-static inline int l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
+static inline void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
 {
        struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
 
        BT_DBG("code 0x%2.2x", code);
 
        if (!skb)
-               return -ENOMEM;
+               return;
 
-       return hci_send_acl(conn->hcon, skb, 0);
+       hci_send_acl(conn->hcon, skb, 0);
 }
 
-static inline int l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
+static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
 {
        struct sk_buff *skb;
        struct l2cap_hdr *lh;
@@ -352,9 +361,19 @@ static inline int l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
        count = min_t(unsigned int, conn->mtu, hlen);
        control |= L2CAP_CTRL_FRAME_TYPE;
 
+       if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
+               control |= L2CAP_CTRL_FINAL;
+               pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
+       }
+
+       if (pi->conn_state & L2CAP_CONN_SEND_PBIT) {
+               control |= L2CAP_CTRL_POLL;
+               pi->conn_state &= ~L2CAP_CONN_SEND_PBIT;
+       }
+
        skb = bt_skb_alloc(count, GFP_ATOMIC);
        if (!skb)
-               return -ENOMEM;
+               return;
 
        lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
        lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
@@ -366,19 +385,20 @@ static inline int l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
                put_unaligned_le16(fcs, skb_put(skb, 2));
        }
 
-       return hci_send_acl(pi->conn->hcon, skb, 0);
+       hci_send_acl(pi->conn->hcon, skb, 0);
 }
 
-static inline int l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control)
+static inline void l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control)
 {
-       if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY)
+       if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
                control |= L2CAP_SUPER_RCV_NOT_READY;
-       else
+               pi->conn_state |= L2CAP_CONN_RNR_SENT;
+       } else
                control |= L2CAP_SUPER_RCV_READY;
 
        control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
 
-       return l2cap_send_sframe(pi, control);
+       l2cap_send_sframe(pi, control);
 }
 
 static void l2cap_do_start(struct sock *sk)
@@ -437,7 +457,8 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
        for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
                bh_lock_sock(sk);
 
-               if (sk->sk_type != SOCK_SEQPACKET) {
+               if (sk->sk_type != SOCK_SEQPACKET &&
+                               sk->sk_type != SOCK_STREAM) {
                        bh_unlock_sock(sk);
                        continue;
                }
@@ -497,7 +518,8 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
        for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
                bh_lock_sock(sk);
 
-               if (sk->sk_type != SOCK_SEQPACKET) {
+               if (sk->sk_type != SOCK_SEQPACKET &&
+                               sk->sk_type != SOCK_STREAM) {
                        l2cap_sock_clear_timer(sk);
                        sk->sk_state = BT_CONNECTED;
                        sk->sk_state_change(sk);
@@ -706,7 +728,8 @@ static void __l2cap_sock_close(struct sock *sk, int reason)
 
        case BT_CONNECTED:
        case BT_CONFIG:
-               if (sk->sk_type == SOCK_SEQPACKET) {
+               if (sk->sk_type == SOCK_SEQPACKET ||
+                               sk->sk_type == SOCK_STREAM) {
                        struct l2cap_conn *conn = l2cap_pi(sk)->conn;
 
                        sk->sk_state = BT_DISCONN;
@@ -717,7 +740,8 @@ static void __l2cap_sock_close(struct sock *sk, int reason)
                break;
 
        case BT_CONNECT2:
-               if (sk->sk_type == SOCK_SEQPACKET) {
+               if (sk->sk_type == SOCK_SEQPACKET ||
+                               sk->sk_type == SOCK_STREAM) {
                        struct l2cap_conn *conn = l2cap_pi(sk)->conn;
                        struct l2cap_conn_rsp rsp;
                        __u16 result;
@@ -772,14 +796,21 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
                pi->omtu = l2cap_pi(parent)->omtu;
                pi->mode = l2cap_pi(parent)->mode;
                pi->fcs  = l2cap_pi(parent)->fcs;
+               pi->max_tx = l2cap_pi(parent)->max_tx;
+               pi->tx_win = l2cap_pi(parent)->tx_win;
                pi->sec_level = l2cap_pi(parent)->sec_level;
                pi->role_switch = l2cap_pi(parent)->role_switch;
                pi->force_reliable = l2cap_pi(parent)->force_reliable;
        } else {
                pi->imtu = L2CAP_DEFAULT_MTU;
                pi->omtu = 0;
-               pi->mode = L2CAP_MODE_BASIC;
+               if (enable_ertm && sk->sk_type == SOCK_STREAM)
+                       pi->mode = L2CAP_MODE_ERTM;
+               else
+                       pi->mode = L2CAP_MODE_BASIC;
+               pi->max_tx = max_transmit;
                pi->fcs  = L2CAP_FCS_CRC16;
+               pi->tx_win = tx_window;
                pi->sec_level = BT_SECURITY_LOW;
                pi->role_switch = 0;
                pi->force_reliable = 0;
@@ -790,6 +821,7 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
        pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
        skb_queue_head_init(TX_QUEUE(sk));
        skb_queue_head_init(SREJ_QUEUE(sk));
+       skb_queue_head_init(BUSY_QUEUE(sk));
        INIT_LIST_HEAD(SREJ_LIST(sk));
 }
 
@@ -833,7 +865,7 @@ static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
 
        sock->state = SS_UNCONNECTED;
 
-       if (sock->type != SOCK_SEQPACKET &&
+       if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM &&
                        sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
                return -ESOCKTNOSUPPORT;
 
@@ -981,7 +1013,8 @@ static int l2cap_do_connect(struct sock *sk)
        l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
 
        if (hcon->state == BT_CONNECTED) {
-               if (sk->sk_type != SOCK_SEQPACKET) {
+               if (sk->sk_type != SOCK_SEQPACKET &&
+                               sk->sk_type != SOCK_STREAM) {
                        l2cap_sock_clear_timer(sk);
                        sk->sk_state = BT_CONNECTED;
                } else
@@ -1015,7 +1048,8 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
 
        lock_sock(sk);
 
-       if (sk->sk_type == SOCK_SEQPACKET && !la.l2_psm) {
+       if ((sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM)
+                       && !la.l2_psm) {
                err = -EINVAL;
                goto done;
        }
@@ -1079,7 +1113,8 @@ static int l2cap_sock_listen(struct socket *sock, int backlog)
 
        lock_sock(sk);
 
-       if (sk->sk_state != BT_BOUND || sock->type != SOCK_SEQPACKET) {
+       if ((sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM)
+                       || sk->sk_state != BT_BOUND) {
                err = -EBADFD;
                goto done;
        }
@@ -1207,10 +1242,40 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *l
        return 0;
 }
 
+static int __l2cap_wait_ack(struct sock *sk)
+{
+       DECLARE_WAITQUEUE(wait, current);
+       int err = 0;
+       int timeo = HZ/5;
+
+       add_wait_queue(sk_sleep(sk), &wait);
+       while ((l2cap_pi(sk)->unacked_frames > 0 && l2cap_pi(sk)->conn)) {
+               set_current_state(TASK_INTERRUPTIBLE);
+
+               if (!timeo)
+                       timeo = HZ/5;
+
+               if (signal_pending(current)) {
+                       err = sock_intr_errno(timeo);
+                       break;
+               }
+
+               release_sock(sk);
+               timeo = schedule_timeout(timeo);
+               lock_sock(sk);
+
+               err = sock_error(sk);
+               if (err)
+                       break;
+       }
+       set_current_state(TASK_RUNNING);
+       remove_wait_queue(sk_sleep(sk), &wait);
+       return err;
+}
+
 static void l2cap_monitor_timeout(unsigned long arg)
 {
        struct sock *sk = (void *) arg;
-       u16 control;
 
        bh_lock_sock(sk);
        if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) {
@@ -1222,15 +1287,13 @@ static void l2cap_monitor_timeout(unsigned long arg)
        l2cap_pi(sk)->retry_count++;
        __mod_monitor_timer();
 
-       control = L2CAP_CTRL_POLL;
-       l2cap_send_rr_or_rnr(l2cap_pi(sk), control);
+       l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
        bh_unlock_sock(sk);
 }
 
 static void l2cap_retrans_timeout(unsigned long arg)
 {
        struct sock *sk = (void *) arg;
-       u16 control;
 
        bh_lock_sock(sk);
        l2cap_pi(sk)->retry_count = 1;
@@ -1238,8 +1301,7 @@ static void l2cap_retrans_timeout(unsigned long arg)
 
        l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
 
-       control = L2CAP_CTRL_POLL;
-       l2cap_send_rr_or_rnr(l2cap_pi(sk), control);
+       l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
        bh_unlock_sock(sk);
 }
 
@@ -1247,7 +1309,8 @@ static void l2cap_drop_acked_frames(struct sock *sk)
 {
        struct sk_buff *skb;
 
-       while ((skb = skb_peek(TX_QUEUE(sk)))) {
+       while ((skb = skb_peek(TX_QUEUE(sk))) &&
+                       l2cap_pi(sk)->unacked_frames) {
                if (bt_cb(skb)->tx_seq == l2cap_pi(sk)->expected_ack_seq)
                        break;
 
@@ -1263,18 +1326,13 @@ static void l2cap_drop_acked_frames(struct sock *sk)
        return;
 }
 
-static inline int l2cap_do_send(struct sock *sk, struct sk_buff *skb)
+static inline void l2cap_do_send(struct sock *sk, struct sk_buff *skb)
 {
        struct l2cap_pinfo *pi = l2cap_pi(sk);
-       int err;
 
        BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len);
 
-       err = hci_send_acl(pi->conn->hcon, skb, 0);
-       if (err < 0)
-               kfree_skb(skb);
-
-       return err;
+       hci_send_acl(pi->conn->hcon, skb, 0);
 }
 
 static int l2cap_streaming_send(struct sock *sk)
@@ -1282,7 +1340,6 @@ static int l2cap_streaming_send(struct sock *sk)
        struct sk_buff *skb, *tx_skb;
        struct l2cap_pinfo *pi = l2cap_pi(sk);
        u16 control, fcs;
-       int err;
 
        while ((skb = sk->sk_send_head)) {
                tx_skb = skb_clone(skb, GFP_ATOMIC);
@@ -1291,16 +1348,12 @@ static int l2cap_streaming_send(struct sock *sk)
                control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
                put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
 
-               if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16) {
+               if (pi->fcs == L2CAP_FCS_CRC16) {
                        fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
                        put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
                }
 
-               err = l2cap_do_send(sk, tx_skb);
-               if (err < 0) {
-                       l2cap_send_disconn_req(pi->conn, sk);
-                       return err;
-               }
+               l2cap_do_send(sk, tx_skb);
 
                pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
 
@@ -1315,48 +1368,44 @@ static int l2cap_streaming_send(struct sock *sk)
        return 0;
 }
 
-static int l2cap_retransmit_frame(struct sock *sk, u8 tx_seq)
+static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq)
 {
        struct l2cap_pinfo *pi = l2cap_pi(sk);
        struct sk_buff *skb, *tx_skb;
        u16 control, fcs;
-       int err;
 
        skb = skb_peek(TX_QUEUE(sk));
-       do {
-               if (bt_cb(skb)->tx_seq != tx_seq) {
-                       if (skb_queue_is_last(TX_QUEUE(sk), skb))
-                               break;
-                       skb = skb_queue_next(TX_QUEUE(sk), skb);
-                       continue;
-               }
+       if (!skb)
+               return;
 
-               if (pi->remote_max_tx &&
-                               bt_cb(skb)->retries == pi->remote_max_tx) {
-                       l2cap_send_disconn_req(pi->conn, sk);
+       do {
+               if (bt_cb(skb)->tx_seq == tx_seq)
                        break;
-               }
 
-               tx_skb = skb_clone(skb, GFP_ATOMIC);
-               bt_cb(skb)->retries++;
-               control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
-               control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
-                               | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
-               put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
+               if (skb_queue_is_last(TX_QUEUE(sk), skb))
+                       return;
 
-               if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16) {
-                       fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
-                       put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
-               }
+       } while ((skb = skb_queue_next(TX_QUEUE(sk), skb)));
 
-               err = l2cap_do_send(sk, tx_skb);
-               if (err < 0) {
-                       l2cap_send_disconn_req(pi->conn, sk);
-                       return err;
-               }
-               break;
-       } while(1);
-       return 0;
+       if (pi->remote_max_tx &&
+                       bt_cb(skb)->retries == pi->remote_max_tx) {
+               l2cap_send_disconn_req(pi->conn, sk);
+               return;
+       }
+
+       tx_skb = skb_clone(skb, GFP_ATOMIC);
+       bt_cb(skb)->retries++;
+       control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
+       control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
+                       | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
+       put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
+
+       if (pi->fcs == L2CAP_FCS_CRC16) {
+               fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
+               put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
+       }
+
+       l2cap_do_send(sk, tx_skb);
 }
 
 static int l2cap_ertm_send(struct sock *sk)
@@ -1364,13 +1413,13 @@ static int l2cap_ertm_send(struct sock *sk)
        struct sk_buff *skb, *tx_skb;
        struct l2cap_pinfo *pi = l2cap_pi(sk);
        u16 control, fcs;
-       int err;
+       int nsent = 0;
 
        if (pi->conn_state & L2CAP_CONN_WAIT_F)
                return 0;
 
        while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk)) &&
-              !(pi->conn_state & L2CAP_CONN_REMOTE_BUSY)) {
+                       !(pi->conn_state & L2CAP_CONN_REMOTE_BUSY)) {
 
                if (pi->remote_max_tx &&
                                bt_cb(skb)->retries == pi->remote_max_tx) {
@@ -1383,35 +1432,97 @@ static int l2cap_ertm_send(struct sock *sk)
                bt_cb(skb)->retries++;
 
                control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
+               if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
+                       control |= L2CAP_CTRL_FINAL;
+                       pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
+               }
                control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
                                | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
                put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
 
 
-               if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16) {
+               if (pi->fcs == L2CAP_FCS_CRC16) {
                        fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2);
                        put_unaligned_le16(fcs, skb->data + tx_skb->len - 2);
                }
 
-               err = l2cap_do_send(sk, tx_skb);
-               if (err < 0) {
-                       l2cap_send_disconn_req(pi->conn, sk);
-                       return err;
-               }
+               l2cap_do_send(sk, tx_skb);
+
                __mod_retrans_timer();
 
                bt_cb(skb)->tx_seq = pi->next_tx_seq;
                pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
 
                pi->unacked_frames++;
+               pi->frames_sent++;
 
                if (skb_queue_is_last(TX_QUEUE(sk), skb))
                        sk->sk_send_head = NULL;
                else
                        sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
+
+               nsent++;
        }
 
-       return 0;
+       return nsent;
+}
+
+static int l2cap_retransmit_frames(struct sock *sk)
+{
+       struct l2cap_pinfo *pi = l2cap_pi(sk);
+       int ret;
+
+       spin_lock_bh(&pi->send_lock);
+
+       if (!skb_queue_empty(TX_QUEUE(sk)))
+               sk->sk_send_head = TX_QUEUE(sk)->next;
+
+       pi->next_tx_seq = pi->expected_ack_seq;
+       ret = l2cap_ertm_send(sk);
+
+       spin_unlock_bh(&pi->send_lock);
+
+       return ret;
+}
+
+static void l2cap_send_ack(struct l2cap_pinfo *pi)
+{
+       struct sock *sk = (struct sock *)pi;
+       u16 control = 0;
+       int nframes;
+
+       control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
+
+       if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
+               control |= L2CAP_SUPER_RCV_NOT_READY;
+               pi->conn_state |= L2CAP_CONN_RNR_SENT;
+               l2cap_send_sframe(pi, control);
+               return;
+       }
+
+       spin_lock_bh(&pi->send_lock);
+       nframes = l2cap_ertm_send(sk);
+       spin_unlock_bh(&pi->send_lock);
+
+       if (nframes > 0)
+               return;
+
+       control |= L2CAP_SUPER_RCV_READY;
+       l2cap_send_sframe(pi, control);
+}
+
+static void l2cap_send_srejtail(struct sock *sk)
+{
+       struct srej_list *tail;
+       u16 control;
+
+       control = L2CAP_SUPER_SELECT_REJECT;
+       control |= L2CAP_CTRL_FINAL;
+
+       tail = list_entry(SREJ_LIST(sk)->prev, struct srej_list, list);
+       control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
+
+       l2cap_send_sframe(l2cap_pi(sk), control);
 }
 
 static inline int l2cap_skbuff_fromiovec(struct sock *sk, struct msghdr *msg, int len, int count, struct sk_buff *skb)
@@ -1420,9 +1531,8 @@ static inline int l2cap_skbuff_fromiovec(struct sock *sk, struct msghdr *msg, in
        struct sk_buff **frag;
        int err, sent = 0;
 
-       if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
+       if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
                return -EFAULT;
-       }
 
        sent += count;
        len  -= count;
@@ -1513,6 +1623,9 @@ static struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *m
 
        BT_DBG("sk %p len %d", sk, (int)len);
 
+       if (!conn)
+               return ERR_PTR(-ENOTCONN);
+
        if (sdulen)
                hlen += 2;
 
@@ -1554,25 +1667,24 @@ static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, siz
        u16 control;
        size_t size = 0;
 
-       __skb_queue_head_init(&sar_queue);
+       skb_queue_head_init(&sar_queue);
        control = L2CAP_SDU_START;
-       skb = l2cap_create_iframe_pdu(sk, msg, pi->max_pdu_size, control, len);
+       skb = l2cap_create_iframe_pdu(sk, msg, pi->remote_mps, control, len);
        if (IS_ERR(skb))
                return PTR_ERR(skb);
 
        __skb_queue_tail(&sar_queue, skb);
-       len -= pi->max_pdu_size;
-       size +=pi->max_pdu_size;
-       control = 0;
+       len -= pi->remote_mps;
+       size += pi->remote_mps;
 
        while (len > 0) {
                size_t buflen;
 
-               if (len > pi->max_pdu_size) {
-                       control |= L2CAP_SDU_CONTINUE;
-                       buflen = pi->max_pdu_size;
+               if (len > pi->remote_mps) {
+                       control = L2CAP_SDU_CONTINUE;
+                       buflen = pi->remote_mps;
                } else {
-                       control |= L2CAP_SDU_END;
+                       control = L2CAP_SDU_END;
                        buflen = len;
                }
 
@@ -1585,11 +1697,12 @@ static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, siz
                __skb_queue_tail(&sar_queue, skb);
                len -= buflen;
                size += buflen;
-               control = 0;
        }
        skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
+       spin_lock_bh(&pi->send_lock);
        if (sk->sk_send_head == NULL)
                sk->sk_send_head = sar_queue.next;
+       spin_unlock_bh(&pi->send_lock);
 
        return size;
 }
@@ -1611,11 +1724,6 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms
        if (msg->msg_flags & MSG_OOB)
                return -EOPNOTSUPP;
 
-       /* Check outgoing MTU */
-       if (sk->sk_type == SOCK_SEQPACKET && pi->mode == L2CAP_MODE_BASIC &&
-           len > pi->omtu)
-               return -EINVAL;
-
        lock_sock(sk);
 
        if (sk->sk_state != BT_CONNECTED) {
@@ -1626,15 +1734,23 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms
        /* Connectionless channel */
        if (sk->sk_type == SOCK_DGRAM) {
                skb = l2cap_create_connless_pdu(sk, msg, len);
-               if (IS_ERR(skb))
+               if (IS_ERR(skb)) {
                        err = PTR_ERR(skb);
-               else
-                       err = l2cap_do_send(sk, skb);
+               } else {
+                       l2cap_do_send(sk, skb);
+                       err = len;
+               }
                goto done;
        }
 
        switch (pi->mode) {
        case L2CAP_MODE_BASIC:
+               /* Check outgoing MTU */
+               if (len > pi->omtu) {
+                       err = -EINVAL;
+                       goto done;
+               }
+
                /* Create a basic PDU */
                skb = l2cap_create_basic_pdu(sk, msg, len);
                if (IS_ERR(skb)) {
@@ -1642,15 +1758,14 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms
                        goto done;
                }
 
-               err = l2cap_do_send(sk, skb);
-               if (!err)
-                       err = len;
+               l2cap_do_send(sk, skb);
+               err = len;
                break;
 
        case L2CAP_MODE_ERTM:
        case L2CAP_MODE_STREAMING:
                /* Entire SDU fits into one PDU */
-               if (len <= pi->max_pdu_size) {
+               if (len <= pi->remote_mps) {
                        control = L2CAP_SDU_UNSEGMENTED;
                        skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0);
                        if (IS_ERR(skb)) {
@@ -1658,8 +1773,15 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms
                                goto done;
                        }
                        __skb_queue_tail(TX_QUEUE(sk), skb);
+
+                       if (pi->mode == L2CAP_MODE_ERTM)
+                               spin_lock_bh(&pi->send_lock);
+
                        if (sk->sk_send_head == NULL)
                                sk->sk_send_head = skb;
+
+                       if (pi->mode == L2CAP_MODE_ERTM)
+                               spin_unlock_bh(&pi->send_lock);
                } else {
                /* Segment SDU into multiples PDUs */
                        err = l2cap_sar_segment_sdu(sk, msg, len);
@@ -1667,12 +1789,15 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms
                                goto done;
                }
 
-               if (pi->mode == L2CAP_MODE_STREAMING)
+               if (pi->mode == L2CAP_MODE_STREAMING) {
                        err = l2cap_streaming_send(sk);
-               else
+               } else {
+                       spin_lock_bh(&pi->send_lock);
                        err = l2cap_ertm_send(sk);
+                       spin_unlock_bh(&pi->send_lock);
+               }
 
-               if (!err)
+               if (err >= 0)
                        err = len;
                break;
 
@@ -1731,6 +1856,8 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us
                opts.flush_to = l2cap_pi(sk)->flush_to;
                opts.mode     = l2cap_pi(sk)->mode;
                opts.fcs      = l2cap_pi(sk)->fcs;
+               opts.max_tx   = l2cap_pi(sk)->max_tx;
+               opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
 
                len = min_t(unsigned int, sizeof(opts), optlen);
                if (copy_from_user((char *) &opts, optval, len)) {
@@ -1738,10 +1865,25 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us
                        break;
                }
 
+               l2cap_pi(sk)->mode = opts.mode;
+               switch (l2cap_pi(sk)->mode) {
+               case L2CAP_MODE_BASIC:
+                       break;
+               case L2CAP_MODE_ERTM:
+               case L2CAP_MODE_STREAMING:
+                       if (enable_ertm)
+                               break;
+                       /* fall through */
+               default:
+                       err = -EINVAL;
+                       break;
+               }
+
                l2cap_pi(sk)->imtu = opts.imtu;
                l2cap_pi(sk)->omtu = opts.omtu;
-               l2cap_pi(sk)->mode = opts.mode;
                l2cap_pi(sk)->fcs  = opts.fcs;
+               l2cap_pi(sk)->max_tx = opts.max_tx;
+               l2cap_pi(sk)->tx_win = (__u8)opts.txwin_size;
                break;
 
        case L2CAP_LM:
@@ -1789,7 +1931,8 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
 
        switch (optname) {
        case BT_SECURITY:
-               if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_RAW) {
+               if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
+                               && sk->sk_type != SOCK_RAW) {
                        err = -EINVAL;
                        break;
                }
@@ -1856,6 +1999,8 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us
                opts.flush_to = l2cap_pi(sk)->flush_to;
                opts.mode     = l2cap_pi(sk)->mode;
                opts.fcs      = l2cap_pi(sk)->fcs;
+               opts.max_tx   = l2cap_pi(sk)->max_tx;
+               opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
 
                len = min_t(unsigned int, len, sizeof(opts));
                if (copy_to_user(optval, (char *) &opts, len))
@@ -1937,7 +2082,8 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch
 
        switch (optname) {
        case BT_SECURITY:
-               if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_RAW) {
+               if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
+                               && sk->sk_type != SOCK_RAW) {
                        err = -EINVAL;
                        break;
                }
@@ -1982,6 +2128,9 @@ static int l2cap_sock_shutdown(struct socket *sock, int how)
 
        lock_sock(sk);
        if (!sk->sk_shutdown) {
+               if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
+                       err = __l2cap_wait_ack(sk);
+
                sk->sk_shutdown = SHUTDOWN_MASK;
                l2cap_sock_clear_timer(sk);
                __l2cap_sock_close(sk, 0);
@@ -2184,19 +2333,35 @@ static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
        *ptr += L2CAP_CONF_OPT_SIZE + len;
 }
 
+static void l2cap_ack_timeout(unsigned long arg)
+{
+       struct sock *sk = (void *) arg;
+
+       bh_lock_sock(sk);
+       l2cap_send_ack(l2cap_pi(sk));
+       bh_unlock_sock(sk);
+}
+
 static inline void l2cap_ertm_init(struct sock *sk)
 {
        l2cap_pi(sk)->expected_ack_seq = 0;
        l2cap_pi(sk)->unacked_frames = 0;
        l2cap_pi(sk)->buffer_seq = 0;
-       l2cap_pi(sk)->num_to_ack = 0;
+       l2cap_pi(sk)->num_acked = 0;
+       l2cap_pi(sk)->frames_sent = 0;
 
        setup_timer(&l2cap_pi(sk)->retrans_timer,
                        l2cap_retrans_timeout, (unsigned long) sk);
        setup_timer(&l2cap_pi(sk)->monitor_timer,
                        l2cap_monitor_timeout, (unsigned long) sk);
+       setup_timer(&l2cap_pi(sk)->ack_timer,
+                       l2cap_ack_timeout, (unsigned long) sk);
 
        __skb_queue_head_init(SREJ_QUEUE(sk));
+       __skb_queue_head_init(BUSY_QUEUE(sk));
+       spin_lock_init(&l2cap_pi(sk)->send_lock);
+
+       INIT_WORK(&l2cap_pi(sk)->busy_work, l2cap_busy_work);
 }
 
 static int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
@@ -2232,7 +2397,7 @@ static int l2cap_build_conf_req(struct sock *sk, void *data)
 {
        struct l2cap_pinfo *pi = l2cap_pi(sk);
        struct l2cap_conf_req *req = data;
-       struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
+       struct l2cap_conf_rfc rfc = { .mode = pi->mode };
        void *ptr = req->data;
 
        BT_DBG("sk %p", sk);
@@ -2261,11 +2426,13 @@ done:
 
        case L2CAP_MODE_ERTM:
                rfc.mode            = L2CAP_MODE_ERTM;
-               rfc.txwin_size      = L2CAP_DEFAULT_TX_WINDOW;
-               rfc.max_transmit    = max_transmit;
+               rfc.txwin_size      = pi->tx_win;
+               rfc.max_transmit    = pi->max_tx;
                rfc.retrans_timeout = 0;
                rfc.monitor_timeout = 0;
                rfc.max_pdu_size    = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
+               if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
+                       rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
 
                l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
                                        sizeof(rfc), (unsigned long) &rfc);
@@ -2287,6 +2454,8 @@ done:
                rfc.retrans_timeout = 0;
                rfc.monitor_timeout = 0;
                rfc.max_pdu_size    = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
+               if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
+                       rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
 
                l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
                                        sizeof(rfc), (unsigned long) &rfc);
@@ -2415,10 +2584,15 @@ done:
                case L2CAP_MODE_ERTM:
                        pi->remote_tx_win = rfc.txwin_size;
                        pi->remote_max_tx = rfc.max_transmit;
-                       pi->max_pdu_size = rfc.max_pdu_size;
+                       if (rfc.max_pdu_size > pi->conn->mtu - 10)
+                               rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
 
-                       rfc.retrans_timeout = L2CAP_DEFAULT_RETRANS_TO;
-                       rfc.monitor_timeout = L2CAP_DEFAULT_MONITOR_TO;
+                       pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
+
+                       rfc.retrans_timeout =
+                               le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO);
+                       rfc.monitor_timeout =
+                               le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO);
 
                        pi->conf_state |= L2CAP_CONF_MODE_DONE;
 
@@ -2428,8 +2602,10 @@ done:
                        break;
 
                case L2CAP_MODE_STREAMING:
-                       pi->remote_tx_win = rfc.txwin_size;
-                       pi->max_pdu_size = rfc.max_pdu_size;
+                       if (rfc.max_pdu_size > pi->conn->mtu - 10)
+                               rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
+
+                       pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
 
                        pi->conf_state |= L2CAP_CONF_MODE_DONE;
 
@@ -2506,13 +2682,12 @@ static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data,
                switch (rfc.mode) {
                case L2CAP_MODE_ERTM:
                        pi->remote_tx_win   = rfc.txwin_size;
-                       pi->retrans_timeout = rfc.retrans_timeout;
-                       pi->monitor_timeout = rfc.monitor_timeout;
-                       pi->max_pdu_size    = le16_to_cpu(rfc.max_pdu_size);
+                       pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
+                       pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
+                       pi->mps    = le16_to_cpu(rfc.max_pdu_size);
                        break;
                case L2CAP_MODE_STREAMING:
-                       pi->max_pdu_size    = le16_to_cpu(rfc.max_pdu_size);
-                       break;
+                       pi->mps    = le16_to_cpu(rfc.max_pdu_size);
                }
        }
 
@@ -2536,6 +2711,42 @@ static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 fla
        return ptr - data;
 }
 
+static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
+{
+       struct l2cap_pinfo *pi = l2cap_pi(sk);
+       int type, olen;
+       unsigned long val;
+       struct l2cap_conf_rfc rfc;
+
+       BT_DBG("sk %p, rsp %p, len %d", sk, rsp, len);
+
+       if ((pi->mode != L2CAP_MODE_ERTM) && (pi->mode != L2CAP_MODE_STREAMING))
+               return;
+
+       while (len >= L2CAP_CONF_OPT_SIZE) {
+               len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
+
+               switch (type) {
+               case L2CAP_CONF_RFC:
+                       if (olen == sizeof(rfc))
+                               memcpy(&rfc, (void *)val, olen);
+                       goto done;
+               }
+       }
+
+done:
+       switch (rfc.mode) {
+       case L2CAP_MODE_ERTM:
+               pi->remote_tx_win   = rfc.txwin_size;
+               pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
+               pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
+               pi->mps    = le16_to_cpu(rfc.max_pdu_size);
+               break;
+       case L2CAP_MODE_STREAMING:
+               pi->mps    = le16_to_cpu(rfc.max_pdu_size);
+       }
+}
+
 static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
 {
        struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
@@ -2815,6 +3026,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
        struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
        u16 scid, flags, result;
        struct sock *sk;
+       int len = cmd->len - sizeof(*rsp);
 
        scid   = __le16_to_cpu(rsp->scid);
        flags  = __le16_to_cpu(rsp->flags);
@@ -2829,11 +3041,11 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
 
        switch (result) {
        case L2CAP_CONF_SUCCESS:
+               l2cap_conf_rfc_get(sk, rsp->data, len);
                break;
 
        case L2CAP_CONF_UNACCEPT:
                if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
-                       int len = cmd->len - sizeof(*rsp);
                        char req[64];
 
                        if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
@@ -2917,8 +3129,10 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd
 
        if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
                skb_queue_purge(SREJ_QUEUE(sk));
+               skb_queue_purge(BUSY_QUEUE(sk));
                del_timer(&l2cap_pi(sk)->retrans_timer);
                del_timer(&l2cap_pi(sk)->monitor_timer);
+               del_timer(&l2cap_pi(sk)->ack_timer);
        }
 
        l2cap_chan_del(sk, ECONNRESET);
@@ -2947,8 +3161,10 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd
 
        if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
                skb_queue_purge(SREJ_QUEUE(sk));
+               skb_queue_purge(BUSY_QUEUE(sk));
                del_timer(&l2cap_pi(sk)->retrans_timer);
                del_timer(&l2cap_pi(sk)->monitor_timer);
+               del_timer(&l2cap_pi(sk)->ack_timer);
        }
 
        l2cap_chan_del(sk, 0);
@@ -3143,7 +3359,40 @@ static int l2cap_check_fcs(struct l2cap_pinfo *pi,  struct sk_buff *skb)
        return 0;
 }
 
-static void l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_seq, u8 sar)
+static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
+{
+       struct l2cap_pinfo *pi = l2cap_pi(sk);
+       u16 control = 0;
+
+       pi->frames_sent = 0;
+       pi->conn_state |= L2CAP_CONN_SEND_FBIT;
+
+       control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
+
+       if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
+               control |= L2CAP_SUPER_RCV_NOT_READY | L2CAP_CTRL_FINAL;
+               l2cap_send_sframe(pi, control);
+               pi->conn_state |= L2CAP_CONN_RNR_SENT;
+               pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
+       }
+
+       if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY && pi->unacked_frames > 0)
+               __mod_retrans_timer();
+
+       pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
+
+       spin_lock_bh(&pi->send_lock);
+       l2cap_ertm_send(sk);
+       spin_unlock_bh(&pi->send_lock);
+
+       if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
+                       pi->frames_sent == 0) {
+               control |= L2CAP_SUPER_RCV_READY;
+               l2cap_send_sframe(pi, control);
+       }
+}
+
+static int l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_seq, u8 sar)
 {
        struct sk_buff *next_skb;
 
@@ -3153,77 +3402,309 @@ static void l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_
        next_skb = skb_peek(SREJ_QUEUE(sk));
        if (!next_skb) {
                __skb_queue_tail(SREJ_QUEUE(sk), skb);
-               return;
+               return 0;
        }
 
        do {
+               if (bt_cb(next_skb)->tx_seq == tx_seq)
+                       return -EINVAL;
+
                if (bt_cb(next_skb)->tx_seq > tx_seq) {
                        __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
-                       return;
+                       return 0;
                }
 
                if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
                        break;
 
-       } while((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
+       } while ((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
 
        __skb_queue_tail(SREJ_QUEUE(sk), skb);
+
+       return 0;
 }
 
-static int l2cap_sar_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
+static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
 {
        struct l2cap_pinfo *pi = l2cap_pi(sk);
        struct sk_buff *_skb;
-       int err = -EINVAL;
+       int err;
 
        switch (control & L2CAP_CTRL_SAR) {
        case L2CAP_SDU_UNSEGMENTED:
-               if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
-                       kfree_skb(pi->sdu);
-                       break;
-               }
+               if (pi->conn_state & L2CAP_CONN_SAR_SDU)
+                       goto drop;
 
                err = sock_queue_rcv_skb(sk, skb);
                if (!err)
-                       return 0;
+                       return err;
 
                break;
 
        case L2CAP_SDU_START:
-               if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
-                       kfree_skb(pi->sdu);
-                       break;
-               }
+               if (pi->conn_state & L2CAP_CONN_SAR_SDU)
+                       goto drop;
 
                pi->sdu_len = get_unaligned_le16(skb->data);
-               skb_pull(skb, 2);
+
+               if (pi->sdu_len > pi->imtu)
+                       goto disconnect;
 
                pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
-               if (!pi->sdu) {
-                       err = -ENOMEM;
-                       break;
-               }
+               if (!pi->sdu)
+                       return -ENOMEM;
+
+               /* pull sdu_len bytes only after alloc, because of Local Busy
+                * condition we have to be sure that this will be executed
+                * only once, i.e., when alloc does not fail */
+               skb_pull(skb, 2);
 
                memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
 
                pi->conn_state |= L2CAP_CONN_SAR_SDU;
                pi->partial_sdu_len = skb->len;
-               err = 0;
                break;
 
        case L2CAP_SDU_CONTINUE:
                if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
-                       break;
+                       goto disconnect;
 
-               memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
+               if (!pi->sdu)
+                       goto disconnect;
 
                pi->partial_sdu_len += skb->len;
                if (pi->partial_sdu_len > pi->sdu_len)
-                       kfree_skb(pi->sdu);
-               else
-                       err = 0;
+                       goto drop;
 
-               break;
+               memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
+
+               break;
+
+       case L2CAP_SDU_END:
+               if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
+                       goto disconnect;
+
+               if (!pi->sdu)
+                       goto disconnect;
+
+               if (!(pi->conn_state & L2CAP_CONN_SAR_RETRY)) {
+                       pi->partial_sdu_len += skb->len;
+
+                       if (pi->partial_sdu_len > pi->imtu)
+                               goto drop;
+
+                       if (pi->partial_sdu_len != pi->sdu_len)
+                               goto drop;
+
+                       memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
+               }
+
+               _skb = skb_clone(pi->sdu, GFP_ATOMIC);
+               if (!_skb) {
+                       pi->conn_state |= L2CAP_CONN_SAR_RETRY;
+                       return -ENOMEM;
+               }
+
+               err = sock_queue_rcv_skb(sk, _skb);
+               if (err < 0) {
+                       kfree_skb(_skb);
+                       pi->conn_state |= L2CAP_CONN_SAR_RETRY;
+                       return err;
+               }
+
+               pi->conn_state &= ~L2CAP_CONN_SAR_RETRY;
+               pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
+
+               kfree_skb(pi->sdu);
+               break;
+       }
+
+       kfree_skb(skb);
+       return 0;
+
+drop:
+       kfree_skb(pi->sdu);
+       pi->sdu = NULL;
+
+disconnect:
+       l2cap_send_disconn_req(pi->conn, sk);
+       kfree_skb(skb);
+       return 0;
+}
+
+static void l2cap_busy_work(struct work_struct *work)
+{
+       DECLARE_WAITQUEUE(wait, current);
+       struct l2cap_pinfo *pi =
+               container_of(work, struct l2cap_pinfo, busy_work);
+       struct sock *sk = (struct sock *)pi;
+       int n_tries = 0, timeo = HZ/5, err;
+       struct sk_buff *skb;
+       u16 control;
+
+       lock_sock(sk);
+
+       add_wait_queue(sk_sleep(sk), &wait);
+       while ((skb = skb_peek(BUSY_QUEUE(sk)))) {
+               set_current_state(TASK_INTERRUPTIBLE);
+
+               if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) {
+                       err = -EBUSY;
+                       l2cap_send_disconn_req(pi->conn, sk);
+                       goto done;
+               }
+
+               if (!timeo)
+                       timeo = HZ/5;
+
+               if (signal_pending(current)) {
+                       err = sock_intr_errno(timeo);
+                       goto done;
+               }
+
+               release_sock(sk);
+               timeo = schedule_timeout(timeo);
+               lock_sock(sk);
+
+               err = sock_error(sk);
+               if (err)
+                       goto done;
+
+               while ((skb = skb_dequeue(BUSY_QUEUE(sk)))) {
+                       control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
+                       err = l2cap_ertm_reassembly_sdu(sk, skb, control);
+                       if (err < 0) {
+                               skb_queue_head(BUSY_QUEUE(sk), skb);
+                               break;
+                       }
+
+                       pi->buffer_seq = (pi->buffer_seq + 1) % 64;
+               }
+
+               if (!skb)
+                       break;
+       }
+
+       if (!(pi->conn_state & L2CAP_CONN_RNR_SENT))
+               goto done;
+
+       control = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
+       control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL;
+       l2cap_send_sframe(pi, control);
+       l2cap_pi(sk)->retry_count = 1;
+
+       del_timer(&pi->retrans_timer);
+       __mod_monitor_timer();
+
+       l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
+
+done:
+       pi->conn_state &= ~L2CAP_CONN_LOCAL_BUSY;
+       pi->conn_state &= ~L2CAP_CONN_RNR_SENT;
+
+       set_current_state(TASK_RUNNING);
+       remove_wait_queue(sk_sleep(sk), &wait);
+
+       release_sock(sk);
+}
+
+static int l2cap_push_rx_skb(struct sock *sk, struct sk_buff *skb, u16 control)
+{
+       struct l2cap_pinfo *pi = l2cap_pi(sk);
+       int sctrl, err;
+
+       if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
+               bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
+               __skb_queue_tail(BUSY_QUEUE(sk), skb);
+               return -EBUSY;
+       }
+
+       err = l2cap_ertm_reassembly_sdu(sk, skb, control);
+       if (err >= 0) {
+               pi->buffer_seq = (pi->buffer_seq + 1) % 64;
+               return err;
+       }
+
+       /* Busy Condition */
+       pi->conn_state |= L2CAP_CONN_LOCAL_BUSY;
+       bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
+       __skb_queue_tail(BUSY_QUEUE(sk), skb);
+
+       sctrl = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
+       sctrl |= L2CAP_SUPER_RCV_NOT_READY;
+       l2cap_send_sframe(pi, sctrl);
+
+       pi->conn_state |= L2CAP_CONN_RNR_SENT;
+
+       queue_work(_busy_wq, &pi->busy_work);
+
+       return err;
+}
+
+static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
+{
+       struct l2cap_pinfo *pi = l2cap_pi(sk);
+       struct sk_buff *_skb;
+       int err = -EINVAL;
+
+       /*
+        * TODO: We have to notify the userland if some data is lost with the
+        * Streaming Mode.
+        */
+
+       switch (control & L2CAP_CTRL_SAR) {
+       case L2CAP_SDU_UNSEGMENTED:
+               if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
+                       kfree_skb(pi->sdu);
+                       break;
+               }
+
+               err = sock_queue_rcv_skb(sk, skb);
+               if (!err)
+                       return 0;
+
+               break;
+
+       case L2CAP_SDU_START:
+               if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
+                       kfree_skb(pi->sdu);
+                       break;
+               }
+
+               pi->sdu_len = get_unaligned_le16(skb->data);
+               skb_pull(skb, 2);
+
+               if (pi->sdu_len > pi->imtu) {
+                       err = -EMSGSIZE;
+                       break;
+               }
+
+               pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
+               if (!pi->sdu) {
+                       err = -ENOMEM;
+                       break;
+               }
+
+               memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
+
+               pi->conn_state |= L2CAP_CONN_SAR_SDU;
+               pi->partial_sdu_len = skb->len;
+               err = 0;
+               break;
+
+       case L2CAP_SDU_CONTINUE:
+               if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
+                       break;
+
+               memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
+
+               pi->partial_sdu_len += skb->len;
+               if (pi->partial_sdu_len > pi->sdu_len)
+                       kfree_skb(pi->sdu);
+               else
+                       err = 0;
+
+               break;
 
        case L2CAP_SDU_END:
                if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
@@ -3234,15 +3715,19 @@ static int l2cap_sar_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 co
                pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
                pi->partial_sdu_len += skb->len;
 
+               if (pi->partial_sdu_len > pi->imtu)
+                       goto drop;
+
                if (pi->partial_sdu_len == pi->sdu_len) {
                        _skb = skb_clone(pi->sdu, GFP_ATOMIC);
                        err = sock_queue_rcv_skb(sk, _skb);
                        if (err < 0)
                                kfree_skb(_skb);
                }
-               kfree_skb(pi->sdu);
                err = 0;
 
+drop:
+               kfree_skb(pi->sdu);
                break;
        }
 
@@ -3253,15 +3738,15 @@ static int l2cap_sar_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 co
 static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
 {
        struct sk_buff *skb;
-       u16 control = 0;
+       u16 control;
 
-       while((skb = skb_peek(SREJ_QUEUE(sk)))) {
+       while ((skb = skb_peek(SREJ_QUEUE(sk)))) {
                if (bt_cb(skb)->tx_seq != tx_seq)
                        break;
 
                skb = skb_dequeue(SREJ_QUEUE(sk));
-               control |= bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
-               l2cap_sar_reassembly_sdu(sk, skb, control);
+               control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
+               l2cap_ertm_reassembly_sdu(sk, skb, control);
                l2cap_pi(sk)->buffer_seq_srej =
                        (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
                tx_seq++;
@@ -3274,7 +3759,7 @@ static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
        struct srej_list *l, *tmp;
        u16 control;
 
-       list_for_each_entry_safe(l,tmp, SREJ_LIST(sk), list) {
+       list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
                if (l->tx_seq == tx_seq) {
                        list_del(&l->list);
                        kfree(l);
@@ -3297,10 +3782,6 @@ static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
        while (tx_seq != pi->expected_tx_seq) {
                control = L2CAP_SUPER_SELECT_REJECT;
                control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
-               if (pi->conn_state & L2CAP_CONN_SEND_PBIT) {
-                       control |= L2CAP_CTRL_POLL;
-                       pi->conn_state &= ~L2CAP_CONN_SEND_PBIT;
-               }
                l2cap_send_sframe(pi, control);
 
                new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
@@ -3315,18 +3796,40 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str
        struct l2cap_pinfo *pi = l2cap_pi(sk);
        u8 tx_seq = __get_txseq(rx_control);
        u8 req_seq = __get_reqseq(rx_control);
-       u16 tx_control = 0;
        u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
+       u8 tx_seq_offset, expected_tx_seq_offset;
+       int num_to_ack = (pi->tx_win/6) + 1;
        int err = 0;
 
        BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
 
+       if (L2CAP_CTRL_FINAL & rx_control &&
+                       l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
+               del_timer(&pi->monitor_timer);
+               if (pi->unacked_frames > 0)
+                       __mod_retrans_timer();
+               pi->conn_state &= ~L2CAP_CONN_WAIT_F;
+       }
+
        pi->expected_ack_seq = req_seq;
        l2cap_drop_acked_frames(sk);
 
        if (tx_seq == pi->expected_tx_seq)
                goto expected;
 
+       tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
+       if (tx_seq_offset < 0)
+               tx_seq_offset += 64;
+
+       /* invalid tx_seq */
+       if (tx_seq_offset >= pi->tx_win) {
+               l2cap_send_disconn_req(pi->conn, sk);
+               goto drop;
+       }
+
+       if (pi->conn_state == L2CAP_CONN_LOCAL_BUSY)
+               goto drop;
+
        if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
                struct srej_list *first;
 
@@ -3342,10 +3845,14 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str
                        if (list_empty(SREJ_LIST(sk))) {
                                pi->buffer_seq = pi->buffer_seq_srej;
                                pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
+                               l2cap_send_ack(pi);
                        }
                } else {
                        struct srej_list *l;
-                       l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
+
+                       /* duplicated tx_seq */
+                       if (l2cap_add_to_srej_queue(sk, skb, tx_seq, sar) < 0)
+                               goto drop;
 
                        list_for_each_entry(l, SREJ_LIST(sk), list) {
                                if (l->tx_seq == tx_seq) {
@@ -3356,12 +3863,22 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str
                        l2cap_send_srejframe(sk, tx_seq);
                }
        } else {
+               expected_tx_seq_offset =
+                       (pi->expected_tx_seq - pi->buffer_seq) % 64;
+               if (expected_tx_seq_offset < 0)
+                       expected_tx_seq_offset += 64;
+
+               /* duplicated tx_seq */
+               if (tx_seq_offset < expected_tx_seq_offset)
+                       goto drop;
+
                pi->conn_state |= L2CAP_CONN_SREJ_SENT;
 
                INIT_LIST_HEAD(SREJ_LIST(sk));
                pi->buffer_seq_srej = pi->buffer_seq;
 
                __skb_queue_head_init(SREJ_QUEUE(sk));
+               __skb_queue_head_init(BUSY_QUEUE(sk));
                l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
 
                pi->conn_state |= L2CAP_CONN_SEND_PBIT;
@@ -3374,153 +3891,189 @@ expected:
        pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
 
        if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
-               l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
+               bt_cb(skb)->tx_seq = tx_seq;
+               bt_cb(skb)->sar = sar;
+               __skb_queue_tail(SREJ_QUEUE(sk), skb);
                return 0;
        }
 
        if (rx_control & L2CAP_CTRL_FINAL) {
                if (pi->conn_state & L2CAP_CONN_REJ_ACT)
                        pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
-               else {
-                       sk->sk_send_head = TX_QUEUE(sk)->next;
-                       pi->next_tx_seq = pi->expected_ack_seq;
-                       l2cap_ertm_send(sk);
-               }
+               else
+                       l2cap_retransmit_frames(sk);
        }
 
-       pi->buffer_seq = (pi->buffer_seq + 1) % 64;
-
-       err = l2cap_sar_reassembly_sdu(sk, skb, rx_control);
+       err = l2cap_push_rx_skb(sk, skb, rx_control);
        if (err < 0)
-               return err;
+               return 0;
+
+       __mod_ack_timer();
+
+       pi->num_acked = (pi->num_acked + 1) % num_to_ack;
+       if (pi->num_acked == num_to_ack - 1)
+               l2cap_send_ack(pi);
 
-       pi->num_to_ack = (pi->num_to_ack + 1) % L2CAP_DEFAULT_NUM_TO_ACK;
-       if (pi->num_to_ack == L2CAP_DEFAULT_NUM_TO_ACK - 1) {
-               tx_control |= L2CAP_SUPER_RCV_READY;
-               tx_control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
-               l2cap_send_sframe(pi, tx_control);
-       }
+       return 0;
+
+drop:
+       kfree_skb(skb);
        return 0;
 }
 
-static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
+static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
 {
        struct l2cap_pinfo *pi = l2cap_pi(sk);
-       u8 tx_seq = __get_reqseq(rx_control);
 
-       BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
+       pi->expected_ack_seq = __get_reqseq(rx_control);
+       l2cap_drop_acked_frames(sk);
 
-       switch (rx_control & L2CAP_CTRL_SUPERVISE) {
-       case L2CAP_SUPER_RCV_READY:
-               if (rx_control & L2CAP_CTRL_POLL) {
-                       u16 control = L2CAP_CTRL_FINAL;
-                       control |= L2CAP_SUPER_RCV_READY |
-                               (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT);
-                       l2cap_send_sframe(l2cap_pi(sk), control);
-                       pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
+       if (rx_control & L2CAP_CTRL_POLL) {
+               if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
+                       if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
+                                       (pi->unacked_frames > 0))
+                               __mod_retrans_timer();
 
-               } else if (rx_control & L2CAP_CTRL_FINAL) {
                        pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
-                       pi->expected_ack_seq = tx_seq;
-                       l2cap_drop_acked_frames(sk);
-
-                       if (pi->conn_state & L2CAP_CONN_REJ_ACT)
-                               pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
-                       else {
-                               sk->sk_send_head = TX_QUEUE(sk)->next;
-                               pi->next_tx_seq = pi->expected_ack_seq;
-                               l2cap_ertm_send(sk);
-                       }
-
-                       if (!(pi->conn_state & L2CAP_CONN_WAIT_F))
-                               break;
+                       l2cap_send_srejtail(sk);
+               } else {
+                       l2cap_send_i_or_rr_or_rnr(sk);
+               }
 
-                       pi->conn_state &= ~L2CAP_CONN_WAIT_F;
-                       del_timer(&pi->monitor_timer);
+       } else if (rx_control & L2CAP_CTRL_FINAL) {
+               pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
 
-                       if (pi->unacked_frames > 0)
-                               __mod_retrans_timer();
-               } else {
-                       pi->expected_ack_seq = tx_seq;
-                       l2cap_drop_acked_frames(sk);
+               if (pi->conn_state & L2CAP_CONN_REJ_ACT)
+                       pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
+               else
+                       l2cap_retransmit_frames(sk);
 
-                       if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
-                           (pi->unacked_frames > 0))
-                               __mod_retrans_timer();
+       } else {
+               if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
+                               (pi->unacked_frames > 0))
+                       __mod_retrans_timer();
 
-                       pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
+               pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
+               if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
+                       l2cap_send_ack(pi);
+               } else {
+                       spin_lock_bh(&pi->send_lock);
                        l2cap_ertm_send(sk);
+                       spin_unlock_bh(&pi->send_lock);
                }
-               break;
+       }
+}
 
-       case L2CAP_SUPER_REJECT:
-               pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
+static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control)
+{
+       struct l2cap_pinfo *pi = l2cap_pi(sk);
+       u8 tx_seq = __get_reqseq(rx_control);
+
+       pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
+
+       pi->expected_ack_seq = tx_seq;
+       l2cap_drop_acked_frames(sk);
 
-               pi->expected_ack_seq = __get_reqseq(rx_control);
+       if (rx_control & L2CAP_CTRL_FINAL) {
+               if (pi->conn_state & L2CAP_CONN_REJ_ACT)
+                       pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
+               else
+                       l2cap_retransmit_frames(sk);
+       } else {
+               l2cap_retransmit_frames(sk);
+
+               if (pi->conn_state & L2CAP_CONN_WAIT_F)
+                       pi->conn_state |= L2CAP_CONN_REJ_ACT;
+       }
+}
+static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control)
+{
+       struct l2cap_pinfo *pi = l2cap_pi(sk);
+       u8 tx_seq = __get_reqseq(rx_control);
+
+       pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
+
+       if (rx_control & L2CAP_CTRL_POLL) {
+               pi->expected_ack_seq = tx_seq;
                l2cap_drop_acked_frames(sk);
+               l2cap_retransmit_one_frame(sk, tx_seq);
 
-               if (rx_control & L2CAP_CTRL_FINAL) {
-                       if (pi->conn_state & L2CAP_CONN_REJ_ACT)
-                               pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
-                       else {
-                               sk->sk_send_head = TX_QUEUE(sk)->next;
-                               pi->next_tx_seq = pi->expected_ack_seq;
-                               l2cap_ertm_send(sk);
-                       }
-               } else {
-                       sk->sk_send_head = TX_QUEUE(sk)->next;
-                       pi->next_tx_seq = pi->expected_ack_seq;
-                       l2cap_ertm_send(sk);
+               spin_lock_bh(&pi->send_lock);
+               l2cap_ertm_send(sk);
+               spin_unlock_bh(&pi->send_lock);
 
-                       if (pi->conn_state & L2CAP_CONN_WAIT_F) {
-                               pi->srej_save_reqseq = tx_seq;
-                               pi->conn_state |= L2CAP_CONN_REJ_ACT;
-                       }
+               if (pi->conn_state & L2CAP_CONN_WAIT_F) {
+                       pi->srej_save_reqseq = tx_seq;
+                       pi->conn_state |= L2CAP_CONN_SREJ_ACT;
+               }
+       } else if (rx_control & L2CAP_CTRL_FINAL) {
+               if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
+                               pi->srej_save_reqseq == tx_seq)
+                       pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
+               else
+                       l2cap_retransmit_one_frame(sk, tx_seq);
+       } else {
+               l2cap_retransmit_one_frame(sk, tx_seq);
+               if (pi->conn_state & L2CAP_CONN_WAIT_F) {
+                       pi->srej_save_reqseq = tx_seq;
+                       pi->conn_state |= L2CAP_CONN_SREJ_ACT;
                }
+       }
+}
 
+static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control)
+{
+       struct l2cap_pinfo *pi = l2cap_pi(sk);
+       u8 tx_seq = __get_reqseq(rx_control);
+
+       pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
+       pi->expected_ack_seq = tx_seq;
+       l2cap_drop_acked_frames(sk);
+
+       if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) {
+               del_timer(&pi->retrans_timer);
+               if (rx_control & L2CAP_CTRL_POLL)
+                       l2cap_send_rr_or_rnr(pi, L2CAP_CTRL_FINAL);
+               return;
+       }
+
+       if (rx_control & L2CAP_CTRL_POLL)
+               l2cap_send_srejtail(sk);
+       else
+               l2cap_send_sframe(pi, L2CAP_SUPER_RCV_READY);
+}
+
+static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
+{
+       BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
+
+       if (L2CAP_CTRL_FINAL & rx_control &&
+                       l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
+               del_timer(&l2cap_pi(sk)->monitor_timer);
+               if (l2cap_pi(sk)->unacked_frames > 0)
+                       __mod_retrans_timer();
+               l2cap_pi(sk)->conn_state &= ~L2CAP_CONN_WAIT_F;
+       }
+
+       switch (rx_control & L2CAP_CTRL_SUPERVISE) {
+       case L2CAP_SUPER_RCV_READY:
+               l2cap_data_channel_rrframe(sk, rx_control);
                break;
 
-       case L2CAP_SUPER_SELECT_REJECT:
-               pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
+       case L2CAP_SUPER_REJECT:
+               l2cap_data_channel_rejframe(sk, rx_control);
+               break;
 
-               if (rx_control & L2CAP_CTRL_POLL) {
-                       pi->expected_ack_seq = tx_seq;
-                       l2cap_drop_acked_frames(sk);
-                       l2cap_retransmit_frame(sk, tx_seq);
-                       l2cap_ertm_send(sk);
-                       if (pi->conn_state & L2CAP_CONN_WAIT_F) {
-                               pi->srej_save_reqseq = tx_seq;
-                               pi->conn_state |= L2CAP_CONN_SREJ_ACT;
-                       }
-               } else if (rx_control & L2CAP_CTRL_FINAL) {
-                       if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
-                                       pi->srej_save_reqseq == tx_seq)
-                               pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
-                       else
-                               l2cap_retransmit_frame(sk, tx_seq);
-               }
-               else {
-                       l2cap_retransmit_frame(sk, tx_seq);
-                       if (pi->conn_state & L2CAP_CONN_WAIT_F) {
-                               pi->srej_save_reqseq = tx_seq;
-                               pi->conn_state |= L2CAP_CONN_SREJ_ACT;
-                       }
-               }
+       case L2CAP_SUPER_SELECT_REJECT:
+               l2cap_data_channel_srejframe(sk, rx_control);
                break;
 
        case L2CAP_SUPER_RCV_NOT_READY:
-               pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
-               pi->expected_ack_seq = tx_seq;
-               l2cap_drop_acked_frames(sk);
-
-               del_timer(&l2cap_pi(sk)->retrans_timer);
-               if (rx_control & L2CAP_CTRL_POLL) {
-                       u16 control = L2CAP_CTRL_FINAL;
-                       l2cap_send_rr_or_rnr(l2cap_pi(sk), control);
-               }
+               l2cap_data_channel_rnrframe(sk, rx_control);
                break;
        }
 
+       kfree_skb(skb);
        return 0;
 }
 
@@ -3529,7 +4082,7 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk
        struct sock *sk;
        struct l2cap_pinfo *pi;
        u16 control, len;
-       u8 tx_seq;
+       u8 tx_seq, req_seq, next_tx_seq_offset, req_seq_offset;
 
        sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
        if (!sk) {
@@ -3574,16 +4127,45 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk
                 * Receiver will miss it and start proper recovery
                 * procedures and ask retransmission.
                 */
-               if (len > L2CAP_DEFAULT_MAX_PDU_SIZE)
+               if (len > pi->mps) {
+                       l2cap_send_disconn_req(pi->conn, sk);
                        goto drop;
+               }
 
                if (l2cap_check_fcs(pi, skb))
                        goto drop;
 
-               if (__is_iframe(control))
+               req_seq = __get_reqseq(control);
+               req_seq_offset = (req_seq - pi->expected_ack_seq) % 64;
+               if (req_seq_offset < 0)
+                       req_seq_offset += 64;
+
+               next_tx_seq_offset =
+                       (pi->next_tx_seq - pi->expected_ack_seq) % 64;
+               if (next_tx_seq_offset < 0)
+                       next_tx_seq_offset += 64;
+
+               /* check for invalid req-seq */
+               if (req_seq_offset > next_tx_seq_offset) {
+                       l2cap_send_disconn_req(pi->conn, sk);
+                       goto drop;
+               }
+
+               if (__is_iframe(control)) {
+                       if (len < 4) {
+                               l2cap_send_disconn_req(pi->conn, sk);
+                               goto drop;
+                       }
+
                        l2cap_data_channel_iframe(sk, control, skb);
-               else
+               } else {
+                       if (len != 0) {
+                               l2cap_send_disconn_req(pi->conn, sk);
+                               goto drop;
+                       }
+
                        l2cap_data_channel_sframe(sk, control, skb);
+               }
 
                goto done;
 
@@ -3598,7 +4180,7 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk
                if (pi->fcs == L2CAP_FCS_CRC16)
                        len -= 2;
 
-               if (len > L2CAP_DEFAULT_MAX_PDU_SIZE || __is_sframe(control))
+               if (len > pi->mps || len < 4 || __is_sframe(control))
                        goto drop;
 
                if (l2cap_check_fcs(pi, skb))
@@ -3609,14 +4191,14 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk
                if (pi->expected_tx_seq == tx_seq)
                        pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
                else
-                       pi->expected_tx_seq = tx_seq + 1;
+                       pi->expected_tx_seq = (tx_seq + 1) % 64;
 
-               l2cap_sar_reassembly_sdu(sk, skb, control);
+               l2cap_streaming_reassembly_sdu(sk, skb, control);
 
                goto done;
 
        default:
-               BT_DBG("sk %p: bad mode 0x%2.2x", sk, l2cap_pi(sk)->mode);
+               BT_DBG("sk %p: bad mode 0x%2.2x", sk, pi->mode);
                break;
        }
 
@@ -3772,7 +4354,7 @@ static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
 
 static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
 {
-       if (sk->sk_type != SOCK_SEQPACKET)
+       if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM)
                return;
 
        if (encrypt == 0x00) {
@@ -4030,6 +4612,10 @@ static int __init l2cap_init(void)
        if (err < 0)
                return err;
 
+       _busy_wq = create_singlethread_workqueue("l2cap");
+       if (!_busy_wq)
+               goto error;
+
        err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
        if (err < 0) {
                BT_ERR("L2CAP socket registration failed");
@@ -4064,6 +4650,9 @@ static void __exit l2cap_exit(void)
 {
        debugfs_remove(l2cap_debugfs);
 
+       flush_workqueue(_busy_wq);
+       destroy_workqueue(_busy_wq);
+
        if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
                BT_ERR("L2CAP socket unregistration failed");
 
@@ -4091,6 +4680,9 @@ MODULE_PARM_DESC(enable_ertm, "Enable enhanced retransmission mode");
 module_param(max_transmit, uint, 0644);
 MODULE_PARM_DESC(max_transmit, "Max transmit value (default = 3)");
 
+module_param(tx_window, uint, 0644);
+MODULE_PARM_DESC(tx_window, "Transmission window size value (default = 63)");
+
 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
 MODULE_VERSION(VERSION);
index b406d3e..4767928 100644 (file)
@@ -165,11 +165,11 @@ static inline int sco_chan_add(struct sco_conn *conn, struct sock *sk, struct so
        int err = 0;
 
        sco_conn_lock(conn);
-       if (conn->sk) {
+       if (conn->sk)
                err = -EBUSY;
-       } else {
+       else
                __sco_chan_add(conn, sk, parent);
-       }
+
        sco_conn_unlock(conn);
        return err;
 }
@@ -241,22 +241,19 @@ static inline int sco_send_frame(struct sock *sk, struct msghdr *msg, int len)
        BT_DBG("sk %p len %d", sk, len);
 
        count = min_t(unsigned int, conn->mtu, len);
-       if (!(skb = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err)))
+       skb = bt_skb_send_alloc(sk, count,
+                       msg->msg_flags & MSG_DONTWAIT, &err);
+       if (!skb)
                return err;
 
        if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
-               err = -EFAULT;
-               goto fail;
+               kfree_skb(skb);
+               return -EFAULT;
        }
 
-       if ((err = hci_send_sco(conn->hcon, skb)) < 0)
-               return err;
+       hci_send_sco(conn->hcon, skb);
 
        return count;
-
-fail:
-       kfree_skb(skb);
-       return err;
 }
 
 static inline void sco_recv_frame(struct sco_conn *conn, struct sk_buff *skb)
@@ -626,7 +623,7 @@ static int sco_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
                            struct msghdr *msg, size_t len)
 {
        struct sock *sk = sock->sk;
-       int err = 0;
+       int err;
 
        BT_DBG("sock %p, sk %p", sock, sk);
 
@@ -851,7 +848,8 @@ static void sco_conn_ready(struct sco_conn *conn)
 
                bh_lock_sock(parent);
 
-               sk = sco_sock_alloc(sock_net(parent), NULL, BTPROTO_SCO, GFP_ATOMIC);
+               sk = sco_sock_alloc(sock_net(parent), NULL,
+                               BTPROTO_SCO, GFP_ATOMIC);
                if (!sk) {
                        bh_unlock_sock(parent);
                        goto done;