* [PATCH 05/47] Bluetooth: Add extra device reference counting for connections
From: Marcel Holtmann @ 2009-08-30 8:50 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev
In-Reply-To: <cover.1251621661.git.marcel@holtmann.org>
The device model itself has no real usable reference counting at the
moment and this causes problems if parents are deleted before their
children. The device model itself handles the memory details of this
correctly, but the uevent order is not consistent. This causes various
problems for systems like HAL or even X.
So until device_put() does a proper cleanup, the device for Bluetooth
connection will be protected with an extra reference counting to ensure
the correct order of uevents when connections are terminated.
This is not an automatic feature. Higher Bluetooth layers like HIDP or
BNEP should grab this new reference to ensure that their uevents are
send before the ones from the parent device.
Based on a report by Brian Rogers <brian@xyzw.org>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
include/net/bluetooth/hci_core.h | 4 ++++
net/bluetooth/hci_conn.c | 17 ++++++++++++++++-
net/bluetooth/hci_event.c | 2 ++
3 files changed, 22 insertions(+), 1 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index c4ca422..25b8a03 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -187,6 +187,7 @@ struct hci_conn {
struct work_struct work_del;
struct device dev;
+ atomic_t devref;
struct hci_dev *hdev;
void *l2cap_data;
@@ -339,6 +340,9 @@ int hci_conn_switch_role(struct hci_conn *conn, __u8 role);
void hci_conn_enter_active_mode(struct hci_conn *conn);
void hci_conn_enter_sniff_mode(struct hci_conn *conn);
+void hci_conn_hold_device(struct hci_conn *conn);
+void hci_conn_put_device(struct hci_conn *conn);
+
static inline void hci_conn_hold(struct hci_conn *conn)
{
atomic_inc(&conn->refcnt);
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index fa47d5d..a975098 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -246,6 +246,8 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
if (hdev->notify)
hdev->notify(hdev, HCI_NOTIFY_CONN_ADD);
+ atomic_set(&conn->devref, 0);
+
hci_conn_init_sysfs(conn);
tasklet_enable(&hdev->tx_task);
@@ -288,7 +290,7 @@ int hci_conn_del(struct hci_conn *conn)
skb_queue_purge(&conn->data_q);
- hci_conn_del_sysfs(conn);
+ hci_conn_put_device(conn);
hci_dev_put(hdev);
@@ -583,6 +585,19 @@ void hci_conn_check_pending(struct hci_dev *hdev)
hci_dev_unlock(hdev);
}
+void hci_conn_hold_device(struct hci_conn *conn)
+{
+ atomic_inc(&conn->devref);
+}
+EXPORT_SYMBOL(hci_conn_hold_device);
+
+void hci_conn_put_device(struct hci_conn *conn)
+{
+ if (atomic_dec_and_test(&conn->devref))
+ hci_conn_del_sysfs(conn);
+}
+EXPORT_SYMBOL(hci_conn_put_device);
+
int hci_get_conn_list(void __user *arg)
{
struct hci_conn_list_req req, *cl;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 184ba0a..e99fe38 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -887,6 +887,7 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
} else
conn->state = BT_CONNECTED;
+ hci_conn_hold_device(conn);
hci_conn_add_sysfs(conn);
if (test_bit(HCI_AUTH, &hdev->flags))
@@ -1693,6 +1694,7 @@ static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_bu
conn->handle = __le16_to_cpu(ev->handle);
conn->state = BT_CONNECTED;
+ hci_conn_hold_device(conn);
hci_conn_add_sysfs(conn);
break;
--
1.6.2.5
^ permalink raw reply related
* [PATCH 04/47] Bluetooth: Disconnect HIDRAW devices on disconnect
From: Marcel Holtmann @ 2009-08-30 8:50 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev
In-Reply-To: <cover.1251621661.git.marcel@holtmann.org>
Currently the HID subsystem will create HIDRAW devices for the transport
driver, but it will not disconnect them. Until the HID subsytem gets
fixed, ensure that HIDRAW and HIDDEV devices are disconnected when the
Bluetooth HID device gets removed.
Based on a patch from Brian Rogers <brian@xyzw.org>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
net/bluetooth/hidp/core.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index a9f7afb..f912d65 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -40,6 +40,7 @@
#include <linux/input.h>
#include <linux/hid.h>
+#include <linux/hidraw.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
@@ -574,6 +575,8 @@ static int hidp_session(void *arg)
if (session->hid) {
if (session->hid->claimed & HID_CLAIMED_INPUT)
hidinput_disconnect(session->hid);
+ if (session->hid->claimed & HID_CLAIMED_HIDRAW)
+ hidraw_disconnect(session->hid);
hid_destroy_device(session->hid);
}
--
1.6.2.5
^ permalink raw reply related
* [PATCH 03/47] Bluetooth: Improve USB driver throughput by increasing the frame size
From: Marcel Holtmann @ 2009-08-30 8:50 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev
In-Reply-To: <cover.1251621661.git.marcel@holtmann.org>
From: Vikram Kandukuri <vkandukuri@atheros.com>
This patch increases the receive buffer size to HCI_MAX_FRAME_SIZE
which improves the RX throughput considerably.
Tested against BRM/Atheros/CSR USB Dongles with PAN profile using
iperf and chariot. This gave significant (around 40%) increase
in performance (increased from 0.8 to 1.5 Mb/s in Sheld room)
Signed-off-by: Vikram Kandukuri <vikram.kandukuri@atheros.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
drivers/bluetooth/btusb.c | 4 +---
1 files changed, 1 insertions(+), 3 deletions(-)
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index e70c57e..124db8c 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -301,7 +301,7 @@ static int btusb_submit_bulk_urb(struct hci_dev *hdev, gfp_t mem_flags)
struct urb *urb;
unsigned char *buf;
unsigned int pipe;
- int err, size;
+ int err, size = HCI_MAX_FRAME_SIZE;
BT_DBG("%s", hdev->name);
@@ -312,8 +312,6 @@ static int btusb_submit_bulk_urb(struct hci_dev *hdev, gfp_t mem_flags)
if (!urb)
return -ENOMEM;
- size = le16_to_cpu(data->bulk_rx_ep->wMaxPacketSize);
-
buf = kmalloc(size, mem_flags);
if (!buf) {
usb_free_urb(urb);
--
1.6.2.5
^ permalink raw reply related
* [PATCH 02/47] Bluetooth: Fix missing scheduling when VIRTUAL_CABLE_UNPLUG is received
From: Marcel Holtmann @ 2009-08-30 8:50 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev
In-Reply-To: <cover.1251621661.git.marcel@holtmann.org>
From: Vikram Kandukuri <vkandukuri@atheros.com>
There is a test case in PTS tool; PTS will send the VIRTUAL_CABLE_UNPLUG
command to IUT. Then IUT should disconnect the channel and kill the HID
session when it receives the command. The VIRTUAL_CABLE_UNPLUG command
is parsed by HID transport, but it is not scheduled to do so. Add a
call to hidp_schedule() to kill the session.
Signed-off-by: Jothikumar Mothilal <jothikumar.mothilal@atheros.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
net/bluetooth/hidp/core.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index b186768..a9f7afb 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -374,6 +374,7 @@ static void hidp_process_hid_control(struct hidp_session *session,
/* Kill session thread */
atomic_inc(&session->terminate);
+ hidp_schedule(session);
}
}
--
1.6.2.5
^ permalink raw reply related
* [PATCH 01/47] Bluetooth: Add proper shutdown support to SCO sockets
From: Marcel Holtmann @ 2009-08-30 8:50 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev
In-Reply-To: <cover.1251621661.git.marcel@holtmann.org>
The SCO sockets for Bluetooth audio setup and streaming are missing the
shutdown implementation. This hasn't been a problem so far, but with a
more deeper integration with PulseAudio it is important to shutdown SCO
sockets properly.
Also the Headset profile 1.2 has more detailed qualification tests that
require that SCO and RFCOMM channels are terminated in the right order. A
proper shutdown function is necessary for this.
Based on a report by Johan Hedberg <johan.hedberg@nokia.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Tested-by: Johan Hedberg <johan.hedberg@nokia.com>
---
net/bluetooth/sco.c | 49 ++++++++++++++++++++++++++++++++++---------------
1 files changed, 34 insertions(+), 15 deletions(-)
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 51ae0c3..13c27f1 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -359,20 +359,9 @@ static void sco_sock_kill(struct sock *sk)
sock_put(sk);
}
-/* Close socket.
- * Must be called on unlocked socket.
- */
-static void sco_sock_close(struct sock *sk)
+static void __sco_sock_close(struct sock *sk)
{
- struct sco_conn *conn;
-
- sco_sock_clear_timer(sk);
-
- lock_sock(sk);
-
- conn = sco_pi(sk)->conn;
-
- BT_DBG("sk %p state %d conn %p socket %p", sk, sk->sk_state, conn, sk->sk_socket);
+ BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
switch (sk->sk_state) {
case BT_LISTEN:
@@ -390,9 +379,15 @@ static void sco_sock_close(struct sock *sk)
sock_set_flag(sk, SOCK_ZAPPED);
break;
}
+}
+/* Must be called on unlocked socket. */
+static void sco_sock_close(struct sock *sk)
+{
+ sco_sock_clear_timer(sk);
+ lock_sock(sk);
+ __sco_sock_close(sk);
release_sock(sk);
-
sco_sock_kill(sk);
}
@@ -748,6 +743,30 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char
return err;
}
+static int sco_sock_shutdown(struct socket *sock, int how)
+{
+ struct sock *sk = sock->sk;
+ int err = 0;
+
+ BT_DBG("sock %p, sk %p", sock, sk);
+
+ if (!sk)
+ return 0;
+
+ lock_sock(sk);
+ if (!sk->sk_shutdown) {
+ sk->sk_shutdown = SHUTDOWN_MASK;
+ sco_sock_clear_timer(sk);
+ __sco_sock_close(sk);
+
+ if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
+ err = bt_sock_wait_state(sk, BT_CLOSED,
+ sk->sk_lingertime);
+ }
+ release_sock(sk);
+ return err;
+}
+
static int sco_sock_release(struct socket *sock)
{
struct sock *sk = sock->sk;
@@ -969,7 +988,7 @@ static const struct proto_ops sco_sock_ops = {
.ioctl = bt_sock_ioctl,
.mmap = sock_no_mmap,
.socketpair = sock_no_socketpair,
- .shutdown = sock_no_shutdown,
+ .shutdown = sco_sock_shutdown,
.setsockopt = sco_sock_setsockopt,
.getsockopt = sco_sock_getsockopt
};
--
1.6.2.5
^ permalink raw reply related
* Pull request: bluetooth-next-2.6 2009-08-30
From: Marcel Holtmann @ 2009-08-30 8:50 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev
Hi Dave,
these are the updates for the Bluetooth subsystem for the 2.6.32 merge
window. On the driver side we have support for Marvell SDIO devices and
the Bluetooth USB driver got support for auto-suspend. On the core stack
part we have support for L2CAP enhanced retransmission mode now. The rest
are random fixes and cleanups.
Regards
Marcel
Please pull from
git://git.kernel.org/pub/scm/linux/kernel/git/holtmann/bluetooth-next-2.6.git master
This will update the following files:
Documentation/00-INDEX | 2 +
Documentation/btmrvl.txt | 119 ++++
drivers/bluetooth/Kconfig | 25 +
drivers/bluetooth/Makefile | 6 +
drivers/bluetooth/btmrvl_debugfs.c | 432 ++++++++++++
drivers/bluetooth/btmrvl_drv.h | 139 ++++
drivers/bluetooth/btmrvl_main.c | 624 +++++++++++++++++
drivers/bluetooth/btmrvl_sdio.c | 1003 ++++++++++++++++++++++++++
drivers/bluetooth/btmrvl_sdio.h | 108 +++
drivers/bluetooth/btusb.c | 198 +++++-
drivers/bluetooth/hci_bcsp.c | 3 +-
include/net/bluetooth/bluetooth.h | 5 +-
include/net/bluetooth/hci_core.h | 10 +-
include/net/bluetooth/l2cap.h | 134 ++++-
include/net/bluetooth/rfcomm.h | 2 +
net/bluetooth/Kconfig | 1 +
net/bluetooth/hci_conn.c | 17 +-
net/bluetooth/hci_core.c | 2 +-
net/bluetooth/hci_event.c | 2 +
net/bluetooth/hidp/core.c | 66 ++-
net/bluetooth/hidp/hidp.h | 2 +
net/bluetooth/l2cap.c | 1357 +++++++++++++++++++++++++++++++++---
net/bluetooth/rfcomm/core.c | 69 ++-
net/bluetooth/sco.c | 49 +-
24 files changed, 4186 insertions(+), 189 deletions(-)
create mode 100644 Documentation/btmrvl.txt
create mode 100644 drivers/bluetooth/btmrvl_debugfs.c
create mode 100644 drivers/bluetooth/btmrvl_drv.h
create mode 100644 drivers/bluetooth/btmrvl_main.c
create mode 100644 drivers/bluetooth/btmrvl_sdio.c
create mode 100644 drivers/bluetooth/btmrvl_sdio.h
through these ChangeSets:
Bing Zhao (5):
Bluetooth: Add btmrvl driver for Marvell Bluetooth devices
Bluetooth: Add Marvell BT-over-SDIO driver
Bluetooth: Add debugfs support to btmrvl driver
Bluetooth: Add documentation for Marvell Bluetooth driver
Bluetooth: Fix incorrect alignment in Marvell BT-over-SDIO driver
Gustavo F. Padovan (15):
Bluetooth: Add configuration support for ERTM and Streaming mode
Bluetooth: Create separate l2cap_send_disconn_req() function
Bluetooth: Add initial support for ERTM packets transfers
Bluetooth: Add support for Segmentation and Reassembly of SDUs
Bluetooth: Initial support for retransmission of packets with REJ
frames
Bluetooth: Add support for Retransmission and Monitor Timers
Bluetooth: Enable Streaming Mode for L2CAP
Bluetooth: Add support for FCS option to L2CAP
Bluetooth: Add support for L2CAP SREJ exception
Bluetooth: Full support for receiving L2CAP SREJ frames
Bluetooth: Add locking scheme to L2CAP timeout callbacks
Bluetooth: Use proper *_unaligned_le{16,32} helpers for L2CAP
Bluetooth: Acknowledge L2CAP packets when receiving RR-frames (F-bit=1)
Bluetooth: Handle L2CAP case when the remote receiver is busy
Bluetooth: Add support for L2CAP 'Send RRorRNR' action
Julia Lawall (1):
Bluetooth: Add missing kmalloc NULL tests to Marvell driver
Luiz Augusto von Dentz (1):
Bluetooth: Fix rejected connection not disconnecting ACL link
Marcel Holtmann (19):
Bluetooth: Add proper shutdown support to SCO sockets
Bluetooth: Disconnect HIDRAW devices on disconnect
Bluetooth: Add extra device reference counting for connections
Bluetooth: Let HIDP grab the device reference for connections
Bluetooth: Fix Kconfig for Marvell Bluetooth driver
Bluetooth: Fix compilation of Marvell driver without debugfs
Bluetooth: Remove pointless ifdef protection for Marvell header files
Bluetooth: Remove pointless casts from Marvell debugfs support
Bluetooth: Some coding style cleanup for Marvell core driver
Bluetooth: Fix complicated assignment of firmware for Marvell devices
Bluetooth: Fix module description strings for Marvell driver
Bluetooth: Remove private device name of Marvell SDIO driver
Bluetooth: Fix Marvell driver to use skb_put and hci_opcode_pack
Bluetooth: Fix last few compiler warning within Marvell core driver
Bluetooth: Remove Enter/Leave debug statements from Marvell driver
Bluetooth: Coding style cleanup from previous rfcomm_init bug fix
Bluetooth: Add module option to enable L2CAP ERTM support
Bluetooth: Allow setting of L2CAP ERTM via socket option
Bluetooth: Add L2CAP RFC option if ERTM is enabled
Oliver Neukum (1):
Bluetooth: Add USB autosuspend support to btusb driver
Randy Dunlap (1):
Bluetooth: Add missing selection of CONFIG_CRC16 for L2CAP layer
Thomas Gleixner (1):
Bluetooth: Convert hdev->req_lock to a mutex
Vikram Kandukuri (2):
Bluetooth: Fix missing scheduling when VIRTUAL_CABLE_UNPLUG is received
Bluetooth: Improve USB driver throughput by increasing the frame size
Wending Weng (1):
Bluetooth: Fix false errors from bcsp_pkt_cull function
^ permalink raw reply
* Re: [RFC PATCH] sched: Fix resource limiting in pfifo_fast
From: Krishna Kumar2 @ 2009-08-30 8:46 UTC (permalink / raw)
To: Jarek Poplawski; +Cc: davem, Eric Dumazet, netdev
In-Reply-To: <4A9A2E79.5030808@gmail.com>
> Jarek Poplawski <jarkao2@gmail.com>
> >> pfifo_fast_enqueue has this check:
> >> if (skb_queue_len(list) < qdisc_dev(qdisc)->tx_queue_len) {
> >>
> >> which allows each band to enqueue upto tx_queue_len skbs for a
> >> total of 3*tx_queue_len skbs. I am not sure if this was the
> >> intention of limiting in qdisc.
> >
> > Yes I noticed that and said to myself :
> > This was to let high priority packets have their own limit,
> > independent on fact that low priority packets filled their queue.
>
>
> Good point, but then logically it could be something like:
> if (skb_queue_len(list) < qdisc_dev(qdisc)->tx_queue_len / 3)
>
> Of course, there is a backward compatibility question, plus
> an sch_prio consistency question.
Jarek, what is the consistency problem?
Thanks,
- KK
^ permalink raw reply
* Re: [RFC PATCH] sched: Fix resource limiting in pfifo_fast
From: Krishna Kumar2 @ 2009-08-30 8:22 UTC (permalink / raw)
To: Eric Dumazet; +Cc: davem, netdev
In-Reply-To: <4A9A223D.1060406@gmail.com>
I had thought of this reason before submitting. But I felt that if we are
filling up the qdisc due to some problem at driver/device, then the issue
should be handled at a different level (increase tx_queue_len, let
packets drop and TCP handle it, etc).
So I am not sure if it is intentionally designed this way, or whether it
needs fixing to reflect a maximum limit.
Thanks,
- KK
> Eric Dumazet <eric.dumazet@gmail.com>
> Re: [RFC PATCH] sched: Fix resource limiting in pfifo_fast
>
> Krishna Kumar a écrit :
> > From: Krishna Kumar <krkumar2@in.ibm.com>
> >
> > pfifo_fast_enqueue has this check:
> > if (skb_queue_len(list) < qdisc_dev(qdisc)->tx_queue_len) {
> >
> > which allows each band to enqueue upto tx_queue_len skbs for a
> > total of 3*tx_queue_len skbs. I am not sure if this was the
> > intention of limiting in qdisc.
>
> Yes I noticed that and said to myself :
> This was to let high priority packets have their own limit,
> independent on fact that low priority packets filled their queue.
>
> >
> > Patch compiled and 32 simultaneous netperf testing ran fine. Also:
> > # tc -s qdisc show dev eth2
> > qdisc pfifo_fast 0: root bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1
1
> > Sent 16835026752 bytes 373116 pkt (dropped 0, overlimits 0 requeues
25)
> > rate 0bit 0pps backlog 0b 0p requeues 25
> >
> > (I am taking next week off, so sorry for any delay in responding)
> >
> > Signed-off-by: Krishna Kumar <krkumar2@in.ibm.com>
> > ---
> >
> > net/sched/sch_generic.c | 8 ++++----
> > 1 file changed, 4 insertions(+), 4 deletions(-)
> >
> > diff -ruNp org/net/sched/sch_generic.c new/net/sched/sch_generic.c
> > --- org/net/sched/sch_generic.c 2009-08-30 11:18:23.000000000 +0530
> > +++ new/net/sched/sch_generic.c 2009-08-30 11:21:50.000000000 +0530
> > @@ -432,11 +432,11 @@ static inline struct sk_buff_head *band2
> >
> > static int pfifo_fast_enqueue(struct sk_buff *skb, struct Qdisc*
qdisc)
> > {
> > - int band = prio2band[skb->priority & TC_PRIO_MAX];
> > - struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
> > - struct sk_buff_head *list = band2list(priv, band);
> > + if (skb_queue_len(&qdisc->q) < qdisc_dev(qdisc)->tx_queue_len) {
> > + int band = prio2band[skb->priority & TC_PRIO_MAX];
> > + struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
> > + struct sk_buff_head *list = band2list(priv, band);
> >
> > - if (skb_queue_len(list) < qdisc_dev(qdisc)->tx_queue_len) {
> > priv->bitmap |= (1 << band);
> > qdisc->q.qlen++;
> > return __qdisc_enqueue_tail(skb, qdisc, list);
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [RFC PATCH] sched: Fix resource limiting in pfifo_fast
From: Jarek Poplawski @ 2009-08-30 7:47 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Krishna Kumar, davem, netdev
In-Reply-To: <4A9A223D.1060406@gmail.com>
Eric Dumazet wrote, On 08/30/2009 08:54 AM:
> Krishna Kumar a écrit :
>> From: Krishna Kumar <krkumar2@in.ibm.com>
>>
>> pfifo_fast_enqueue has this check:
>> if (skb_queue_len(list) < qdisc_dev(qdisc)->tx_queue_len) {
>>
>> which allows each band to enqueue upto tx_queue_len skbs for a
>> total of 3*tx_queue_len skbs. I am not sure if this was the
>> intention of limiting in qdisc.
>
> Yes I noticed that and said to myself :
> This was to let high priority packets have their own limit,
> independent on fact that low priority packets filled their queue.
Good point, but then logically it could be something like:
if (skb_queue_len(list) < qdisc_dev(qdisc)->tx_queue_len / 3)
Of course, there is a backward compatibility question, plus
an sch_prio consistency question.
Jarek P.
^ permalink raw reply
* Re: [RFC PATCH] sched: Fix resource limiting in pfifo_fast
From: Eric Dumazet @ 2009-08-30 6:54 UTC (permalink / raw)
To: Krishna Kumar; +Cc: davem, netdev
In-Reply-To: <20090830062344.6380.16713.sendpatchset@localhost.localdomain>
Krishna Kumar a écrit :
> From: Krishna Kumar <krkumar2@in.ibm.com>
>
> pfifo_fast_enqueue has this check:
> if (skb_queue_len(list) < qdisc_dev(qdisc)->tx_queue_len) {
>
> which allows each band to enqueue upto tx_queue_len skbs for a
> total of 3*tx_queue_len skbs. I am not sure if this was the
> intention of limiting in qdisc.
Yes I noticed that and said to myself :
This was to let high priority packets have their own limit,
independent on fact that low priority packets filled their queue.
>
> Patch compiled and 32 simultaneous netperf testing ran fine. Also:
> # tc -s qdisc show dev eth2
> qdisc pfifo_fast 0: root bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
> Sent 16835026752 bytes 373116 pkt (dropped 0, overlimits 0 requeues 25)
> rate 0bit 0pps backlog 0b 0p requeues 25
>
> (I am taking next week off, so sorry for any delay in responding)
>
> Signed-off-by: Krishna Kumar <krkumar2@in.ibm.com>
> ---
>
> net/sched/sch_generic.c | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff -ruNp org/net/sched/sch_generic.c new/net/sched/sch_generic.c
> --- org/net/sched/sch_generic.c 2009-08-30 11:18:23.000000000 +0530
> +++ new/net/sched/sch_generic.c 2009-08-30 11:21:50.000000000 +0530
> @@ -432,11 +432,11 @@ static inline struct sk_buff_head *band2
>
> static int pfifo_fast_enqueue(struct sk_buff *skb, struct Qdisc* qdisc)
> {
> - int band = prio2band[skb->priority & TC_PRIO_MAX];
> - struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
> - struct sk_buff_head *list = band2list(priv, band);
> + if (skb_queue_len(&qdisc->q) < qdisc_dev(qdisc)->tx_queue_len) {
> + int band = prio2band[skb->priority & TC_PRIO_MAX];
> + struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
> + struct sk_buff_head *list = band2list(priv, band);
>
> - if (skb_queue_len(list) < qdisc_dev(qdisc)->tx_queue_len) {
> priv->bitmap |= (1 << band);
> qdisc->q.qlen++;
> return __qdisc_enqueue_tail(skb, qdisc, list);
^ permalink raw reply
* [PATCH 03/13] TProxy: move dst_cookie to the first cacheline in ipv6_pinfo
From: Balazs Scheidler @ 2009-08-30 6:52 UTC (permalink / raw)
To: netfilter-devel, netdev
While looking for a place to add a new bitfield in ipv6_pinfo,
I've found a 32 bit hole (in 64 bit mode) at the beginning of the struct.
Since dst_cookie is used in the output fastpath, I've moved this field to
fill the hole. The original place of dst_cookie is now empty, but
can become a place to add further fields to the struct.
Signed-off-by: Balazs Scheidler <bazsi@balabit.hu>
---
include/linux/ipv6.h | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index c662efa..be4c9c6 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -285,6 +285,7 @@ struct ipv6_pinfo {
struct in6_addr saddr;
struct in6_addr rcv_saddr;
struct in6_addr daddr;
+ __u32 dst_cookie;
struct in6_pktinfo sticky_pktinfo;
struct in6_addr *daddr_cache;
#ifdef CONFIG_IPV6_SUBTREES
@@ -348,7 +349,7 @@ struct ipv6_pinfo {
*/
__u8 tclass;
- __u32 dst_cookie;
+ /* 32 bits hole on 64 bit platforms */
struct ipv6_mc_socklist *ipv6_mc_list;
struct ipv6_ac_socklist *ipv6_ac_list;
--
1.6.0.4
^ permalink raw reply related
* [RFC PATCH] sched: Fix resource limiting in pfifo_fast
From: Krishna Kumar @ 2009-08-30 6:23 UTC (permalink / raw)
To: davem; +Cc: netdev, Krishna Kumar
From: Krishna Kumar <krkumar2@in.ibm.com>
pfifo_fast_enqueue has this check:
if (skb_queue_len(list) < qdisc_dev(qdisc)->tx_queue_len) {
which allows each band to enqueue upto tx_queue_len skbs for a
total of 3*tx_queue_len skbs. I am not sure if this was the
intention of limiting in qdisc.
Patch compiled and 32 simultaneous netperf testing ran fine. Also:
# tc -s qdisc show dev eth2
qdisc pfifo_fast 0: root bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
Sent 16835026752 bytes 373116 pkt (dropped 0, overlimits 0 requeues 25)
rate 0bit 0pps backlog 0b 0p requeues 25
(I am taking next week off, so sorry for any delay in responding)
Signed-off-by: Krishna Kumar <krkumar2@in.ibm.com>
---
net/sched/sch_generic.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff -ruNp org/net/sched/sch_generic.c new/net/sched/sch_generic.c
--- org/net/sched/sch_generic.c 2009-08-30 11:18:23.000000000 +0530
+++ new/net/sched/sch_generic.c 2009-08-30 11:21:50.000000000 +0530
@@ -432,11 +432,11 @@ static inline struct sk_buff_head *band2
static int pfifo_fast_enqueue(struct sk_buff *skb, struct Qdisc* qdisc)
{
- int band = prio2band[skb->priority & TC_PRIO_MAX];
- struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
- struct sk_buff_head *list = band2list(priv, band);
+ if (skb_queue_len(&qdisc->q) < qdisc_dev(qdisc)->tx_queue_len) {
+ int band = prio2band[skb->priority & TC_PRIO_MAX];
+ struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
+ struct sk_buff_head *list = band2list(priv, band);
- if (skb_queue_len(list) < qdisc_dev(qdisc)->tx_queue_len) {
priv->bitmap |= (1 << band);
qdisc->q.qlen++;
return __qdisc_enqueue_tail(skb, qdisc, list);
^ permalink raw reply
* [PATCH] net: convert one non-symbolic return value in dev_queue_xmit
From: Krishna Kumar @ 2009-08-30 6:21 UTC (permalink / raw)
To: davem; +Cc: netdev, Krishna Kumar
From: Krishna Kumar <krkumar2@in.ibm.com>
net: convert remaining non-symbolic return values in dev_queue_xmit
Patch compiled and 32 simultaneous netperf testing ran fine.
Signed-off-by: Krishna Kumar <krkumar2@in.ibm.com>
---
net/core/dev.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff -ruNp org/net/core/dev.c new/net/core/dev.c
--- org/net/core/dev.c 2009-08-28 21:36:46.000000000 +0530
+++ new/net/core/dev.c 2009-08-28 21:40:36.000000000 +0530
@@ -1917,7 +1917,7 @@ gso:
HARD_TX_LOCK(dev, txq, cpu);
if (!netif_tx_queue_stopped(txq)) {
- rc = 0;
+ rc = NET_XMIT_SUCCESS;
if (!dev_hard_start_xmit(skb, dev, txq)) {
HARD_TX_UNLOCK(dev, txq);
goto out;
^ permalink raw reply
* [PATCH] netdevice: Use existing macros
From: Krishna Kumar @ 2009-08-30 6:21 UTC (permalink / raw)
To: davem; +Cc: netdev, Krishna Kumar
From: Krishna Kumar <krkumar2@in.ibm.com>
netdevice: Consolidate to use existing macros where available.
Patch compiled and 32 simultaneous netperf testing ran fine.
Signed-off-by: Krishna Kumar <krkumar2@in.ibm.com>
---
include/linux/netdevice.h | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff -ruNp org/include/linux/netdevice.h new/include/linux/netdevice.h
--- org/include/linux/netdevice.h 2009-08-29 13:53:51.000000000 +0530
+++ new/include/linux/netdevice.h 2009-08-29 13:54:07.000000000 +0530
@@ -1257,7 +1257,7 @@ static inline void netif_tx_wake_queue(s
{
#ifdef CONFIG_NETPOLL_TRAP
if (netpoll_trap()) {
- clear_bit(__QUEUE_STATE_XOFF, &dev_queue->state);
+ netif_tx_start_queue(dev_queue);
return;
}
#endif
@@ -1363,7 +1363,8 @@ static inline int netif_running(const st
static inline void netif_start_subqueue(struct net_device *dev, u16 queue_index)
{
struct netdev_queue *txq = netdev_get_tx_queue(dev, queue_index);
- clear_bit(__QUEUE_STATE_XOFF, &txq->state);
+
+ netif_tx_start_queue(txq);
}
/**
@@ -1380,7 +1381,7 @@ static inline void netif_stop_subqueue(s
if (netpoll_trap())
return;
#endif
- set_bit(__QUEUE_STATE_XOFF, &txq->state);
+ netif_tx_stop_queue(txq);
}
/**
@@ -1394,7 +1395,8 @@ static inline int __netif_subqueue_stopp
u16 queue_index)
{
struct netdev_queue *txq = netdev_get_tx_queue(dev, queue_index);
- return test_bit(__QUEUE_STATE_XOFF, &txq->state);
+
+ return netif_tx_queue_stopped(txq);
}
static inline int netif_subqueue_stopped(const struct net_device *dev,
@@ -1746,8 +1748,7 @@ static inline void netif_tx_unlock(struc
* force a schedule.
*/
clear_bit(__QUEUE_STATE_FROZEN, &txq->state);
- if (!test_bit(__QUEUE_STATE_XOFF, &txq->state))
- __netif_schedule(txq->qdisc);
+ netif_schedule_queue(txq);
}
spin_unlock(&dev->tx_global_lock);
}
^ permalink raw reply
* [PATCH 2/2 next] sky2: B0_Y2LED controls the LEDs for both ports
From: Mike McCormack @ 2009-08-30 3:58 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev, Rene Mayrhofer, Richard Leitner
Only disable LED status control when both ports are disabled.
The previous code disabled LED status control unconditionally
in sky2_down.
Tested with the limitation that my sky2 interface has no LEDs
and a single port.
Signed-off-by: Mike McCormack <mikem@ring3k.org>
---
drivers/net/sky2.c | 23 ++++++++++++++++++++---
1 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 2827f0d..864b8dc 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -213,6 +213,22 @@ static inline u16 gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg)
return v;
}
+static void sky2_disable_status_led(struct sky2_port *sky2)
+{
+ struct sky2_hw *hw = sky2->hw;
+ struct net_device *otherdev = hw->dev[sky2->port^1];
+
+ if (!(otherdev && netif_running(otherdev))) {
+ sky2_write8(hw, B0_Y2LED, LED_STAT_OFF);
+ }
+}
+
+static void sky2_enable_status_led(struct sky2_port *sky2)
+{
+ struct sky2_hw *hw = sky2->hw;
+
+ sky2_write8(hw, B0_Y2LED, LED_STAT_ON);
+}
static void sky2_power_on(struct sky2_hw *hw)
{
@@ -1530,6 +1546,8 @@ static int sky2_up(struct net_device *dev)
if (err)
goto err_out;
+ sky2_enable_status_led(sky2);
+
/* Enable interrupts from phy/mac for port */
imask = sky2_read32(hw, B0_IMSK);
imask |= portirq_msk[port];
@@ -1886,8 +1904,7 @@ static int sky2_down(struct net_device *dev)
sky2_phy_power_down(hw, port);
spin_unlock_bh(&sky2->phy_lock);
- /* turn off LED's */
- sky2_write16(hw, B0_Y2LED, LED_STAT_OFF);
+ sky2_disable_status_led(sky2);
sky2_tx_reset(hw, port);
@@ -2989,7 +3006,7 @@ static void sky2_reset(struct sky2_hw *hw)
sky2_write8(hw, B2_TI_CTRL, TIM_STOP);
sky2_write8(hw, B2_TI_CTRL, TIM_CLR_IRQ);
- sky2_write8(hw, B0_Y2LED, LED_STAT_ON);
+ sky2_write8(hw, B0_Y2LED, LED_STAT_OFF);
/* Turn off descriptor polling */
sky2_write32(hw, B28_DPT_CTRL, DPT_STOP);
--
1.5.6.5
^ permalink raw reply related
* [PATCH 1/2 next] sky2: Fix B0_Y2LED to match vendor driver
From: Mike McCormack @ 2009-08-30 3:58 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev, Rene Mayrhofer, Richard Leitner
B0_LED is 0x0006 in the vendor driver, but was 0x0005 in sky2.
B0_LED is right next to B0_POWER_CTRL, so this is possibly
accounts for the device being accidently powered down as
reported by Rene Mayrhofer.
Signed-off-by: Mike McCormack <mikem@ring3k.org>
---
drivers/net/sky2.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index 73c9547..a1f3d5f 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -155,7 +155,7 @@ enum pci_cfg_reg1 {
enum csr_regs {
B0_RAP = 0x0000,
B0_CTST = 0x0004,
- B0_Y2LED = 0x0005,
+ B0_Y2LED = 0x0006,
B0_POWER_CTRL = 0x0007,
B0_ISRC = 0x0008,
B0_IMSK = 0x000c,
--
1.5.6.5
^ permalink raw reply related
* Re: [PATCH] sky2: Don't try to turn led off in sky2_down()
From: Mike McCormack @ 2009-08-30 0:37 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev, Rene Mayrhofer, Richard Leitner
In-Reply-To: <20090829105727.6281202e@s6510>
Stephen Hemminger wrote:
> On Sat, 29 Aug 2009 22:10:33 +0900
> Mike McCormack <mikem@ring3k.org> wrote:
>
>> There are a few problems with the following line of code in sky2_down()
>>
>> sky2_write16(hw, B0_Y2LED, LED_STAT_OFF);
>>
>> * It doesn't specify which port's LED to turn off.
>> * We don't turn send LED_STAT_ON on in sky2_up()
>> * B0_LED is 0x0006 in the vendor driver, but 0x0005 in sky2.
>> B0_LED is right next to B0_POWER_CTRL, so this is possibly
>> accounts for the device being accidently powered down as
>> reported by Rene Mayrhofer.
>
> I would rather just change the definition of B0_LED to the correct value.
How does that address the first problem? If there are two ports, which port's LED are we turning off?
thanks,
Mike
^ permalink raw reply
* Re: UDP multicast packet loss not reported if TX ring overrun?
From: Mark Smith @ 2009-08-30 0:21 UTC (permalink / raw)
To: David Miller; +Cc: cl, sri, dlstevens, eric.dumazet, netdev, niv
In-Reply-To: <20090828.122459.245170385.davem@davemloft.net>
On Fri, 28 Aug 2009 12:24:59 -0700 (PDT)
David Miller <davem@davemloft.net> wrote:
> From: Christoph Lameter <cl@linux-foundation.org>
> Date: Fri, 28 Aug 2009 09:53:40 -0400 (EDT)
>
> > Seems though that the qdisc drop count does not flow into the tx_dropped
> > counter for the interface.
>
> And it should not.
>
> The qdisc drops the packet due to flow control, not the hardware
> device.
>
> Device drops are for things like transmission errors on the wire.
>
> If you start incrementing tx_dropped here, people won't be able
> to tell they have a deteriorating cable or bad switch or similar.
And it does, because Cisco do it this way, although they record them as
TX errors not drops. It's quite annoying to have to keep reminding
yourself that the errors shown on the traffic graphs probably aren't
actually errors - of course real errors then become hidden in the
"normal" ones.
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* netconsole as normal console for userspace messages?
From: Arkadiusz Miskiewicz @ 2009-08-30 0:12 UTC (permalink / raw)
To: netdev
Hi,
Can netconsole be somehow used to see userspace messages, too? Something
similar to console=ttySX... just =netconsole.
--
Arkadiusz Miśkiewicz PLD/Linux Team
arekm / maven.pl http://ftp.pld-linux.org/
^ permalink raw reply
* Re: [PATCH 00/17] tg3: 5717 support part 1
From: David Miller @ 2009-08-29 22:44 UTC (permalink / raw)
To: mcarlson; +Cc: netdev, andy
In-Reply-To: <1251585276.29660@xw6200>
From: "Matt Carlson" <mcarlson@broadcom.com>
Date: Fri, 28 Aug 2009 15:27:50 -0700
> This patchset adds two patches for the 5785 and starts support for the
> 5717 ASIC rev. The 5717 ASIC rev is a new dual-port NetXtreme I server
> controller family that supports MSIX, jumbo frames, TSS and RSS. The
> devices can operate with copper and / or serdes phys. This patchset
> gets the ball rolling by taking care of a few housekeeping items and
> then preparing the napi and interrupt routines for multiple interrupt
> vector support.
>
> Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
The interrupt and NAPI stuff looks much more generic and cleaner now,
nice work!
All applied to net-next-2.6, thanks!
^ permalink raw reply
* [PATCH 17/17] tg3: Update version to 3.101
From: Matt Carlson @ 2009-08-29 0:03 UTC (permalink / raw)
To: davem; +Cc: netdev, andy
This patch updates the tg3 version to 3.101.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
---
drivers/net/tg3.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index e36b0b2..a7d14aa 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -68,8 +68,8 @@
#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "3.100"
-#define DRV_MODULE_RELDATE "August 25, 2009"
+#define DRV_MODULE_VERSION "3.101"
+#define DRV_MODULE_RELDATE "August 28, 2009"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
--
1.6.3.3
^ permalink raw reply related
* [PATCH 16/17] tg3: Move per-int tx members to a per-int struct
From: Matt Carlson @ 2009-08-29 0:03 UTC (permalink / raw)
To: davem; +Cc: netdev, andy
This patch moves the tx_prod, tx_cons, tx_pending, tx_ring, and
tx_buffers transmit ring device members to a per-interrupt structure.
It also adds a new transmit producer mailbox member (prodmbox) and
converts the code to use it rather than a preprocessor constant.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
---
drivers/net/tg3.c | 150 +++++++++++++++++++++++++++-------------------------
drivers/net/tg3.h | 15 +++---
2 files changed, 86 insertions(+), 79 deletions(-)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 939574c..e36b0b2 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -136,7 +136,7 @@
#define TG3_RX_JMB_MAP_SZ TG3_RX_DMA_TO_MAP_SZ(TG3_RX_JMB_DMA_SZ)
/* minimum number of free TX descriptors required to wake up TX process */
-#define TG3_TX_WAKEUP_THRESH(tp) ((tp)->tx_pending / 4)
+#define TG3_TX_WAKEUP_THRESH(tnapi) ((tnapi)->tx_pending / 4)
#define TG3_RAW_IP_ALIGN 2
@@ -656,7 +656,7 @@ static inline unsigned int tg3_has_work(struct tg3_napi *tnapi)
work_exists = 1;
}
/* check for RX/TX work to do */
- if (sblk->idx[0].tx_consumer != tp->tx_cons ||
+ if (sblk->idx[0].tx_consumer != tnapi->tx_cons ||
sblk->idx[0].rx_producer != tnapi->rx_rcb_ptr)
work_exists = 1;
@@ -4269,11 +4269,11 @@ static void tg3_tx_recover(struct tg3 *tp)
spin_unlock(&tp->lock);
}
-static inline u32 tg3_tx_avail(struct tg3 *tp)
+static inline u32 tg3_tx_avail(struct tg3_napi *tnapi)
{
smp_mb();
- return (tp->tx_pending -
- ((tp->tx_prod - tp->tx_cons) & (TG3_TX_RING_SIZE - 1)));
+ return tnapi->tx_pending -
+ ((tnapi->tx_prod - tnapi->tx_cons) & (TG3_TX_RING_SIZE - 1));
}
/* Tigon3 never reports partial packet sends. So we do not
@@ -4284,10 +4284,10 @@ static void tg3_tx(struct tg3_napi *tnapi)
{
struct tg3 *tp = tnapi->tp;
u32 hw_idx = tnapi->hw_status->idx[0].tx_consumer;
- u32 sw_idx = tp->tx_cons;
+ u32 sw_idx = tnapi->tx_cons;
while (sw_idx != hw_idx) {
- struct tx_ring_info *ri = &tp->tx_buffers[sw_idx];
+ struct tx_ring_info *ri = &tnapi->tx_buffers[sw_idx];
struct sk_buff *skb = ri->skb;
int i, tx_bug = 0;
@@ -4303,7 +4303,7 @@ static void tg3_tx(struct tg3_napi *tnapi)
sw_idx = NEXT_TX(sw_idx);
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
- ri = &tp->tx_buffers[sw_idx];
+ ri = &tnapi->tx_buffers[sw_idx];
if (unlikely(ri->skb != NULL || sw_idx == hw_idx))
tx_bug = 1;
sw_idx = NEXT_TX(sw_idx);
@@ -4317,7 +4317,7 @@ static void tg3_tx(struct tg3_napi *tnapi)
}
}
- tp->tx_cons = sw_idx;
+ tnapi->tx_cons = sw_idx;
/* Need to make the tx_cons update visible to tg3_start_xmit()
* before checking for netif_queue_stopped(). Without the
@@ -4327,10 +4327,10 @@ static void tg3_tx(struct tg3_napi *tnapi)
smp_mb();
if (unlikely(netif_queue_stopped(tp->dev) &&
- (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH(tp)))) {
+ (tg3_tx_avail(tnapi) > TG3_TX_WAKEUP_THRESH(tnapi)))) {
netif_tx_lock(tp->dev);
if (netif_queue_stopped(tp->dev) &&
- (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH(tp)))
+ (tg3_tx_avail(tnapi) > TG3_TX_WAKEUP_THRESH(tnapi)))
netif_wake_queue(tp->dev);
netif_tx_unlock(tp->dev);
}
@@ -4668,7 +4668,7 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
}
/* run TX completion thread */
- if (sblk->idx[0].tx_consumer != tp->tx_cons) {
+ if (tnapi->hw_status->idx[0].tx_consumer != tnapi->tx_cons) {
tg3_tx(tnapi);
if (unlikely(tp->tg3_flags & TG3_FLAG_TX_RECOVERY_PENDING))
return work_done;
@@ -5044,13 +5044,14 @@ static inline int tg3_40bit_overflow_test(struct tg3 *tp, dma_addr_t mapping,
#endif
}
-static void tg3_set_txd(struct tg3 *, int, dma_addr_t, int, u32, u32);
+static void tg3_set_txd(struct tg3_napi *, int, dma_addr_t, int, u32, u32);
/* Workaround 4GB and 40-bit hardware DMA bugs. */
static int tigon3_dma_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb,
u32 last_plus_one, u32 *start,
u32 base_flags, u32 mss)
{
+ struct tg3_napi *tnapi = &tp->napi[0];
struct sk_buff *new_skb;
dma_addr_t new_addr = 0;
u32 entry = *start;
@@ -5085,7 +5086,7 @@ static int tigon3_dma_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb,
dev_kfree_skb(new_skb);
new_skb = NULL;
} else {
- tg3_set_txd(tp, entry, new_addr, new_skb->len,
+ tg3_set_txd(tnapi, entry, new_addr, new_skb->len,
base_flags, 1 | (mss << 1));
*start = NEXT_TX(entry);
}
@@ -5094,11 +5095,10 @@ static int tigon3_dma_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb,
/* Now clean up the sw ring entries. */
i = 0;
while (entry != last_plus_one) {
- if (i == 0) {
- tp->tx_buffers[entry].skb = new_skb;
- } else {
- tp->tx_buffers[entry].skb = NULL;
- }
+ if (i == 0)
+ tnapi->tx_buffers[entry].skb = new_skb;
+ else
+ tnapi->tx_buffers[entry].skb = NULL;
entry = NEXT_TX(entry);
i++;
}
@@ -5109,11 +5109,11 @@ static int tigon3_dma_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb,
return ret;
}
-static void tg3_set_txd(struct tg3 *tp, int entry,
+static void tg3_set_txd(struct tg3_napi *tnapi, int entry,
dma_addr_t mapping, int len, u32 flags,
u32 mss_and_is_end)
{
- struct tg3_tx_buffer_desc *txd = &tp->tx_ring[entry];
+ struct tg3_tx_buffer_desc *txd = &tnapi->tx_ring[entry];
int is_end = (mss_and_is_end & 0x1);
u32 mss = (mss_and_is_end >> 1);
u32 vlan_tag = 0;
@@ -5141,6 +5141,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
u32 len, entry, base_flags, mss;
struct skb_shared_info *sp;
dma_addr_t mapping;
+ struct tg3_napi *tnapi = &tp->napi[0];
len = skb_headlen(skb);
@@ -5149,7 +5150,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
* interrupt. Furthermore, IRQ processing runs lockless so we have
* no IRQ context deadlocks to worry about either. Rejoice!
*/
- if (unlikely(tg3_tx_avail(tp) <= (skb_shinfo(skb)->nr_frags + 1))) {
+ if (unlikely(tg3_tx_avail(tnapi) <= (skb_shinfo(skb)->nr_frags + 1))) {
if (!netif_queue_stopped(dev)) {
netif_stop_queue(dev);
@@ -5160,7 +5161,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_BUSY;
}
- entry = tp->tx_prod;
+ entry = tnapi->tx_prod;
base_flags = 0;
mss = 0;
if ((mss = skb_shinfo(skb)->gso_size) != 0) {
@@ -5208,9 +5209,9 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
mapping = sp->dma_head;
- tp->tx_buffers[entry].skb = skb;
+ tnapi->tx_buffers[entry].skb = skb;
- tg3_set_txd(tp, entry, mapping, len, base_flags,
+ tg3_set_txd(tnapi, entry, mapping, len, base_flags,
(skb_shinfo(skb)->nr_frags == 0) | (mss << 1));
entry = NEXT_TX(entry);
@@ -5225,9 +5226,9 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
len = frag->size;
mapping = sp->dma_maps[i];
- tp->tx_buffers[entry].skb = NULL;
+ tnapi->tx_buffers[entry].skb = NULL;
- tg3_set_txd(tp, entry, mapping, len,
+ tg3_set_txd(tnapi, entry, mapping, len,
base_flags, (i == last) | (mss << 1));
entry = NEXT_TX(entry);
@@ -5235,12 +5236,12 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
/* Packets are ready, update Tx producer idx local and on card. */
- tw32_tx_mbox((MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW), entry);
+ tw32_tx_mbox(tnapi->prodmbox, entry);
- tp->tx_prod = entry;
- if (unlikely(tg3_tx_avail(tp) <= (MAX_SKB_FRAGS + 1))) {
+ tnapi->tx_prod = entry;
+ if (unlikely(tg3_tx_avail(tnapi) <= (MAX_SKB_FRAGS + 1))) {
netif_stop_queue(dev);
- if (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH(tp))
+ if (tg3_tx_avail(tnapi) > TG3_TX_WAKEUP_THRESH(tnapi))
netif_wake_queue(tp->dev);
}
@@ -5258,11 +5259,12 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *, struct net_device *);
static int tg3_tso_bug(struct tg3 *tp, struct sk_buff *skb)
{
struct sk_buff *segs, *nskb;
+ u32 frag_cnt_est = skb_shinfo(skb)->gso_segs * 3;
/* Estimate the number of fragments in the worst case */
- if (unlikely(tg3_tx_avail(tp) <= (skb_shinfo(skb)->gso_segs * 3))) {
+ if (unlikely(tg3_tx_avail(&tp->napi[0]) <= frag_cnt_est)) {
netif_stop_queue(tp->dev);
- if (tg3_tx_avail(tp) <= (skb_shinfo(skb)->gso_segs * 3))
+ if (tg3_tx_avail(&tp->napi[0]) <= frag_cnt_est)
return NETDEV_TX_BUSY;
netif_wake_queue(tp->dev);
@@ -5295,6 +5297,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev)
struct skb_shared_info *sp;
int would_hit_hwbug;
dma_addr_t mapping;
+ struct tg3_napi *tnapi = &tp->napi[0];
len = skb_headlen(skb);
@@ -5303,7 +5306,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev)
* interrupt. Furthermore, IRQ processing runs lockless so we have
* no IRQ context deadlocks to worry about either. Rejoice!
*/
- if (unlikely(tg3_tx_avail(tp) <= (skb_shinfo(skb)->nr_frags + 1))) {
+ if (unlikely(tg3_tx_avail(tnapi) <= (skb_shinfo(skb)->nr_frags + 1))) {
if (!netif_queue_stopped(dev)) {
netif_stop_queue(dev);
@@ -5314,7 +5317,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_BUSY;
}
- entry = tp->tx_prod;
+ entry = tnapi->tx_prod;
base_flags = 0;
if (skb->ip_summed == CHECKSUM_PARTIAL)
base_flags |= TXD_FLAG_TCPUDP_CSUM;
@@ -5384,7 +5387,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev)
mapping = sp->dma_head;
- tp->tx_buffers[entry].skb = skb;
+ tnapi->tx_buffers[entry].skb = skb;
would_hit_hwbug = 0;
@@ -5393,7 +5396,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev)
else if (tg3_4g_overflow_test(mapping, len))
would_hit_hwbug = 1;
- tg3_set_txd(tp, entry, mapping, len, base_flags,
+ tg3_set_txd(tnapi, entry, mapping, len, base_flags,
(skb_shinfo(skb)->nr_frags == 0) | (mss << 1));
entry = NEXT_TX(entry);
@@ -5409,7 +5412,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev)
len = frag->size;
mapping = sp->dma_maps[i];
- tp->tx_buffers[entry].skb = NULL;
+ tnapi->tx_buffers[entry].skb = NULL;
if (tg3_4g_overflow_test(mapping, len))
would_hit_hwbug = 1;
@@ -5418,10 +5421,10 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev)
would_hit_hwbug = 1;
if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
- tg3_set_txd(tp, entry, mapping, len,
+ tg3_set_txd(tnapi, entry, mapping, len,
base_flags, (i == last)|(mss << 1));
else
- tg3_set_txd(tp, entry, mapping, len,
+ tg3_set_txd(tnapi, entry, mapping, len,
base_flags, (i == last));
entry = NEXT_TX(entry);
@@ -5446,12 +5449,12 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev)
}
/* Packets are ready, update Tx producer idx local and on card. */
- tw32_tx_mbox((MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW), entry);
+ tw32_tx_mbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW, entry);
- tp->tx_prod = entry;
- if (unlikely(tg3_tx_avail(tp) <= (MAX_SKB_FRAGS + 1))) {
+ tnapi->tx_prod = entry;
+ if (unlikely(tg3_tx_avail(tnapi) <= (MAX_SKB_FRAGS + 1))) {
netif_stop_queue(dev);
- if (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH(tp))
+ if (tg3_tx_avail(tnapi) > TG3_TX_WAKEUP_THRESH(tnapi))
netif_wake_queue(tp->dev);
}
@@ -5522,8 +5525,8 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu)
static void tg3_rx_prodring_free(struct tg3 *tp,
struct tg3_rx_prodring_set *tpr)
{
- struct ring_info *rxp;
int i;
+ struct ring_info *rxp;
for (i = 0; i < TG3_RX_RING_SIZE; i++) {
rxp = &tpr->rx_std_buffers[i];
@@ -5710,13 +5713,14 @@ err_out:
*/
static void tg3_free_rings(struct tg3 *tp)
{
+ struct tg3_napi *tnapi = &tp->napi[0];
int i;
for (i = 0; i < TG3_TX_RING_SIZE; ) {
struct tx_ring_info *txp;
struct sk_buff *skb;
- txp = &tp->tx_buffers[i];
+ txp = &tnapi->tx_buffers[i];
skb = txp->skb;
if (skb == NULL) {
@@ -5751,7 +5755,7 @@ static int tg3_init_rings(struct tg3 *tp)
tg3_free_rings(tp);
/* Zero out all descriptors. */
- memset(tp->tx_ring, 0, TG3_TX_RING_BYTES);
+ memset(tnapi->tx_ring, 0, TG3_TX_RING_BYTES);
tnapi->rx_rcb_ptr = 0;
memset(tnapi->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp));
@@ -5767,12 +5771,12 @@ static void tg3_free_consistent(struct tg3 *tp)
{
struct tg3_napi *tnapi = &tp->napi[0];
- kfree(tp->tx_buffers);
- tp->tx_buffers = NULL;
- if (tp->tx_ring) {
+ kfree(tnapi->tx_buffers);
+ tnapi->tx_buffers = NULL;
+ if (tnapi->tx_ring) {
pci_free_consistent(tp->pdev, TG3_TX_RING_BYTES,
- tp->tx_ring, tp->tx_desc_mapping);
- tp->tx_ring = NULL;
+ tnapi->tx_ring, tnapi->tx_desc_mapping);
+ tnapi->tx_ring = NULL;
}
if (tnapi->rx_rcb) {
pci_free_consistent(tp->pdev, TG3_RX_RCB_RING_BYTES(tp),
@@ -5804,14 +5808,14 @@ static int tg3_alloc_consistent(struct tg3 *tp)
if (tg3_rx_prodring_init(tp, &tp->prodring[0]))
return -ENOMEM;
- tp->tx_buffers = kzalloc(sizeof(struct tx_ring_info) *
- TG3_TX_RING_SIZE, GFP_KERNEL);
- if (!tp->tx_buffers)
+ tnapi->tx_buffers = kzalloc(sizeof(struct tx_ring_info) *
+ TG3_TX_RING_SIZE, GFP_KERNEL);
+ if (!tnapi->tx_buffers)
goto err_out;
- tp->tx_ring = pci_alloc_consistent(tp->pdev, TG3_TX_RING_BYTES,
- &tp->tx_desc_mapping);
- if (!tp->tx_ring)
+ tnapi->tx_ring = pci_alloc_consistent(tp->pdev, TG3_TX_RING_BYTES,
+ &tnapi->tx_desc_mapping);
+ if (!tnapi->tx_ring)
goto err_out;
tnapi->hw_status = pci_alloc_consistent(tp->pdev,
@@ -7094,13 +7098,15 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
BDINFO_FLAGS_DISABLED);
}
- tp->tx_prod = 0;
- tp->tx_cons = 0;
- tw32_mailbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW, 0);
+ tp->napi[0].tx_prod = 0;
+ tp->napi[0].tx_cons = 0;
tw32_tx_mbox(MAILBOX_SNDNIC_PROD_IDX_0 + TG3_64BIT_REG_LOW, 0);
+ val = MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW;
+ tw32_mailbox(val, 0);
+
tg3_set_bdinfo(tp, NIC_SRAM_SEND_RCB,
- tp->tx_desc_mapping,
+ tp->napi[0].tx_desc_mapping,
(TG3_TX_RING_SIZE <<
BDINFO_FLAGS_MAXLEN_SHIFT),
NIC_SRAM_TX_BUFFER_DESC);
@@ -9093,7 +9099,7 @@ static void tg3_get_ringparam(struct net_device *dev, struct ethtool_ringparam *
else
ering->rx_jumbo_pending = 0;
- ering->tx_pending = tp->tx_pending;
+ ering->tx_pending = tp->napi[0].tx_pending;
}
static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
@@ -9123,7 +9129,7 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e
tp->rx_pending > 63)
tp->rx_pending = 63;
tp->rx_jumbo_pending = ering->rx_jumbo_pending;
- tp->tx_pending = ering->tx_pending;
+ tp->napi[0].tx_pending = ering->tx_pending;
if (netif_running(dev)) {
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
@@ -9928,14 +9934,13 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
num_pkts = 0;
- tg3_set_txd(tp, tp->tx_prod, map, tx_len, 0, 1);
+ tg3_set_txd(tnapi, tnapi->tx_prod, map, tx_len, 0, 1);
- tp->tx_prod++;
+ tnapi->tx_prod++;
num_pkts++;
- tw32_tx_mbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW,
- tp->tx_prod);
- tr32_mailbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW);
+ tw32_tx_mbox(tnapi->prodmbox, tnapi->tx_prod);
+ tr32_mailbox(tnapi->prodmbox);
udelay(10);
@@ -9948,7 +9953,7 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
tx_idx = tnapi->hw_status->idx[0].tx_consumer;
rx_idx = rnapi->hw_status->idx[0].rx_producer;
- if ((tx_idx == tp->tx_prod) &&
+ if ((tx_idx == tnapi->tx_prod) &&
(rx_idx == (rx_start_idx + num_pkts)))
break;
}
@@ -9956,7 +9961,7 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
pci_unmap_single(tp->pdev, map, tx_len, PCI_DMA_TODEVICE);
dev_kfree_skb(skb);
- if (tx_idx != tp->tx_prod)
+ if (tx_idx != tnapi->tx_prod)
goto out;
if (rx_idx != rx_start_idx + num_pkts)
@@ -13415,11 +13420,12 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
tp->rx_pending = TG3_DEF_RX_RING_PENDING;
tp->rx_jumbo_pending = TG3_DEF_RX_JUMBO_RING_PENDING;
- tp->tx_pending = TG3_DEF_TX_RING_PENDING;
tp->napi[0].tp = tp;
tp->napi[0].int_mbox = MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW;
tp->napi[0].consmbox = MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW;
+ tp->napi[0].prodmbox = MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW;
+ tp->napi[0].tx_pending = TG3_DEF_TX_RING_PENDING;
netif_napi_add(dev, &tp->napi[0].napi, tg3_poll, 64);
dev->ethtool_ops = &tg3_ethtool_ops;
dev->watchdog_timeo = TG3_TX_TIMEOUT;
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index b91ac29..a816b2c 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -2497,13 +2497,21 @@ struct tg3_napi {
u32 last_tag;
u32 last_irq_tag;
u32 int_mbox;
+ u32 tx_prod;
+ u32 tx_cons;
+ u32 tx_pending;
+ u32 prodmbox;
+
u32 consmbox;
u32 rx_rcb_ptr;
struct tg3_rx_buffer_desc *rx_rcb;
+ struct tg3_tx_buffer_desc *tx_ring;
+ struct tx_ring_info *tx_buffers;
dma_addr_t status_mapping;
dma_addr_t rx_rcb_mapping;
+ dma_addr_t tx_desc_mapping;
};
struct tg3 {
@@ -2563,13 +2571,6 @@ struct tg3 {
/* begin "tx thread" cacheline section */
void (*write32_tx_mbox) (struct tg3 *, u32,
u32);
- u32 tx_prod;
- u32 tx_cons;
- u32 tx_pending;
-
- struct tg3_tx_buffer_desc *tx_ring;
- struct tx_ring_info *tx_buffers;
- dma_addr_t tx_desc_mapping;
/* begin "rx thread" cacheline section */
struct tg3_napi napi[TG3_IRQ_MAX_VECS];
--
1.6.3.3
^ permalink raw reply related
* [PATCH 12/17] tg3: Convert ISR parameter to tnapi
From: Matt Carlson @ 2009-08-29 0:01 UTC (permalink / raw)
To: davem; +Cc: netdev, andy
This patch migrates the ISR parameter from struct net_device to struct
tg3_napi. Checkpatch complains about the existence of the preexisting
IRQF_SAMPLE_RANDOM flag. I've opted to keep this patch conservative and
let it continue to exist until the flag gets officially purged from the
kernel.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
---
drivers/net/tg3.c | 49 +++++++++++++++++++++++++------------------------
1 files changed, 25 insertions(+), 24 deletions(-)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index b308c40..bf9a333 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -4757,14 +4757,14 @@ static inline void tg3_full_unlock(struct tg3 *tp)
*/
static irqreturn_t tg3_msi_1shot(int irq, void *dev_id)
{
- struct net_device *dev = dev_id;
- struct tg3 *tp = netdev_priv(dev);
+ struct tg3_napi *tnapi = dev_id;
+ struct tg3 *tp = tnapi->tp;
prefetch(tp->hw_status);
prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
if (likely(!tg3_irq_sync(tp)))
- napi_schedule(&tp->napi[0].napi);
+ napi_schedule(&tnapi->napi);
return IRQ_HANDLED;
}
@@ -4775,8 +4775,8 @@ static irqreturn_t tg3_msi_1shot(int irq, void *dev_id)
*/
static irqreturn_t tg3_msi(int irq, void *dev_id)
{
- struct net_device *dev = dev_id;
- struct tg3 *tp = netdev_priv(dev);
+ struct tg3_napi *tnapi = dev_id;
+ struct tg3 *tp = tnapi->tp;
prefetch(tp->hw_status);
prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
@@ -4789,15 +4789,15 @@ static irqreturn_t tg3_msi(int irq, void *dev_id)
*/
tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
if (likely(!tg3_irq_sync(tp)))
- napi_schedule(&tp->napi[0].napi);
+ napi_schedule(&tnapi->napi);
return IRQ_RETVAL(1);
}
static irqreturn_t tg3_interrupt(int irq, void *dev_id)
{
- struct net_device *dev = dev_id;
- struct tg3 *tp = netdev_priv(dev);
+ struct tg3_napi *tnapi = dev_id;
+ struct tg3 *tp = tnapi->tp;
struct tg3_hw_status *sblk = tp->hw_status;
unsigned int handled = 1;
@@ -4831,7 +4831,7 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id)
sblk->status &= ~SD_STATUS_UPDATED;
if (likely(tg3_has_work(tp))) {
prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
- napi_schedule(&tp->napi[0].napi);
+ napi_schedule(&tnapi->napi);
} else {
/* No work, shared interrupt perhaps? re-enable
* interrupts, and flush that PCI write
@@ -4845,8 +4845,8 @@ out:
static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
{
- struct net_device *dev = dev_id;
- struct tg3 *tp = netdev_priv(dev);
+ struct tg3_napi *tnapi = dev_id;
+ struct tg3 *tp = tnapi->tp;
struct tg3_hw_status *sblk = tp->hw_status;
unsigned int handled = 1;
@@ -4889,7 +4889,7 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
- napi_schedule(&tp->napi[0].napi);
+ napi_schedule(&tnapi->napi);
out:
return IRQ_RETVAL(handled);
@@ -4898,8 +4898,8 @@ out:
/* ISR for interrupt test */
static irqreturn_t tg3_test_isr(int irq, void *dev_id)
{
- struct net_device *dev = dev_id;
- struct tg3 *tp = netdev_priv(dev);
+ struct tg3_napi *tnapi = dev_id;
+ struct tg3 *tp = tnapi->tp;
struct tg3_hw_status *sblk = tp->hw_status;
if ((sblk->status & SD_STATUS_UPDATED) ||
@@ -7697,7 +7697,7 @@ static int tg3_request_irq(struct tg3 *tp)
{
irq_handler_t fn;
unsigned long flags;
- struct net_device *dev = tp->dev;
+ char *name = tp->dev->name;
if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
fn = tg3_msi;
@@ -7710,11 +7710,12 @@ static int tg3_request_irq(struct tg3 *tp)
fn = tg3_interrupt_tagged;
flags = IRQF_SHARED | IRQF_SAMPLE_RANDOM;
}
- return (request_irq(tp->pdev->irq, fn, flags, dev->name, dev));
+ return request_irq(tp->pdev->irq, fn, flags, name, &tp->napi[0]);
}
static int tg3_test_interrupt(struct tg3 *tp)
{
+ struct tg3_napi *tnapi = &tp->napi[0];
struct net_device *dev = tp->dev;
int err, i, intr_ok = 0;
@@ -7723,10 +7724,10 @@ static int tg3_test_interrupt(struct tg3 *tp)
tg3_disable_ints(tp);
- free_irq(tp->pdev->irq, dev);
+ free_irq(tp->pdev->irq, tnapi);
err = request_irq(tp->pdev->irq, tg3_test_isr,
- IRQF_SHARED | IRQF_SAMPLE_RANDOM, dev->name, dev);
+ IRQF_SHARED | IRQF_SAMPLE_RANDOM, dev->name, tnapi);
if (err)
return err;
@@ -7754,7 +7755,7 @@ static int tg3_test_interrupt(struct tg3 *tp)
tg3_disable_ints(tp);
- free_irq(tp->pdev->irq, dev);
+ free_irq(tp->pdev->irq, tnapi);
err = tg3_request_irq(tp);
@@ -7772,7 +7773,6 @@ static int tg3_test_interrupt(struct tg3 *tp)
*/
static int tg3_test_msi(struct tg3 *tp)
{
- struct net_device *dev = tp->dev;
int err;
u16 pci_cmd;
@@ -7803,7 +7803,8 @@ static int tg3_test_msi(struct tg3 *tp)
"the PCI maintainer and include system chipset information.\n",
tp->dev->name);
- free_irq(tp->pdev->irq, dev);
+ free_irq(tp->pdev->irq, &tp->napi[0]);
+
pci_disable_msi(tp->pdev);
tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI;
@@ -7823,7 +7824,7 @@ static int tg3_test_msi(struct tg3 *tp)
tg3_full_unlock(tp);
if (err)
- free_irq(tp->pdev->irq, dev);
+ free_irq(tp->pdev->irq, &tp->napi[0]);
return err;
}
@@ -8002,7 +8003,7 @@ static int tg3_open(struct net_device *dev)
return 0;
err_out2:
- free_irq(tp->pdev->irq, dev);
+ free_irq(tp->pdev->irq, &tp->napi[0]);
err_out1:
napi_disable(&tp->napi[0].napi);
@@ -8266,7 +8267,7 @@ static int tg3_close(struct net_device *dev)
tg3_full_unlock(tp);
- free_irq(tp->pdev->irq, dev);
+ free_irq(tp->pdev->irq, &tp->napi[0]);
tg3_ints_fini(tp);
--
1.6.3.3
^ permalink raw reply related
* [PATCH 09/17] tg3: Use ext rx bds
From: Matt Carlson @ 2009-08-29 0:00 UTC (permalink / raw)
To: davem; +Cc: netdev, andy
The 5717 only uses extended buffer descriptors for the jumbo producer
ring. Extended buffer descriptors are available on all devices that
support a separate jumbo producer ring so make the change universal.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
---
drivers/net/tg3.c | 17 +++++++++--------
drivers/net/tg3.h | 2 +-
2 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 053d4e8..3725ac8 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -117,10 +117,10 @@
#define TG3_RX_RING_BYTES (sizeof(struct tg3_rx_buffer_desc) * \
TG3_RX_RING_SIZE)
-#define TG3_RX_JUMBO_RING_BYTES (sizeof(struct tg3_rx_buffer_desc) * \
- TG3_RX_JUMBO_RING_SIZE)
+#define TG3_RX_JUMBO_RING_BYTES (sizeof(struct tg3_ext_rx_buffer_desc) * \
+ TG3_RX_JUMBO_RING_SIZE)
#define TG3_RX_RCB_RING_BYTES(tp) (sizeof(struct tg3_rx_buffer_desc) * \
- TG3_RX_RCB_RING_SIZE(tp))
+ TG3_RX_RCB_RING_SIZE(tp))
#define TG3_TX_RING_BYTES (sizeof(struct tg3_tx_buffer_desc) * \
TG3_TX_RING_SIZE)
#define NEXT_TX(N) (((N) + 1) & (TG3_TX_RING_SIZE - 1))
@@ -4367,7 +4367,7 @@ static int tg3_alloc_rx_skb(struct tg3 *tp, u32 opaque_key,
case RXD_OPAQUE_RING_JUMBO:
dest_idx = dest_idx_unmasked % TG3_RX_JUMBO_RING_SIZE;
- desc = &tpr->rx_jmb[dest_idx];
+ desc = &tpr->rx_jmb[dest_idx].std;
map = &tpr->rx_jmb_buffers[dest_idx];
if (src_idx >= 0)
src_map = &tpr->rx_jmb_buffers[src_idx];
@@ -4428,9 +4428,9 @@ static void tg3_recycle_rx(struct tg3 *tp, u32 opaque_key,
case RXD_OPAQUE_RING_JUMBO:
dest_idx = dest_idx_unmasked % TG3_RX_JUMBO_RING_SIZE;
- dest_desc = &tpr->rx_jmb[dest_idx];
+ dest_desc = &tpr->rx_jmb[dest_idx].std;
dest_map = &tpr->rx_jmb_buffers[dest_idx];
- src_desc = &tpr->rx_jmb[src_idx];
+ src_desc = &tpr->rx_jmb[src_idx].std;
src_map = &tpr->rx_jmb_buffers[src_idx];
break;
@@ -5614,7 +5614,7 @@ static int tg3_rx_prodring_alloc(struct tg3 *tp,
for (i = 0; i < TG3_RX_JUMBO_RING_SIZE; i++) {
struct tg3_rx_buffer_desc *rxd;
- rxd = &tpr->rx_jmb[i];
+ rxd = &tpr->rx_jmb[i].std;
rxd->idx_len = TG3_RX_JMB_DMA_SZ << RXD_LEN_SHIFT;
rxd->type_flags = (RXD_FLAG_END << RXD_FLAGS_SHIFT) |
RXD_FLAG_JUMBO;
@@ -7053,7 +7053,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW,
((u64) tpr->rx_jmb_mapping & 0xffffffff));
tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_MAXLEN_FLAGS,
- RX_JUMBO_MAX_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT);
+ (RX_JUMBO_MAX_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT) |
+ BDINFO_FLAGS_USE_EXT_RECV);
tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_NIC_ADDR,
NIC_SRAM_RX_JUMBO_BUFFER_DESC);
} else {
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 7a27cff..982171f 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -2480,7 +2480,7 @@ struct tg3_rx_prodring_set {
u32 rx_std_ptr;
u32 rx_jmb_ptr;
struct tg3_rx_buffer_desc *rx_std;
- struct tg3_rx_buffer_desc *rx_jmb;
+ struct tg3_ext_rx_buffer_desc *rx_jmb;
struct ring_info *rx_std_buffers;
struct ring_info *rx_jmb_buffers;
dma_addr_t rx_std_mapping;
--
1.6.3.3
^ permalink raw reply related
* [PATCH 15/17] tg3: Move per-int rx members to per-int struct
From: Matt Carlson @ 2009-08-29 0:03 UTC (permalink / raw)
To: davem; +Cc: netdev, andy
This patch moves the rx_rcb, rx_rcb_mapping, and rx_rcb_ptr return ring
device members to a per-interrupt structure. It also adds a new return
ring consumer mailbox register member (consmbox) and converts the code
to use it rather than a preprocessor constant.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
---
drivers/net/tg3.c | 57 +++++++++++++++++++++++++++++-----------------------
drivers/net/tg3.h | 9 ++++---
2 files changed, 37 insertions(+), 29 deletions(-)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 5b8d6e0..939574c 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -657,7 +657,7 @@ static inline unsigned int tg3_has_work(struct tg3_napi *tnapi)
}
/* check for RX/TX work to do */
if (sblk->idx[0].tx_consumer != tp->tx_cons ||
- sblk->idx[0].rx_producer != tp->rx_rcb_ptr)
+ sblk->idx[0].rx_producer != tnapi->rx_rcb_ptr)
work_exists = 1;
return work_exists;
@@ -4480,7 +4480,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
{
struct tg3 *tp = tnapi->tp;
u32 work_mask, rx_std_posted = 0;
- u32 sw_idx = tp->rx_rcb_ptr;
+ u32 sw_idx = tnapi->rx_rcb_ptr;
u16 hw_idx;
int received;
struct tg3_rx_prodring_set *tpr = &tp->prodring[0];
@@ -4494,7 +4494,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
work_mask = 0;
received = 0;
while (sw_idx != hw_idx && budget > 0) {
- struct tg3_rx_buffer_desc *desc = &tp->rx_rcb[sw_idx];
+ struct tg3_rx_buffer_desc *desc = &tnapi->rx_rcb[sw_idx];
unsigned int len;
struct sk_buff *skb;
dma_addr_t dma_addr;
@@ -4622,8 +4622,8 @@ next_pkt_nopost:
}
/* ACK the status ring. */
- tp->rx_rcb_ptr = sw_idx;
- tw32_rx_mbox(MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW, sw_idx);
+ tnapi->rx_rcb_ptr = sw_idx;
+ tw32_rx_mbox(tnapi->consmbox, sw_idx);
/* Refill RX ring(s). */
if (work_mask & RXD_OPAQUE_RING_STD) {
@@ -4678,7 +4678,7 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
* All RX "locking" is done by ensuring outside
* code synchronizes with tg3->napi.poll()
*/
- if (sblk->idx[0].rx_producer != tp->rx_rcb_ptr)
+ if (sblk->idx[0].rx_producer != tnapi->rx_rcb_ptr)
work_done += tg3_rx(tnapi, budget - work_done);
return work_done;
@@ -4768,7 +4768,7 @@ static irqreturn_t tg3_msi_1shot(int irq, void *dev_id)
struct tg3 *tp = tnapi->tp;
prefetch(tnapi->hw_status);
- prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
+ prefetch(&tnapi->rx_rcb[tnapi->rx_rcb_ptr]);
if (likely(!tg3_irq_sync(tp)))
napi_schedule(&tnapi->napi);
@@ -4786,7 +4786,7 @@ static irqreturn_t tg3_msi(int irq, void *dev_id)
struct tg3 *tp = tnapi->tp;
prefetch(tnapi->hw_status);
- prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
+ prefetch(&tnapi->rx_rcb[tnapi->rx_rcb_ptr]);
/*
* Writing any value to intr-mbox-0 clears PCI INTA# and
* chip-internal interrupt pending events.
@@ -4837,7 +4837,7 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id)
goto out;
sblk->status &= ~SD_STATUS_UPDATED;
if (likely(tg3_has_work(tnapi))) {
- prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
+ prefetch(&tnapi->rx_rcb[tnapi->rx_rcb_ptr]);
napi_schedule(&tnapi->napi);
} else {
/* No work, shared interrupt perhaps? re-enable
@@ -4894,7 +4894,7 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
if (tg3_irq_sync(tp))
goto out;
- prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
+ prefetch(&tnapi->rx_rcb[tnapi->rx_rcb_ptr]);
napi_schedule(&tnapi->napi);
@@ -5745,13 +5745,17 @@ static void tg3_free_rings(struct tg3 *tp)
*/
static int tg3_init_rings(struct tg3 *tp)
{
+ struct tg3_napi *tnapi = &tp->napi[0];
+
/* Free up all the SKBs. */
tg3_free_rings(tp);
/* Zero out all descriptors. */
- memset(tp->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp));
memset(tp->tx_ring, 0, TG3_TX_RING_BYTES);
+ tnapi->rx_rcb_ptr = 0;
+ memset(tnapi->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp));
+
return tg3_rx_prodring_alloc(tp, &tp->prodring[0]);
}
@@ -5765,16 +5769,16 @@ static void tg3_free_consistent(struct tg3 *tp)
kfree(tp->tx_buffers);
tp->tx_buffers = NULL;
- if (tp->rx_rcb) {
- pci_free_consistent(tp->pdev, TG3_RX_RCB_RING_BYTES(tp),
- tp->rx_rcb, tp->rx_rcb_mapping);
- tp->rx_rcb = NULL;
- }
if (tp->tx_ring) {
pci_free_consistent(tp->pdev, TG3_TX_RING_BYTES,
tp->tx_ring, tp->tx_desc_mapping);
tp->tx_ring = NULL;
}
+ if (tnapi->rx_rcb) {
+ pci_free_consistent(tp->pdev, TG3_RX_RCB_RING_BYTES(tp),
+ tnapi->rx_rcb, tnapi->rx_rcb_mapping);
+ tnapi->rx_rcb = NULL;
+ }
if (tnapi->hw_status) {
pci_free_consistent(tp->pdev, TG3_HW_STATUS_SIZE,
tnapi->hw_status,
@@ -5805,11 +5809,6 @@ static int tg3_alloc_consistent(struct tg3 *tp)
if (!tp->tx_buffers)
goto err_out;
- tp->rx_rcb = pci_alloc_consistent(tp->pdev, TG3_RX_RCB_RING_BYTES(tp),
- &tp->rx_rcb_mapping);
- if (!tp->rx_rcb)
- goto err_out;
-
tp->tx_ring = pci_alloc_consistent(tp->pdev, TG3_TX_RING_BYTES,
&tp->tx_desc_mapping);
if (!tp->tx_ring)
@@ -5823,6 +5822,14 @@ static int tg3_alloc_consistent(struct tg3 *tp)
memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE);
+ tnapi->rx_rcb = pci_alloc_consistent(tp->pdev,
+ TG3_RX_RCB_RING_BYTES(tp),
+ &tnapi->rx_rcb_mapping);
+ if (!tnapi->rx_rcb)
+ goto err_out;
+
+ memset(tnapi->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp));
+
tp->hw_stats = pci_alloc_consistent(tp->pdev,
sizeof(struct tg3_hw_stats),
&tp->stats_mapping);
@@ -7109,11 +7116,10 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
}
}
- tp->rx_rcb_ptr = 0;
- tw32_rx_mbox(MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW, 0);
+ tw32_rx_mbox(tp->napi[0].consmbox, 0);
tg3_set_bdinfo(tp, NIC_SRAM_RCV_RET_RCB,
- tp->rx_rcb_mapping,
+ tp->napi[0].rx_rcb_mapping,
(TG3_RX_RCB_RING_SIZE(tp) <<
BDINFO_FLAGS_MAXLEN_SHIFT),
0);
@@ -9956,7 +9962,7 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
if (rx_idx != rx_start_idx + num_pkts)
goto out;
- desc = &tp->rx_rcb[rx_start_idx];
+ desc = &rnapi->rx_rcb[rx_start_idx];
desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK;
opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK;
if (opaque_key != RXD_OPAQUE_RING_STD)
@@ -13413,6 +13419,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
tp->napi[0].tp = tp;
tp->napi[0].int_mbox = MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW;
+ tp->napi[0].consmbox = MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW;
netif_napi_add(dev, &tp->napi[0].napi, tg3_poll, 64);
dev->ethtool_ops = &tg3_ethtool_ops;
dev->watchdog_timeo = TG3_TX_TIMEOUT;
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index f46e619..b91ac29 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -2497,8 +2497,13 @@ struct tg3_napi {
u32 last_tag;
u32 last_irq_tag;
u32 int_mbox;
+ u32 consmbox;
+ u32 rx_rcb_ptr;
+
+ struct tg3_rx_buffer_desc *rx_rcb;
dma_addr_t status_mapping;
+ dma_addr_t rx_rcb_mapping;
};
struct tg3 {
@@ -2570,7 +2575,6 @@ struct tg3 {
struct tg3_napi napi[TG3_IRQ_MAX_VECS];
void (*write32_rx_mbox) (struct tg3 *, u32,
u32);
- u32 rx_rcb_ptr;
u32 rx_pending;
u32 rx_jumbo_pending;
u32 rx_std_max_post;
@@ -2579,9 +2583,6 @@ struct tg3 {
struct vlan_group *vlgrp;
#endif
- struct tg3_rx_buffer_desc *rx_rcb;
- dma_addr_t rx_rcb_mapping;
-
struct tg3_rx_prodring_set prodring[1];
--
1.6.3.3
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox