dect
/
linux-2.6
Archived
13
0
Fork 0

Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (94 commits)
  pkt_sched: Prevent livelock in TX queue running.
  Revert "pkt_sched: Add BH protection for qdisc_stab_lock."
  Revert "pkt_sched: Protect gen estimators under est_lock."
  pkt_sched: remove bogus block (cleanup)
  nf_nat: use secure_ipv4_port_ephemeral() for NAT port randomization
  netfilter: ctnetlink: sleepable allocation with spin lock bh
  netfilter: ctnetlink: fix sleep in read-side lock section
  netfilter: ctnetlink: fix double helper assignation for NAT'ed conntracks
  netfilter: ipt_addrtype: Fix matching of inverted destination address type
  dccp: Fix panic caused by too early termination of retransmission mechanism
  pkt_sched: Don't hold qdisc lock over qdisc_destroy().
  pkt_sched: Add lockdep annotation for qdisc locks
  pkt_sched: Never schedule non-root qdiscs.
  removed unused #include <version.h>
  rt2x00: Fix txdone_entry_desc_flags
  b43: Fix for another Bluetooth Coexistence SPROM Programming error for BCM4306
  mac80211: remove kdoc references to IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE
  p54u: reset skb's data/tail pointer on requeue
  p54: move p54_vdcf_init to the right place.
  iwlwifi: fix printk newlines
  ...
This commit is contained in:
Linus Torvalds 2008-08-19 09:59:02 -07:00
commit 4309e09242
114 changed files with 1540 additions and 905 deletions

View File

@ -363,6 +363,11 @@ This rule exists because users of the rfkill subsystem expect to get (and set,
when possible) the overall transmitter rfkill state, not of a particular rfkill
line.
5. During suspend, the rfkill class will attempt to soft-block the radio
through a call to rfkill->toggle_radio, and will try to restore its previous
state during resume. After a rfkill class is suspended, it will *not* call
rfkill->toggle_radio until it is resumed.
Example of a WLAN wireless driver connected to the rfkill subsystem:
--------------------------------------------------------------------

View File

@ -942,96 +942,21 @@ M: joern@lazybastard.org
L: linux-mtd@lists.infradead.org
S: Maintained
BLUETOOTH DRIVERS
P: Marcel Holtmann
M: marcel@holtmann.org
L: linux-bluetooth@vger.kernel.org
W: http://www.bluez.org/
S: Maintained
BLUETOOTH SUBSYSTEM
P: Marcel Holtmann
M: marcel@holtmann.org
P: Maxim Krasnyansky
M: maxk@qualcomm.com
L: linux-bluetooth@vger.kernel.org
W: http://bluez.sf.net
W: http://www.bluez.org
W: http://www.holtmann.org/linux/bluetooth/
W: http://www.bluez.org/
T: git kernel.org:/pub/scm/linux/kernel/git/holtmann/bluetooth-2.6.git
S: Maintained
BLUETOOTH RFCOMM LAYER
P: Marcel Holtmann
M: marcel@holtmann.org
P: Maxim Krasnyansky
M: maxk@qualcomm.com
S: Maintained
BLUETOOTH BNEP LAYER
P: Marcel Holtmann
M: marcel@holtmann.org
P: Maxim Krasnyansky
M: maxk@qualcomm.com
S: Maintained
BLUETOOTH CMTP LAYER
P: Marcel Holtmann
M: marcel@holtmann.org
S: Maintained
BLUETOOTH HIDP LAYER
P: Marcel Holtmann
M: marcel@holtmann.org
S: Maintained
BLUETOOTH HCI UART DRIVER
P: Marcel Holtmann
M: marcel@holtmann.org
P: Maxim Krasnyansky
M: maxk@qualcomm.com
S: Maintained
BLUETOOTH HCI USB DRIVER
P: Marcel Holtmann
M: marcel@holtmann.org
P: Maxim Krasnyansky
M: maxk@qualcomm.com
S: Maintained
BLUETOOTH HCI BCM203X DRIVER
P: Marcel Holtmann
M: marcel@holtmann.org
S: Maintained
BLUETOOTH HCI BPA10X DRIVER
P: Marcel Holtmann
M: marcel@holtmann.org
S: Maintained
BLUETOOTH HCI BFUSB DRIVER
P: Marcel Holtmann
M: marcel@holtmann.org
S: Maintained
BLUETOOTH HCI DTL1 DRIVER
P: Marcel Holtmann
M: marcel@holtmann.org
S: Maintained
BLUETOOTH HCI BLUECARD DRIVER
P: Marcel Holtmann
M: marcel@holtmann.org
S: Maintained
BLUETOOTH HCI BT3C DRIVER
P: Marcel Holtmann
M: marcel@holtmann.org
S: Maintained
BLUETOOTH HCI BTUART DRIVER
P: Marcel Holtmann
M: marcel@holtmann.org
S: Maintained
BLUETOOTH HCI VHCI DRIVER
P: Maxim Krasnyansky
M: maxk@qualcomm.com
S: Maintained
BONDING DRIVER
P: Jay Vosburgh
M: fubar@us.ibm.com

View File

@ -3,8 +3,8 @@ menu "Bluetooth device drivers"
depends on BT
config BT_HCIUSB
tristate "HCI USB driver"
depends on USB
tristate "HCI USB driver (old version)"
depends on USB && BT_HCIBTUSB=n
help
Bluetooth HCI USB driver.
This driver is required if you want to use Bluetooth devices with
@ -23,15 +23,13 @@ config BT_HCIUSB_SCO
Say Y here to compile support for SCO over HCI USB.
config BT_HCIBTUSB
tristate "HCI USB driver (alternate version)"
depends on USB && EXPERIMENTAL && BT_HCIUSB=n
tristate "HCI USB driver"
depends on USB
help
Bluetooth HCI USB driver.
This driver is required if you want to use Bluetooth devices with
USB interface.
This driver is still experimental and has no SCO support.
Say Y here to compile support for Bluetooth USB devices into the
kernel or say M to compile it as module (btusb).

View File

@ -60,7 +60,7 @@
/* ======================== Module parameters ======================== */
MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>, Jose Orlando Pereira <jop@di.uminho.pt>");
MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
MODULE_DESCRIPTION("Bluetooth driver for the 3Com Bluetooth PCMCIA card");
MODULE_LICENSE("GPL");
MODULE_FIRMWARE("BT3CPCC.bin");

View File

@ -2,7 +2,7 @@
*
* Generic Bluetooth USB driver
*
* Copyright (C) 2005-2007 Marcel Holtmann <marcel@holtmann.org>
* Copyright (C) 2005-2008 Marcel Holtmann <marcel@holtmann.org>
*
*
* This program is free software; you can redistribute it and/or modify
@ -41,7 +41,7 @@
#define BT_DBG(D...)
#endif
#define VERSION "0.2"
#define VERSION "0.3"
static int ignore_dga;
static int ignore_csr;
@ -160,12 +160,16 @@ static struct usb_device_id blacklist_table[] = {
{ } /* Terminating entry */
};
#define BTUSB_MAX_ISOC_FRAMES 10
#define BTUSB_INTR_RUNNING 0
#define BTUSB_BULK_RUNNING 1
#define BTUSB_ISOC_RUNNING 2
struct btusb_data {
struct hci_dev *hdev;
struct usb_device *udev;
struct usb_interface *isoc;
spinlock_t lock;
@ -176,10 +180,15 @@ struct btusb_data {
struct usb_anchor tx_anchor;
struct usb_anchor intr_anchor;
struct usb_anchor bulk_anchor;
struct usb_anchor isoc_anchor;
struct usb_endpoint_descriptor *intr_ep;
struct usb_endpoint_descriptor *bulk_tx_ep;
struct usb_endpoint_descriptor *bulk_rx_ep;
struct usb_endpoint_descriptor *isoc_tx_ep;
struct usb_endpoint_descriptor *isoc_rx_ep;
int isoc_altsetting;
};
static void btusb_intr_complete(struct urb *urb)
@ -195,6 +204,8 @@ static void btusb_intr_complete(struct urb *urb)
return;
if (urb->status == 0) {
hdev->stat.byte_rx += urb->actual_length;
if (hci_recv_fragment(hdev, HCI_EVENT_PKT,
urb->transfer_buffer,
urb->actual_length) < 0) {
@ -216,7 +227,7 @@ static void btusb_intr_complete(struct urb *urb)
}
}
static inline int btusb_submit_intr_urb(struct hci_dev *hdev)
static int btusb_submit_intr_urb(struct hci_dev *hdev)
{
struct btusb_data *data = hdev->driver_data;
struct urb *urb;
@ -226,6 +237,9 @@ static inline int btusb_submit_intr_urb(struct hci_dev *hdev)
BT_DBG("%s", hdev->name);
if (!data->intr_ep)
return -ENODEV;
urb = usb_alloc_urb(0, GFP_ATOMIC);
if (!urb)
return -ENOMEM;
@ -274,6 +288,8 @@ static void btusb_bulk_complete(struct urb *urb)
return;
if (urb->status == 0) {
hdev->stat.byte_rx += urb->actual_length;
if (hci_recv_fragment(hdev, HCI_ACLDATA_PKT,
urb->transfer_buffer,
urb->actual_length) < 0) {
@ -295,7 +311,7 @@ static void btusb_bulk_complete(struct urb *urb)
}
}
static inline int btusb_submit_bulk_urb(struct hci_dev *hdev)
static int btusb_submit_bulk_urb(struct hci_dev *hdev)
{
struct btusb_data *data = hdev->driver_data;
struct urb *urb;
@ -305,6 +321,9 @@ static inline int btusb_submit_bulk_urb(struct hci_dev *hdev)
BT_DBG("%s", hdev->name);
if (!data->bulk_rx_ep)
return -ENODEV;
urb = usb_alloc_urb(0, GFP_KERNEL);
if (!urb)
return -ENOMEM;
@ -339,6 +358,127 @@ static inline int btusb_submit_bulk_urb(struct hci_dev *hdev)
return err;
}
static void btusb_isoc_complete(struct urb *urb)
{
struct hci_dev *hdev = urb->context;
struct btusb_data *data = hdev->driver_data;
int i, err;
BT_DBG("%s urb %p status %d count %d", hdev->name,
urb, urb->status, urb->actual_length);
if (!test_bit(HCI_RUNNING, &hdev->flags))
return;
if (urb->status == 0) {
for (i = 0; i < urb->number_of_packets; i++) {
unsigned int offset = urb->iso_frame_desc[i].offset;
unsigned int length = urb->iso_frame_desc[i].actual_length;
if (urb->iso_frame_desc[i].status)
continue;
hdev->stat.byte_rx += length;
if (hci_recv_fragment(hdev, HCI_SCODATA_PKT,
urb->transfer_buffer + offset,
length) < 0) {
BT_ERR("%s corrupted SCO packet", hdev->name);
hdev->stat.err_rx++;
}
}
}
if (!test_bit(BTUSB_ISOC_RUNNING, &data->flags))
return;
usb_anchor_urb(urb, &data->isoc_anchor);
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err < 0) {
BT_ERR("%s urb %p failed to resubmit (%d)",
hdev->name, urb, -err);
usb_unanchor_urb(urb);
}
}
static void inline __fill_isoc_descriptor(struct urb *urb, int len, int mtu)
{
int i, offset = 0;
BT_DBG("len %d mtu %d", len, mtu);
for (i = 0; i < BTUSB_MAX_ISOC_FRAMES && len >= mtu;
i++, offset += mtu, len -= mtu) {
urb->iso_frame_desc[i].offset = offset;
urb->iso_frame_desc[i].length = mtu;
}
if (len && i < BTUSB_MAX_ISOC_FRAMES) {
urb->iso_frame_desc[i].offset = offset;
urb->iso_frame_desc[i].length = len;
i++;
}
urb->number_of_packets = i;
}
static int btusb_submit_isoc_urb(struct hci_dev *hdev)
{
struct btusb_data *data = hdev->driver_data;
struct urb *urb;
unsigned char *buf;
unsigned int pipe;
int err, size;
BT_DBG("%s", hdev->name);
if (!data->isoc_rx_ep)
return -ENODEV;
urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_KERNEL);
if (!urb)
return -ENOMEM;
size = le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize) *
BTUSB_MAX_ISOC_FRAMES;
buf = kmalloc(size, GFP_KERNEL);
if (!buf) {
usb_free_urb(urb);
return -ENOMEM;
}
pipe = usb_rcvisocpipe(data->udev, data->isoc_rx_ep->bEndpointAddress);
urb->dev = data->udev;
urb->pipe = pipe;
urb->context = hdev;
urb->complete = btusb_isoc_complete;
urb->interval = data->isoc_rx_ep->bInterval;
urb->transfer_flags = URB_FREE_BUFFER | URB_ISO_ASAP;
urb->transfer_buffer = buf;
urb->transfer_buffer_length = size;
__fill_isoc_descriptor(urb, size,
le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize));
usb_anchor_urb(urb, &data->isoc_anchor);
err = usb_submit_urb(urb, GFP_KERNEL);
if (err < 0) {
BT_ERR("%s urb %p submission failed (%d)",
hdev->name, urb, -err);
usb_unanchor_urb(urb);
kfree(buf);
}
usb_free_urb(urb);
return err;
}
static void btusb_tx_complete(struct urb *urb)
{
struct sk_buff *skb = urb->context;
@ -392,6 +532,9 @@ static int btusb_close(struct hci_dev *hdev)
if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
return 0;
clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
usb_kill_anchored_urbs(&data->intr_anchor);
clear_bit(BTUSB_BULK_RUNNING, &data->flags);
usb_kill_anchored_urbs(&data->bulk_anchor);
@ -453,6 +596,9 @@ static int btusb_send_frame(struct sk_buff *skb)
break;
case HCI_ACLDATA_PKT:
if (!data->bulk_tx_ep || hdev->conn_hash.acl_num < 1)
return -ENODEV;
urb = usb_alloc_urb(0, GFP_ATOMIC);
if (!urb)
return -ENOMEM;
@ -467,9 +613,31 @@ static int btusb_send_frame(struct sk_buff *skb)
break;
case HCI_SCODATA_PKT:
if (!data->isoc_tx_ep || hdev->conn_hash.sco_num < 1)
return -ENODEV;
urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_ATOMIC);
if (!urb)
return -ENOMEM;
pipe = usb_sndisocpipe(data->udev,
data->isoc_tx_ep->bEndpointAddress);
urb->dev = data->udev;
urb->pipe = pipe;
urb->context = skb;
urb->complete = btusb_tx_complete;
urb->interval = data->isoc_tx_ep->bInterval;
urb->transfer_flags = URB_ISO_ASAP;
urb->transfer_buffer = skb->data;
urb->transfer_buffer_length = skb->len;
__fill_isoc_descriptor(urb, skb->len,
le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize));
hdev->stat.sco_tx++;
kfree_skb(skb);
return 0;
break;
default:
return -EILSEQ;
@ -508,22 +676,86 @@ static void btusb_notify(struct hci_dev *hdev, unsigned int evt)
schedule_work(&data->work);
}
static int inline __set_isoc_interface(struct hci_dev *hdev, int altsetting)
{
struct btusb_data *data = hdev->driver_data;
struct usb_interface *intf = data->isoc;
struct usb_endpoint_descriptor *ep_desc;
int i, err;
if (!data->isoc)
return -ENODEV;
err = usb_set_interface(data->udev, 1, altsetting);
if (err < 0) {
BT_ERR("%s setting interface failed (%d)", hdev->name, -err);
return err;
}
data->isoc_altsetting = altsetting;
data->isoc_tx_ep = NULL;
data->isoc_rx_ep = NULL;
for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
ep_desc = &intf->cur_altsetting->endpoint[i].desc;
if (!data->isoc_tx_ep && usb_endpoint_is_isoc_out(ep_desc)) {
data->isoc_tx_ep = ep_desc;
continue;
}
if (!data->isoc_rx_ep && usb_endpoint_is_isoc_in(ep_desc)) {
data->isoc_rx_ep = ep_desc;
continue;
}
}
if (!data->isoc_tx_ep || !data->isoc_rx_ep) {
BT_ERR("%s invalid SCO descriptors", hdev->name);
return -ENODEV;
}
return 0;
}
static void btusb_work(struct work_struct *work)
{
struct btusb_data *data = container_of(work, struct btusb_data, work);
struct hci_dev *hdev = data->hdev;
if (hdev->conn_hash.acl_num == 0) {
if (hdev->conn_hash.acl_num > 0) {
if (!test_and_set_bit(BTUSB_BULK_RUNNING, &data->flags)) {
if (btusb_submit_bulk_urb(hdev) < 0)
clear_bit(BTUSB_BULK_RUNNING, &data->flags);
else
btusb_submit_bulk_urb(hdev);
}
} else {
clear_bit(BTUSB_BULK_RUNNING, &data->flags);
usb_kill_anchored_urbs(&data->bulk_anchor);
return;
}
if (!test_and_set_bit(BTUSB_BULK_RUNNING, &data->flags)) {
if (btusb_submit_bulk_urb(hdev) < 0)
clear_bit(BTUSB_BULK_RUNNING, &data->flags);
else
btusb_submit_bulk_urb(hdev);
if (hdev->conn_hash.sco_num > 0) {
if (data->isoc_altsetting != 2) {
clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
usb_kill_anchored_urbs(&data->isoc_anchor);
if (__set_isoc_interface(hdev, 2) < 0)
return;
}
if (!test_and_set_bit(BTUSB_ISOC_RUNNING, &data->flags)) {
if (btusb_submit_isoc_urb(hdev) < 0)
clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
else
btusb_submit_isoc_urb(hdev);
}
} else {
clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
usb_kill_anchored_urbs(&data->isoc_anchor);
__set_isoc_interface(hdev, 0);
}
}
@ -597,6 +829,7 @@ static int btusb_probe(struct usb_interface *intf,
init_usb_anchor(&data->tx_anchor);
init_usb_anchor(&data->intr_anchor);
init_usb_anchor(&data->bulk_anchor);
init_usb_anchor(&data->isoc_anchor);
hdev = hci_alloc_dev();
if (!hdev) {
@ -620,6 +853,9 @@ static int btusb_probe(struct usb_interface *intf,
hdev->owner = THIS_MODULE;
/* interface numbers are hardcoded in the spec */
data->isoc = usb_ifnum_to_if(data->udev, 1);
if (reset || id->driver_info & BTUSB_RESET)
set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks);
@ -628,11 +864,16 @@ static int btusb_probe(struct usb_interface *intf,
set_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks);
}
if (id->driver_info & BTUSB_BROKEN_ISOC)
data->isoc = NULL;
if (id->driver_info & BTUSB_SNIFFER) {
struct usb_device *udev = interface_to_usbdev(intf);
struct usb_device *udev = data->udev;
if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997)
set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
data->isoc = NULL;
}
if (id->driver_info & BTUSB_BCM92035) {
@ -646,6 +887,16 @@ static int btusb_probe(struct usb_interface *intf,
}
}
if (data->isoc) {
err = usb_driver_claim_interface(&btusb_driver,
data->isoc, NULL);
if (err < 0) {
hci_free_dev(hdev);
kfree(data);
return err;
}
}
err = hci_register_dev(hdev);
if (err < 0) {
hci_free_dev(hdev);
@ -670,6 +921,9 @@ static void btusb_disconnect(struct usb_interface *intf)
hdev = data->hdev;
if (data->isoc)
usb_driver_release_interface(&btusb_driver, data->isoc);
usb_set_intfdata(intf, NULL);
hci_unregister_dev(hdev);

View File

@ -577,7 +577,7 @@ module_exit(hci_uart_exit);
module_param(reset, bool, 0644);
MODULE_PARM_DESC(reset, "Send HCI reset command on initialization");
MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
MODULE_DESCRIPTION("Bluetooth HCI UART driver ver " VERSION);
MODULE_VERSION(VERSION);
MODULE_LICENSE("GPL");

View File

@ -1130,7 +1130,7 @@ module_param(isoc, int, 0644);
MODULE_PARM_DESC(isoc, "Set isochronous transfers for SCO over HCI support");
#endif
MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
MODULE_DESCRIPTION("Bluetooth HCI USB driver ver " VERSION);
MODULE_VERSION(VERSION);
MODULE_LICENSE("GPL");

View File

@ -377,7 +377,7 @@ module_exit(vhci_exit);
module_param(minor, int, 0444);
MODULE_PARM_DESC(minor, "Miscellaneous minor device number");
MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
MODULE_DESCRIPTION("Bluetooth virtual HCI driver ver " VERSION);
MODULE_VERSION(VERSION);
MODULE_LICENSE("GPL");

View File

@ -1571,6 +1571,7 @@ u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport)
return half_md4_transform(hash, keyptr->secret);
}
EXPORT_SYMBOL_GPL(secure_ipv4_port_ephemeral);
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,

View File

@ -1172,7 +1172,7 @@ config ETH16I
config NE2000
tristate "NE2000/NE1000 support"
depends on NET_ISA || (Q40 && m) || M32R || TOSHIBA_RBTX4927 || TOSHIBA_RBTX4938
depends on NET_ISA || (Q40 && m) || M32R || MACH_TX49XX
select CRC32
---help---
If you have a network (Ethernet) card of this type, say Y and read

View File

@ -52,7 +52,6 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/version.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/ioport.h>

View File

@ -551,7 +551,7 @@ static int eth_poll(struct napi_struct *napi, int budget)
if ((skb = netdev_alloc_skb(dev, RX_BUFF_SIZE))) {
phys = dma_map_single(&dev->dev, skb->data,
RX_BUFF_SIZE, DMA_FROM_DEVICE);
if (dma_mapping_error(phys)) {
if (dma_mapping_error(&dev->dev, phys)) {
dev_kfree_skb(skb);
skb = NULL;
}
@ -698,7 +698,7 @@ static int eth_xmit(struct sk_buff *skb, struct net_device *dev)
#endif
phys = dma_map_single(&dev->dev, mem, bytes, DMA_TO_DEVICE);
if (dma_mapping_error(phys)) {
if (dma_mapping_error(&dev->dev, phys)) {
#ifdef __ARMEB__
dev_kfree_skb(skb);
#else
@ -883,7 +883,7 @@ static int init_queues(struct port *port)
desc->buf_len = MAX_MRU;
desc->data = dma_map_single(&port->netdev->dev, data,
RX_BUFF_SIZE, DMA_FROM_DEVICE);
if (dma_mapping_error(desc->data)) {
if (dma_mapping_error(&port->netdev->dev, desc->data)) {
free_buffer(buff);
return -EIO;
}

View File

@ -355,7 +355,7 @@ static int atl1e_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
struct atl1e_adapter *adapter = netdev_priv(netdev);
if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE |
WAKE_MCAST | WAKE_BCAST | WAKE_MCAST))
WAKE_UCAST | WAKE_MCAST | WAKE_BCAST))
return -EOPNOTSUPP;
/* these settings will always override what we currently have */
adapter->wol = 0;

View File

@ -807,7 +807,7 @@ err_out:
static int au1000_init(struct net_device *dev)
{
struct au1000_private *aup = (struct au1000_private *) dev->priv;
u32 flags;
unsigned long flags;
int i;
u32 control;

View File

@ -554,7 +554,7 @@ static int ax_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
spin_lock_irqsave(&ax->mii_lock, flags);
mii_ethtool_gset(&ax->mii, cmd);
spin_lock_irqsave(&ax->mii_lock, flags);
spin_unlock_irqrestore(&ax->mii_lock, flags);
return 0;
}
@ -567,7 +567,7 @@ static int ax_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
spin_lock_irqsave(&ax->mii_lock, flags);
rc = mii_ethtool_sset(&ax->mii, cmd);
spin_lock_irqsave(&ax->mii_lock, flags);
spin_unlock_irqrestore(&ax->mii_lock, flags);
return rc;
}

View File

@ -35,8 +35,8 @@
#include <linux/time.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
#ifdef NETIF_F_HW_VLAN_TX
#include <linux/if_vlan.h>
#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
#define BCM_VLAN 1
#endif
#include <net/ip.h>
@ -57,8 +57,8 @@
#define DRV_MODULE_NAME "bnx2"
#define PFX DRV_MODULE_NAME ": "
#define DRV_MODULE_VERSION "1.7.9"
#define DRV_MODULE_RELDATE "July 18, 2008"
#define DRV_MODULE_VERSION "1.8.0"
#define DRV_MODULE_RELDATE "Aug 14, 2008"
#define RUN_AT(x) (jiffies + (x))
@ -2876,6 +2876,8 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
struct sw_bd *rx_buf;
struct sk_buff *skb;
dma_addr_t dma_addr;
u16 vtag = 0;
int hw_vlan __maybe_unused = 0;
sw_ring_cons = RX_RING_IDX(sw_cons);
sw_ring_prod = RX_RING_IDX(sw_prod);
@ -2919,7 +2921,7 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
if (len <= bp->rx_copy_thresh) {
struct sk_buff *new_skb;
new_skb = netdev_alloc_skb(bp->dev, len + 2);
new_skb = netdev_alloc_skb(bp->dev, len + 6);
if (new_skb == NULL) {
bnx2_reuse_rx_skb(bp, rxr, skb, sw_ring_cons,
sw_ring_prod);
@ -2928,9 +2930,9 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
/* aligned copy */
skb_copy_from_linear_data_offset(skb,
BNX2_RX_OFFSET - 2,
new_skb->data, len + 2);
skb_reserve(new_skb, 2);
BNX2_RX_OFFSET - 6,
new_skb->data, len + 6);
skb_reserve(new_skb, 6);
skb_put(new_skb, len);
bnx2_reuse_rx_skb(bp, rxr, skb,
@ -2941,6 +2943,25 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
dma_addr, (sw_ring_cons << 16) | sw_ring_prod)))
goto next_rx;
if ((status & L2_FHDR_STATUS_L2_VLAN_TAG) &&
!(bp->rx_mode & BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG)) {
vtag = rx_hdr->l2_fhdr_vlan_tag;
#ifdef BCM_VLAN
if (bp->vlgrp)
hw_vlan = 1;
else
#endif
{
struct vlan_ethhdr *ve = (struct vlan_ethhdr *)
__skb_push(skb, 4);
memmove(ve, skb->data + 4, ETH_ALEN * 2);
ve->h_vlan_proto = htons(ETH_P_8021Q);
ve->h_vlan_TCI = htons(vtag);
len += 4;
}
}
skb->protocol = eth_type_trans(skb, bp->dev);
if ((len > (bp->dev->mtu + ETH_HLEN)) &&
@ -2962,10 +2983,8 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
}
#ifdef BCM_VLAN
if ((status & L2_FHDR_STATUS_L2_VLAN_TAG) && bp->vlgrp) {
vlan_hwaccel_receive_skb(skb, bp->vlgrp,
rx_hdr->l2_fhdr_vlan_tag);
}
if (hw_vlan)
vlan_hwaccel_receive_skb(skb, bp->vlgrp, vtag);
else
#endif
netif_receive_skb(skb);
@ -3237,10 +3256,10 @@ bnx2_set_rx_mode(struct net_device *dev)
BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG);
sort_mode = 1 | BNX2_RPM_SORT_USER0_BC_EN;
#ifdef BCM_VLAN
if (!bp->vlgrp && !(bp->flags & BNX2_FLAG_ASF_ENABLE))
if (!bp->vlgrp && (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN))
rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG;
#else
if (!(bp->flags & BNX2_FLAG_ASF_ENABLE))
if (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN)
rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG;
#endif
if (dev->flags & IFF_PROMISC) {
@ -5963,10 +5982,12 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
vlan_tag_flags |= TX_BD_FLAGS_TCP_UDP_CKSUM;
}
#ifdef BCM_VLAN
if (bp->vlgrp && vlan_tx_tag_present(skb)) {
vlan_tag_flags |=
(TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16));
}
#endif
if ((mss = skb_shinfo(skb)->gso_size)) {
u32 tcp_opt_len, ip_tcp_len;
struct iphdr *iph;

View File

@ -21,7 +21,6 @@
#include <linux/delay.h>
#include <linux/ethtool.h>
#include <linux/mutex.h>
#include <linux/version.h>
#include "bnx2x_reg.h"
#include "bnx2x_fw_defs.h"

View File

@ -44,7 +44,6 @@
#include <net/ip.h>
#include <net/tcp.h>
#include <net/checksum.h>
#include <linux/version.h>
#include <net/ip6_checksum.h>
#include <linux/workqueue.h>
#include <linux/crc32.h>

View File

@ -26,7 +26,6 @@
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/version.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>

View File

@ -389,7 +389,7 @@
/* Interrupt Cause Set */
#define E1000_ICS_LSC E1000_ICR_LSC /* Link Status Change */
#define E1000_ICS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
#define E1000_ICS_RXSEQ E1000_ICR_RXSEQ /* Rx sequence error */
#define E1000_ICS_RXDMT0 E1000_ICR_RXDMT0 /* Rx desc min. threshold */
/* Transmit Descriptor Control */

View File

@ -326,6 +326,7 @@ struct e1000_info {
#define FLAG_RX_CSUM_ENABLED (1 << 28)
#define FLAG_TSO_FORCE (1 << 29)
#define FLAG_RX_RESTART_NOW (1 << 30)
#define FLAG_MSI_TEST_FAILED (1 << 31)
#define E1000_RX_DESC_PS(R, i) \
(&(((union e1000_rx_desc_packet_split *)((R).desc))[i]))

View File

@ -177,7 +177,7 @@ static u32 e1000_get_link(struct net_device *netdev)
u32 status;
status = er32(STATUS);
return (status & E1000_STATUS_LU);
return (status & E1000_STATUS_LU) ? 1 : 0;
}
static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)

View File

@ -510,9 +510,12 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
netdev_alloc_skb(netdev, length + NET_IP_ALIGN);
if (new_skb) {
skb_reserve(new_skb, NET_IP_ALIGN);
memcpy(new_skb->data - NET_IP_ALIGN,
skb->data - NET_IP_ALIGN,
length + NET_IP_ALIGN);
skb_copy_to_linear_data_offset(new_skb,
-NET_IP_ALIGN,
(skb->data -
NET_IP_ALIGN),
(length +
NET_IP_ALIGN));
/* save the skb in buffer_info as good */
buffer_info->skb = skb;
skb = new_skb;
@ -1233,26 +1236,36 @@ static irqreturn_t e1000_intr(int irq, void *data)
return IRQ_HANDLED;
}
/**
* e1000_request_irq - initialize interrupts
*
* Attempts to configure interrupts using the best available
* capabilities of the hardware and kernel.
**/
static int e1000_request_irq(struct e1000_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
irq_handler_t handler = e1000_intr;
int irq_flags = IRQF_SHARED;
int err;
if (!pci_enable_msi(adapter->pdev)) {
adapter->flags |= FLAG_MSI_ENABLED;
handler = e1000_intr_msi;
irq_flags = 0;
if (!(adapter->flags & FLAG_MSI_TEST_FAILED)) {
err = pci_enable_msi(adapter->pdev);
if (!err) {
adapter->flags |= FLAG_MSI_ENABLED;
irq_flags = 0;
}
}
err = request_irq(adapter->pdev->irq, handler, irq_flags, netdev->name,
netdev);
err = request_irq(adapter->pdev->irq,
((adapter->flags & FLAG_MSI_ENABLED) ?
&e1000_intr_msi : &e1000_intr),
irq_flags, netdev->name, netdev);
if (err) {
e_err("Unable to allocate %s interrupt (return: %d)\n",
adapter->flags & FLAG_MSI_ENABLED ? "MSI":"INTx", err);
if (adapter->flags & FLAG_MSI_ENABLED)
if (adapter->flags & FLAG_MSI_ENABLED) {
pci_disable_msi(adapter->pdev);
adapter->flags &= ~FLAG_MSI_ENABLED;
}
e_err("Unable to allocate interrupt, Error: %d\n", err);
}
return err;
@ -2591,6 +2604,135 @@ err:
return -ENOMEM;
}
/**
* e1000_intr_msi_test - Interrupt Handler
* @irq: interrupt number
* @data: pointer to a network interface device structure
**/
static irqreturn_t e1000_intr_msi_test(int irq, void *data)
{
struct net_device *netdev = data;
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
u32 icr = er32(ICR);
e_dbg("%s: icr is %08X\n", netdev->name, icr);
if (icr & E1000_ICR_RXSEQ) {
adapter->flags &= ~FLAG_MSI_TEST_FAILED;
wmb();
}
return IRQ_HANDLED;
}
/**
* e1000_test_msi_interrupt - Returns 0 for successful test
* @adapter: board private struct
*
* code flow taken from tg3.c
**/
static int e1000_test_msi_interrupt(struct e1000_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
struct e1000_hw *hw = &adapter->hw;
int err;
/* poll_enable hasn't been called yet, so don't need disable */
/* clear any pending events */
er32(ICR);
/* free the real vector and request a test handler */
e1000_free_irq(adapter);
/* Assume that the test fails, if it succeeds then the test
* MSI irq handler will unset this flag */
adapter->flags |= FLAG_MSI_TEST_FAILED;
err = pci_enable_msi(adapter->pdev);
if (err)
goto msi_test_failed;
err = request_irq(adapter->pdev->irq, &e1000_intr_msi_test, 0,
netdev->name, netdev);
if (err) {
pci_disable_msi(adapter->pdev);
goto msi_test_failed;
}
wmb();
e1000_irq_enable(adapter);
/* fire an unusual interrupt on the test handler */
ew32(ICS, E1000_ICS_RXSEQ);
e1e_flush();
msleep(50);
e1000_irq_disable(adapter);
rmb();
if (adapter->flags & FLAG_MSI_TEST_FAILED) {
err = -EIO;
e_info("MSI interrupt test failed!\n");
}
free_irq(adapter->pdev->irq, netdev);
pci_disable_msi(adapter->pdev);
if (err == -EIO)
goto msi_test_failed;
/* okay so the test worked, restore settings */
e_dbg("%s: MSI interrupt test succeeded!\n", netdev->name);
msi_test_failed:
/* restore the original vector, even if it failed */
e1000_request_irq(adapter);
return err;
}
/**
* e1000_test_msi - Returns 0 if MSI test succeeds or INTx mode is restored
* @adapter: board private struct
*
* code flow taken from tg3.c, called with e1000 interrupts disabled.
**/
static int e1000_test_msi(struct e1000_adapter *adapter)
{
int err;
u16 pci_cmd;
if (!(adapter->flags & FLAG_MSI_ENABLED))
return 0;
/* disable SERR in case the MSI write causes a master abort */
pci_read_config_word(adapter->pdev, PCI_COMMAND, &pci_cmd);
pci_write_config_word(adapter->pdev, PCI_COMMAND,
pci_cmd & ~PCI_COMMAND_SERR);
err = e1000_test_msi_interrupt(adapter);
/* restore previous setting of command word */
pci_write_config_word(adapter->pdev, PCI_COMMAND, pci_cmd);
/* success ! */
if (!err)
return 0;
/* EIO means MSI test failed */
if (err != -EIO)
return err;
/* back to INTx mode */
e_warn("MSI interrupt test failed, using legacy interrupt.\n");
e1000_free_irq(adapter);
err = e1000_request_irq(adapter);
return err;
}
/**
* e1000_open - Called when a network interface is made active
* @netdev: network interface device structure
@ -2649,6 +2791,19 @@ static int e1000_open(struct net_device *netdev)
if (err)
goto err_req_irq;
/*
* Work around PCIe errata with MSI interrupts causing some chipsets to
* ignore e1000e MSI messages, which means we need to test our MSI
* interrupt now
*/
{
err = e1000_test_msi(adapter);
if (err) {
e_err("Interrupt allocation failed\n");
goto err_req_irq;
}
}
/* From here on the code is the same as e1000e_up() */
clear_bit(__E1000_DOWN, &adapter->state);
@ -3055,7 +3210,7 @@ static void e1000_watchdog_task(struct work_struct *work)
case SPEED_10:
txb2b = 0;
netdev->tx_queue_len = 10;
adapter->tx_timeout_factor = 14;
adapter->tx_timeout_factor = 16;
break;
case SPEED_100:
txb2b = 0;
@ -3721,7 +3876,7 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
struct e1000_adapter *adapter = netdev_priv(netdev);
int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) ||
if ((new_mtu < ETH_ZLEN + ETH_FCS_LEN + VLAN_HLEN) ||
(max_frame > MAX_JUMBO_FRAME_SIZE)) {
e_err("Invalid MTU setting\n");
return -EINVAL;

View File

@ -324,14 +324,27 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
adapter->itr = 20000;
break;
default:
e1000_validate_option(&adapter->itr, &opt,
adapter);
/*
* save the setting, because the dynamic bits
* change itr. clear the lower two bits
* because they are used as control
* Save the setting, because the dynamic bits
* change itr.
*/
adapter->itr_setting = adapter->itr & ~3;
if (e1000_validate_option(&adapter->itr, &opt,
adapter) &&
(adapter->itr == 3)) {
/*
* In case of invalid user value,
* default to conservative mode.
*/
adapter->itr_setting = adapter->itr;
adapter->itr = 20000;
} else {
/*
* Clear the lower two bits because
* they are used as control.
*/
adapter->itr_setting =
adapter->itr & ~3;
}
break;
}
} else {

View File

@ -134,9 +134,7 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int l
static void gfar_vlan_rx_register(struct net_device *netdev,
struct vlan_group *grp);
void gfar_halt(struct net_device *dev);
#ifdef CONFIG_PM
static void gfar_halt_nodisable(struct net_device *dev);
#endif
void gfar_start(struct net_device *dev);
static void gfar_clear_exact_match(struct net_device *dev);
static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr);
@ -631,7 +629,6 @@ static void init_registers(struct net_device *dev)
}
#ifdef CONFIG_PM
/* Halt the receive and transmit queues */
static void gfar_halt_nodisable(struct net_device *dev)
{
@ -657,7 +654,6 @@ static void gfar_halt_nodisable(struct net_device *dev)
cpu_relax();
}
}
#endif
/* Halt the receive and transmit queues */
void gfar_halt(struct net_device *dev)
@ -666,6 +662,8 @@ void gfar_halt(struct net_device *dev)
struct gfar __iomem *regs = priv->regs;
u32 tempval;
gfar_halt_nodisable(dev);
/* Disable Rx and Tx */
tempval = gfar_read(&regs->maccfg1);
tempval &= ~(MACCFG1_RX_EN | MACCFG1_TX_EN);

View File

@ -33,7 +33,6 @@
#include <asm/uaccess.h>
#include <linux/module.h>
#include <linux/version.h>
#include "gianfar.h"

View File

@ -7,7 +7,6 @@
#ifndef __LINUX_IPG_H
#define __LINUX_IPG_H
#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
@ -21,7 +20,6 @@
#include <linux/etherdevice.h>
#include <linux/init.h>
#include <linux/skbuff.h>
#include <linux/version.h>
#include <asm/bitops.h>
/*

View File

@ -190,6 +190,7 @@ static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw)
case IXGBE_DEV_ID_82598AF_DUAL_PORT:
case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
case IXGBE_DEV_ID_82598EB_CX4:
case IXGBE_DEV_ID_82598_CX4_DUAL_PORT:
media_type = ixgbe_media_type_fiber;
break;
case IXGBE_DEV_ID_82598AT_DUAL_PORT:

View File

@ -48,7 +48,7 @@ char ixgbe_driver_name[] = "ixgbe";
static const char ixgbe_driver_string[] =
"Intel(R) 10 Gigabit PCI Express Network Driver";
#define DRV_VERSION "1.3.18-k2"
#define DRV_VERSION "1.3.18-k4"
const char ixgbe_driver_version[] = DRV_VERSION;
static const char ixgbe_copyright[] =
"Copyright (c) 1999-2007 Intel Corporation.";
@ -72,6 +72,8 @@ static struct pci_device_id ixgbe_pci_tbl[] = {
board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_CX4),
board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598_CX4_DUAL_PORT),
board_82598 },
/* required last entry */
{0, }

View File

@ -39,6 +39,7 @@
#define IXGBE_DEV_ID_82598AF_SINGLE_PORT 0x10C7
#define IXGBE_DEV_ID_82598AT_DUAL_PORT 0x10C8
#define IXGBE_DEV_ID_82598EB_CX4 0x10DD
#define IXGBE_DEV_ID_82598_CX4_DUAL_PORT 0x10EC
/* General Registers */
#define IXGBE_CTRL 0x00000

View File

@ -64,68 +64,6 @@ struct pcpu_lstats {
unsigned long bytes;
};
/* KISS: just allocate small chunks and copy bits.
*
* So, in fact, this is documentation, explaining what we expect
* of largesending device modulo TCP checksum, which is ignored for loopback.
*/
#ifdef LOOPBACK_TSO
static void emulate_large_send_offload(struct sk_buff *skb)
{
struct iphdr *iph = ip_hdr(skb);
struct tcphdr *th = (struct tcphdr *)(skb_network_header(skb) +
(iph->ihl * 4));
unsigned int doffset = (iph->ihl + th->doff) * 4;
unsigned int mtu = skb_shinfo(skb)->gso_size + doffset;
unsigned int offset = 0;
u32 seq = ntohl(th->seq);
u16 id = ntohs(iph->id);
while (offset + doffset < skb->len) {
unsigned int frag_size = min(mtu, skb->len - offset) - doffset;
struct sk_buff *nskb = alloc_skb(mtu + 32, GFP_ATOMIC);
if (!nskb)
break;
skb_reserve(nskb, 32);
skb_set_mac_header(nskb, -ETH_HLEN);
skb_reset_network_header(nskb);
iph = ip_hdr(nskb);
skb_copy_to_linear_data(nskb, skb_network_header(skb),
doffset);
if (skb_copy_bits(skb,
doffset + offset,
nskb->data + doffset,
frag_size))
BUG();
skb_put(nskb, doffset + frag_size);
nskb->ip_summed = CHECKSUM_UNNECESSARY;
nskb->dev = skb->dev;
nskb->priority = skb->priority;
nskb->protocol = skb->protocol;
nskb->dst = dst_clone(skb->dst);
memcpy(nskb->cb, skb->cb, sizeof(skb->cb));
nskb->pkt_type = skb->pkt_type;
th = (struct tcphdr *)(skb_network_header(nskb) + iph->ihl * 4);
iph->tot_len = htons(frag_size + doffset);
iph->id = htons(id);
iph->check = 0;
iph->check = ip_fast_csum((unsigned char *) iph, iph->ihl);
th->seq = htonl(seq);
if (offset + doffset + frag_size < skb->len)
th->fin = th->psh = 0;
netif_rx(nskb);
offset += frag_size;
seq += frag_size;
id++;
}
dev_kfree_skb(skb);
}
#endif /* LOOPBACK_TSO */
/*
* The higher levels take care of making this non-reentrant (it's
* called with bh's disabled).
@ -137,9 +75,6 @@ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev)
skb_orphan(skb);
skb->protocol = eth_type_trans(skb,dev);
#ifndef LOOPBACK_MUST_CHECKSUM
skb->ip_summed = CHECKSUM_UNNECESSARY;
#endif
#ifdef LOOPBACK_TSO
if (skb_is_gso(skb)) {
@ -234,9 +169,7 @@ static void loopback_setup(struct net_device *dev)
dev->type = ARPHRD_LOOPBACK; /* 0x0001*/
dev->flags = IFF_LOOPBACK;
dev->features = NETIF_F_SG | NETIF_F_FRAGLIST
#ifdef LOOPBACK_TSO
| NETIF_F_TSO
#endif
| NETIF_F_NO_CSUM
| NETIF_F_HIGHDMA
| NETIF_F_LLTX

View File

@ -3548,7 +3548,11 @@ static void myri10ge_probe_slices(struct myri10ge_priv *mgp)
/* try to load the slice aware rss firmware */
old_fw = mgp->fw_name;
if (old_fw == myri10ge_fw_aligned)
if (myri10ge_fw_name != NULL) {
dev_info(&mgp->pdev->dev, "overriding rss firmware to %s\n",
myri10ge_fw_name);
mgp->fw_name = myri10ge_fw_name;
} else if (old_fw == myri10ge_fw_aligned)
mgp->fw_name = myri10ge_fw_rss_aligned;
else
mgp->fw_name = myri10ge_fw_rss_unaligned;

View File

@ -118,7 +118,7 @@ bad_clone_list[] __initdata = {
{"E-LAN100", "E-LAN200", {0x00, 0x00, 0x5d}}, /* Broken ne1000 clones */
{"PCM-4823", "PCM-4823", {0x00, 0xc0, 0x6c}}, /* Broken Advantech MoBo */
{"REALTEK", "RTL8019", {0x00, 0x00, 0xe8}}, /* no-name with Realtek chip */
#if defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)
#ifdef CONFIG_MACH_TX49XX
{"RBHMA4X00-RTL8019", "RBHMA4X00/RTL8019", {0x00, 0x60, 0x0a}}, /* Toshiba built-in */
#endif
{"LCS-8834", "LCS-8836", {0x04, 0x04, 0x37}}, /* ShinyNet (SET) */
@ -142,7 +142,7 @@ bad_clone_list[] __initdata = {
#if defined(CONFIG_PLAT_MAPPI)
# define DCR_VAL 0x4b
#elif defined(CONFIG_PLAT_OAKS32R) || \
defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)
defined(CONFIG_MACH_TX49XX)
# define DCR_VAL 0x48 /* 8-bit mode */
#else
# define DCR_VAL 0x49

View File

@ -66,8 +66,8 @@
#define _NETXEN_NIC_LINUX_MAJOR 4
#define _NETXEN_NIC_LINUX_MINOR 0
#define _NETXEN_NIC_LINUX_SUBVERSION 0
#define NETXEN_NIC_LINUX_VERSIONID "4.0.0"
#define _NETXEN_NIC_LINUX_SUBVERSION 11
#define NETXEN_NIC_LINUX_VERSIONID "4.0.11"
#define NETXEN_VERSION_CODE(a, b, c) (((a) << 16) + ((b) << 8) + (c))
@ -1615,7 +1615,8 @@ dma_watchdog_wakeup(struct netxen_adapter *adapter)
int netxen_is_flash_supported(struct netxen_adapter *adapter);
int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 mac[]);
int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 *mac);
int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac);
extern void netxen_change_ringparam(struct netxen_adapter *adapter);
extern int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr,
int *valp);

View File

@ -733,31 +733,56 @@ static int netxen_get_flash_block(struct netxen_adapter *adapter, int base,
return 0;
}
int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 mac[])
int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 *mac)
{
__le32 *pmac = (__le32 *) & mac[0];
__le32 *pmac = (__le32 *) mac;
u32 offset;
if (netxen_get_flash_block(adapter,
NETXEN_USER_START +
offsetof(struct netxen_new_user_info,
mac_addr),
FLASH_NUM_PORTS * sizeof(u64), pmac) == -1) {
offset = NETXEN_USER_START +
offsetof(struct netxen_new_user_info, mac_addr) +
adapter->portnum * sizeof(u64);
if (netxen_get_flash_block(adapter, offset, sizeof(u64), pmac) == -1)
return -1;
}
if (*mac == cpu_to_le64(~0ULL)) {
offset = NETXEN_USER_START_OLD +
offsetof(struct netxen_user_old_info, mac_addr) +
adapter->portnum * sizeof(u64);
if (netxen_get_flash_block(adapter,
NETXEN_USER_START_OLD +
offsetof(struct netxen_user_old_info,
mac_addr),
FLASH_NUM_PORTS * sizeof(u64),
pmac) == -1)
offset, sizeof(u64), pmac) == -1)
return -1;
if (*mac == cpu_to_le64(~0ULL))
return -1;
}
return 0;
}
int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac)
{
uint32_t crbaddr, mac_hi, mac_lo;
int pci_func = adapter->ahw.pci_func;
crbaddr = CRB_MAC_BLOCK_START +
(4 * ((pci_func/2) * 3)) + (4 * (pci_func & 1));
adapter->hw_read_wx(adapter, crbaddr, &mac_lo, 4);
adapter->hw_read_wx(adapter, crbaddr+4, &mac_hi, 4);
mac_hi = cpu_to_le32(mac_hi);
mac_lo = cpu_to_le32(mac_lo);
if (pci_func & 1)
*mac = ((mac_lo >> 16) | ((u64)mac_hi << 16));
else
*mac = ((mac_lo) | ((u64)mac_hi << 32));
return 0;
}
#define CRB_WIN_LOCK_TIMEOUT 100000000
static int crb_win_lock(struct netxen_adapter *adapter)
@ -2183,10 +2208,10 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter)
if (adapter->portnum == 0) {
get_brd_name_by_type(board_info->board_type, brd_name);
printk("NetXen %s Board S/N %s Chip id 0x%x\n",
brd_name, serial_num, board_info->chip_id);
printk("NetXen Firmware version %d.%d.%d\n", fw_major,
fw_minor, fw_build);
printk(KERN_INFO "NetXen %s Board S/N %s Chip rev 0x%x\n",
brd_name, serial_num, adapter->ahw.revision_id);
printk(KERN_INFO "NetXen Firmware version %d.%d.%d\n",
fw_major, fw_minor, fw_build);
}
if (NETXEN_VERSION_CODE(fw_major, fw_minor, fw_build) <

View File

@ -1079,10 +1079,12 @@ int netxen_initialize_adapter_offload(struct netxen_adapter *adapter)
void netxen_free_adapter_offload(struct netxen_adapter *adapter)
{
int i;
int i = 100;
if (adapter->dummy_dma.addr) {
i = 100;
if (!adapter->dummy_dma.addr)
return;
if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
do {
if (dma_watchdog_shutdown_request(adapter) == 1)
break;
@ -1090,17 +1092,17 @@ void netxen_free_adapter_offload(struct netxen_adapter *adapter)
if (dma_watchdog_shutdown_poll_result(adapter) == 1)
break;
} while (--i);
}
if (i) {
pci_free_consistent(adapter->pdev,
NETXEN_HOST_DUMMY_DMA_SIZE,
adapter->dummy_dma.addr,
adapter->dummy_dma.phys_addr);
adapter->dummy_dma.addr = NULL;
} else {
printk(KERN_ERR "%s: dma_watchdog_shutdown failed\n",
adapter->netdev->name);
}
if (i) {
pci_free_consistent(adapter->pdev,
NETXEN_HOST_DUMMY_DMA_SIZE,
adapter->dummy_dma.addr,
adapter->dummy_dma.phys_addr);
adapter->dummy_dma.addr = NULL;
} else {
printk(KERN_ERR "%s: dma_watchdog_shutdown failed\n",
adapter->netdev->name);
}
}

View File

@ -149,76 +149,18 @@ static uint32_t msi_tgt_status[8] = {
static struct netxen_legacy_intr_set legacy_intr[] = NX_LEGACY_INTR_CONFIG;
static void netxen_nic_disable_int(struct netxen_adapter *adapter)
static inline void netxen_nic_disable_int(struct netxen_adapter *adapter)
{
u32 mask = 0x7ff;
int retries = 32;
int pci_fn = adapter->ahw.pci_func;
if (adapter->msi_mode != MSI_MODE_MULTIFUNC)
adapter->pci_write_normalize(adapter,
adapter->crb_intr_mask, 0);
if (adapter->intr_scheme != -1 &&
adapter->intr_scheme != INTR_SCHEME_PERPORT)
adapter->pci_write_immediate(adapter, ISR_INT_MASK, mask);
if (!NETXEN_IS_MSI_FAMILY(adapter)) {
do {
adapter->pci_write_immediate(adapter,
adapter->legacy_intr.tgt_status_reg,
0xffffffff);
mask = adapter->pci_read_immediate(adapter,
ISR_INT_VECTOR);
if (!(mask & 0x80))
break;
udelay(10);
} while (--retries);
if (!retries) {
printk(KERN_NOTICE "%s: Failed to disable interrupt\n",
netxen_nic_driver_name);
}
} else {
if (adapter->msi_mode == MSI_MODE_MULTIFUNC) {
adapter->pci_write_immediate(adapter,
msi_tgt_status[pci_fn], 0xffffffff);
}
}
adapter->pci_write_normalize(adapter, adapter->crb_intr_mask, 0);
}
static void netxen_nic_enable_int(struct netxen_adapter *adapter)
static inline void netxen_nic_enable_int(struct netxen_adapter *adapter)
{
u32 mask;
if (adapter->intr_scheme != -1 &&
adapter->intr_scheme != INTR_SCHEME_PERPORT) {
switch (adapter->ahw.board_type) {
case NETXEN_NIC_GBE:
mask = 0x77b;
break;
case NETXEN_NIC_XGBE:
mask = 0x77f;
break;
default:
mask = 0x7ff;
break;
}
adapter->pci_write_immediate(adapter, ISR_INT_MASK, mask);
}
adapter->pci_write_normalize(adapter, adapter->crb_intr_mask, 0x1);
if (!NETXEN_IS_MSI_FAMILY(adapter)) {
mask = 0xbff;
if (adapter->intr_scheme == INTR_SCHEME_PERPORT)
adapter->pci_write_immediate(adapter,
adapter->legacy_intr.tgt_mask_reg, mask);
else
adapter->pci_write_normalize(adapter,
CRB_INT_VECTOR, 0);
}
if (!NETXEN_IS_MSI_FAMILY(adapter))
adapter->pci_write_immediate(adapter,
adapter->legacy_intr.tgt_mask_reg, 0xfbff);
}
static int nx_set_dma_mask(struct netxen_adapter *adapter, uint8_t revision_id)
@ -501,6 +443,44 @@ static void netxen_init_msix_entries(struct netxen_adapter *adapter)
adapter->msix_entries[i].entry = i;
}
static int
netxen_read_mac_addr(struct netxen_adapter *adapter)
{
int i;
unsigned char *p;
__le64 mac_addr;
DECLARE_MAC_BUF(mac);
struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
if (netxen_is_flash_supported(adapter) != 0)
return -EIO;
if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
if (netxen_p3_get_mac_addr(adapter, &mac_addr) != 0)
return -EIO;
} else {
if (netxen_get_flash_mac_addr(adapter, &mac_addr) != 0)
return -EIO;
}
p = (unsigned char *)&mac_addr;
for (i = 0; i < 6; i++)
netdev->dev_addr[i] = *(p + 5 - i);
memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len);
/* set station address */
if (!is_valid_ether_addr(netdev->perm_addr)) {
dev_warn(&pdev->dev, "Bad MAC address %s.\n",
print_mac(mac, netdev->dev_addr));
} else
adapter->macaddr_set(adapter, netdev->dev_addr);
return 0;
}
/*
* netxen_nic_probe()
*
@ -529,10 +509,8 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
unsigned long mem_base, mem_len, db_base, db_len, pci_len0 = 0;
int i = 0, err;
int first_driver, first_boot;
__le64 mac_addr[FLASH_NUM_PORTS + 1];
u32 val;
int pci_func_id = PCI_FUNC(pdev->devfn);
DECLARE_MAC_BUF(mac);
struct netxen_legacy_intr_set *legacy_intrp;
uint8_t revision_id;
@ -545,6 +523,13 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
return -ENODEV;
}
if (pdev->revision >= NX_P3_A0 && pdev->revision < NX_P3_B1) {
printk(KERN_WARNING "NetXen chip revisions between 0x%x-0x%x"
"will not be enabled.\n",
NX_P3_A0, NX_P3_B1);
return -ENODEV;
}
if ((err = pci_enable_device(pdev)))
return err;
@ -898,34 +883,14 @@ request_msi:
goto err_out_disable_msi;
init_timer(&adapter->watchdog_timer);
adapter->ahw.linkup = 0;
adapter->watchdog_timer.function = &netxen_watchdog;
adapter->watchdog_timer.data = (unsigned long)adapter;
INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task);
INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task);
if (netxen_is_flash_supported(adapter) == 0 &&
netxen_get_flash_mac_addr(adapter, mac_addr) == 0) {
unsigned char *p;
p = (unsigned char *)&mac_addr[adapter->portnum];
netdev->dev_addr[0] = *(p + 5);
netdev->dev_addr[1] = *(p + 4);
netdev->dev_addr[2] = *(p + 3);
netdev->dev_addr[3] = *(p + 2);
netdev->dev_addr[4] = *(p + 1);
netdev->dev_addr[5] = *(p + 0);
memcpy(netdev->perm_addr, netdev->dev_addr,
netdev->addr_len);
if (!is_valid_ether_addr(netdev->perm_addr)) {
printk(KERN_ERR "%s: Bad MAC address %s.\n",
netxen_nic_driver_name,
print_mac(mac, netdev->dev_addr));
} else {
adapter->macaddr_set(adapter, netdev->dev_addr);
}
}
err = netxen_read_mac_addr(adapter);
if (err)
dev_warn(&pdev->dev, "failed to read mac addr\n");
netif_carrier_off(netdev);
netif_stop_queue(netdev);
@ -1000,6 +965,7 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {
netxen_free_hw_resources(adapter);
netxen_release_rx_buffers(adapter);
netxen_free_sw_resources(adapter);
}
@ -1069,6 +1035,15 @@ static int netxen_nic_open(struct net_device *netdev)
goto err_out_free_sw;
}
if ((adapter->msi_mode != MSI_MODE_MULTIFUNC) ||
(adapter->intr_scheme != INTR_SCHEME_PERPORT)) {
printk(KERN_ERR "%s: Firmware interrupt scheme is "
"incompatible with driver\n",
netdev->name);
adapter->driver_mismatch = 1;
goto err_out_free_hw;
}
if (adapter->fw_major < 4) {
adapter->crb_addr_cmd_producer =
crb_cmd_producer[adapter->portnum];
@ -1094,7 +1069,7 @@ static int netxen_nic_open(struct net_device *netdev)
flags, netdev->name, adapter);
if (err) {
printk(KERN_ERR "request_irq failed with: %d\n", err);
goto err_out_free_hw;
goto err_out_free_rxbuf;
}
adapter->is_up = NETXEN_ADAPTER_UP_MAGIC;
@ -1116,6 +1091,7 @@ static int netxen_nic_open(struct net_device *netdev)
if (adapter->set_mtu)
adapter->set_mtu(adapter, netdev->mtu);
adapter->ahw.linkup = 0;
mod_timer(&adapter->watchdog_timer, jiffies);
napi_enable(&adapter->napi);
@ -1127,6 +1103,8 @@ static int netxen_nic_open(struct net_device *netdev)
err_out_free_irq:
free_irq(adapter->irq, adapter);
err_out_free_rxbuf:
netxen_release_rx_buffers(adapter);
err_out_free_hw:
netxen_free_hw_resources(adapter);
err_out_free_sw:
@ -1152,10 +1130,8 @@ static int netxen_nic_close(struct net_device *netdev)
netxen_release_tx_buffers(adapter);
if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {
FLUSH_SCHEDULED_WORK();
del_timer_sync(&adapter->watchdog_timer);
}
FLUSH_SCHEDULED_WORK();
del_timer_sync(&adapter->watchdog_timer);
return 0;
}
@ -1458,7 +1434,8 @@ void netxen_watchdog_task(struct work_struct *work)
netxen_nic_handle_phy_intr(adapter);
mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
if (netif_running(adapter->netdev))
mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
}
static void netxen_tx_timeout(struct net_device *netdev)
@ -1518,18 +1495,9 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
return stats;
}
static inline void
netxen_handle_int(struct netxen_adapter *adapter)
{
netxen_nic_disable_int(adapter);
napi_schedule(&adapter->napi);
}
static irqreturn_t netxen_intr(int irq, void *data)
{
struct netxen_adapter *adapter = data;
u32 our_int = 0;
u32 status = 0;
status = adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
@ -1544,22 +1512,32 @@ static irqreturn_t netxen_intr(int irq, void *data)
if (!ISR_LEGACY_INT_TRIGGERED(status))
return IRQ_NONE;
} else if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
} else {
unsigned long our_int = 0;
our_int = adapter->pci_read_normalize(adapter, CRB_INT_VECTOR);
/* not our interrupt */
if ((our_int & (0x80 << adapter->portnum)) == 0)
if (!test_and_clear_bit((7 + adapter->portnum), &our_int))
return IRQ_NONE;
if (adapter->intr_scheme == INTR_SCHEME_PERPORT) {
/* claim interrupt */
adapter->pci_write_normalize(adapter,
CRB_INT_VECTOR,
our_int & ~((u32)(0x80 << adapter->portnum)));
}
/* claim interrupt */
adapter->pci_write_normalize(adapter,
CRB_INT_VECTOR, (our_int & 0xffffffff));
}
netxen_handle_int(adapter);
/* clear interrupt */
if (adapter->fw_major < 4)
netxen_nic_disable_int(adapter);
adapter->pci_write_immediate(adapter,
adapter->legacy_intr.tgt_status_reg,
0xffffffff);
/* read twice to ensure write is flushed */
adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
napi_schedule(&adapter->napi);
return IRQ_HANDLED;
}
@ -1568,7 +1546,11 @@ static irqreturn_t netxen_msi_intr(int irq, void *data)
{
struct netxen_adapter *adapter = data;
netxen_handle_int(adapter);
/* clear interrupt */
adapter->pci_write_immediate(adapter,
msi_tgt_status[adapter->ahw.pci_func], 0xffffffff);
napi_schedule(&adapter->napi);
return IRQ_HANDLED;
}

View File

@ -125,6 +125,8 @@
#define CRB_SW_INT_MASK_2 NETXEN_NIC_REG(0x1e4)
#define CRB_SW_INT_MASK_3 NETXEN_NIC_REG(0x1e8)
#define CRB_MAC_BLOCK_START NETXEN_CAM_RAM(0x1c0)
/*
* capabilities register, can be used to selectively enable/disable features
* for backward compability

View File

@ -46,7 +46,6 @@
#include <linux/err.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/slab.h>

View File

@ -61,7 +61,6 @@
*/
#include <linux/module.h>
#include <linux/version.h>
#include <linux/string.h>
#include <linux/list.h>
#include <asm/uaccess.h>

View File

@ -24,7 +24,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/moduleparam.h>
#include <linux/string.h>
#include <linux/timer.h>

View File

@ -20,7 +20,6 @@
* the file called "COPYING".
*/
#include <linux/version.h>
#include <linux/init.h>
#include <linux/dma-mapping.h>
#include <linux/etherdevice.h>

View File

@ -24,7 +24,6 @@
#include <linux/crc32.h>
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/dma-mapping.h>
@ -666,11 +665,16 @@ static void sky2_phy_power_down(struct sky2_hw *hw, unsigned port)
if (hw->chip_id != CHIP_ID_YUKON_EC) {
if (hw->chip_id == CHIP_ID_YUKON_EC_U) {
ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
/* select page 2 to access MAC control register */
gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 2);
ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
/* enable Power Down */
ctrl |= PHY_M_PC_POW_D_ENA;
gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
/* set page register back to 0 */
gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0);
}
/* set IEEE compatible Power Down Mode (dev. #4.99) */

View File

@ -27,7 +27,6 @@
#include <linux/sched.h>
#include <linux/tty.h>
#include <linux/if_vlan.h>
#include <linux/version.h>
#include <linux/interrupt.h>
#include <linux/vmalloc.h>
#include <asm/byteorder.h>

View File

@ -66,8 +66,8 @@
#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
#define DRV_MODULE_VERSION "3.93"
#define DRV_MODULE_RELDATE "May 22, 2008"
#define DRV_MODULE_VERSION "3.94"
#define DRV_MODULE_RELDATE "August 14, 2008"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
@ -536,6 +536,7 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum)
return 0;
switch (locknum) {
case TG3_APE_LOCK_GRC:
case TG3_APE_LOCK_MEM:
break;
default:
@ -573,6 +574,7 @@ static void tg3_ape_unlock(struct tg3 *tp, int locknum)
return;
switch (locknum) {
case TG3_APE_LOCK_GRC:
case TG3_APE_LOCK_MEM:
break;
default:
@ -1017,16 +1019,44 @@ static void tg3_mdio_fini(struct tg3 *tp)
}
}
/* tp->lock is held. */
static inline void tg3_generate_fw_event(struct tg3 *tp)
{
u32 val;
val = tr32(GRC_RX_CPU_EVENT);
val |= GRC_RX_CPU_DRIVER_EVENT;
tw32_f(GRC_RX_CPU_EVENT, val);
tp->last_event_jiffies = jiffies;
}
#define TG3_FW_EVENT_TIMEOUT_USEC 2500
/* tp->lock is held. */
static void tg3_wait_for_event_ack(struct tg3 *tp)
{
int i;
unsigned int delay_cnt;
long time_remain;
/* Wait for up to 2.5 milliseconds */
for (i = 0; i < 250000; i++) {
/* If enough time has passed, no wait is necessary. */
time_remain = (long)(tp->last_event_jiffies + 1 +
usecs_to_jiffies(TG3_FW_EVENT_TIMEOUT_USEC)) -
(long)jiffies;
if (time_remain < 0)
return;
/* Check if we can shorten the wait time. */
delay_cnt = jiffies_to_usecs(time_remain);
if (delay_cnt > TG3_FW_EVENT_TIMEOUT_USEC)
delay_cnt = TG3_FW_EVENT_TIMEOUT_USEC;
delay_cnt = (delay_cnt >> 3) + 1;
for (i = 0; i < delay_cnt; i++) {
if (!(tr32(GRC_RX_CPU_EVENT) & GRC_RX_CPU_DRIVER_EVENT))
break;
udelay(10);
udelay(8);
}
}
@ -1075,9 +1105,7 @@ static void tg3_ump_link_report(struct tg3 *tp)
val = 0;
tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 12, val);
val = tr32(GRC_RX_CPU_EVENT);
val |= GRC_RX_CPU_DRIVER_EVENT;
tw32_f(GRC_RX_CPU_EVENT, val);
tg3_generate_fw_event(tp);
}
static void tg3_link_report(struct tg3 *tp)
@ -2124,6 +2152,13 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
(tp->tg3_flags & TG3_FLAG_WOL_ENABLE))
mac_mode |= MAC_MODE_MAGIC_PKT_ENABLE;
if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) {
mac_mode |= tp->mac_mode &
(MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN);
if (mac_mode & MAC_MODE_APE_TX_EN)
mac_mode |= MAC_MODE_TDE_ENABLE;
}
tw32_f(MAC_MODE, mac_mode);
udelay(100);
@ -5493,7 +5528,7 @@ static void tg3_ape_send_event(struct tg3 *tp, u32 event)
return;
apedata = tg3_ape_read32(tp, TG3_APE_FW_STATUS);
if (apedata != APE_FW_STATUS_READY)
if (!(apedata & APE_FW_STATUS_READY))
return;
/* Wait for up to 1 millisecond for APE to service previous event. */
@ -5760,6 +5795,8 @@ static int tg3_chip_reset(struct tg3 *tp)
tg3_mdio_stop(tp);
tg3_ape_lock(tp, TG3_APE_LOCK_GRC);
/* No matching tg3_nvram_unlock() after this because
* chip reset below will undo the nvram lock.
*/
@ -5908,12 +5945,19 @@ static int tg3_chip_reset(struct tg3 *tp)
} else if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) {
tp->mac_mode = MAC_MODE_PORT_MODE_GMII;
tw32_f(MAC_MODE, tp->mac_mode);
} else if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) {
tp->mac_mode &= (MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN);
if (tp->mac_mode & MAC_MODE_APE_TX_EN)
tp->mac_mode |= MAC_MODE_TDE_ENABLE;
tw32_f(MAC_MODE, tp->mac_mode);
} else
tw32_f(MAC_MODE, 0);
udelay(40);
tg3_mdio_start(tp);
tg3_ape_unlock(tp, TG3_APE_LOCK_GRC);
err = tg3_poll_fw(tp);
if (err)
return err;
@ -5935,6 +5979,7 @@ static int tg3_chip_reset(struct tg3 *tp)
tg3_read_mem(tp, NIC_SRAM_DATA_CFG, &nic_cfg);
if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) {
tp->tg3_flags |= TG3_FLAG_ENABLE_ASF;
tp->last_event_jiffies = jiffies;
if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS)
tp->tg3_flags2 |= TG3_FLG2_ASF_NEW_HANDSHAKE;
}
@ -5948,15 +5993,12 @@ static void tg3_stop_fw(struct tg3 *tp)
{
if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) &&
!(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)) {
u32 val;
/* Wait for RX cpu to ACK the previous event. */
tg3_wait_for_event_ack(tp);
tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_PAUSE_FW);
val = tr32(GRC_RX_CPU_EVENT);
val |= GRC_RX_CPU_DRIVER_EVENT;
tw32(GRC_RX_CPU_EVENT, val);
tg3_generate_fw_event(tp);
/* Wait for RX cpu to ACK this event. */
tg3_wait_for_event_ack(tp);
@ -7406,7 +7448,11 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
udelay(10);
}
tp->mac_mode = MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE |
if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
tp->mac_mode &= MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN;
else
tp->mac_mode = 0;
tp->mac_mode |= MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE |
MAC_MODE_TDE_ENABLE | MAC_MODE_RDE_ENABLE | MAC_MODE_FHDE_ENABLE;
if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) &&
@ -7840,9 +7886,8 @@ static void tg3_timer(unsigned long __opaque)
* resets.
*/
if (!--tp->asf_counter) {
if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) {
u32 val;
if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) &&
!(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)) {
tg3_wait_for_event_ack(tp);
tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX,
@ -7850,9 +7895,8 @@ static void tg3_timer(unsigned long __opaque)
tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4);
/* 5 seconds timeout */
tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5);
val = tr32(GRC_RX_CPU_EVENT);
val |= GRC_RX_CPU_DRIVER_EVENT;
tw32_f(GRC_RX_CPU_EVENT, val);
tg3_generate_fw_event(tp);
}
tp->asf_counter = tp->asf_multiplier;
}
@ -8422,6 +8466,11 @@ static inline unsigned long get_stat64(tg3_stat64_t *val)
return ret;
}
static inline u64 get_estat64(tg3_stat64_t *val)
{
return ((u64)val->high << 32) | ((u64)val->low);
}
static unsigned long calc_crc_errors(struct tg3 *tp)
{
struct tg3_hw_stats *hw_stats = tp->hw_stats;
@ -8450,7 +8499,7 @@ static unsigned long calc_crc_errors(struct tg3 *tp)
#define ESTAT_ADD(member) \
estats->member = old_estats->member + \
get_stat64(&hw_stats->member)
get_estat64(&hw_stats->member)
static struct tg3_ethtool_stats *tg3_get_estats(struct tg3 *tp)
{
@ -12416,6 +12465,13 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
tp->misc_host_ctrl);
}
/* Preserve the APE MAC_MODE bits */
if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
tp->mac_mode = tr32(MAC_MODE) |
MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN;
else
tp->mac_mode = TG3_DEF_MAC_MODE;
/* these are limited to 10/100 only */
if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 &&
(grc_misc_cfg == 0x8000 || grc_misc_cfg == 0x4000)) ||
@ -13275,7 +13331,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
tp->pdev = pdev;
tp->dev = dev;
tp->pm_cap = pm_cap;
tp->mac_mode = TG3_DEF_MAC_MODE;
tp->rx_mode = TG3_DEF_RX_MODE;
tp->tx_mode = TG3_DEF_TX_MODE;

View File

@ -325,6 +325,8 @@
#define MAC_MODE_TDE_ENABLE 0x00200000
#define MAC_MODE_RDE_ENABLE 0x00400000
#define MAC_MODE_FHDE_ENABLE 0x00800000
#define MAC_MODE_APE_RX_EN 0x08000000
#define MAC_MODE_APE_TX_EN 0x10000000
#define MAC_STATUS 0x00000404
#define MAC_STATUS_PCS_SYNCED 0x00000001
#define MAC_STATUS_SIGNAL_DET 0x00000002
@ -1889,6 +1891,7 @@
#define APE_EVENT_STATUS_EVENT_PENDING 0x80000000
/* APE convenience enumerations. */
#define TG3_APE_LOCK_GRC 1
#define TG3_APE_LOCK_MEM 4
#define TG3_EEPROM_SB_F1R2_MBA_OFF 0x10
@ -2429,7 +2432,10 @@ struct tg3 {
struct tg3_ethtool_stats estats;
struct tg3_ethtool_stats estats_prev;
union {
unsigned long phy_crc_errors;
unsigned long last_event_jiffies;
};
u32 rx_offset;
u32 tg3_flags;

View File

@ -360,8 +360,8 @@ TLan_GetSKB( const struct tlan_list_tag *tag)
{
unsigned long addr;
addr = tag->buffer[8].address;
addr |= (tag->buffer[9].address << 16) << 16;
addr = tag->buffer[9].address;
addr |= (tag->buffer[8].address << 16) << 16;
return (struct sk_buff *) addr;
}
@ -1984,7 +1984,6 @@ static void TLan_ResetLists( struct net_device *dev )
TLanList *list;
dma_addr_t list_phys;
struct sk_buff *skb;
void *t = NULL;
priv->txHead = 0;
priv->txTail = 0;
@ -2022,7 +2021,8 @@ static void TLan_ResetLists( struct net_device *dev )
}
skb_reserve( skb, NET_IP_ALIGN );
list->buffer[0].address = pci_map_single(priv->pciDev, t,
list->buffer[0].address = pci_map_single(priv->pciDev,
skb->data,
TLAN_MAX_FRAME_SIZE,
PCI_DMA_FROMDEVICE);
TLan_StoreSKB(list, skb);

View File

@ -358,6 +358,66 @@ static unsigned int tun_chr_poll(struct file *file, poll_table * wait)
return mask;
}
/* prepad is the amount to reserve at front. len is length after that.
* linear is a hint as to how much to copy (usually headers). */
static struct sk_buff *tun_alloc_skb(size_t prepad, size_t len, size_t linear,
gfp_t gfp)
{
struct sk_buff *skb;
unsigned int i;
skb = alloc_skb(prepad + len, gfp|__GFP_NOWARN);
if (skb) {
skb_reserve(skb, prepad);
skb_put(skb, len);
return skb;
}
/* Under a page? Don't bother with paged skb. */
if (prepad + len < PAGE_SIZE)
return NULL;
/* Start with a normal skb, and add pages. */
skb = alloc_skb(prepad + linear, gfp);
if (!skb)
return NULL;
skb_reserve(skb, prepad);
skb_put(skb, linear);
len -= linear;
for (i = 0; i < MAX_SKB_FRAGS; i++) {
skb_frag_t *f = &skb_shinfo(skb)->frags[i];
f->page = alloc_page(gfp|__GFP_ZERO);
if (!f->page)
break;
f->page_offset = 0;
f->size = PAGE_SIZE;
skb->data_len += PAGE_SIZE;
skb->len += PAGE_SIZE;
skb->truesize += PAGE_SIZE;
skb_shinfo(skb)->nr_frags++;
if (len < PAGE_SIZE) {
len = 0;
break;
}
len -= PAGE_SIZE;
}
/* Too large, or alloc fail? */
if (unlikely(len)) {
kfree_skb(skb);
skb = NULL;
}
return skb;
}
/* Get packet from user space buffer */
static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv, size_t count)
{
@ -391,14 +451,12 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv,
return -EINVAL;
}
if (!(skb = alloc_skb(len + align, GFP_KERNEL))) {
if (!(skb = tun_alloc_skb(align, len, gso.hdr_len, GFP_KERNEL))) {
tun->dev->stats.rx_dropped++;
return -ENOMEM;
}
if (align)
skb_reserve(skb, align);
if (memcpy_fromiovec(skb_put(skb, len), iv, len)) {
if (skb_copy_datagram_from_iovec(skb, 0, iv, len)) {
tun->dev->stats.rx_dropped++;
kfree_skb(skb);
return -EFAULT;
@ -748,6 +806,36 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
return err;
}
static int tun_get_iff(struct net *net, struct file *file, struct ifreq *ifr)
{
struct tun_struct *tun = file->private_data;
if (!tun)
return -EBADFD;
DBG(KERN_INFO "%s: tun_get_iff\n", tun->dev->name);
strcpy(ifr->ifr_name, tun->dev->name);
ifr->ifr_flags = 0;
if (ifr->ifr_flags & TUN_TUN_DEV)
ifr->ifr_flags |= IFF_TUN;
else
ifr->ifr_flags |= IFF_TAP;
if (tun->flags & TUN_NO_PI)
ifr->ifr_flags |= IFF_NO_PI;
if (tun->flags & TUN_ONE_QUEUE)
ifr->ifr_flags |= IFF_ONE_QUEUE;
if (tun->flags & TUN_VNET_HDR)
ifr->ifr_flags |= IFF_VNET_HDR;
return 0;
}
/* This is like a cut-down ethtool ops, except done via tun fd so no
* privs required. */
static int set_offload(struct net_device *dev, unsigned long arg)
@ -833,6 +921,15 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
DBG(KERN_INFO "%s: tun_chr_ioctl cmd %d\n", tun->dev->name, cmd);
switch (cmd) {
case TUNGETIFF:
ret = tun_get_iff(current->nsproxy->net_ns, file, &ifr);
if (ret)
return ret;
if (copy_to_user(argp, &ifr, sizeof(ifr)))
return -EFAULT;
break;
case TUNSETNOCSUM:
/* Disable/Enable checksum */
if (arg)

View File

@ -128,7 +128,6 @@ static const int multicast_filter_limit = 32;
#include <asm/io.h>
#include <asm/uaccess.h>
#include <linux/in6.h>
#include <linux/version.h>
#include <linux/dma-mapping.h>
#include "typhoon.h"

View File

@ -154,17 +154,6 @@ config USB_NET_AX8817X
This driver creates an interface named "ethX", where X depends on
what other networking devices you have in use.
config USB_HSO
tristate "Option USB High Speed Mobile Devices"
depends on USB && RFKILL
default n
help
Choose this option if you have an Option HSDPA/HSUPA card.
These cards support downlink speeds of 7.2Mbps or greater.
To compile this driver as a module, choose M here: the
module will be called hso.
config USB_NET_CDCETHER
tristate "CDC Ethernet support (smart devices such as cable modems)"
depends on USB_USBNET
@ -337,5 +326,15 @@ config USB_NET_ZAURUS
really need this non-conformant variant of CDC Ethernet (or in
some cases CDC MDLM) protocol, not "g_ether".
config USB_HSO
tristate "Option USB High Speed Mobile Devices"
depends on USB && RFKILL
default n
help
Choose this option if you have an Option HSDPA/HSUPA card.
These cards support downlink speeds of 7.2Mbps or greater.
To compile this driver as a module, choose M here: the
module will be called hso.
endmenu

View File

@ -102,8 +102,12 @@
#define MAX_RX_URBS 2
#define get_serial_by_tty(x) \
(x ? (struct hso_serial *)x->driver_data : NULL)
static inline struct hso_serial *get_serial_by_tty(struct tty_struct *tty)
{
if (tty)
return tty->driver_data;
return NULL;
}
/*****************************************************************************/
/* Debugging functions */
@ -294,24 +298,25 @@ static int hso_get_activity(struct hso_device *hso_dev);
/* #define DEBUG */
#define dev2net(x) (x->port_data.dev_net)
#define dev2ser(x) (x->port_data.dev_serial)
static inline struct hso_net *dev2net(struct hso_device *hso_dev)
{
return hso_dev->port_data.dev_net;
}
static inline struct hso_serial *dev2ser(struct hso_device *hso_dev)
{
return hso_dev->port_data.dev_serial;
}
/* Debugging functions */
#ifdef DEBUG
static void dbg_dump(int line_count, const char *func_name, unsigned char *buf,
unsigned int len)
{
u8 i = 0;
static char name[255];
printk(KERN_DEBUG "[%d:%s]: len %d", line_count, func_name, len);
for (i = 0; i < len; i++) {
if (!(i % 16))
printk("\n 0x%03x: ", i);
printk("%02x ", (unsigned char)buf[i]);
}
printk("\n");
sprintf(name, "hso[%d:%s]", line_count, func_name);
print_hex_dump_bytes(name, DUMP_PREFIX_NONE, buf, len);
}
#define DUMP(buf_, len_) \
@ -528,13 +533,12 @@ static struct hso_serial *get_serial_by_shared_int_and_type(
static struct hso_serial *get_serial_by_index(unsigned index)
{
struct hso_serial *serial;
struct hso_serial *serial = NULL;
unsigned long flags;
if (!serial_table[index])
return NULL;
spin_lock_irqsave(&serial_table_lock, flags);
serial = dev2ser(serial_table[index]);
if (serial_table[index])
serial = dev2ser(serial_table[index]);
spin_unlock_irqrestore(&serial_table_lock, flags);
return serial;
@ -561,6 +565,7 @@ static int get_free_serial_index(void)
static void set_serial_by_index(unsigned index, struct hso_serial *serial)
{
unsigned long flags;
spin_lock_irqsave(&serial_table_lock, flags);
if (serial)
serial_table[index] = serial->parent;
@ -569,7 +574,7 @@ static void set_serial_by_index(unsigned index, struct hso_serial *serial)
spin_unlock_irqrestore(&serial_table_lock, flags);
}
/* log a meaningfull explanation of an USB status */
/* log a meaningful explanation of an USB status */
static void log_usb_status(int status, const char *function)
{
char *explanation;
@ -1103,8 +1108,8 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp)
/* reset the rts and dtr */
/* do the actual close */
serial->open_count--;
kref_put(&serial->parent->ref, hso_serial_ref_free);
if (serial->open_count <= 0) {
kref_put(&serial->parent->ref, hso_serial_ref_free);
serial->open_count = 0;
if (serial->tty) {
serial->tty->driver_data = NULL;
@ -1467,7 +1472,8 @@ static void hso_std_serial_write_bulk_callback(struct urb *urb)
return;
}
hso_put_activity(serial->parent);
tty_wakeup(serial->tty);
if (serial->tty)
tty_wakeup(serial->tty);
hso_kick_transmit(serial);
D1(" ");
@ -1538,7 +1544,8 @@ static void ctrl_callback(struct urb *urb)
clear_bit(HSO_SERIAL_FLAG_RX_SENT, &serial->flags);
} else {
hso_put_activity(serial->parent);
tty_wakeup(serial->tty);
if (serial->tty)
tty_wakeup(serial->tty);
/* response to a write command */
hso_kick_transmit(serial);
}
@ -2652,7 +2659,7 @@ static void hso_free_interface(struct usb_interface *interface)
hso_stop_net_device(network_table[i]);
cancel_work_sync(&network_table[i]->async_put_intf);
cancel_work_sync(&network_table[i]->async_get_intf);
if(rfk)
if (rfk)
rfkill_unregister(rfk);
hso_free_net_device(network_table[i]);
}
@ -2723,7 +2730,7 @@ static int hso_mux_submit_intr_urb(struct hso_shared_int *shared_int,
}
/* operations setup of the serial interface */
static struct tty_operations hso_serial_ops = {
static const struct tty_operations hso_serial_ops = {
.open = hso_serial_open,
.close = hso_serial_close,
.write = hso_serial_write,

View File

@ -40,7 +40,6 @@
*
*/
#include <linux/version.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/hardirq.h>
@ -587,7 +586,6 @@ ath5k_pci_suspend(struct pci_dev *pdev, pm_message_t state)
ath5k_stop_hw(sc);
free_irq(pdev->irq, sc);
pci_disable_msi(pdev);
pci_save_state(pdev);
pci_disable_device(pdev);
pci_set_power_state(pdev, PCI_D3hot);
@ -616,12 +614,10 @@ ath5k_pci_resume(struct pci_dev *pdev)
*/
pci_write_config_byte(pdev, 0x41, 0);
pci_enable_msi(pdev);
err = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
if (err) {
ATH5K_ERR(sc, "request_irq failed\n");
goto err_msi;
goto err_no_irq;
}
err = ath5k_init(sc);
@ -642,8 +638,7 @@ ath5k_pci_resume(struct pci_dev *pdev)
return 0;
err_irq:
free_irq(pdev->irq, sc);
err_msi:
pci_disable_msi(pdev);
err_no_irq:
pci_disable_device(pdev);
return err;
}

View File

@ -5017,7 +5017,11 @@ static void ath9k_hw_spur_mitigate(struct ath_hal *ah,
for (i = 0; i < 123; i++) {
if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
if ((abs(cur_vit_mask - bin)) < 75)
/* workaround for gcc bug #37014 */
volatile int tmp = abs(cur_vit_mask - bin);
if (tmp < 75)
mask_amt = 1;
else
mask_amt = 0;

View File

@ -33,7 +33,6 @@
#include <linux/moduleparam.h>
#include <linux/if_arp.h>
#include <linux/etherdevice.h>
#include <linux/version.h>
#include <linux/firmware.h>
#include <linux/wireless.h>
#include <linux/workqueue.h>
@ -4615,7 +4614,9 @@ static void b43_sprom_fixup(struct ssb_bus *bus)
if (bus->bustype == SSB_BUSTYPE_PCI) {
pdev = bus->host_pci;
if (IS_PDEV(pdev, BROADCOM, 0x4318, ASUSTEK, 0x100F) ||
IS_PDEV(pdev, BROADCOM, 0x4320, DELL, 0x0003) ||
IS_PDEV(pdev, BROADCOM, 0x4320, LINKSYS, 0x0015) ||
IS_PDEV(pdev, BROADCOM, 0x4320, LINKSYS, 0x0014) ||
IS_PDEV(pdev, BROADCOM, 0x4320, LINKSYS, 0x0013))
bus->sprom.boardflags_lo &= ~B43_BFL_BTCOEXIST;
}

View File

@ -157,7 +157,6 @@ that only one external action is invoked at a time.
#include <linux/stringify.h>
#include <linux/tcp.h>
#include <linux/types.h>
#include <linux/version.h>
#include <linux/time.h>
#include <linux/firmware.h>
#include <linux/acpi.h>

View File

@ -31,7 +31,6 @@
******************************************************************************/
#include "ipw2200.h"
#include <linux/version.h>
#ifndef KBUILD_EXTMOD

View File

@ -26,7 +26,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>

View File

@ -26,7 +26,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
@ -967,7 +966,7 @@ static int iwl4965_interpolate_chan(struct iwl_priv *priv, u32 channel,
s = iwl4965_get_sub_band(priv, channel);
if (s >= EEPROM_TX_POWER_BANDS) {
IWL_ERROR("Tx Power can not find channel %d ", channel);
IWL_ERROR("Tx Power can not find channel %d\n", channel);
return -1;
}

View File

@ -25,7 +25,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>

View File

@ -29,7 +29,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>

View File

@ -28,7 +28,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/version.h>
#include <net/mac80211.h>
struct iwl_priv; /* FIXME: remove */

View File

@ -63,7 +63,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/init.h>
#include <net/mac80211.h>
@ -146,7 +145,7 @@ int iwlcore_eeprom_verify_signature(struct iwl_priv *priv)
{
u32 gp = iwl_read32(priv, CSR_EEPROM_GP);
if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) {
IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x", gp);
IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x\n", gp);
return -ENOENT;
}
return 0;
@ -227,7 +226,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
ret = priv->cfg->ops->lib->eeprom_ops.verify_signature(priv);
if (ret < 0) {
IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x", gp);
IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x\n", gp);
ret = -ENOENT;
goto err;
}
@ -254,7 +253,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
}
if (!(r & CSR_EEPROM_REG_READ_VALID_MSK)) {
IWL_ERROR("Time out reading EEPROM[%d]", addr);
IWL_ERROR("Time out reading EEPROM[%d]\n", addr);
ret = -ETIMEDOUT;
goto done;
}

View File

@ -28,7 +28,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/version.h>
#include <net/mac80211.h>
#include "iwl-dev.h" /* FIXME: remove */

View File

@ -29,7 +29,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/init.h>
#include <net/mac80211.h>

View File

@ -207,7 +207,7 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
case WLAN_HT_CAP_MIMO_PS_DISABLED:
break;
default:
IWL_WARNING("Invalid MIMO PS mode %d", mimo_ps_mode);
IWL_WARNING("Invalid MIMO PS mode %d\n", mimo_ps_mode);
break;
}
@ -969,7 +969,7 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
return priv->hw_params.bcast_sta_id;
default:
IWL_WARNING("Unknown mode of operation: %d", priv->iw_mode);
IWL_WARNING("Unknown mode of operation: %d\n", priv->iw_mode);
return priv->hw_params.bcast_sta_id;
}
}

View File

@ -493,7 +493,7 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
/* Alloc keep-warm buffer */
ret = iwl_kw_alloc(priv);
if (ret) {
IWL_ERROR("Keep Warm allocation failed");
IWL_ERROR("Keep Warm allocation failed\n");
goto error_kw;
}
spin_lock_irqsave(&priv->lock, flags);
@ -1463,7 +1463,7 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn);
if (scd_flow >= priv->hw_params.max_txq_num) {
IWL_ERROR("BUG_ON scd_flow is bigger than number of queues");
IWL_ERROR("BUG_ON scd_flow is bigger than number of queues\n");
return;
}

View File

@ -29,7 +29,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
@ -1558,7 +1557,7 @@ int iwl3945_eeprom_init(struct iwl3945_priv *priv)
BUILD_BUG_ON(sizeof(priv->eeprom) != IWL_EEPROM_IMAGE_SIZE);
if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) {
IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x", gp);
IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x\n", gp);
return -ENOENT;
}
@ -1583,7 +1582,7 @@ int iwl3945_eeprom_init(struct iwl3945_priv *priv)
}
if (!(r & CSR_EEPROM_REG_READ_VALID_MSK)) {
IWL_ERROR("Time out reading EEPROM[%d]", addr);
IWL_ERROR("Time out reading EEPROM[%d]\n", addr);
return -ETIMEDOUT;
}
e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
@ -2507,7 +2506,7 @@ static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *h
return priv->hw_setting.bcast_sta_id;
default:
IWL_WARNING("Unknown mode of operation: %d", priv->iw_mode);
IWL_WARNING("Unknown mode of operation: %d\n", priv->iw_mode);
return priv->hw_setting.bcast_sta_id;
}
}

View File

@ -413,12 +413,12 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
last_addr = range->end_addr;
__skb_unlink(entry, &priv->tx_queue);
memset(&info->status, 0, sizeof(info->status));
priv->tx_stats[skb_get_queue_mapping(skb)].len--;
entry_hdr = (struct p54_control_hdr *) entry->data;
entry_data = (struct p54_tx_control_allocdata *) entry_hdr->data;
if ((entry_hdr->magic1 & cpu_to_le16(0x4000)) != 0)
pad = entry_data->align[0];
priv->tx_stats[entry_data->hw_queue - 4].len--;
if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
if (!(payload->status & 0x01))
info->flags |= IEEE80211_TX_STAT_ACK;
@ -557,6 +557,7 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
struct p54_tx_control_allocdata *txhdr;
size_t padding, len;
u8 rate;
u8 cts_rate = 0x20;
current_queue = &priv->tx_stats[skb_get_queue_mapping(skb)];
if (unlikely(current_queue->len > current_queue->limit))
@ -581,28 +582,28 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
hdr->type = (info->flags & IEEE80211_TX_CTL_NO_ACK) ? 0 : cpu_to_le16(1);
hdr->retry1 = hdr->retry2 = info->control.retry_limit;
memset(txhdr->wep_key, 0x0, 16);
txhdr->padding = 0;
txhdr->padding2 = 0;
/* TODO: add support for alternate retry TX rates */
rate = ieee80211_get_tx_rate(dev, info)->hw_value;
if (info->flags & IEEE80211_TX_CTL_SHORT_PREAMBLE)
if (info->flags & IEEE80211_TX_CTL_SHORT_PREAMBLE) {
rate |= 0x10;
if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS)
cts_rate |= 0x10;
}
if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) {
rate |= 0x40;
else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)
cts_rate |= ieee80211_get_rts_cts_rate(dev, info)->hw_value;
} else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) {
rate |= 0x20;
cts_rate |= ieee80211_get_rts_cts_rate(dev, info)->hw_value;
}
memset(txhdr->rateset, rate, 8);
txhdr->wep_key_present = 0;
txhdr->wep_key_len = 0;
txhdr->frame_type = cpu_to_le32(skb_get_queue_mapping(skb) + 4);
txhdr->magic4 = 0;
txhdr->antenna = (info->antenna_sel_tx == 0) ?
txhdr->key_type = 0;
txhdr->key_len = 0;
txhdr->hw_queue = skb_get_queue_mapping(skb) + 4;
txhdr->tx_antenna = (info->antenna_sel_tx == 0) ?
2 : info->antenna_sel_tx - 1;
txhdr->output_power = 0x7f; // HW Maximum
txhdr->magic5 = (info->flags & IEEE80211_TX_CTL_NO_ACK) ?
0 : ((rate > 0x3) ? cpu_to_le32(0x33) : cpu_to_le32(0x23));
txhdr->cts_rate = (info->flags & IEEE80211_TX_CTL_NO_ACK) ?
0 : cts_rate;
if (padding)
txhdr->align[0] = padding;
@ -836,10 +837,21 @@ static int p54_start(struct ieee80211_hw *dev)
struct p54_common *priv = dev->priv;
int err;
if (!priv->cached_vdcf) {
priv->cached_vdcf = kzalloc(sizeof(struct p54_tx_control_vdcf)+
priv->tx_hdr_len + sizeof(struct p54_control_hdr),
GFP_KERNEL);
if (!priv->cached_vdcf)
return -ENOMEM;
}
err = priv->open(dev);
if (!err)
priv->mode = IEEE80211_IF_TYPE_MNTR;
p54_init_vdcf(dev);
return err;
}
@ -1019,15 +1031,6 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
dev->extra_tx_headroom = sizeof(struct p54_control_hdr) + 4 +
sizeof(struct p54_tx_control_allocdata);
priv->cached_vdcf = kzalloc(sizeof(struct p54_tx_control_vdcf) +
priv->tx_hdr_len + sizeof(struct p54_control_hdr), GFP_KERNEL);
if (!priv->cached_vdcf) {
ieee80211_free_hw(dev);
return NULL;
}
p54_init_vdcf(dev);
mutex_init(&priv->conf_mutex);
return dev;

View File

@ -183,16 +183,16 @@ struct p54_frame_sent_hdr {
struct p54_tx_control_allocdata {
u8 rateset[8];
u16 padding;
u8 wep_key_present;
u8 wep_key_len;
u8 wep_key[16];
__le32 frame_type;
u32 padding2;
__le16 magic4;
u8 antenna;
u8 unalloc0[2];
u8 key_type;
u8 key_len;
u8 key[16];
u8 hw_queue;
u8 unalloc1[9];
u8 tx_antenna;
u8 output_power;
__le32 magic5;
u8 cts_rate;
u8 unalloc2[3];
u8 align[0];
} __attribute__ ((packed));

View File

@ -109,7 +109,17 @@ static void p54u_rx_cb(struct urb *urb)
urb->context = skb;
skb_queue_tail(&priv->rx_queue, skb);
} else {
if (!priv->hw_type)
skb_push(skb, sizeof(struct net2280_tx_hdr));
skb_reset_tail_pointer(skb);
skb_trim(skb, 0);
if (urb->transfer_buffer != skb_tail_pointer(skb)) {
/* this should not happen */
WARN_ON(1);
urb->transfer_buffer = skb_tail_pointer(skb);
}
skb_queue_tail(&priv->rx_queue, skb);
}

View File

@ -173,10 +173,10 @@ struct rxdone_entry_desc {
* frame transmission failed due to excessive retries.
*/
enum txdone_entry_desc_flags {
TXDONE_UNKNOWN = 1 << 0,
TXDONE_SUCCESS = 1 << 1,
TXDONE_FAILURE = 1 << 2,
TXDONE_EXCESSIVE_RETRY = 1 << 3,
TXDONE_UNKNOWN,
TXDONE_SUCCESS,
TXDONE_FAILURE,
TXDONE_EXCESSIVE_RETRY,
};
/**

View File

@ -181,6 +181,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
* (Only indirectly by looking at the failed TX counters
* in the register).
*/
txdesc.flags = 0;
if (!urb->status)
__set_bit(TXDONE_UNKNOWN, &txdesc.flags);
else

View File

@ -40,6 +40,7 @@ static struct usb_device_id rtl8187_table[] __devinitdata = {
/* Netgear */
{USB_DEVICE(0x0846, 0x6100), .driver_info = DEVICE_RTL8187},
{USB_DEVICE(0x0846, 0x6a00), .driver_info = DEVICE_RTL8187},
{USB_DEVICE(0x0846, 0x4260), .driver_info = DEVICE_RTL8187B},
/* HP */
{USB_DEVICE(0x03f0, 0xca02), .driver_info = DEVICE_RTL8187},
/* Sitecom */

View File

@ -1165,15 +1165,19 @@ EXPORT_SYMBOL(ssb_dma_translation);
int ssb_dma_set_mask(struct ssb_device *dev, u64 mask)
{
#ifdef CONFIG_SSB_PCIHOST
int err;
#endif
switch (dev->bus->bustype) {
case SSB_BUSTYPE_PCI:
#ifdef CONFIG_SSB_PCIHOST
err = pci_set_dma_mask(dev->bus->host_pci, mask);
if (err)
return err;
err = pci_set_consistent_dma_mask(dev->bus->host_pci, mask);
return err;
#endif
case SSB_BUSTYPE_SSB:
return dma_set_mask(dev->dev, mask);
default:
@ -1188,6 +1192,7 @@ void * ssb_dma_alloc_consistent(struct ssb_device *dev, size_t size,
{
switch (dev->bus->bustype) {
case SSB_BUSTYPE_PCI:
#ifdef CONFIG_SSB_PCIHOST
if (gfp_flags & GFP_DMA) {
/* Workaround: The PCI API does not support passing
* a GFP flag. */
@ -1195,6 +1200,7 @@ void * ssb_dma_alloc_consistent(struct ssb_device *dev, size_t size,
size, dma_handle, gfp_flags);
}
return pci_alloc_consistent(dev->bus->host_pci, size, dma_handle);
#endif
case SSB_BUSTYPE_SSB:
return dma_alloc_coherent(dev->dev, size, dma_handle, gfp_flags);
default:
@ -1210,6 +1216,7 @@ void ssb_dma_free_consistent(struct ssb_device *dev, size_t size,
{
switch (dev->bus->bustype) {
case SSB_BUSTYPE_PCI:
#ifdef CONFIG_SSB_PCIHOST
if (gfp_flags & GFP_DMA) {
/* Workaround: The PCI API does not support passing
* a GFP flag. */
@ -1220,6 +1227,7 @@ void ssb_dma_free_consistent(struct ssb_device *dev, size_t size,
pci_free_consistent(dev->bus->host_pci, size,
vaddr, dma_handle);
return;
#endif
case SSB_BUSTYPE_SSB:
dma_free_coherent(dev->dev, size, vaddr, dma_handle);
return;

View File

@ -45,6 +45,7 @@
#define TUNGETFEATURES _IOR('T', 207, unsigned int)
#define TUNSETOFFLOAD _IOW('T', 208, unsigned int)
#define TUNSETTXFILTER _IOW('T', 209, unsigned int)
#define TUNGETIFF _IOR('T', 210, unsigned int)
/* TUNSETIFF ifr flags */
#define IFF_TUN 0x0001

View File

@ -1452,6 +1452,10 @@ extern int skb_copy_datagram_iovec(const struct sk_buff *from,
extern int skb_copy_and_csum_datagram_iovec(struct sk_buff *skb,
int hlen,
struct iovec *iov);
extern int skb_copy_datagram_from_iovec(struct sk_buff *skb,
int offset,
struct iovec *from,
int len);
extern void skb_free_datagram(struct sock *sk, struct sk_buff *skb);
extern int skb_kill_datagram(struct sock *sk, struct sk_buff *skb,
unsigned int flags);

View File

@ -80,7 +80,8 @@ extern struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net,
struct net_device *dev,
int strict);
extern int ipv6_dev_get_saddr(struct net_device *dev,
extern int ipv6_dev_get_saddr(struct net *net,
struct net_device *dev,
const struct in6_addr *daddr,
unsigned int srcprefs,
struct in6_addr *saddr);

View File

@ -107,6 +107,7 @@ struct rt6_rtnl_dump_arg
{
struct sk_buff *skb;
struct netlink_callback *cb;
struct net *net;
};
extern int rt6_dump_route(struct rt6_info *rt, void *p_arg);

View File

@ -708,10 +708,7 @@ enum ieee80211_tkip_key_type {
* rely on the host system for such buffering. This option is used
* to configure the IEEE 802.11 upper layer to buffer broadcast and
* multicast frames when there are power saving stations so that
* the driver can fetch them with ieee80211_get_buffered_bc(). Note
* that not setting this flag works properly only when the
* %IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE is also not set because
* otherwise the stack will not know when the DTIM beacon was sent.
* the driver can fetch them with ieee80211_get_buffered_bc().
*
* @IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE:
* Hardware is not capable of short slot operation on the 2.4 GHz band.
@ -1099,10 +1096,8 @@ enum ieee80211_ampdu_mlme_action {
* See the section "Frame filtering" for more information.
* This callback must be implemented and atomic.
*
* @set_tim: Set TIM bit. If the hardware/firmware takes care of beacon
* generation (that is, %IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE is set)
* mac80211 calls this function when a TIM bit must be set or cleared
* for a given AID. Must be atomic.
* @set_tim: Set TIM bit. mac80211 calls this function when a TIM bit
* must be set or cleared for a given AID. Must be atomic.
*
* @set_key: See the section "Hardware crypto acceleration"
* This callback can sleep, and is only called between add_interface

View File

@ -27,6 +27,7 @@ enum qdisc_state_t
{
__QDISC_STATE_RUNNING,
__QDISC_STATE_SCHED,
__QDISC_STATE_DEACTIVATED,
};
struct qdisc_size_table {
@ -60,7 +61,6 @@ struct Qdisc
struct gnet_stats_basic bstats;
struct gnet_stats_queue qstats;
struct gnet_stats_rate_est rate_est;
struct rcu_head q_rcu;
int (*reshape_fail)(struct sk_buff *skb,
struct Qdisc *q);

View File

@ -456,7 +456,7 @@ static void __exit bt_exit(void)
subsys_initcall(bt_init);
module_exit(bt_exit);
MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
MODULE_DESCRIPTION("Bluetooth Core ver " VERSION);
MODULE_VERSION(VERSION);
MODULE_LICENSE("GPL");

View File

@ -736,7 +736,7 @@ MODULE_PARM_DESC(compress_src, "Compress sources headers");
module_param(compress_dst, bool, 0644);
MODULE_PARM_DESC(compress_dst, "Compress destination headers");
MODULE_AUTHOR("David Libault <david.libault@inventel.fr>, Maxim Krasnyansky <maxk@qualcomm.com>");
MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
MODULE_DESCRIPTION("Bluetooth BNEP ver " VERSION);
MODULE_VERSION(VERSION);
MODULE_LICENSE("GPL");

View File

@ -3,8 +3,6 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
@ -12,10 +10,164 @@
#undef BT_DBG
#define BT_DBG(D...)
#endif
struct class *bt_class = NULL;
EXPORT_SYMBOL_GPL(bt_class);
static struct workqueue_struct *btaddconn;
static struct workqueue_struct *btdelconn;
static inline char *typetostr(int type)
static inline char *link_typetostr(int type)
{
switch (type) {
case ACL_LINK:
return "ACL";
case SCO_LINK:
return "SCO";
case ESCO_LINK:
return "eSCO";
default:
return "UNKNOWN";
}
}
static ssize_t show_link_type(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_conn *conn = dev_get_drvdata(dev);
return sprintf(buf, "%s\n", link_typetostr(conn->type));
}
static ssize_t show_link_address(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_conn *conn = dev_get_drvdata(dev);
bdaddr_t bdaddr;
baswap(&bdaddr, &conn->dst);
return sprintf(buf, "%s\n", batostr(&bdaddr));
}
static ssize_t show_link_features(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_conn *conn = dev_get_drvdata(dev);
return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
conn->features[0], conn->features[1],
conn->features[2], conn->features[3],
conn->features[4], conn->features[5],
conn->features[6], conn->features[7]);
}
#define LINK_ATTR(_name,_mode,_show,_store) \
struct device_attribute link_attr_##_name = __ATTR(_name,_mode,_show,_store)
static LINK_ATTR(type, S_IRUGO, show_link_type, NULL);
static LINK_ATTR(address, S_IRUGO, show_link_address, NULL);
static LINK_ATTR(features, S_IRUGO, show_link_features, NULL);
static struct attribute *bt_link_attrs[] = {
&link_attr_type.attr,
&link_attr_address.attr,
&link_attr_features.attr,
NULL
};
static struct attribute_group bt_link_group = {
.attrs = bt_link_attrs,
};
static struct attribute_group *bt_link_groups[] = {
&bt_link_group,
NULL
};
static void bt_link_release(struct device *dev)
{
void *data = dev_get_drvdata(dev);
kfree(data);
}
static struct device_type bt_link = {
.name = "link",
.groups = bt_link_groups,
.release = bt_link_release,
};
static void add_conn(struct work_struct *work)
{
struct hci_conn *conn = container_of(work, struct hci_conn, work);
flush_workqueue(btdelconn);
if (device_add(&conn->dev) < 0) {
BT_ERR("Failed to register connection device");
return;
}
}
void hci_conn_add_sysfs(struct hci_conn *conn)
{
struct hci_dev *hdev = conn->hdev;
BT_DBG("conn %p", conn);
conn->dev.type = &bt_link;
conn->dev.class = bt_class;
conn->dev.parent = &hdev->dev;
snprintf(conn->dev.bus_id, BUS_ID_SIZE, "%s:%d",
hdev->name, conn->handle);
dev_set_drvdata(&conn->dev, conn);
device_initialize(&conn->dev);
INIT_WORK(&conn->work, add_conn);
queue_work(btaddconn, &conn->work);
}
/*
* The rfcomm tty device will possibly retain even when conn
* is down, and sysfs doesn't support move zombie device,
* so we should move the device before conn device is destroyed.
*/
static int __match_tty(struct device *dev, void *data)
{
return !strncmp(dev->bus_id, "rfcomm", 6);
}
static void del_conn(struct work_struct *work)
{
struct hci_conn *conn = container_of(work, struct hci_conn, work);
struct hci_dev *hdev = conn->hdev;
while (1) {
struct device *dev;
dev = device_find_child(&conn->dev, NULL, __match_tty);
if (!dev)
break;
device_move(dev, NULL);
put_device(dev);
}
device_del(&conn->dev);
put_device(&conn->dev);
hci_dev_put(hdev);
}
void hci_conn_del_sysfs(struct hci_conn *conn)
{
BT_DBG("conn %p", conn);
if (!device_is_registered(&conn->dev))
return;
INIT_WORK(&conn->work, del_conn);
queue_work(btdelconn, &conn->work);
}
static inline char *host_typetostr(int type)
{
switch (type) {
case HCI_VIRTUAL:
@ -40,7 +192,7 @@ static inline char *typetostr(int type)
static ssize_t show_type(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
return sprintf(buf, "%s\n", typetostr(hdev->type));
return sprintf(buf, "%s\n", host_typetostr(hdev->type));
}
static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf)
@ -221,183 +373,62 @@ static DEVICE_ATTR(sniff_max_interval, S_IRUGO | S_IWUSR,
static DEVICE_ATTR(sniff_min_interval, S_IRUGO | S_IWUSR,
show_sniff_min_interval, store_sniff_min_interval);
static struct device_attribute *bt_attrs[] = {
&dev_attr_type,
&dev_attr_name,
&dev_attr_class,
&dev_attr_address,
&dev_attr_features,
&dev_attr_manufacturer,
&dev_attr_hci_version,
&dev_attr_hci_revision,
&dev_attr_inquiry_cache,
&dev_attr_idle_timeout,
&dev_attr_sniff_max_interval,
&dev_attr_sniff_min_interval,
static struct attribute *bt_host_attrs[] = {
&dev_attr_type.attr,
&dev_attr_name.attr,
&dev_attr_class.attr,
&dev_attr_address.attr,
&dev_attr_features.attr,
&dev_attr_manufacturer.attr,
&dev_attr_hci_version.attr,
&dev_attr_hci_revision.attr,
&dev_attr_inquiry_cache.attr,
&dev_attr_idle_timeout.attr,
&dev_attr_sniff_max_interval.attr,
&dev_attr_sniff_min_interval.attr,
NULL
};
static ssize_t show_conn_type(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_conn *conn = dev_get_drvdata(dev);
return sprintf(buf, "%s\n", conn->type == ACL_LINK ? "ACL" : "SCO");
}
static struct attribute_group bt_host_group = {
.attrs = bt_host_attrs,
};
static ssize_t show_conn_address(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_conn *conn = dev_get_drvdata(dev);
bdaddr_t bdaddr;
baswap(&bdaddr, &conn->dst);
return sprintf(buf, "%s\n", batostr(&bdaddr));
}
static ssize_t show_conn_features(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_conn *conn = dev_get_drvdata(dev);
return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
conn->features[0], conn->features[1],
conn->features[2], conn->features[3],
conn->features[4], conn->features[5],
conn->features[6], conn->features[7]);
}
#define CONN_ATTR(_name,_mode,_show,_store) \
struct device_attribute conn_attr_##_name = __ATTR(_name,_mode,_show,_store)
static CONN_ATTR(type, S_IRUGO, show_conn_type, NULL);
static CONN_ATTR(address, S_IRUGO, show_conn_address, NULL);
static CONN_ATTR(features, S_IRUGO, show_conn_features, NULL);
static struct device_attribute *conn_attrs[] = {
&conn_attr_type,
&conn_attr_address,
&conn_attr_features,
static struct attribute_group *bt_host_groups[] = {
&bt_host_group,
NULL
};
struct class *bt_class = NULL;
EXPORT_SYMBOL_GPL(bt_class);
static struct bus_type bt_bus = {
.name = "bluetooth",
};
static struct platform_device *bt_platform;
static void bt_release(struct device *dev)
static void bt_host_release(struct device *dev)
{
void *data = dev_get_drvdata(dev);
kfree(data);
}
static void add_conn(struct work_struct *work)
{
struct hci_conn *conn = container_of(work, struct hci_conn, work);
int i;
flush_workqueue(btdelconn);
if (device_add(&conn->dev) < 0) {
BT_ERR("Failed to register connection device");
return;
}
for (i = 0; conn_attrs[i]; i++)
if (device_create_file(&conn->dev, conn_attrs[i]) < 0)
BT_ERR("Failed to create connection attribute");
}
void hci_conn_add_sysfs(struct hci_conn *conn)
{
struct hci_dev *hdev = conn->hdev;
BT_DBG("conn %p", conn);
conn->dev.bus = &bt_bus;
conn->dev.parent = &hdev->dev;
conn->dev.release = bt_release;
snprintf(conn->dev.bus_id, BUS_ID_SIZE, "%s:%d",
hdev->name, conn->handle);
dev_set_drvdata(&conn->dev, conn);
device_initialize(&conn->dev);
INIT_WORK(&conn->work, add_conn);
queue_work(btaddconn, &conn->work);
}
/*
* The rfcomm tty device will possibly retain even when conn
* is down, and sysfs doesn't support move zombie device,
* so we should move the device before conn device is destroyed.
*/
static int __match_tty(struct device *dev, void *data)
{
return !strncmp(dev->bus_id, "rfcomm", 6);
}
static void del_conn(struct work_struct *work)
{
struct hci_conn *conn = container_of(work, struct hci_conn, work);
struct hci_dev *hdev = conn->hdev;
while (1) {
struct device *dev;
dev = device_find_child(&conn->dev, NULL, __match_tty);
if (!dev)
break;
device_move(dev, NULL);
put_device(dev);
}
device_del(&conn->dev);
put_device(&conn->dev);
hci_dev_put(hdev);
}
void hci_conn_del_sysfs(struct hci_conn *conn)
{
BT_DBG("conn %p", conn);
if (!device_is_registered(&conn->dev))
return;
INIT_WORK(&conn->work, del_conn);
queue_work(btdelconn, &conn->work);
}
static struct device_type bt_host = {
.name = "host",
.groups = bt_host_groups,
.release = bt_host_release,
};
int hci_register_sysfs(struct hci_dev *hdev)
{
struct device *dev = &hdev->dev;
unsigned int i;
int err;
BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
dev->bus = &bt_bus;
dev->type = &bt_host;
dev->class = bt_class;
dev->parent = hdev->parent;
strlcpy(dev->bus_id, hdev->name, BUS_ID_SIZE);
dev->release = bt_release;
dev_set_drvdata(dev, hdev);
err = device_register(dev);
if (err < 0)
return err;
for (i = 0; bt_attrs[i]; i++)
if (device_create_file(dev, bt_attrs[i]) < 0)
BT_ERR("Failed to create device attribute");
return 0;
}
@ -410,59 +441,30 @@ void hci_unregister_sysfs(struct hci_dev *hdev)
int __init bt_sysfs_init(void)
{
int err;
btaddconn = create_singlethread_workqueue("btaddconn");
if (!btaddconn) {
err = -ENOMEM;
goto out;
}
if (!btaddconn)
return -ENOMEM;
btdelconn = create_singlethread_workqueue("btdelconn");
if (!btdelconn) {
err = -ENOMEM;
goto out_del;
destroy_workqueue(btaddconn);
return -ENOMEM;
}
bt_platform = platform_device_register_simple("bluetooth", -1, NULL, 0);
if (IS_ERR(bt_platform)) {
err = PTR_ERR(bt_platform);
goto out_platform;
}
err = bus_register(&bt_bus);
if (err < 0)
goto out_bus;
bt_class = class_create(THIS_MODULE, "bluetooth");
if (IS_ERR(bt_class)) {
err = PTR_ERR(bt_class);
goto out_class;
destroy_workqueue(btdelconn);
destroy_workqueue(btaddconn);
return PTR_ERR(bt_class);
}
return 0;
out_class:
bus_unregister(&bt_bus);
out_bus:
platform_device_unregister(bt_platform);
out_platform:
destroy_workqueue(btdelconn);
out_del:
destroy_workqueue(btaddconn);
out:
return err;
}
void bt_sysfs_cleanup(void)
{
destroy_workqueue(btaddconn);
destroy_workqueue(btdelconn);
class_destroy(bt_class);
bus_unregister(&bt_bus);
platform_device_unregister(bt_platform);
}

View File

@ -2516,7 +2516,7 @@ EXPORT_SYMBOL(l2cap_load);
module_init(l2cap_init);
module_exit(l2cap_exit);
MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
MODULE_VERSION(VERSION);
MODULE_LICENSE("GPL");

View File

@ -2115,7 +2115,7 @@ MODULE_PARM_DESC(channel_mtu, "Default MTU for the RFCOMM channel");
module_param(l2cap_mtu, uint, 0644);
MODULE_PARM_DESC(l2cap_mtu, "Default MTU for the L2CAP connection");
MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
MODULE_DESCRIPTION("Bluetooth RFCOMM ver " VERSION);
MODULE_VERSION(VERSION);
MODULE_LICENSE("GPL");

View File

@ -1002,7 +1002,7 @@ module_exit(sco_exit);
module_param(disable_esco, bool, 0644);
MODULE_PARM_DESC(disable_esco, "Disable eSCO connection creation");
MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
MODULE_DESCRIPTION("Bluetooth SCO ver " VERSION);
MODULE_VERSION(VERSION);
MODULE_LICENSE("GPL");

View File

@ -148,11 +148,16 @@ static int br_set_tx_csum(struct net_device *dev, u32 data)
}
static struct ethtool_ops br_ethtool_ops = {
.get_drvinfo = br_getinfo,
.get_link = ethtool_op_get_link,
.set_sg = br_set_sg,
.set_tx_csum = br_set_tx_csum,
.set_tso = br_set_tso,
.get_drvinfo = br_getinfo,
.get_link = ethtool_op_get_link,
.get_tx_csum = ethtool_op_get_tx_csum,
.set_tx_csum = br_set_tx_csum,
.get_sg = ethtool_op_get_sg,
.set_sg = br_set_sg,
.get_tso = ethtool_op_get_tso,
.set_tso = br_set_tso,
.get_ufo = ethtool_op_get_ufo,
.get_flags = ethtool_op_get_flags,
};
void br_dev_setup(struct net_device *dev)

View File

@ -339,6 +339,93 @@ fault:
return -EFAULT;
}
/**
* skb_copy_datagram_from_iovec - Copy a datagram from an iovec.
* @skb: buffer to copy
* @offset: offset in the buffer to start copying to
* @from: io vector to copy to
* @len: amount of data to copy to buffer from iovec
*
* Returns 0 or -EFAULT.
* Note: the iovec is modified during the copy.
*/
int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset,
struct iovec *from, int len)
{
int start = skb_headlen(skb);
int i, copy = start - offset;
/* Copy header. */
if (copy > 0) {
if (copy > len)
copy = len;
if (memcpy_fromiovec(skb->data + offset, from, copy))
goto fault;
if ((len -= copy) == 0)
return 0;
offset += copy;
}
/* Copy paged appendix. Hmm... why does this look so complicated? */
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
int end;
WARN_ON(start > offset + len);
end = start + skb_shinfo(skb)->frags[i].size;
if ((copy = end - offset) > 0) {
int err;
u8 *vaddr;
skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
struct page *page = frag->page;
if (copy > len)
copy = len;
vaddr = kmap(page);
err = memcpy_fromiovec(vaddr + frag->page_offset +
offset - start, from, copy);
kunmap(page);
if (err)
goto fault;
if (!(len -= copy))
return 0;
offset += copy;
}
start = end;
}
if (skb_shinfo(skb)->frag_list) {
struct sk_buff *list = skb_shinfo(skb)->frag_list;
for (; list; list = list->next) {
int end;
WARN_ON(start > offset + len);
end = start + list->len;
if ((copy = end - offset) > 0) {
if (copy > len)
copy = len;
if (skb_copy_datagram_from_iovec(list,
offset - start,
from, copy))
goto fault;
if ((len -= copy) == 0)
return 0;
offset += copy;
}
start = end;
}
}
if (!len)
return 0;
fault:
return -EFAULT;
}
EXPORT_SYMBOL(skb_copy_datagram_from_iovec);
static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset,
u8 __user *to, int len,
__wsum *csump)

View File

@ -1339,19 +1339,23 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
}
static inline void __netif_reschedule(struct Qdisc *q)
{
struct softnet_data *sd;
unsigned long flags;
local_irq_save(flags);
sd = &__get_cpu_var(softnet_data);
q->next_sched = sd->output_queue;
sd->output_queue = q;
raise_softirq_irqoff(NET_TX_SOFTIRQ);
local_irq_restore(flags);
}
void __netif_schedule(struct Qdisc *q)
{
if (!test_and_set_bit(__QDISC_STATE_SCHED, &q->state)) {
struct softnet_data *sd;
unsigned long flags;
local_irq_save(flags);
sd = &__get_cpu_var(softnet_data);
q->next_sched = sd->output_queue;
sd->output_queue = q;
raise_softirq_irqoff(NET_TX_SOFTIRQ);
local_irq_restore(flags);
}
if (!test_and_set_bit(__QDISC_STATE_SCHED, &q->state))
__netif_reschedule(q);
}
EXPORT_SYMBOL(__netif_schedule);
@ -1800,9 +1804,13 @@ gso:
spin_lock(root_lock);
rc = qdisc_enqueue_root(skb, q);
qdisc_run(q);
if (unlikely(test_bit(__QDISC_STATE_DEACTIVATED, &q->state))) {
kfree_skb(skb);
rc = NET_XMIT_DROP;
} else {
rc = qdisc_enqueue_root(skb, q);
qdisc_run(q);
}
spin_unlock(root_lock);
goto out;
@ -1974,15 +1982,17 @@ static void net_tx_action(struct softirq_action *h)
head = head->next_sched;
smp_mb__before_clear_bit();
clear_bit(__QDISC_STATE_SCHED, &q->state);
root_lock = qdisc_lock(q);
if (spin_trylock(root_lock)) {
smp_mb__before_clear_bit();
clear_bit(__QDISC_STATE_SCHED,
&q->state);
qdisc_run(q);
spin_unlock(root_lock);
} else {
__netif_schedule(q);
if (!test_bit(__QDISC_STATE_DEACTIVATED,
&q->state))
__netif_reschedule(q);
}
}
}
@ -2084,7 +2094,8 @@ static int ing_filter(struct sk_buff *skb)
q = rxq->qdisc;
if (q != &noop_qdisc) {
spin_lock(qdisc_lock(q));
result = qdisc_enqueue_root(skb, q);
if (likely(!test_bit(__QDISC_STATE_DEACTIVATED, &q->state)))
result = qdisc_enqueue_root(skb, q);
spin_unlock(qdisc_lock(q));
}

View File

@ -99,7 +99,7 @@ struct gen_estimator_head
static struct gen_estimator_head elist[EST_MAX_INTERVAL+1];
/* Protects against NULL dereference and RCU write-side */
/* Protects against NULL dereference */
static DEFINE_RWLOCK(est_lock);
static void est_timer(unsigned long arg)
@ -185,7 +185,6 @@ int gen_new_estimator(struct gnet_stats_basic *bstats,
est->last_packets = bstats->packets;
est->avpps = rate_est->pps<<10;
write_lock_bh(&est_lock);
if (!elist[idx].timer.function) {
INIT_LIST_HEAD(&elist[idx].list);
setup_timer(&elist[idx].timer, est_timer, idx);
@ -195,7 +194,6 @@ int gen_new_estimator(struct gnet_stats_basic *bstats,
mod_timer(&elist[idx].timer, jiffies + ((HZ/4) << idx));
list_add_rcu(&est->list, &elist[idx].list);
write_unlock_bh(&est_lock);
return 0;
}
@ -214,6 +212,7 @@ static void __gen_kill_estimator(struct rcu_head *head)
* Removes the rate estimator specified by &bstats and &rate_est
* and deletes the timer.
*
* NOTE: Called under rtnl_mutex
*/
void gen_kill_estimator(struct gnet_stats_basic *bstats,
struct gnet_stats_rate_est *rate_est)
@ -227,17 +226,17 @@ void gen_kill_estimator(struct gnet_stats_basic *bstats,
if (!elist[idx].timer.function)
continue;
write_lock_bh(&est_lock);
list_for_each_entry_safe(e, n, &elist[idx].list, list) {
if (e->rate_est != rate_est || e->bstats != bstats)
continue;
write_lock_bh(&est_lock);
e->bstats = NULL;
write_unlock_bh(&est_lock);
list_del_rcu(&e->list);
call_rcu(&e->e_rcu, __gen_kill_estimator);
}
write_unlock_bh(&est_lock);
}
}

View File

@ -2256,14 +2256,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features)
segs = nskb;
tail = nskb;
nskb->dev = skb->dev;
skb_copy_queue_mapping(nskb, skb);
nskb->priority = skb->priority;
nskb->protocol = skb->protocol;
nskb->vlan_tci = skb->vlan_tci;
nskb->dst = dst_clone(skb->dst);
memcpy(nskb->cb, skb->cb, sizeof(skb->cb));
nskb->pkt_type = skb->pkt_type;
__copy_skb_header(nskb, skb);
nskb->mac_len = skb->mac_len;
skb_reserve(nskb, headroom);
@ -2274,6 +2267,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features)
skb_copy_from_linear_data(skb, skb_put(nskb, doffset),
doffset);
if (!sg) {
nskb->ip_summed = CHECKSUM_NONE;
nskb->csum = skb_copy_and_csum_bits(skb, offset,
skb_put(nskb, len),
len, 0);
@ -2283,8 +2277,6 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features)
frag = skb_shinfo(nskb)->frags;
k = 0;
nskb->ip_summed = CHECKSUM_PARTIAL;
nskb->csum = skb->csum;
skb_copy_from_linear_data_offset(skb, offset,
skb_put(nskb, hsize), hsize);

View File

@ -411,12 +411,6 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk,
struct dccp_sock *dp = dccp_sk(sk);
long tstamp = dccp_timestamp();
/* Stop the REQUEST timer */
inet_csk_clear_xmit_timer(sk, ICSK_TIME_RETRANS);
WARN_ON(sk->sk_send_head == NULL);
__kfree_skb(sk->sk_send_head);
sk->sk_send_head = NULL;
if (!between48(DCCP_SKB_CB(skb)->dccpd_ack_seq,
dp->dccps_awl, dp->dccps_awh)) {
dccp_pr_debug("invalid ackno: S.AWL=%llu, "
@ -441,6 +435,12 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk,
DCCP_ACKVEC_STATE_RECEIVED))
goto out_invalid_packet; /* FIXME: change error code */
/* Stop the REQUEST timer */
inet_csk_clear_xmit_timer(sk, ICSK_TIME_RETRANS);
WARN_ON(sk->sk_send_head == NULL);
kfree_skb(sk->sk_send_head);
sk->sk_send_head = NULL;
dp->dccps_isr = DCCP_SKB_CB(skb)->dccpd_seq;
dccp_update_gsr(sk, dp->dccps_isr);
/*

View File

@ -70,7 +70,7 @@ addrtype_mt_v1(const struct sk_buff *skb, const struct net_device *in,
(info->flags & IPT_ADDRTYPE_INVERT_SOURCE);
if (ret && info->dest)
ret &= match_type(dev, iph->daddr, info->dest) ^
(info->flags & IPT_ADDRTYPE_INVERT_DEST);
!!(info->flags & IPT_ADDRTYPE_INVERT_DEST);
return ret;
}

View File

@ -73,9 +73,13 @@ bool nf_nat_proto_unique_tuple(struct nf_conntrack_tuple *tuple,
range_size = ntohs(range->max.all) - min + 1;
}
off = *rover;
if (range->flags & IP_NAT_RANGE_PROTO_RANDOM)
off = net_random();
off = secure_ipv4_port_ephemeral(tuple->src.u3.ip, tuple->dst.u3.ip,
maniptype == IP_NAT_MANIP_SRC
? tuple->dst.u.all
: tuple->src.u.all);
else
off = *rover;
for (i = 0; i < range_size; i++, off++) {
*portptr = htons(min + off % range_size);

View File

@ -2914,6 +2914,68 @@ static int ipv4_sysctl_rtcache_flush_strategy(ctl_table *table,
return 0;
}
static void rt_secret_reschedule(int old)
{
struct net *net;
int new = ip_rt_secret_interval;
int diff = new - old;
if (!diff)
return;
rtnl_lock();
for_each_net(net) {
int deleted = del_timer_sync(&net->ipv4.rt_secret_timer);
if (!new)
continue;
if (deleted) {
long time = net->ipv4.rt_secret_timer.expires - jiffies;
if (time <= 0 || (time += diff) <= 0)
time = 0;
net->ipv4.rt_secret_timer.expires = time;
} else
net->ipv4.rt_secret_timer.expires = new;
net->ipv4.rt_secret_timer.expires += jiffies;
add_timer(&net->ipv4.rt_secret_timer);
}
rtnl_unlock();
}
static int ipv4_sysctl_rt_secret_interval(ctl_table *ctl, int write,
struct file *filp,
void __user *buffer, size_t *lenp,
loff_t *ppos)
{
int old = ip_rt_secret_interval;
int ret = proc_dointvec_jiffies(ctl, write, filp, buffer, lenp, ppos);
rt_secret_reschedule(old);
return ret;
}
static int ipv4_sysctl_rt_secret_interval_strategy(ctl_table *table,
int __user *name,
int nlen,
void __user *oldval,
size_t __user *oldlenp,
void __user *newval,
size_t newlen)
{
int old = ip_rt_secret_interval;
int ret = sysctl_jiffies(table, name, nlen, oldval, oldlenp, newval,
newlen);
rt_secret_reschedule(old);
return ret;
}
static ctl_table ipv4_route_table[] = {
{
.ctl_name = NET_IPV4_ROUTE_GC_THRESH,
@ -3048,8 +3110,8 @@ static ctl_table ipv4_route_table[] = {
.data = &ip_rt_secret_interval,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec_jiffies,
.strategy = &sysctl_jiffies,
.proc_handler = &ipv4_sysctl_rt_secret_interval,
.strategy = &ipv4_sysctl_rt_secret_interval_strategy,
},
{ .ctl_name = 0 }
};
@ -3126,10 +3188,12 @@ static __net_init int rt_secret_timer_init(struct net *net)
net->ipv4.rt_secret_timer.data = (unsigned long)net;
init_timer_deferrable(&net->ipv4.rt_secret_timer);
net->ipv4.rt_secret_timer.expires =
jiffies + net_random() % ip_rt_secret_interval +
ip_rt_secret_interval;
add_timer(&net->ipv4.rt_secret_timer);
if (ip_rt_secret_interval) {
net->ipv4.rt_secret_timer.expires =
jiffies + net_random() % ip_rt_secret_interval +
ip_rt_secret_interval;
add_timer(&net->ipv4.rt_secret_timer);
}
return 0;
}

View File

@ -1106,13 +1106,12 @@ out:
return ret;
}
int ipv6_dev_get_saddr(struct net_device *dst_dev,
int ipv6_dev_get_saddr(struct net *net, struct net_device *dst_dev,
const struct in6_addr *daddr, unsigned int prefs,
struct in6_addr *saddr)
{
struct ipv6_saddr_score scores[2],
*score = &scores[0], *hiscore = &scores[1];
struct net *net = dev_net(dst_dev);
struct ipv6_saddr_dst dst;
struct net_device *dev;
int dst_type;

View File

@ -93,7 +93,8 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
if (flags & RT6_LOOKUP_F_SRCPREF_COA)
srcprefs |= IPV6_PREFER_SRC_COA;
if (ipv6_dev_get_saddr(ip6_dst_idev(&rt->u.dst)->dev,
if (ipv6_dev_get_saddr(net,
ip6_dst_idev(&rt->u.dst)->dev,
&flp->fl6_dst, srcprefs,
&saddr))
goto again;

View File

@ -378,6 +378,7 @@ static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
arg.skb = skb;
arg.cb = cb;
arg.net = net;
w->args = &arg;
for (h = s_h; h < FIB_TABLE_HASHSZ; h++, s_e = 0) {

View File

@ -934,7 +934,7 @@ static int ip6_dst_lookup_tail(struct sock *sk,
goto out_err_release;
if (ipv6_addr_any(&fl->fl6_src)) {
err = ipv6_dev_get_saddr(ip6_dst_idev(*dst)->dev,
err = ipv6_dev_get_saddr(net, ip6_dst_idev(*dst)->dev,
&fl->fl6_dst,
sk ? inet6_sk(sk)->srcprefs : 0,
&fl->fl6_src);

View File

@ -911,7 +911,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
} else {
if (np->rxopt.bits.rxinfo) {
struct in6_pktinfo src_info;
src_info.ipi6_ifindex = np->mcast_oif;
src_info.ipi6_ifindex = np->mcast_oif ? np->mcast_oif : sk->sk_bound_dev_if;
ipv6_addr_copy(&src_info.ipi6_addr, &np->daddr);
put_cmsg(&msg, SOL_IPV6, IPV6_PKTINFO, sizeof(src_info), &src_info);
}
@ -921,7 +921,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
}
if (np->rxopt.bits.rxoinfo) {
struct in6_pktinfo src_info;
src_info.ipi6_ifindex = np->mcast_oif;
src_info.ipi6_ifindex = np->mcast_oif ? np->mcast_oif : sk->sk_bound_dev_if;
ipv6_addr_copy(&src_info.ipi6_addr, &np->daddr);
put_cmsg(&msg, SOL_IPV6, IPV6_2292PKTINFO, sizeof(src_info), &src_info);
}

Some files were not shown because too many files have changed in this diff Show More