* Re: [PATCH] tcp: fix MSG_SENDPAGE_NOTLAST logic
From: David Miller @ 2013-01-07 4:59 UTC (permalink / raw)
To: eric.dumazet; +Cc: w, netdev, linux-kernel
In-Reply-To: <1357532509.6919.1715.camel@edumazet-glaptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Sun, 06 Jan 2013 20:21:49 -0800
> From: Eric Dumazet <edumazet@google.com>
>
> commit 35f9c09fe9c72e (tcp: tcp_sendpages() should call tcp_push() once)
> added an internal flag : MSG_SENDPAGE_NOTLAST meant to be set on all
> frags but the last one for a splice() call.
>
> The condition used to set the flag in pipe_to_sendpage() relied on
> splice() user passing the exact number of bytes present in the pipe,
> or a smaller one.
>
> But some programs pass an arbitrary high value, and the test fails.
>
> The effect of this bug is a lack of tcp_push() at the end of a
> splice(pipe -> socket) call, and possibly very slow or erratic TCP
> sessions.
>
> We should both test sd->total_len and fact that another fragment
> is in the pipe (pipe->nrbufs > 1)
>
> Many thanks to Willy for providing very clear bug report, bisection
> and test programs.
>
> Reported-by: Willy Tarreau <w@1wt.eu>
> Bisected-by: Willy Tarreau <w@1wt.eu>
> Tested-by: Willy Tarreau <w@1wt.eu>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
Applied and queued up for -stable, thanks everyone.
^ permalink raw reply
* Re: Bug#697357: bridging broken over bond interfaces
From: Ben Hutchings @ 2013-01-07 4:58 UTC (permalink / raw)
To: netdev
Cc: Bastian Blank, 697357, Peter Palfrader, Stephen Hemminger,
Jay Vosburgh, Andy Gospodarek
In-Reply-To: <20130104124012.GH14827@anguilla.noreply.org>
[-- Attachment #1: Type: text/plain, Size: 2384 bytes --]
Forwarding this to netdev since the bug is still present in Linux 3.7.1.
For those joining us, this thread is archive at
<http://bugs.debian.org/697357>.
On Fri, 2013-01-04 at 13:40 +0100, Peter Palfrader wrote:
> On Fri, 04 Jan 2013, Bastian Blank wrote:
>
> > On Fri, Jan 04, 2013 at 12:17:12PM +0100, Peter Palfrader wrote:
> > > I tried to set up a new KVM host in the usual way:
> > > - have a bond0 interface over all physcial eth* interfaces
> > > - create a br0 over that bond0 and any vnet* interfaces for the
> > > guests.
>
> Also, arp works through the bridge, forgot to mention that.
>
> > > * Manually switching the eth* to promiscious mode makes stuff work.
> >
> > Okay, so a workaround is available.
> >
> > When did it last work? Does it work with the kernel from experimental?
>
> It works nicely on stable, e.g. pasquini.debian.org:
>
> | weasel@pasquini:~$ sudo brctl show
> | bridge name bridge id STP enabled interfaces
> | br0 8000.e83935a9ec10 no bond0
> | tap0
> | tap1
> | tap2
> | br1 8000.e83935a9ec10 no bond0.221
> | br2 8000.da1343affe92 no bond0.3301
> | tap3
>
> And there the bond interface is promisc automatically:
> weasel@pasquini:~$ ip a | grep -i bond
> | 2: eth0: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master bond0 state UP qlen 1000
> | 3: eth1: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master bond0 state UP qlen 1000
> | 4: bond0: <BROADCAST,MULTICAST,PROMISC,MASTER,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
> | 7: bond0.221@bond0: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
> | 9: bond0.3301@bond0: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
>
> Likewise it works as expected when one does br directly on eth0, without any
> bonding.
>
> It's also broken with linux-image-3.7-trunk-amd64_3.7.1-1~experimental.1_amd64.deb.
--
Ben Hutchings
If you seem to know what you are doing, you'll be given more to do.
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]
^ permalink raw reply
* [RFC PATCH] vsprintf: Add %p*D extension for 80211 SSIDs
From: Joe Perches @ 2013-01-07 4:49 UTC (permalink / raw)
To: John W. Linville; +Cc: Chen Gang, stas.yakovlev, linux-wireless, netdev
In-Reply-To: <1357528746.4940.31.camel@joe-AO722>
On Sun, 2013-01-06 at 19:19 -0800, Joe Perches wrote:
> Maybe these days this should be another vsprintf %p extension
> like %pM when the DECLARE_MAC_BUF/print_mac uses were converted.
>
> (or maybe extend %ph for ssids with %*phs, length, array)
Maybe like this:
lib/vsprintf.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 55 insertions(+), 2 deletions(-)
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index fab33a9..98916a0 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -26,6 +26,7 @@
#include <linux/math64.h>
#include <linux/uaccess.h>
#include <linux/ioport.h>
+#include <linux/ieee80211.h>
#include <net/addrconf.h>
#include <asm/page.h> /* for PAGE_SIZE */
@@ -660,10 +661,59 @@ char *resource_string(char *buf, char *end, struct resource *res,
}
static noinline_for_stack
+char *ssid_string(char *buf, char *end, u8 *addr, struct printf_spec spec,
+ const char *fmt)
+{
+ int i, len = 1; /* if we pass %*p, field width remains
+ negative value, fallback to the default */
+
+ if (spec.field_width == 0)
+ /* nothing to print */
+ return buf;
+
+ if (ZERO_OR_NULL_PTR(addr))
+ /* NULL pointer */
+ return string(buf, end, NULL, spec);
+
+ if (spec.field_width > 0)
+ len = min_t(int, spec.field_width, IEEE80211_MAX_SSID_LEN);
+
+ for (i = 0; i < len && buf < end; i++) {
+ if (isprint(addr[i])) {
+ *buf++ = addr[i];
+ continue;
+ }
+ *buf++ = '\\';
+ if (buf >= end)
+ continue;
+ if (addr[i] == '\0')
+ *buf++ = '0';
+ else if (addr[i] == '\n')
+ *buf++ = 'n';
+ else if (addr[i] == '\r')
+ *buf++ = 'r';
+ else if (addr[i] == '\t')
+ *buf++ = 't';
+ else if (addr[i] == '\\')
+ *buf++ = '\\';
+ else {
+ if (buf < end)
+ *buf++ = ((addr[i] >> 6) & 7) + '0';
+ if (buf < end)
+ *buf++ = ((addr[i] >> 3) & 7) + '0';
+ if (buf < end)
+ *buf++ = ((addr[i] >> 0) & 7) + '0';
+ }
+ }
+
+ return buf;
+}
+
+static noinline_for_stack
char *hex_string(char *buf, char *end, u8 *addr, struct printf_spec spec,
const char *fmt)
{
- int i, len = 1; /* if we pass '%ph[CDN]', field witdh remains
+ int i, len = 1; /* if we pass '%ph[CDN]', field width remains
negative value, fallback to the default */
char separator;
@@ -695,7 +745,6 @@ char *hex_string(char *buf, char *end, u8 *addr, struct printf_spec spec,
for (i = 0; i < len && buf < end - 1; i++) {
buf = hex_byte_pack(buf, addr[i]);
-
if (buf < end && separator && i != len - 1)
*buf++ = separator;
}
@@ -1016,6 +1065,8 @@ int kptr_restrict __read_mostly;
* [0][1][2][3]-[4][5]-[6][7]-[8][9]-[10][11][12][13][14][15]
* little endian output byte order is:
* [3][2][1][0]-[5][4]-[7][6]-[8][9]-[10][11][12][13][14][15]
+ * - 'D' For a 80211 SSID, it prints the SSID escaping any non-printable
+ characters with a leading \ and octal or [0nrt\]
* - 'V' For a struct va_format which contains a format string * and va_list *,
* call vsnprintf(->format, *->va_list).
* Implements a "recursive vsnprintf".
@@ -1088,6 +1139,8 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
break;
case 'U':
return uuid_string(buf, end, ptr, spec, fmt);
+ case 'D':
+ return ssid_string(buf, end, ptr, spec, fmt);
case 'V':
{
va_list va;
^ permalink raw reply related
* [PATCH] drivers/net/wireless/iwlegacy: use strlcpy instead of strncpy
From: Chen Gang @ 2013-01-07 4:42 UTC (permalink / raw)
To: sgruszka, linville; +Cc: linux-wireless, netdev
The fields must be null-terminated, or simple_strtoul will cause issue.
Signed-off-by: Chen Gang <gang.chen@asianux.com>
---
drivers/net/wireless/iwlegacy/3945-mac.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c
index d604b40..3726cd6 100644
--- a/drivers/net/wireless/iwlegacy/3945-mac.c
+++ b/drivers/net/wireless/iwlegacy/3945-mac.c
@@ -3273,7 +3273,7 @@ il3945_store_measurement(struct device *d, struct device_attribute *attr,
if (count) {
char *p = buffer;
- strncpy(buffer, buf, min(sizeof(buffer), count));
+ strlcpy(buffer, buf, sizeof(buffer));
channel = simple_strtoul(p, NULL, 0);
if (channel)
params.channel = channel;
--
1.7.10.4
^ permalink raw reply related
* Re: [PATCH V3 2/2] vhost: handle polling errors
From: Jason Wang @ 2013-01-07 4:38 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: kvm, eric.dumazet, netdev, linux-kernel, virtualization, davem
In-Reply-To: <20130106132201.GC18612@redhat.com>
On 01/06/2013 09:22 PM, Michael S. Tsirkin wrote:
> On Sun, Jan 06, 2013 at 03:18:38PM +0800, Jason Wang wrote:
>> Polling errors were ignored by vhost/vhost_net, this may lead to crash when
>> trying to remove vhost from waitqueue when after the polling is failed. Solve
>> this problem by:
>>
>> - checking the poll->wqh before trying to remove from waitqueue
>> - report an error when poll() returns a POLLERR in vhost_start_poll()
>> - report an error when vhost_start_poll() fails in
>> vhost_vring_ioctl()/vhost_net_set_backend() which is used to notify the
>> failure to userspace.
>> - report an error in the data path in vhost_net when meet polling errors.
>>
>> After those changes, we can safely drop the tx polling state in vhost_net since
>> it was replaced by the checking of poll->wqh.
>>
>> Signed-off-by: Jason Wang <jasowang@redhat.com>
>> ---
>> drivers/vhost/net.c | 74 ++++++++++++++++--------------------------------
>> drivers/vhost/vhost.c | 31 +++++++++++++++-----
>> drivers/vhost/vhost.h | 2 +-
>> 3 files changed, 49 insertions(+), 58 deletions(-)
>>
>> diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
>> index d10ad6f..125c1e5 100644
>> --- a/drivers/vhost/net.c
>> +++ b/drivers/vhost/net.c
>> @@ -64,20 +64,10 @@ enum {
>> VHOST_NET_VQ_MAX = 2,
>> };
>>
>> -enum vhost_net_poll_state {
>> - VHOST_NET_POLL_DISABLED = 0,
>> - VHOST_NET_POLL_STARTED = 1,
>> - VHOST_NET_POLL_STOPPED = 2,
>> -};
>> -
>> struct vhost_net {
>> struct vhost_dev dev;
>> struct vhost_virtqueue vqs[VHOST_NET_VQ_MAX];
>> struct vhost_poll poll[VHOST_NET_VQ_MAX];
>> - /* Tells us whether we are polling a socket for TX.
>> - * We only do this when socket buffer fills up.
>> - * Protected by tx vq lock. */
>> - enum vhost_net_poll_state tx_poll_state;
>> /* Number of TX recently submitted.
>> * Protected by tx vq lock. */
>> unsigned tx_packets;
>> @@ -155,24 +145,6 @@ static void copy_iovec_hdr(const struct iovec *from, struct iovec *to,
>> }
>> }
>>
>> -/* Caller must have TX VQ lock */
>> -static void tx_poll_stop(struct vhost_net *net)
>> -{
>> - if (likely(net->tx_poll_state != VHOST_NET_POLL_STARTED))
>> - return;
>> - vhost_poll_stop(net->poll + VHOST_NET_VQ_TX);
>> - net->tx_poll_state = VHOST_NET_POLL_STOPPED;
>> -}
>> -
>> -/* Caller must have TX VQ lock */
>> -static void tx_poll_start(struct vhost_net *net, struct socket *sock)
>> -{
>> - if (unlikely(net->tx_poll_state != VHOST_NET_POLL_STOPPED))
>> - return;
>> - vhost_poll_start(net->poll + VHOST_NET_VQ_TX, sock->file);
>> - net->tx_poll_state = VHOST_NET_POLL_STARTED;
>> -}
>> -
>> /* In case of DMA done not in order in lower device driver for some reason.
>> * upend_idx is used to track end of used idx, done_idx is used to track head
>> * of used idx. Once lower device DMA done contiguously, we will signal KVM
>> @@ -227,6 +199,7 @@ static void vhost_zerocopy_callback(struct ubuf_info *ubuf, bool success)
>> static void handle_tx(struct vhost_net *net)
>> {
>> struct vhost_virtqueue *vq = &net->dev.vqs[VHOST_NET_VQ_TX];
>> + struct vhost_poll *poll = net->poll + VHOST_NET_VQ_TX;
>> unsigned out, in, s;
>> int head;
>> struct msghdr msg = {
>> @@ -252,7 +225,8 @@ static void handle_tx(struct vhost_net *net)
>> wmem = atomic_read(&sock->sk->sk_wmem_alloc);
>> if (wmem >= sock->sk->sk_sndbuf) {
>> mutex_lock(&vq->mutex);
>> - tx_poll_start(net, sock);
>> + if (vhost_poll_start(poll, sock->file))
>> + vq_err(vq, "Fail to start TX polling\n");
> s/Fail/Failed/
>
> A question though: how can this happen? Could you clarify please?
> Maybe we can find a way to prevent this error?
Two conditions I think this can happen:
1) a buggy userspace disable a queue through TUNSETQUEUE
2) the net device were gone
For 1, looks like we can delay the disabling until the refcnt goes to
zero. For 2 may needs more changes. Not sure it's worth to do this work,
maybe a warning is enough just like other failure.
>
>> mutex_unlock(&vq->mutex);
>> return;
>> }
>> @@ -261,7 +235,7 @@ static void handle_tx(struct vhost_net *net)
>> vhost_disable_notify(&net->dev, vq);
>>
>> if (wmem < sock->sk->sk_sndbuf / 2)
>> - tx_poll_stop(net);
>> + vhost_poll_stop(poll);
>> hdr_size = vq->vhost_hlen;
>> zcopy = vq->ubufs;
>>
>> @@ -283,8 +257,10 @@ static void handle_tx(struct vhost_net *net)
>>
>> wmem = atomic_read(&sock->sk->sk_wmem_alloc);
>> if (wmem >= sock->sk->sk_sndbuf * 3 / 4) {
>> - tx_poll_start(net, sock);
>> - set_bit(SOCK_ASYNC_NOSPACE, &sock->flags);
>> + if (vhost_poll_start(poll, sock->file))
>> + vq_err(vq, "Fail to start TX polling\n");
>> + else
>> + set_bit(SOCK_ASYNC_NOSPACE, &sock->flags);
>> break;
>> }
>> /* If more outstanding DMAs, queue the work.
>> @@ -294,8 +270,10 @@ static void handle_tx(struct vhost_net *net)
>> (vq->upend_idx - vq->done_idx) :
>> (vq->upend_idx + UIO_MAXIOV - vq->done_idx);
>> if (unlikely(num_pends > VHOST_MAX_PEND)) {
>> - tx_poll_start(net, sock);
>> - set_bit(SOCK_ASYNC_NOSPACE, &sock->flags);
>> + if (vhost_poll_start(poll, sock->file))
>> + vq_err(vq, "Fail to start TX polling\n");
>> + else
>> + set_bit(SOCK_ASYNC_NOSPACE, &sock->flags);
>> break;
>> }
>> if (unlikely(vhost_enable_notify(&net->dev, vq))) {
>> @@ -360,7 +338,8 @@ static void handle_tx(struct vhost_net *net)
>> }
>> vhost_discard_vq_desc(vq, 1);
>> if (err == -EAGAIN || err == -ENOBUFS)
>> - tx_poll_start(net, sock);
>> + if (vhost_poll_start(poll, sock->file))
>> + vq_err(vq, "Fail to start TX polling\n");
>> break;
>> }
>> if (err != len)
>> @@ -623,7 +602,6 @@ static int vhost_net_open(struct inode *inode, struct file *f)
>>
>> vhost_poll_init(n->poll + VHOST_NET_VQ_TX, handle_tx_net, POLLOUT, dev);
>> vhost_poll_init(n->poll + VHOST_NET_VQ_RX, handle_rx_net, POLLIN, dev);
>> - n->tx_poll_state = VHOST_NET_POLL_DISABLED;
>>
>> f->private_data = n;
>>
>> @@ -633,29 +611,25 @@ static int vhost_net_open(struct inode *inode, struct file *f)
>> static void vhost_net_disable_vq(struct vhost_net *n,
>> struct vhost_virtqueue *vq)
>> {
>> + struct vhost_poll *poll = n->poll + (vq - n->vqs);
>> +
>> if (!vq->private_data)
>> return;
>> - if (vq == n->vqs + VHOST_NET_VQ_TX) {
>> - tx_poll_stop(n);
>> - n->tx_poll_state = VHOST_NET_POLL_DISABLED;
>> - } else
>> - vhost_poll_stop(n->poll + VHOST_NET_VQ_RX);
>> + vhost_poll_stop(poll);
>> }
>>
>> -static void vhost_net_enable_vq(struct vhost_net *n,
>> +static int vhost_net_enable_vq(struct vhost_net *n,
>> struct vhost_virtqueue *vq)
>> {
>> struct socket *sock;
>> + struct vhost_poll *poll = n->poll + (vq - n->vqs);
>>
>> sock = rcu_dereference_protected(vq->private_data,
>> lockdep_is_held(&vq->mutex));
>> if (!sock)
>> - return;
>> - if (vq == n->vqs + VHOST_NET_VQ_TX) {
>> - n->tx_poll_state = VHOST_NET_POLL_STOPPED;
>> - tx_poll_start(n, sock);
>> - } else
>> - vhost_poll_start(n->poll + VHOST_NET_VQ_RX, sock->file);
>> + return 0;
>> +
>> + return vhost_poll_start(poll, sock->file);
>> }
>>
>> static struct socket *vhost_net_stop_vq(struct vhost_net *n,
>> @@ -833,7 +807,9 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
>> r = vhost_init_used(vq);
>> if (r)
>> goto err_used;
>> - vhost_net_enable_vq(n, vq);
>> + r = vhost_net_enable_vq(n, vq);
>> + if (r)
>> + goto err_used;
>>
>> oldubufs = vq->ubufs;
>> vq->ubufs = ubufs;
>> diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
>> index 34389f7..5c7a466 100644
>> --- a/drivers/vhost/vhost.c
>> +++ b/drivers/vhost/vhost.c
>> @@ -77,26 +77,41 @@ void vhost_poll_init(struct vhost_poll *poll, vhost_work_fn_t fn,
>> init_poll_funcptr(&poll->table, vhost_poll_func);
>> poll->mask = mask;
>> poll->dev = dev;
>> + poll->wqh = NULL;
>>
>> vhost_work_init(&poll->work, fn);
>> }
>>
>> +/* Stop polling a file. After this function returns, it becomes safe to drop the
>> + * file reference. You must also flush afterwards. */
>> +void vhost_poll_stop(struct vhost_poll *poll)
>> +{
>> + if (poll->wqh) {
>> + remove_wait_queue(poll->wqh, &poll->wait);
>> + poll->wqh = NULL;
>> + }
>> +}
>> +
>> /* Start polling a file. We add ourselves to file's wait queue. The caller must
>> * keep a reference to a file until after vhost_poll_stop is called. */
>> -void vhost_poll_start(struct vhost_poll *poll, struct file *file)
>> +int vhost_poll_start(struct vhost_poll *poll, struct file *file)
>> {
>> unsigned long mask;
>> + int ret = 0;
>> +
>> + if (poll->wqh)
>> + return -EBUSY;
>>
> I think this should return success: we are already polling.
> Otherwise this would trigger a bug below I think.
Ok.
>
>> mask = file->f_op->poll(file, &poll->table);
>> if (mask)
>> vhost_poll_wakeup(&poll->wait, 0, 0, (void *)mask);
>> -}
>>
>> -/* Stop polling a file. After this function returns, it becomes safe to drop the
>> - * file reference. You must also flush afterwards. */
>> -void vhost_poll_stop(struct vhost_poll *poll)
>> -{
>> - remove_wait_queue(poll->wqh, &poll->wait);
>> + if (mask & POLLERR) {
>> + ret = -EINVAL;
>> + vhost_poll_stop(poll);
>> + }
>> +
>> + return ret;
>> }
>>
>> static bool vhost_work_seq_done(struct vhost_dev *dev, struct vhost_work *work,
>> @@ -792,7 +807,7 @@ long vhost_vring_ioctl(struct vhost_dev *d, int ioctl, void __user *argp)
>> fput(filep);
>>
>> if (pollstart && vq->handle_kick)
>> - vhost_poll_start(&vq->poll, vq->kick);
>> + r = vhost_poll_start(&vq->poll, vq->kick);
>>
>> mutex_unlock(&vq->mutex);
>>
>> diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
>> index 2639c58..17261e2 100644
>> --- a/drivers/vhost/vhost.h
>> +++ b/drivers/vhost/vhost.h
>> @@ -42,7 +42,7 @@ void vhost_work_queue(struct vhost_dev *dev, struct vhost_work *work);
>>
>> void vhost_poll_init(struct vhost_poll *poll, vhost_work_fn_t fn,
>> unsigned long mask, struct vhost_dev *dev);
>> -void vhost_poll_start(struct vhost_poll *poll, struct file *file);
>> +int vhost_poll_start(struct vhost_poll *poll, struct file *file);
>> void vhost_poll_stop(struct vhost_poll *poll);
>> void vhost_poll_flush(struct vhost_poll *poll);
>> void vhost_poll_queue(struct vhost_poll *poll);
>> --
>> 1.7.1
> --
> 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
* [PATCH] tcp: fix MSG_SENDPAGE_NOTLAST logic
From: Eric Dumazet @ 2013-01-07 4:21 UTC (permalink / raw)
To: Willy Tarreau, David Miller; +Cc: netdev, linux-kernel
In-Reply-To: <20130106195359.GN16031@1wt.eu>
From: Eric Dumazet <edumazet@google.com>
commit 35f9c09fe9c72e (tcp: tcp_sendpages() should call tcp_push() once)
added an internal flag : MSG_SENDPAGE_NOTLAST meant to be set on all
frags but the last one for a splice() call.
The condition used to set the flag in pipe_to_sendpage() relied on
splice() user passing the exact number of bytes present in the pipe,
or a smaller one.
But some programs pass an arbitrary high value, and the test fails.
The effect of this bug is a lack of tcp_push() at the end of a
splice(pipe -> socket) call, and possibly very slow or erratic TCP
sessions.
We should both test sd->total_len and fact that another fragment
is in the pipe (pipe->nrbufs > 1)
Many thanks to Willy for providing very clear bug report, bisection
and test programs.
Reported-by: Willy Tarreau <w@1wt.eu>
Bisected-by: Willy Tarreau <w@1wt.eu>
Tested-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
fs/splice.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/splice.c b/fs/splice.c
index 8890604..6909d89 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -696,8 +696,10 @@ static int pipe_to_sendpage(struct pipe_inode_info *pipe,
return -EINVAL;
more = (sd->flags & SPLICE_F_MORE) ? MSG_MORE : 0;
- if (sd->len < sd->total_len)
+
+ if (sd->len < sd->total_len && pipe->nrbufs > 1)
more |= MSG_SENDPAGE_NOTLAST;
+
return file->f_op->sendpage(file, buf->page, buf->offset,
sd->len, &pos, more);
}
^ permalink raw reply related
* Re: [PATCH net-next v3 0/3] netpoll: add IPv6 support
From: David Miller @ 2013-01-07 3:49 UTC (permalink / raw)
To: amwang; +Cc: netdev
In-Reply-To: <1357527485.20798.4.camel@cr0>
From: Cong Wang <amwang@redhat.com>
Date: Mon, 07 Jan 2013 10:58:05 +0800
> On Thu, 2013-01-03 at 19:20 -0800, David Miller wrote:
>> From: Cong Wang <amwang@redhat.com>
>> Date: Fri, 4 Jan 2013 11:14:30 +0800
>>
>> > (Resend with a cover letter)
>> >
>> > v3: fix CONFIG_IPV6=m case
>> >
>> > v2: use bool for ipv6 flag
>> > fix !CONFIG_IPV6 case
>> >
>> > This patchset implements netpoll over IPv6.
>>
>> Thanks for submitting this properly.
>>
>> But disallowing ipv6 netpoll support when IPV6=m is an unacceptable
>> limitation, compiling IPV6 as a module is common and in fact
>> recommended.
>>
>> We've solved problems like this before, by putting the needed ipv6
>> routines into a seperate library that is built statically into the
>> kernel when necessary.
>>
>> You should use a similar approach here.
>
> Hmm, here we need ndisc_parse_options() and udp6_csum_init(). Not sure
> if both can be inlined?
I didn't say "inline", read my email again.
We put such routines into a static library of ipv6 routines
that gets statically built into vmlinux even if ipv6 is
modular.
I'm not explaining this agin.
^ permalink raw reply
* Re: [PATCH 19/19] netfilter: gre: fix resource leak when unregister gre proto
From: Gao feng @ 2013-01-07 3:43 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel, netdev, canqunzhang, kaber, ebiederm
In-Reply-To: <20130107032711.GA18953@1984>
On 01/07/13 11:27, Pablo Neira Ayuso wrote:
> On Mon, Jan 07, 2013 at 11:05:12AM +0800, Gao feng wrote:
>> On 01/07/13 10:59, Gao feng wrote:
>>> On 01/07/13 10:38, Pablo Neira Ayuso wrote:
>>>> On Mon, Jan 07, 2013 at 03:15:17AM +0100, Pablo Neira Ayuso wrote:
>>>>> Hi Gao,
>>>>>
>>>>> On Mon, Jan 07, 2013 at 09:27:37AM +0800, Gao feng wrote:
>>>>>> Hi Pablo,
>>>>>>
>>>>>> On 01/05/13 11:50, Pablo Neira Ayuso wrote:
>>>>>>> Hi Gao,
>>>>>>>
>>>>>>> On Fri, Dec 28, 2012 at 10:36:46AM +0800, Gao feng wrote:
>>>>>>>> Currectly we unregister proto before all conntrack entries of
>>>>>>>> this proto being destroyed. so in function destroy_conntrack
>>>>>>>> we can't find proper l4proto to call l4proto->destroy.
>>>>>>>> this will cause resource leak.
>>>>>>>
>>>>>>> Good catch.
>>>>>>>
>>>>>>> But better to remove the entries before unregistering the protocol
>>>>>>> tracker, so l4proto->destroy is always called.
>>>>>>>
>>>>>>
>>>>>> I think the reason we unregister proto before remove all entries
>>>>>> is to avoid new entry for this protocol being created.
>>>>>>
>>>>>> If we remove all contrack entries before unregistration, there maybe
>>>>>> some new entries being created between nf_ct_iterate_cleanup and
>>>>>> nf_conntrack_l4proto_unregister_net.this will cause some terrible things.
>>>>>
>>>>> Leaks are less likely to happen, but may well still happen while
>>>>> racing with protocol removal, agreed.
>>>>>
>>>>>> SO I think we should make proto unavailable first,remove all entries next,
>>>>>> and remove proto from nf_ct_protos arrays finally.
>>>>>
>>>>> Your proposal adds a branch in the packet path to fix an issue that is
>>>>> specific of the GRE protocol tracker. In the current code, this fixes
>>>>> the memory leak while removing the nf_conntrack_proto_gre module,
>>>>> which is a rare operation.
>>>>>
>>>>> We have to come with a less intrusive solution.
>>>>
>>>> Wait. The existing code is calling nf_ct_gre_keymap_flush in
>>>> proto_gre_net_exit path, so those keymap objects are not leaked.
>>>
>>> Agree, it looks like nf_ct_gre_keymap_flush is added to solve this
>>> problem.
>>>
>>> Please ignore this patch.
>>
>> I mean ignore the codes of gre part.
>> I still think nf_ct_iterate_cleanup doesn't make sure all entries being
>> destroyed.
>
> There is another round of nf_ct_iterate cleanup in
> nf_conntrack_cleanup_net. So I don't see any possible leak so far. Let
> me know if you find anything.
>
Ok,I am wrong...
Please ignore this patch. ;)
^ permalink raw reply
* Re: [PATCH] drivers/net/wireless/ipw2x00: use strlcpy instead of strncpy
From: Chen Gang F T @ 2013-01-07 3:42 UTC (permalink / raw)
To: Joe Perches; +Cc: Chen Gang, stas.yakovlev, linville, linux-wireless, netdev
In-Reply-To: <1357528746.4940.31.camel@joe-AO722>
[-- Attachment #1: Type: text/plain, Size: 5228 bytes --]
于 2013年01月07日 11:19, Joe Perches 写道:
> On Mon, 2013-01-07 at 10:49 +0800, Chen Gang wrote:
>> but I think the original author intended to use escaped instead of ssid
>> DECLARE_SSID_BUF(ssid) (line 5525, 5737)
>> use ssid to print debug information directly
>> (such as: line 5530..5535, 5545..5549, 5745..5749, ...)
>> when need print additional information, use escaped
>> (line 5559..5569, 5773..5782, 5791..5799)
>>
>> so, I still suggest:
>> only fix the bug (use strlcpy instead of strncpy)
>> and not touch original features which orignal author intended using.
>
> More likely John Linville just missed the conversions.
> 4+ years ago.
>
I wonder why it is not integrated into main branch.
maybe we miss it.
if so, I suggest to integrate it (better also add Reported-by gang.chen@asianux.com :-) )
maybe original author intended using short length.
if so, I suggest to integrate my patch (using strlcpy instead of strncpy).
for me:
using long size instead of original short size, will change the output format.
it seems not a good idea to change the original output format.
(especially, the original output format has existence 4+ years).
so, at least:
for only fixing bug, not touching original features
it is an executable method (is a valuable patch).
although maybe it is not a best method (is not a very good patch).
Regards
gchen.
> commit 9387b7caf3049168fc97a8a9111af8fe2143af18
> Author: John W. Linville <linville@tuxdriver.com>
> Date: Tue Sep 30 20:59:05 2008 -0400
>
> wireless: use individual buffers for printing ssid values
>
> Also change escape_ssid to print_ssid to match print_mac semantics.
>
> Signed-off-by: John W. Linville <linville@tuxdriver.com>
>
> Maybe these days this should be another vsprintf %p extension
> like %pM when the DECLARE_MAC_BUF/print_mac uses were converted.
>
> (or maybe extend %ph for ssids with %*phs, length, array)
>
> But if and until then, I suggest this instead:
>
> drivers/net/wireless/ipw2x00/ipw2200.c | 38 ++++++++++++++--------------------
> 1 file changed, 15 insertions(+), 23 deletions(-)
>
> diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
> index 844f201..3dc6a92 100644
> --- a/drivers/net/wireless/ipw2x00/ipw2200.c
> +++ b/drivers/net/wireless/ipw2x00/ipw2200.c
> @@ -5556,15 +5556,12 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv,
> ((network->ssid_len != priv->essid_len) ||
> memcmp(network->ssid, priv->essid,
> min(network->ssid_len, priv->essid_len)))) {
> - char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
> + DECLARE_SSID_BUF(escaped);
>
> - strncpy(escaped,
> - print_ssid(ssid, network->ssid,
> - network->ssid_len),
> - sizeof(escaped));
> - IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
> - "because of ESSID mismatch: '%s'.\n",
> - escaped, network->bssid,
> + IPW_DEBUG_MERGE("Network '%s (%pM)' excluded because of ESSID mismatch: '%s'\n",
> + print_ssid(escaped, network->ssid,
> + network->ssid_len),
> + network->bssid,
> print_ssid(ssid, priv->essid,
> priv->essid_len));
> return 0;
> @@ -5770,14 +5767,11 @@ static int ipw_best_network(struct ipw_priv *priv,
> ((network->ssid_len != priv->essid_len) ||
> memcmp(network->ssid, priv->essid,
> min(network->ssid_len, priv->essid_len)))) {
> - char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
> - strncpy(escaped,
> - print_ssid(ssid, network->ssid,
> - network->ssid_len),
> - sizeof(escaped));
> - IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
> - "because of ESSID mismatch: '%s'.\n",
> - escaped, network->bssid,
> + DECLARE_SSID_BUF(escaped);
> + IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded because of ESSID mismatch: '%s'\n",
> + print_ssid(escaped, network->ssid,
> + network->ssid_len),
> + network->bssid,
> print_ssid(ssid, priv->essid,
> priv->essid_len));
> return 0;
> @@ -5787,13 +5781,11 @@ static int ipw_best_network(struct ipw_priv *priv,
> /* If the old network rate is better than this one, don't bother
> * testing everything else. */
> if (match->network && match->network->stats.rssi > network->stats.rssi) {
> - char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
> - strncpy(escaped,
> - print_ssid(ssid, network->ssid, network->ssid_len),
> - sizeof(escaped));
> - IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded because "
> - "'%s (%pM)' has a stronger signal.\n",
> - escaped, network->bssid,
> + DECLARE_SSID_BUF(escaped);
> + IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded because '%s (%pM)' has a stronger signal\n",
> + print_ssid(escaped, network->ssid,
> + network->ssid_len),
> + network->bssid,
> print_ssid(ssid, match->network->ssid,
> match->network->ssid_len),
> match->network->bssid);
>
>
> --
> 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
>
--
Chen Gang
Flying Transformer
[-- Attachment #2: chen_gang_flying_transformer.vcf --]
[-- Type: text/x-vcard, Size: 67 bytes --]
begin:vcard
fn:Chen Gang
n:;Chen Gang
version:2.1
end:vcard
^ permalink raw reply
* Re: [PATCH 19/19] netfilter: gre: fix resource leak when unregister gre proto
From: Pablo Neira Ayuso @ 2013-01-07 3:27 UTC (permalink / raw)
To: Gao feng; +Cc: netfilter-devel, netdev, canqunzhang, kaber, ebiederm
In-Reply-To: <50EA3B68.1080001@cn.fujitsu.com>
On Mon, Jan 07, 2013 at 11:05:12AM +0800, Gao feng wrote:
> On 01/07/13 10:59, Gao feng wrote:
> > On 01/07/13 10:38, Pablo Neira Ayuso wrote:
> >> On Mon, Jan 07, 2013 at 03:15:17AM +0100, Pablo Neira Ayuso wrote:
> >>> Hi Gao,
> >>>
> >>> On Mon, Jan 07, 2013 at 09:27:37AM +0800, Gao feng wrote:
> >>>> Hi Pablo,
> >>>>
> >>>> On 01/05/13 11:50, Pablo Neira Ayuso wrote:
> >>>>> Hi Gao,
> >>>>>
> >>>>> On Fri, Dec 28, 2012 at 10:36:46AM +0800, Gao feng wrote:
> >>>>>> Currectly we unregister proto before all conntrack entries of
> >>>>>> this proto being destroyed. so in function destroy_conntrack
> >>>>>> we can't find proper l4proto to call l4proto->destroy.
> >>>>>> this will cause resource leak.
> >>>>>
> >>>>> Good catch.
> >>>>>
> >>>>> But better to remove the entries before unregistering the protocol
> >>>>> tracker, so l4proto->destroy is always called.
> >>>>>
> >>>>
> >>>> I think the reason we unregister proto before remove all entries
> >>>> is to avoid new entry for this protocol being created.
> >>>>
> >>>> If we remove all contrack entries before unregistration, there maybe
> >>>> some new entries being created between nf_ct_iterate_cleanup and
> >>>> nf_conntrack_l4proto_unregister_net.this will cause some terrible things.
> >>>
> >>> Leaks are less likely to happen, but may well still happen while
> >>> racing with protocol removal, agreed.
> >>>
> >>>> SO I think we should make proto unavailable first,remove all entries next,
> >>>> and remove proto from nf_ct_protos arrays finally.
> >>>
> >>> Your proposal adds a branch in the packet path to fix an issue that is
> >>> specific of the GRE protocol tracker. In the current code, this fixes
> >>> the memory leak while removing the nf_conntrack_proto_gre module,
> >>> which is a rare operation.
> >>>
> >>> We have to come with a less intrusive solution.
> >>
> >> Wait. The existing code is calling nf_ct_gre_keymap_flush in
> >> proto_gre_net_exit path, so those keymap objects are not leaked.
> >
> > Agree, it looks like nf_ct_gre_keymap_flush is added to solve this
> > problem.
> >
> > Please ignore this patch.
>
> I mean ignore the codes of gre part.
> I still think nf_ct_iterate_cleanup doesn't make sure all entries being
> destroyed.
There is another round of nf_ct_iterate cleanup in
nf_conntrack_cleanup_net. So I don't see any possible leak so far. Let
me know if you find anything.
Thanks.
^ permalink raw reply
* Re: [PATCH] drivers/net/wireless/ipw2x00: use strlcpy instead of strncpy
From: Joe Perches @ 2013-01-07 3:19 UTC (permalink / raw)
To: Chen Gang; +Cc: stas.yakovlev, linville, linux-wireless, netdev
In-Reply-To: <50EA37CE.1090901@asianux.com>
On Mon, 2013-01-07 at 10:49 +0800, Chen Gang wrote:
> but I think the original author intended to use escaped instead of ssid
> DECLARE_SSID_BUF(ssid) (line 5525, 5737)
> use ssid to print debug information directly
> (such as: line 5530..5535, 5545..5549, 5745..5749, ...)
> when need print additional information, use escaped
> (line 5559..5569, 5773..5782, 5791..5799)
>
> so, I still suggest:
> only fix the bug (use strlcpy instead of strncpy)
> and not touch original features which orignal author intended using.
More likely John Linville just missed the conversions.
4+ years ago.
commit 9387b7caf3049168fc97a8a9111af8fe2143af18
Author: John W. Linville <linville@tuxdriver.com>
Date: Tue Sep 30 20:59:05 2008 -0400
wireless: use individual buffers for printing ssid values
Also change escape_ssid to print_ssid to match print_mac semantics.
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Maybe these days this should be another vsprintf %p extension
like %pM when the DECLARE_MAC_BUF/print_mac uses were converted.
(or maybe extend %ph for ssids with %*phs, length, array)
But if and until then, I suggest this instead:
drivers/net/wireless/ipw2x00/ipw2200.c | 38 ++++++++++++++--------------------
1 file changed, 15 insertions(+), 23 deletions(-)
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 844f201..3dc6a92 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -5556,15 +5556,12 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv,
((network->ssid_len != priv->essid_len) ||
memcmp(network->ssid, priv->essid,
min(network->ssid_len, priv->essid_len)))) {
- char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
+ DECLARE_SSID_BUF(escaped);
- strncpy(escaped,
- print_ssid(ssid, network->ssid,
- network->ssid_len),
- sizeof(escaped));
- IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
- "because of ESSID mismatch: '%s'.\n",
- escaped, network->bssid,
+ IPW_DEBUG_MERGE("Network '%s (%pM)' excluded because of ESSID mismatch: '%s'\n",
+ print_ssid(escaped, network->ssid,
+ network->ssid_len),
+ network->bssid,
print_ssid(ssid, priv->essid,
priv->essid_len));
return 0;
@@ -5770,14 +5767,11 @@ static int ipw_best_network(struct ipw_priv *priv,
((network->ssid_len != priv->essid_len) ||
memcmp(network->ssid, priv->essid,
min(network->ssid_len, priv->essid_len)))) {
- char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
- strncpy(escaped,
- print_ssid(ssid, network->ssid,
- network->ssid_len),
- sizeof(escaped));
- IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
- "because of ESSID mismatch: '%s'.\n",
- escaped, network->bssid,
+ DECLARE_SSID_BUF(escaped);
+ IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded because of ESSID mismatch: '%s'\n",
+ print_ssid(escaped, network->ssid,
+ network->ssid_len),
+ network->bssid,
print_ssid(ssid, priv->essid,
priv->essid_len));
return 0;
@@ -5787,13 +5781,11 @@ static int ipw_best_network(struct ipw_priv *priv,
/* If the old network rate is better than this one, don't bother
* testing everything else. */
if (match->network && match->network->stats.rssi > network->stats.rssi) {
- char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
- strncpy(escaped,
- print_ssid(ssid, network->ssid, network->ssid_len),
- sizeof(escaped));
- IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded because "
- "'%s (%pM)' has a stronger signal.\n",
- escaped, network->bssid,
+ DECLARE_SSID_BUF(escaped);
+ IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded because '%s (%pM)' has a stronger signal\n",
+ print_ssid(escaped, network->ssid,
+ network->ssid_len),
+ network->bssid,
print_ssid(ssid, match->network->ssid,
match->network->ssid_len),
match->network->bssid);
^ permalink raw reply related
* Re: [PATCH 19/19] netfilter: gre: fix resource leak when unregister gre proto
From: Gao feng @ 2013-01-07 3:05 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel, netdev, canqunzhang, kaber, ebiederm
In-Reply-To: <50EA3A1F.8020108@cn.fujitsu.com>
On 01/07/13 10:59, Gao feng wrote:
> On 01/07/13 10:38, Pablo Neira Ayuso wrote:
>> On Mon, Jan 07, 2013 at 03:15:17AM +0100, Pablo Neira Ayuso wrote:
>>> Hi Gao,
>>>
>>> On Mon, Jan 07, 2013 at 09:27:37AM +0800, Gao feng wrote:
>>>> Hi Pablo,
>>>>
>>>> On 01/05/13 11:50, Pablo Neira Ayuso wrote:
>>>>> Hi Gao,
>>>>>
>>>>> On Fri, Dec 28, 2012 at 10:36:46AM +0800, Gao feng wrote:
>>>>>> Currectly we unregister proto before all conntrack entries of
>>>>>> this proto being destroyed. so in function destroy_conntrack
>>>>>> we can't find proper l4proto to call l4proto->destroy.
>>>>>> this will cause resource leak.
>>>>>
>>>>> Good catch.
>>>>>
>>>>> But better to remove the entries before unregistering the protocol
>>>>> tracker, so l4proto->destroy is always called.
>>>>>
>>>>
>>>> I think the reason we unregister proto before remove all entries
>>>> is to avoid new entry for this protocol being created.
>>>>
>>>> If we remove all contrack entries before unregistration, there maybe
>>>> some new entries being created between nf_ct_iterate_cleanup and
>>>> nf_conntrack_l4proto_unregister_net.this will cause some terrible things.
>>>
>>> Leaks are less likely to happen, but may well still happen while
>>> racing with protocol removal, agreed.
>>>
>>>> SO I think we should make proto unavailable first,remove all entries next,
>>>> and remove proto from nf_ct_protos arrays finally.
>>>
>>> Your proposal adds a branch in the packet path to fix an issue that is
>>> specific of the GRE protocol tracker. In the current code, this fixes
>>> the memory leak while removing the nf_conntrack_proto_gre module,
>>> which is a rare operation.
>>>
>>> We have to come with a less intrusive solution.
>>
>> Wait. The existing code is calling nf_ct_gre_keymap_flush in
>> proto_gre_net_exit path, so those keymap objects are not leaked.
>
> Agree, it looks like nf_ct_gre_keymap_flush is added to solve this
> problem.
>
> Please ignore this patch.
I mean ignore the codes of gre part.
I still think nf_ct_iterate_cleanup doesn't make sure all entries being
destroyed.
I will resend this patch.
Thanks!
^ permalink raw reply
* [PATCH v2 1/1 net-next] net: fec: report correct hardware stamping info to ethtool
From: Frank Li @ 2013-01-07 2:25 UTC (permalink / raw)
To: lznuaa, shawn.guo, richardcochran, davem, linux-arm-kernel,
netdev
Cc: s.hauer, Frank Li
Report correct hardware stamping capability by ethtool interface.
The v1.0 ptp4l check it.
Signed-off-by: Frank Li <Frank.Li@freescale.com>
---
Change v1->v2
1. s/capibilty/capability/
2. apply Sascha's feedback
avoid return the return value of ethtool_op_get_ts_info()
when bufdesc_ex == 1
drivers/net/ethernet/freescale/fec.c | 31 ++++++++++++++++++++++++++++++-
1 files changed, 30 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c
index a379319..1c117e5 100644
--- a/drivers/net/ethernet/freescale/fec.c
+++ b/drivers/net/ethernet/freescale/fec.c
@@ -1173,12 +1173,41 @@ static void fec_enet_get_drvinfo(struct net_device *ndev,
strcpy(info->bus_info, dev_name(&ndev->dev));
}
+static int fec_enet_get_ts_info(struct net_device *ndev,
+ struct ethtool_ts_info *info)
+{
+ struct fec_enet_private *fep = netdev_priv(ndev);
+
+ if (fep->bufdesc_ex) {
+
+ info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE |
+ SOF_TIMESTAMPING_RX_SOFTWARE |
+ SOF_TIMESTAMPING_SOFTWARE |
+ SOF_TIMESTAMPING_TX_HARDWARE |
+ SOF_TIMESTAMPING_RX_HARDWARE |
+ SOF_TIMESTAMPING_RAW_HARDWARE;
+ if (fep->ptp_clock)
+ info->phc_index = ptp_clock_index(fep->ptp_clock);
+ else
+ info->phc_index = -1;
+
+ info->tx_types = (1 << HWTSTAMP_TX_OFF) |
+ (1 << HWTSTAMP_TX_ON);
+
+ info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
+ (1 << HWTSTAMP_FILTER_ALL);
+ return 0;
+ } else {
+ return ethtool_op_get_ts_info(ndev, info);
+ }
+}
+
static const struct ethtool_ops fec_enet_ethtool_ops = {
.get_settings = fec_enet_get_settings,
.set_settings = fec_enet_set_settings,
.get_drvinfo = fec_enet_get_drvinfo,
.get_link = ethtool_op_get_link,
- .get_ts_info = ethtool_op_get_ts_info,
+ .get_ts_info = fec_enet_get_ts_info,
};
static int fec_enet_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
--
1.7.1
^ permalink raw reply related
* Re: [PATCH 19/19] netfilter: gre: fix resource leak when unregister gre proto
From: Gao feng @ 2013-01-07 2:59 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel, netdev, canqunzhang, kaber, ebiederm
In-Reply-To: <20130107023808.GA14431@1984>
On 01/07/13 10:38, Pablo Neira Ayuso wrote:
> On Mon, Jan 07, 2013 at 03:15:17AM +0100, Pablo Neira Ayuso wrote:
>> Hi Gao,
>>
>> On Mon, Jan 07, 2013 at 09:27:37AM +0800, Gao feng wrote:
>>> Hi Pablo,
>>>
>>> On 01/05/13 11:50, Pablo Neira Ayuso wrote:
>>>> Hi Gao,
>>>>
>>>> On Fri, Dec 28, 2012 at 10:36:46AM +0800, Gao feng wrote:
>>>>> Currectly we unregister proto before all conntrack entries of
>>>>> this proto being destroyed. so in function destroy_conntrack
>>>>> we can't find proper l4proto to call l4proto->destroy.
>>>>> this will cause resource leak.
>>>>
>>>> Good catch.
>>>>
>>>> But better to remove the entries before unregistering the protocol
>>>> tracker, so l4proto->destroy is always called.
>>>>
>>>
>>> I think the reason we unregister proto before remove all entries
>>> is to avoid new entry for this protocol being created.
>>>
>>> If we remove all contrack entries before unregistration, there maybe
>>> some new entries being created between nf_ct_iterate_cleanup and
>>> nf_conntrack_l4proto_unregister_net.this will cause some terrible things.
>>
>> Leaks are less likely to happen, but may well still happen while
>> racing with protocol removal, agreed.
>>
>>> SO I think we should make proto unavailable first,remove all entries next,
>>> and remove proto from nf_ct_protos arrays finally.
>>
>> Your proposal adds a branch in the packet path to fix an issue that is
>> specific of the GRE protocol tracker. In the current code, this fixes
>> the memory leak while removing the nf_conntrack_proto_gre module,
>> which is a rare operation.
>>
>> We have to come with a less intrusive solution.
>
> Wait. The existing code is calling nf_ct_gre_keymap_flush in
> proto_gre_net_exit path, so those keymap objects are not leaked.
Agree, it looks like nf_ct_gre_keymap_flush is added to solve this
problem.
Please ignore this patch.
Thanks!
^ permalink raw reply
* Re: [PATCH net-next v3 0/3] netpoll: add IPv6 support
From: Cong Wang @ 2013-01-07 2:58 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20130103.192041.782458185484678551.davem@davemloft.net>
On Thu, 2013-01-03 at 19:20 -0800, David Miller wrote:
> From: Cong Wang <amwang@redhat.com>
> Date: Fri, 4 Jan 2013 11:14:30 +0800
>
> > (Resend with a cover letter)
> >
> > v3: fix CONFIG_IPV6=m case
> >
> > v2: use bool for ipv6 flag
> > fix !CONFIG_IPV6 case
> >
> > This patchset implements netpoll over IPv6.
>
> Thanks for submitting this properly.
>
> But disallowing ipv6 netpoll support when IPV6=m is an unacceptable
> limitation, compiling IPV6 as a module is common and in fact
> recommended.
>
> We've solved problems like this before, by putting the needed ipv6
> routines into a seperate library that is built statically into the
> kernel when necessary.
>
> You should use a similar approach here.
Hmm, here we need ndisc_parse_options() and udp6_csum_init(). Not sure
if both can be inlined?
Thanks!
^ permalink raw reply
* Re: [PATCH] drivers/net/wireless/ipw2x00: use strlcpy instead of strncpy
From: Chen Gang F T @ 2013-01-07 2:57 UTC (permalink / raw)
To: Chen Gang
Cc: Joe Perches, stas.yakovlev-Re5JQEeQqe8AvxtiuMwx3w,
linville-2XuSBdqkA4R54TAoqtyWWQ,
linux-wireless-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <50EA37CE.1090901-bOixZGp5f+dBDgjK7y7TUQ@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 8770 bytes --]
于 2013年01月07日 10:49, Chen Gang 写道:
> 于 2013年01月05日 22:42, Joe Perches 写道:
>> This happens because escaped is declared the wrong size.
>>
>> It'd be better to change
>> char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
>> to
>> DECLARE_SSID_BUF(escaped);
>> and use
>> print_ssid(escaped, network->ssid, network->ssid_len)
>> in the debug.
>>
>
> if what you said is true:
> it is better to delete escaped variable
> use ssid instead of escaped, directly.
>
oh, sorry, it is my fault.
we need use duplicate buffer to print different contents, at the same time.
:-)
but I still suggest to keep original author using
maybe he intend to keep the print size for output format
so I think it is better to only fix bug, not touch the features.
Regards
gchen.
> but I think the original author intended to use escaped instead of ssid
> DECLARE_SSID_BUF(ssid) (line 5525, 5737)
> use ssid to print debug information directly
> (such as: line 5530..5535, 5545..5549, 5745..5749, ...)
> when need print additional information, use escaped
> (line 5559..5569, 5773..5782, 5791..5799)
>
> so, I still suggest:
> only fix the bug (use strlcpy instead of strncpy)
> and not touch original features which orignal author intended using.
>
> Regards
>
> gchen.
>
> in drivers/net/wireless/ipw2x00/ipw2200.c:
>
> 5519 static int ipw_find_adhoc_network(struct ipw_priv *priv,
> 5520 struct ipw_network_match *match,
> 5521 struct libipw_network *network,
> 5522 int roaming)
> 5523 {
> 5524 struct ipw_supported_rates rates;
> 5525 DECLARE_SSID_BUF(ssid);
> 5526
> 5527 /* Verify that this network's capability is compatible with the
> 5528 * current mode (AdHoc or Infrastructure) */
> 5529 if ((priv->ieee->iw_mode == IW_MODE_ADHOC &&
> 5530 !(network->capability & WLAN_CAPABILITY_IBSS))) {
> 5531 IPW_DEBUG_MERGE("Network '%s (%pM)' excluded due to "
> 5532 "capability mismatch.\n",
> 5533 print_ssid(ssid, network->ssid,
> 5534 network->ssid_len),
> 5535 network->bssid);
> 5536 return 0;
> 5537 }
> 5538
> 5539 if (unlikely(roaming)) {
> 5540 /* If we are roaming, then ensure check if this is a valid
> 5541 * network to try and roam to */
> 5542 if ((network->ssid_len != match->network->ssid_len) ||
> 5543 memcmp(network->ssid, match->network->ssid,
> 5544 network->ssid_len)) {
> 5545 IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
> 5546 "because of non-network ESSID.\n",
> 5547 print_ssid(ssid, network->ssid,
> 5548 network->ssid_len),
> 5549 network->bssid);
> 5550 return 0;
> 5551 }
> 5552 } else {
> 5553 /* If an ESSID has been configured then compare the broadcast
> 5554 * ESSID to ours */
> 5555 if ((priv->config & CFG_STATIC_ESSID) &&
> 5556 ((network->ssid_len != priv->essid_len) ||
> 5557 memcmp(network->ssid, priv->essid,
> 5558 min(network->ssid_len, priv->essid_len)))) {
> 5559 char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
> 5560
> 5561 strncpy(escaped,
> 5562 print_ssid(ssid, network->ssid,
> 5563 network->ssid_len),
> 5564 sizeof(escaped));
> 5565 IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
> 5566 "because of ESSID mismatch: '%s'.\n",
> 5567 escaped, network->bssid,
> 5568 print_ssid(ssid, priv->essid,
> 5569 priv->essid_len));
> 5570 return 0;
> 5571 }
> 5572 }
> ...
>
> 5732 static int ipw_best_network(struct ipw_priv *priv,
> 5733 struct ipw_network_match *match,
> 5734 struct libipw_network *network, int roaming)
> 5735 {
> 5736 struct ipw_supported_rates rates;
> 5737 DECLARE_SSID_BUF(ssid);
> 5738
> 5739 /* Verify that this network's capability is compatible with the
> 5740 * current mode (AdHoc or Infrastructure) */
> 5741 if ((priv->ieee->iw_mode == IW_MODE_INFRA &&
> 5742 !(network->capability & WLAN_CAPABILITY_ESS)) ||
> 5743 (priv->ieee->iw_mode == IW_MODE_ADHOC &&
> 5744 !(network->capability & WLAN_CAPABILITY_IBSS))) {
> 5745 IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded due to "
> 5746 "capability mismatch.\n",
> 5747 print_ssid(ssid, network->ssid,
> 5748 network->ssid_len),
> 5749 network->bssid);
> 5750 return 0;
> 5751 }
> 5752
> 5753 if (unlikely(roaming)) {
> 5754 /* If we are roaming, then ensure check if this is a valid
> 5755 * network to try and roam to */
> 5756 if ((network->ssid_len != match->network->ssid_len) ||
> 5757 memcmp(network->ssid, match->network->ssid,
> 5758 network->ssid_len)) {
> 5759 IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
> 5760 "because of non-network ESSID.\n",
> 5761 print_ssid(ssid, network->ssid,
> 5762 network->ssid_len),
> 5763 network->bssid);
> 5764 return 0;
> 5765 }
> 5766 } else {
> 5767 /* If an ESSID has been configured then compare the broadcast
> 5768 * ESSID to ours */
> 5769 if ((priv->config & CFG_STATIC_ESSID) &&
> 5770 ((network->ssid_len != priv->essid_len) ||
> 5771 memcmp(network->ssid, priv->essid,
> 5772 min(network->ssid_len, priv->essid_len)))) {
> 5773 char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
> 5774 strncpy(escaped,
> 5775 print_ssid(ssid, network->ssid,
> 5776 network->ssid_len),
> 5777 sizeof(escaped));
> 5778 IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
> 5779 "because of ESSID mismatch: '%s'.\n",
> 5780 escaped, network->bssid,
> 5781 print_ssid(ssid, priv->essid,
> 5782 priv->essid_len));
> 5783 return 0;
> 5784 }
> 5785 }
> 5786
> 5787 /* If the old network rate is better than this one, don't bother
> 5788 * testing everything else. */
> 5789 if (match->network && match->network->stats.rssi > network->stats.rssi) {
> 5790 char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
> 5791 strncpy(escaped,
> 5792 print_ssid(ssid, network->ssid, network->ssid_len),
> 5793 sizeof(escaped));
> 5794 IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded because "
> 5795 "'%s (%pM)' has a stronger signal.\n",
> 5796 escaped, network->bssid,
> 5797 print_ssid(ssid, match->network->ssid,
> 5798 match->network->ssid_len),
> 5799 match->network->bssid);
> 5800 return 0;
> 5801 }
>
--
Chen Gang
Flying Transformer
[-- Attachment #2: chen_gang_flying_transformer.vcf --]
[-- Type: text/x-vcard, Size: 67 bytes --]
begin:vcard
fn:Chen Gang
n:;Chen Gang
version:2.1
end:vcard
^ permalink raw reply
* Re: [PATCH] drivers/net/wireless/ipw2x00: use strlcpy instead of strncpy
From: Chen Gang @ 2013-01-07 2:49 UTC (permalink / raw)
To: Joe Perches; +Cc: stas.yakovlev, linville, linux-wireless, netdev
In-Reply-To: <1357396966.21156.4.camel@joe-AO722>
于 2013年01月05日 22:42, Joe Perches 写道:
> This happens because escaped is declared the wrong size.
>
> It'd be better to change
> char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
> to
> DECLARE_SSID_BUF(escaped);
> and use
> print_ssid(escaped, network->ssid, network->ssid_len)
> in the debug.
>
if what you said is true:
it is better to delete escaped variable
use ssid instead of escaped, directly.
but I think the original author intended to use escaped instead of ssid
DECLARE_SSID_BUF(ssid) (line 5525, 5737)
use ssid to print debug information directly
(such as: line 5530..5535, 5545..5549, 5745..5749, ...)
when need print additional information, use escaped
(line 5559..5569, 5773..5782, 5791..5799)
so, I still suggest:
only fix the bug (use strlcpy instead of strncpy)
and not touch original features which orignal author intended using.
Regards
gchen.
in drivers/net/wireless/ipw2x00/ipw2200.c:
5519 static int ipw_find_adhoc_network(struct ipw_priv *priv,
5520 struct ipw_network_match *match,
5521 struct libipw_network *network,
5522 int roaming)
5523 {
5524 struct ipw_supported_rates rates;
5525 DECLARE_SSID_BUF(ssid);
5526
5527 /* Verify that this network's capability is compatible with the
5528 * current mode (AdHoc or Infrastructure) */
5529 if ((priv->ieee->iw_mode == IW_MODE_ADHOC &&
5530 !(network->capability & WLAN_CAPABILITY_IBSS))) {
5531 IPW_DEBUG_MERGE("Network '%s (%pM)' excluded due to "
5532 "capability mismatch.\n",
5533 print_ssid(ssid, network->ssid,
5534 network->ssid_len),
5535 network->bssid);
5536 return 0;
5537 }
5538
5539 if (unlikely(roaming)) {
5540 /* If we are roaming, then ensure check if this is a valid
5541 * network to try and roam to */
5542 if ((network->ssid_len != match->network->ssid_len) ||
5543 memcmp(network->ssid, match->network->ssid,
5544 network->ssid_len)) {
5545 IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
5546 "because of non-network ESSID.\n",
5547 print_ssid(ssid, network->ssid,
5548 network->ssid_len),
5549 network->bssid);
5550 return 0;
5551 }
5552 } else {
5553 /* If an ESSID has been configured then compare the broadcast
5554 * ESSID to ours */
5555 if ((priv->config & CFG_STATIC_ESSID) &&
5556 ((network->ssid_len != priv->essid_len) ||
5557 memcmp(network->ssid, priv->essid,
5558 min(network->ssid_len, priv->essid_len)))) {
5559 char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
5560
5561 strncpy(escaped,
5562 print_ssid(ssid, network->ssid,
5563 network->ssid_len),
5564 sizeof(escaped));
5565 IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
5566 "because of ESSID mismatch: '%s'.\n",
5567 escaped, network->bssid,
5568 print_ssid(ssid, priv->essid,
5569 priv->essid_len));
5570 return 0;
5571 }
5572 }
...
5732 static int ipw_best_network(struct ipw_priv *priv,
5733 struct ipw_network_match *match,
5734 struct libipw_network *network, int roaming)
5735 {
5736 struct ipw_supported_rates rates;
5737 DECLARE_SSID_BUF(ssid);
5738
5739 /* Verify that this network's capability is compatible with the
5740 * current mode (AdHoc or Infrastructure) */
5741 if ((priv->ieee->iw_mode == IW_MODE_INFRA &&
5742 !(network->capability & WLAN_CAPABILITY_ESS)) ||
5743 (priv->ieee->iw_mode == IW_MODE_ADHOC &&
5744 !(network->capability & WLAN_CAPABILITY_IBSS))) {
5745 IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded due to "
5746 "capability mismatch.\n",
5747 print_ssid(ssid, network->ssid,
5748 network->ssid_len),
5749 network->bssid);
5750 return 0;
5751 }
5752
5753 if (unlikely(roaming)) {
5754 /* If we are roaming, then ensure check if this is a valid
5755 * network to try and roam to */
5756 if ((network->ssid_len != match->network->ssid_len) ||
5757 memcmp(network->ssid, match->network->ssid,
5758 network->ssid_len)) {
5759 IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
5760 "because of non-network ESSID.\n",
5761 print_ssid(ssid, network->ssid,
5762 network->ssid_len),
5763 network->bssid);
5764 return 0;
5765 }
5766 } else {
5767 /* If an ESSID has been configured then compare the broadcast
5768 * ESSID to ours */
5769 if ((priv->config & CFG_STATIC_ESSID) &&
5770 ((network->ssid_len != priv->essid_len) ||
5771 memcmp(network->ssid, priv->essid,
5772 min(network->ssid_len, priv->essid_len)))) {
5773 char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
5774 strncpy(escaped,
5775 print_ssid(ssid, network->ssid,
5776 network->ssid_len),
5777 sizeof(escaped));
5778 IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
5779 "because of ESSID mismatch: '%s'.\n",
5780 escaped, network->bssid,
5781 print_ssid(ssid, priv->essid,
5782 priv->essid_len));
5783 return 0;
5784 }
5785 }
5786
5787 /* If the old network rate is better than this one, don't bother
5788 * testing everything else. */
5789 if (match->network && match->network->stats.rssi > network->stats.rssi) {
5790 char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
5791 strncpy(escaped,
5792 print_ssid(ssid, network->ssid, network->ssid_len),
5793 sizeof(escaped));
5794 IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded because "
5795 "'%s (%pM)' has a stronger signal.\n",
5796 escaped, network->bssid,
5797 print_ssid(ssid, match->network->ssid,
5798 match->network->ssid_len),
5799 match->network->bssid);
5800 return 0;
5801 }
--
Chen Gang
Asianux Corporation
^ permalink raw reply
* Re: [PATCH 19/19] netfilter: gre: fix resource leak when unregister gre proto
From: Pablo Neira Ayuso @ 2013-01-07 2:38 UTC (permalink / raw)
To: Gao feng; +Cc: netfilter-devel, netdev, canqunzhang, kaber, ebiederm
In-Reply-To: <20130107021517.GA12215@1984>
On Mon, Jan 07, 2013 at 03:15:17AM +0100, Pablo Neira Ayuso wrote:
> Hi Gao,
>
> On Mon, Jan 07, 2013 at 09:27:37AM +0800, Gao feng wrote:
> > Hi Pablo,
> >
> > On 01/05/13 11:50, Pablo Neira Ayuso wrote:
> > > Hi Gao,
> > >
> > > On Fri, Dec 28, 2012 at 10:36:46AM +0800, Gao feng wrote:
> > >> Currectly we unregister proto before all conntrack entries of
> > >> this proto being destroyed. so in function destroy_conntrack
> > >> we can't find proper l4proto to call l4proto->destroy.
> > >> this will cause resource leak.
> > >
> > > Good catch.
> > >
> > > But better to remove the entries before unregistering the protocol
> > > tracker, so l4proto->destroy is always called.
> > >
> >
> > I think the reason we unregister proto before remove all entries
> > is to avoid new entry for this protocol being created.
> >
> > If we remove all contrack entries before unregistration, there maybe
> > some new entries being created between nf_ct_iterate_cleanup and
> > nf_conntrack_l4proto_unregister_net.this will cause some terrible things.
>
> Leaks are less likely to happen, but may well still happen while
> racing with protocol removal, agreed.
>
> > SO I think we should make proto unavailable first,remove all entries next,
> > and remove proto from nf_ct_protos arrays finally.
>
> Your proposal adds a branch in the packet path to fix an issue that is
> specific of the GRE protocol tracker. In the current code, this fixes
> the memory leak while removing the nf_conntrack_proto_gre module,
> which is a rare operation.
>
> We have to come with a less intrusive solution.
Wait. The existing code is calling nf_ct_gre_keymap_flush in
proto_gre_net_exit path, so those keymap objects are not leaked.
^ permalink raw reply
* Re: [PATCH 19/19] netfilter: gre: fix resource leak when unregister gre proto
From: Pablo Neira Ayuso @ 2013-01-07 2:15 UTC (permalink / raw)
To: Gao feng; +Cc: netfilter-devel, netdev, canqunzhang, kaber, ebiederm
In-Reply-To: <50EA2489.3070309@cn.fujitsu.com>
Hi Gao,
On Mon, Jan 07, 2013 at 09:27:37AM +0800, Gao feng wrote:
> Hi Pablo,
>
> On 01/05/13 11:50, Pablo Neira Ayuso wrote:
> > Hi Gao,
> >
> > On Fri, Dec 28, 2012 at 10:36:46AM +0800, Gao feng wrote:
> >> Currectly we unregister proto before all conntrack entries of
> >> this proto being destroyed. so in function destroy_conntrack
> >> we can't find proper l4proto to call l4proto->destroy.
> >> this will cause resource leak.
> >
> > Good catch.
> >
> > But better to remove the entries before unregistering the protocol
> > tracker, so l4proto->destroy is always called.
> >
>
> I think the reason we unregister proto before remove all entries
> is to avoid new entry for this protocol being created.
>
> If we remove all contrack entries before unregistration, there maybe
> some new entries being created between nf_ct_iterate_cleanup and
> nf_conntrack_l4proto_unregister_net.this will cause some terrible things.
Leaks are less likely to happen, but may well still happen while
racing with protocol removal, agreed.
> SO I think we should make proto unavailable first,remove all entries next,
> and remove proto from nf_ct_protos arrays finally.
Your proposal adds a branch in the packet path to fix an issue that is
specific of the GRE protocol tracker. In the current code, this fixes
the memory leak while removing the nf_conntrack_proto_gre module,
which is a rare operation.
We have to come with a less intrusive solution.
Regards.
^ permalink raw reply
* Re: [PATCH 19/19] netfilter: gre: fix resource leak when unregister gre proto
From: Gao feng @ 2013-01-07 1:27 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel, netdev, canqunzhang, kaber, ebiederm
In-Reply-To: <20130105035048.GA20027@1984>
Hi Pablo,
On 01/05/13 11:50, Pablo Neira Ayuso wrote:
> Hi Gao,
>
> On Fri, Dec 28, 2012 at 10:36:46AM +0800, Gao feng wrote:
>> Currectly we unregister proto before all conntrack entries of
>> this proto being destroyed. so in function destroy_conntrack
>> we can't find proper l4proto to call l4proto->destroy.
>> this will cause resource leak.
>
> Good catch.
>
> But better to remove the entries before unregistering the protocol
> tracker, so l4proto->destroy is always called.
>
I think the reason we unregister proto before remove all entries
is to avoid new entry for this protocol being created.
If we remove all contrack entries before unregistration, there maybe
some new entries being created between nf_ct_iterate_cleanup and
nf_conntrack_l4proto_unregister_net.this will cause some terrible things.
SO I think we should make proto unavailable first,remove all entries next,
and remove proto from nf_ct_protos arrays finally.
^ permalink raw reply
* [PATCH] chelsio: Use netdev_<level> and pr_<level>
From: Joe Perches @ 2013-01-06 23:34 UTC (permalink / raw)
To: Divy Le Ray, Dimitris Michailidis, Casey Leedom; +Cc: netdev, linux-kernel
Use more current logging styles.
Convert printks to pr_<level> and
printks with ("%s: ...", dev->name to netdev_<level>(dev, "...
Add pr_fmt #defines where appropriate.
Coalesce formats.
Use pr_<level>_once where appropriate.
Signed-off-by: Joe Perches <joe@perches.com>
---
drivers/net/ethernet/chelsio/cxgb/cxgb2.c | 28 +++++------
drivers/net/ethernet/chelsio/cxgb/sge.c | 6 +--
drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c | 42 ++++++++---------
drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c | 54 ++++++++++------------
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 2 +-
.../net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c | 23 ++++-----
6 files changed, 66 insertions(+), 89 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb/cxgb2.c b/drivers/net/ethernet/chelsio/cxgb/cxgb2.c
index c8fdeaa..20d2085 100644
--- a/drivers/net/ethernet/chelsio/cxgb/cxgb2.c
+++ b/drivers/net/ethernet/chelsio/cxgb/cxgb2.c
@@ -131,7 +131,7 @@ static void t1_set_rxmode(struct net_device *dev)
static void link_report(struct port_info *p)
{
if (!netif_carrier_ok(p->dev))
- printk(KERN_INFO "%s: link down\n", p->dev->name);
+ netdev_info(p->dev, "link down\n");
else {
const char *s = "10Mbps";
@@ -141,9 +141,9 @@ static void link_report(struct port_info *p)
case SPEED_100: s = "100Mbps"; break;
}
- printk(KERN_INFO "%s: link up, %s, %s-duplex\n",
- p->dev->name, s,
- p->link_config.duplex == DUPLEX_FULL ? "full" : "half");
+ netdev_info(p->dev, "link up, %s, %s-duplex\n",
+ s, p->link_config.duplex == DUPLEX_FULL
+ ? "full" : "half");
}
}
@@ -976,19 +976,13 @@ static const struct net_device_ops cxgb_netdev_ops = {
static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
- static int version_printed;
-
int i, err, pci_using_dac = 0;
unsigned long mmio_start, mmio_len;
const struct board_info *bi;
struct adapter *adapter = NULL;
struct port_info *pi;
- if (!version_printed) {
- printk(KERN_INFO "%s - version %s\n", DRV_DESCRIPTION,
- DRV_VERSION);
- ++version_printed;
- }
+ pr_info_once("%s - version %s\n", DRV_DESCRIPTION, DRV_VERSION);
err = pci_enable_device(pdev);
if (err)
@@ -1124,8 +1118,8 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
for (i = 0; i < bi->port_number; ++i) {
err = register_netdev(adapter->port[i].dev);
if (err)
- pr_warning("%s: cannot register net device %s, skipping\n",
- pci_name(pdev), adapter->port[i].dev->name);
+ pr_warn("%s: cannot register net device %s, skipping\n",
+ pci_name(pdev), adapter->port[i].dev->name);
else {
/*
* Change the name we use for messages to the name of
@@ -1143,10 +1137,10 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
goto out_release_adapter_res;
}
- printk(KERN_INFO "%s: %s (rev %d), %s %dMHz/%d-bit\n", adapter->name,
- bi->desc, adapter->params.chip_revision,
- adapter->params.pci.is_pcix ? "PCIX" : "PCI",
- adapter->params.pci.speed, adapter->params.pci.width);
+ pr_info("%s: %s (rev %d), %s %dMHz/%d-bit\n",
+ adapter->name, bi->desc, adapter->params.chip_revision,
+ adapter->params.pci.is_pcix ? "PCIX" : "PCI",
+ adapter->params.pci.speed, adapter->params.pci.width);
/*
* Set the T1B ASIC and memory clocks.
diff --git a/drivers/net/ethernet/chelsio/cxgb/sge.c b/drivers/net/ethernet/chelsio/cxgb/sge.c
index d84872e..4829769 100644
--- a/drivers/net/ethernet/chelsio/cxgb/sge.c
+++ b/drivers/net/ethernet/chelsio/cxgb/sge.c
@@ -1822,8 +1822,8 @@ netdev_tx_t t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
*/
if (unlikely(skb->len < ETH_HLEN ||
skb->len > dev->mtu + eth_hdr_len(skb->data))) {
- pr_debug("%s: packet size %d hdr %d mtu%d\n", dev->name,
- skb->len, eth_hdr_len(skb->data), dev->mtu);
+ netdev_dbg(dev, "packet size %d hdr %d mtu%d\n",
+ skb->len, eth_hdr_len(skb->data), dev->mtu);
dev_kfree_skb_any(skb);
return NETDEV_TX_OK;
}
@@ -1831,7 +1831,7 @@ netdev_tx_t t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (skb->ip_summed == CHECKSUM_PARTIAL &&
ip_hdr(skb)->protocol == IPPROTO_UDP) {
if (unlikely(skb_checksum_help(skb))) {
- pr_debug("%s: unable to do udp checksum\n", dev->name);
+ netdev_dbg(dev, "unable to do udp checksum\n");
dev_kfree_skb_any(skb);
return NETDEV_TX_OK;
}
diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
index f15ee32..2b5e621 100644
--- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
@@ -29,6 +29,9 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
@@ -153,7 +156,7 @@ struct workqueue_struct *cxgb3_wq;
static void link_report(struct net_device *dev)
{
if (!netif_carrier_ok(dev))
- printk(KERN_INFO "%s: link down\n", dev->name);
+ netdev_info(dev, "link down\n");
else {
const char *s = "10Mbps";
const struct port_info *p = netdev_priv(dev);
@@ -170,8 +173,9 @@ static void link_report(struct net_device *dev)
break;
}
- printk(KERN_INFO "%s: link up, %s, %s-duplex\n", dev->name, s,
- p->link_config.duplex == DUPLEX_FULL ? "full" : "half");
+ netdev_info(dev, "link up, %s, %s-duplex\n",
+ s, p->link_config.duplex == DUPLEX_FULL
+ ? "full" : "half");
}
}
@@ -318,10 +322,10 @@ void t3_os_phymod_changed(struct adapter *adap, int port_id)
const struct port_info *pi = netdev_priv(dev);
if (pi->phy.modtype == phy_modtype_none)
- printk(KERN_INFO "%s: PHY module unplugged\n", dev->name);
+ netdev_info(dev, "PHY module unplugged\n");
else
- printk(KERN_INFO "%s: %s PHY module inserted\n", dev->name,
- mod_str[pi->phy.modtype]);
+ netdev_info(dev, "%s PHY module inserted\n",
+ mod_str[pi->phy.modtype]);
}
static void cxgb_set_rxmode(struct net_device *dev)
@@ -1422,8 +1426,7 @@ static int cxgb_open(struct net_device *dev)
if (is_offload(adapter) && !ofld_disable) {
err = offload_open(dev);
if (err)
- printk(KERN_WARNING
- "Could not initialize offload capabilities\n");
+ pr_warn("Could not initialize offload capabilities\n");
}
netif_set_real_num_tx_queues(dev, pi->nqsets);
@@ -3132,14 +3135,13 @@ static void print_port_info(struct adapter *adap, const struct adapter_info *ai)
if (!test_bit(i, &adap->registered_device_map))
continue;
- printk(KERN_INFO "%s: %s %s %sNIC (rev %d) %s%s\n",
- dev->name, ai->desc, pi->phy.desc,
- is_offload(adap) ? "R" : "", adap->params.rev, buf,
- (adap->flags & USING_MSIX) ? " MSI-X" :
- (adap->flags & USING_MSI) ? " MSI" : "");
+ netdev_info(dev, "%s %s %sNIC (rev %d) %s%s\n",
+ ai->desc, pi->phy.desc,
+ is_offload(adap) ? "R" : "", adap->params.rev, buf,
+ (adap->flags & USING_MSIX) ? " MSI-X" :
+ (adap->flags & USING_MSI) ? " MSI" : "");
if (adap->name == dev->name && adap->params.vpd.mclk)
- printk(KERN_INFO
- "%s: %uMB CM, %uMB PMTX, %uMB PMRX, S/N: %s\n",
+ pr_info("%s: %uMB CM, %uMB PMTX, %uMB PMRX, S/N: %s\n",
adap->name, t3_mc7_size(&adap->cm) >> 20,
t3_mc7_size(&adap->pmtx) >> 20,
t3_mc7_size(&adap->pmrx) >> 20,
@@ -3177,24 +3179,18 @@ static void cxgb3_init_iscsi_mac(struct net_device *dev)
NETIF_F_IPV6_CSUM | NETIF_F_HIGHDMA)
static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
- static int version_printed;
-
int i, err, pci_using_dac = 0;
resource_size_t mmio_start, mmio_len;
const struct adapter_info *ai;
struct adapter *adapter = NULL;
struct port_info *pi;
- if (!version_printed) {
- printk(KERN_INFO "%s - version %s\n", DRV_DESC, DRV_VERSION);
- ++version_printed;
- }
+ pr_info_once("%s - version %s\n", DRV_DESC, DRV_VERSION);
if (!cxgb3_wq) {
cxgb3_wq = create_singlethread_workqueue(DRV_NAME);
if (!cxgb3_wq) {
- printk(KERN_ERR DRV_NAME
- ": cannot initialize work queue\n");
+ pr_err("cannot initialize work queue\n");
return -ENOMEM;
}
}
diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c
index 3f1f501..91d02eb 100644
--- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c
+++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c
@@ -30,6 +30,8 @@
* SOFTWARE.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/list.h>
#include <linux/slab.h>
#include <net/neighbour.h>
@@ -235,8 +237,7 @@ static int cxgb_ulp_iscsi_ctl(struct adapter *adapter, unsigned int req,
if ((val >> S_MAXRXDATA) != 0x3f60) {
val &= (M_RXCOALESCESIZE << S_RXCOALESCESIZE);
val |= V_MAXRXDATA(0x3f60);
- printk(KERN_INFO
- "%s, iscsi set MaxRxData to 16224 (0x%x).\n",
+ pr_info("%s, iscsi set MaxRxData to 16224 (0x%x)\n",
adapter->name, val);
t3_write_reg(adapter, A_TP_PARA_REG2, val);
}
@@ -256,8 +257,7 @@ static int cxgb_ulp_iscsi_ctl(struct adapter *adapter, unsigned int req,
for (i = 0; i < 4; i++)
val |= (uiip->pgsz_factor[i] & 0xF) << (8 * i);
if (val && (val != t3_read_reg(adapter, A_ULPRX_ISCSI_PSZ))) {
- printk(KERN_INFO
- "%s, setting iscsi pgsz 0x%x, %u,%u,%u,%u.\n",
+ pr_info("%s, setting iscsi pgsz 0x%x, %u,%u,%u,%u\n",
adapter->name, val, uiip->pgsz_factor[0],
uiip->pgsz_factor[1], uiip->pgsz_factor[2],
uiip->pgsz_factor[3]);
@@ -709,8 +709,7 @@ static int do_smt_write_rpl(struct t3cdev *dev, struct sk_buff *skb)
struct cpl_smt_write_rpl *rpl = cplhdr(skb);
if (rpl->status != CPL_ERR_NONE)
- printk(KERN_ERR
- "Unexpected SMT_WRITE_RPL status %u for entry %u\n",
+ pr_err("Unexpected SMT_WRITE_RPL status %u for entry %u\n",
rpl->status, GET_TID(rpl));
return CPL_RET_BUF_DONE;
@@ -721,8 +720,7 @@ static int do_l2t_write_rpl(struct t3cdev *dev, struct sk_buff *skb)
struct cpl_l2t_write_rpl *rpl = cplhdr(skb);
if (rpl->status != CPL_ERR_NONE)
- printk(KERN_ERR
- "Unexpected L2T_WRITE_RPL status %u for entry %u\n",
+ pr_err("Unexpected L2T_WRITE_RPL status %u for entry %u\n",
rpl->status, GET_TID(rpl));
return CPL_RET_BUF_DONE;
@@ -733,8 +731,7 @@ static int do_rte_write_rpl(struct t3cdev *dev, struct sk_buff *skb)
struct cpl_rte_write_rpl *rpl = cplhdr(skb);
if (rpl->status != CPL_ERR_NONE)
- printk(KERN_ERR
- "Unexpected RTE_WRITE_RPL status %u for entry %u\n",
+ pr_err("Unexpected RTE_WRITE_RPL status %u for entry %u\n",
rpl->status, GET_TID(rpl));
return CPL_RET_BUF_DONE;
@@ -754,7 +751,7 @@ static int do_act_open_rpl(struct t3cdev *dev, struct sk_buff *skb)
t3c_tid->
ctx);
} else {
- printk(KERN_ERR "%s: received clientless CPL command 0x%x\n",
+ pr_err("%s: received clientless CPL command 0x%x\n",
dev->name, CPL_ACT_OPEN_RPL);
return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG;
}
@@ -772,7 +769,7 @@ static int do_stid_rpl(struct t3cdev *dev, struct sk_buff *skb)
return t3c_tid->client->handlers[p->opcode] (dev, skb,
t3c_tid->ctx);
} else {
- printk(KERN_ERR "%s: received clientless CPL command 0x%x\n",
+ pr_err("%s: received clientless CPL command 0x%x\n",
dev->name, p->opcode);
return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG;
}
@@ -790,7 +787,7 @@ static int do_hwtid_rpl(struct t3cdev *dev, struct sk_buff *skb)
return t3c_tid->client->handlers[p->opcode]
(dev, skb, t3c_tid->ctx);
} else {
- printk(KERN_ERR "%s: received clientless CPL command 0x%x\n",
+ pr_err("%s: received clientless CPL command 0x%x\n",
dev->name, p->opcode);
return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG;
}
@@ -817,7 +814,7 @@ static int do_cr(struct t3cdev *dev, struct sk_buff *skb)
return t3c_tid->client->handlers[CPL_PASS_ACCEPT_REQ]
(dev, skb, t3c_tid->ctx);
} else {
- printk(KERN_ERR "%s: received clientless CPL command 0x%x\n",
+ pr_err("%s: received clientless CPL command 0x%x\n",
dev->name, CPL_PASS_ACCEPT_REQ);
return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG;
}
@@ -911,7 +908,7 @@ static int do_act_establish(struct t3cdev *dev, struct sk_buff *skb)
return t3c_tid->client->handlers[CPL_ACT_ESTABLISH]
(dev, skb, t3c_tid->ctx);
} else {
- printk(KERN_ERR "%s: received clientless CPL command 0x%x\n",
+ pr_err("%s: received clientless CPL command 0x%x\n",
dev->name, CPL_ACT_ESTABLISH);
return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG;
}
@@ -957,7 +954,7 @@ static int do_term(struct t3cdev *dev, struct sk_buff *skb)
return t3c_tid->client->handlers[opcode] (dev, skb,
t3c_tid->ctx);
} else {
- printk(KERN_ERR "%s: received clientless CPL command 0x%x\n",
+ pr_err("%s: received clientless CPL command 0x%x\n",
dev->name, opcode);
return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG;
}
@@ -994,8 +991,7 @@ static struct notifier_block nb = {
*/
static int do_bad_cpl(struct t3cdev *dev, struct sk_buff *skb)
{
- printk(KERN_ERR "%s: received bad CPL command 0x%x\n", dev->name,
- *skb->data);
+ pr_err("%s: received bad CPL command 0x%x\n", dev->name, *skb->data);
return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG;
}
@@ -1013,8 +1009,8 @@ void t3_register_cpl_handler(unsigned int opcode, cpl_handler_func h)
if (opcode < NUM_CPL_CMDS)
cpl_handlers[opcode] = h ? h : do_bad_cpl;
else
- printk(KERN_ERR "T3C: handler registration for "
- "opcode %x failed\n", opcode);
+ pr_err("T3C: handler registration for opcode %x failed\n",
+ opcode);
}
EXPORT_SYMBOL(t3_register_cpl_handler);
@@ -1033,9 +1029,8 @@ static int process_rx(struct t3cdev *dev, struct sk_buff **skbs, int n)
if (ret & CPL_RET_UNKNOWN_TID) {
union opcode_tid *p = cplhdr(skb);
- printk(KERN_ERR "%s: CPL message (opcode %u) had "
- "unknown TID %u\n", dev->name, opcode,
- G_TID(ntohl(p->opcode_tid)));
+ pr_err("%s: CPL message (opcode %u) had unknown TID %u\n",
+ dev->name, opcode, G_TID(ntohl(p->opcode_tid)));
}
#endif
if (ret & CPL_RET_BUF_DONE)
@@ -1099,7 +1094,7 @@ static void set_l2t_ix(struct t3cdev *tdev, u32 tid, struct l2t_entry *e)
skb = alloc_skb(sizeof(*req), GFP_ATOMIC);
if (!skb) {
- printk(KERN_ERR "%s: cannot allocate skb!\n", __func__);
+ pr_err("%s: cannot allocate skb!\n", __func__);
return;
}
skb->priority = CPL_PRIORITY_CONTROL;
@@ -1132,23 +1127,22 @@ static void cxgb_redirect(struct dst_entry *old, struct neighbour *old_neigh,
if (!is_offloading(olddev))
return;
if (!is_offloading(newdev)) {
- printk(KERN_WARNING "%s: Redirect to non-offload "
- "device ignored.\n", __func__);
+ pr_warn("%s: Redirect to non-offload device ignored\n",
+ __func__);
return;
}
tdev = dev2t3cdev(olddev);
BUG_ON(!tdev);
if (tdev != dev2t3cdev(newdev)) {
- printk(KERN_WARNING "%s: Redirect to different "
- "offload device ignored.\n", __func__);
+ pr_warn("%s: Redirect to different offload device ignored\n",
+ __func__);
return;
}
/* Add new L2T entry */
e = t3_l2t_get(tdev, new, newdev, daddr);
if (!e) {
- printk(KERN_ERR "%s: couldn't allocate new l2t entry!\n",
- __func__);
+ pr_err("%s: couldn't allocate new l2t entry!\n", __func__);
return;
}
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index f0718e1..aa63b66 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -5131,7 +5131,7 @@ static int __init cxgb4_init_module(void)
/* Debugfs support is optional, just warn if this fails */
cxgb4_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
if (!cxgb4_debugfs_root)
- pr_warning("could not create debugfs entry, continuing\n");
+ pr_warn("could not create debugfs entry, continuing\n");
ret = pci_register_driver(&cxgb4_driver);
if (ret < 0)
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
index 0188df7..56b46ab 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
@@ -33,6 +33,8 @@
* SOFTWARE.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
@@ -196,11 +198,10 @@ void t4vf_os_link_changed(struct adapter *adapter, int pidx, int link_ok)
break;
}
- printk(KERN_INFO "%s: link up, %s, full-duplex, %s PAUSE\n",
- dev->name, s, fc);
+ netdev_info(dev, "link up, %s, full-duplex, %s PAUSE\n", s, fc);
} else {
netif_carrier_off(dev);
- printk(KERN_INFO "%s: link down\n", dev->name);
+ netdev_info(dev, "link down\n");
}
}
@@ -2465,8 +2466,6 @@ static const struct net_device_ops cxgb4vf_netdev_ops = {
static int cxgb4vf_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
- static int version_printed;
-
int pci_using_dac;
int err, pidx;
unsigned int pmask;
@@ -2478,10 +2477,7 @@ static int cxgb4vf_pci_probe(struct pci_dev *pdev,
* Print our driver banner the first time we're called to initialize a
* device.
*/
- if (version_printed == 0) {
- printk(KERN_INFO "%s - version %s\n", DRV_DESC, DRV_VERSION);
- version_printed = 1;
- }
+ pr_info_once("%s - version %s\n", DRV_DESC, DRV_VERSION);
/*
* Initialize generic PCI device state.
@@ -2920,18 +2916,15 @@ static int __init cxgb4vf_module_init(void)
* Vet our module parameters.
*/
if (msi != MSI_MSIX && msi != MSI_MSI) {
- printk(KERN_WARNING KBUILD_MODNAME
- ": bad module parameter msi=%d; must be %d"
- " (MSI-X or MSI) or %d (MSI)\n",
- msi, MSI_MSIX, MSI_MSI);
+ pr_warn("bad module parameter msi=%d; must be %d (MSI-X or MSI) or %d (MSI)\n",
+ msi, MSI_MSIX, MSI_MSI);
return -EINVAL;
}
/* Debugfs support is optional, just warn if this fails */
cxgb4vf_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
if (IS_ERR_OR_NULL(cxgb4vf_debugfs_root))
- printk(KERN_WARNING KBUILD_MODNAME ": could not create"
- " debugfs entry, continuing\n");
+ pr_warn("could not create debugfs entry, continuing\n");
ret = pci_register_driver(&cxgb4vf_driver);
if (ret < 0 && !IS_ERR_OR_NULL(cxgb4vf_debugfs_root))
^ permalink raw reply related
* [patch net-next] ethtool: set addr_assign_type to NET_ADDR_SET when addr is passed on create
From: Jiri Pirko @ 2013-01-06 22:41 UTC (permalink / raw)
To: netdev; +Cc: davem, bhutchings, shemminger, sassmann
In case user passed address via netlink during create, NET_ADDR_PERM was set.
That is not correct so fix this by setting NET_ADDR_SET.
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
net/core/rtnetlink.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 9969afb..9a419b0 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1667,9 +1667,11 @@ struct net_device *rtnl_create_link(struct net *net,
if (tb[IFLA_MTU])
dev->mtu = nla_get_u32(tb[IFLA_MTU]);
- if (tb[IFLA_ADDRESS])
+ if (tb[IFLA_ADDRESS]) {
memcpy(dev->dev_addr, nla_data(tb[IFLA_ADDRESS]),
nla_len(tb[IFLA_ADDRESS]));
+ dev->addr_assign_type = NET_ADDR_SET;
+ }
if (tb[IFLA_BROADCAST])
memcpy(dev->broadcast, nla_data(tb[IFLA_BROADCAST]),
nla_len(tb[IFLA_BROADCAST]));
--
1.8.1
^ permalink raw reply related
* [patch net] ethtool: set addr_assign_type to NET_ADDR_SET when addr is passed on create
From: Jiri Pirko @ 2013-01-06 22:38 UTC (permalink / raw)
To: netdev; +Cc: davem, bhutchings, shemminger, sassmann
In case user passed address via netlink during create, NET_ADDR_PERM was set.
That is not correct so fix this by setting NET_ADDR_SET.
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
net/core/rtnetlink.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 9969afb..9a419b0 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1667,9 +1667,11 @@ struct net_device *rtnl_create_link(struct net *net,
if (tb[IFLA_MTU])
dev->mtu = nla_get_u32(tb[IFLA_MTU]);
- if (tb[IFLA_ADDRESS])
+ if (tb[IFLA_ADDRESS]) {
memcpy(dev->dev_addr, nla_data(tb[IFLA_ADDRESS]),
nla_len(tb[IFLA_ADDRESS]));
+ dev->addr_assign_type = NET_ADDR_SET;
+ }
if (tb[IFLA_BROADCAST])
memcpy(dev->broadcast, nla_data(tb[IFLA_BROADCAST]),
nla_len(tb[IFLA_BROADCAST]));
--
1.8.1
^ permalink raw reply related
* [PATCH 1/4 net-next] tg3: Add support for new 5762 ASIC
From: Michael Chan @ 2013-01-06 22:51 UTC (permalink / raw)
To: davem; +Cc: netdev, nsujir
Add basic support for 5762 which is a 57765_PLUS class device.
Signed-off-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/ethernet/broadcom/tg3.c | 91 +++++++++++++++++++++++++---------
drivers/net/ethernet/broadcom/tg3.h | 15 +++++-
2 files changed, 81 insertions(+), 25 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 78ea90c..01e3201 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -2632,6 +2632,9 @@ out:
tg3_writephy(tp, MII_TG3_FET_PTEST, 0x12);
}
+ if (tp->pci_chip_rev_id == CHIPREV_ID_5762_A0)
+ tg3_phydsp_write(tp, 0xffb, 0x4000);
+
tg3_phy_toggle_automdix(tp, 1);
tg3_phy_set_wirespeed(tp);
return 0;
@@ -4037,6 +4040,7 @@ static int tg3_phy_autoneg_cfg(struct tg3 *tp, u32 advertise, u32 flowctrl)
tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, val);
/* Fall through */
case ASIC_REV_5720:
+ case ASIC_REV_5762:
if (!tg3_phydsp_read(tp, MII_TG3_DSP_CH34TP2, &val))
tg3_phydsp_write(tp, MII_TG3_DSP_CH34TP2, val |
MII_TG3_DSP_CH34TP2_HIBW01);
@@ -5484,7 +5488,8 @@ static int tg3_setup_phy(struct tg3 *tp, int force_reset)
val = (2 << TX_LENGTHS_IPG_CRS_SHIFT) |
(6 << TX_LENGTHS_IPG_SHIFT);
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
val |= tr32(MAC_TX_LENGTHS) &
(TX_LENGTHS_JMB_FRM_LEN_MSK |
TX_LENGTHS_CNT_DWN_VAL_MSK);
@@ -8672,7 +8677,8 @@ static void tg3_rings_reset(struct tg3 *tp)
limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE * 16;
else if (tg3_flag(tp, 5717_PLUS))
limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE * 4;
- else if (tg3_flag(tp, 57765_CLASS))
+ else if (tg3_flag(tp, 57765_CLASS) ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE * 2;
else
limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE;
@@ -8689,6 +8695,7 @@ static void tg3_rings_reset(struct tg3 *tp)
else if (!tg3_flag(tp, 5705_PLUS))
limit = NIC_SRAM_RCV_RET_RCB + TG3_BDINFO_SIZE * 16;
else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762 ||
tg3_flag(tp, 57765_CLASS))
limit = NIC_SRAM_RCV_RET_RCB + TG3_BDINFO_SIZE * 4;
else
@@ -8979,9 +8986,12 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
/* Enable MAC control of LPI */
if (tp->phy_flags & TG3_PHYFLG_EEE_CAP) {
- tw32_f(TG3_CPMU_EEE_LNKIDL_CTRL,
- TG3_CPMU_EEE_LNKIDL_PCIE_NL0 |
- TG3_CPMU_EEE_LNKIDL_UART_IDL);
+ val = TG3_CPMU_EEE_LNKIDL_PCIE_NL0 |
+ TG3_CPMU_EEE_LNKIDL_UART_IDL;
+ if (tp->pci_chip_rev_id == CHIPREV_ID_57765_A0)
+ val |= TG3_CPMU_EEE_LNKIDL_APE_TX_MT;
+
+ tw32_f(TG3_CPMU_EEE_LNKIDL_CTRL, val);
tw32_f(TG3_CPMU_EEE_CTRL,
TG3_CPMU_EEE_CTRL_EXIT_20_1_US);
@@ -9156,7 +9166,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
if (tp->pci_chip_rev_id == CHIPREV_ID_57765_A0)
val &= ~DMA_RWCTRL_CRDRDR_RDMA_MRRS_MSK;
if (!tg3_flag(tp, 57765_CLASS) &&
- GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717)
+ GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717 &&
+ GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5762)
val |= DMA_RWCTRL_TAGGED_STAT_WA;
tw32(TG3PCI_DMA_RW_CTRL, val | tp->dma_rwctrl);
} else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5784 &&
@@ -9308,7 +9319,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_MAXLEN_FLAGS,
val | BDINFO_FLAGS_USE_EXT_RECV);
if (!tg3_flag(tp, USE_JUMBO_BDFLAG) ||
- tg3_flag(tp, 57765_CLASS))
+ tg3_flag(tp, 57765_CLASS) ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_NIC_ADDR,
NIC_SRAM_RX_JUMBO_BUFFER_DESC);
} else {
@@ -9350,7 +9362,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
(6 << TX_LENGTHS_IPG_SHIFT) |
(32 << TX_LENGTHS_SLOT_TIME_SHIFT);
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
val |= tr32(MAC_TX_LENGTHS) &
(TX_LENGTHS_JMB_FRM_LEN_MSK |
TX_LENGTHS_CNT_DWN_VAL_MSK);
@@ -9404,7 +9417,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
rdmac_mode |= RDMAC_MODE_IPV6_LSO_EN;
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
rdmac_mode |= tr32(RDMAC_MODE) & RDMAC_MODE_H2BNC_VLAN_DET;
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
@@ -9412,8 +9426,16 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
tg3_flag(tp, 57765_PLUS)) {
- val = tr32(TG3_RDMA_RSRVCTRL_REG);
- if (tp->pci_chip_rev_id == CHIPREV_ID_5719_A0) {
+ u32 tgtreg;
+
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
+ tgtreg = TG3_RDMA_RSRVCTRL_REG2;
+ else
+ tgtreg = TG3_RDMA_RSRVCTRL_REG;
+
+ val = tr32(tgtreg);
+ if (tp->pci_chip_rev_id == CHIPREV_ID_5719_A0 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762) {
val &= ~(TG3_RDMA_RSRVCTRL_TXMRGN_MASK |
TG3_RDMA_RSRVCTRL_FIFO_LWM_MASK |
TG3_RDMA_RSRVCTRL_FIFO_HWM_MASK);
@@ -9421,14 +9443,21 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
TG3_RDMA_RSRVCTRL_FIFO_LWM_1_5K |
TG3_RDMA_RSRVCTRL_FIFO_HWM_1_5K;
}
- tw32(TG3_RDMA_RSRVCTRL_REG,
- val | TG3_RDMA_RSRVCTRL_FIFO_OFLW_FIX);
+ tw32(tgtreg, val | TG3_RDMA_RSRVCTRL_FIFO_OFLW_FIX);
}
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) {
- val = tr32(TG3_LSO_RD_DMA_CRPTEN_CTRL);
- tw32(TG3_LSO_RD_DMA_CRPTEN_CTRL, val |
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762) {
+ u32 tgtreg;
+
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
+ tgtreg = TG3_LSO_RD_DMA_CRPTEN_CTRL2;
+ else
+ tgtreg = TG3_LSO_RD_DMA_CRPTEN_CTRL;
+
+ val = tr32(tgtreg);
+ tw32(tgtreg, val |
TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_BD_4K |
TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_LSO_4K);
}
@@ -9661,7 +9690,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
tp->tx_mode |= TX_MODE_MBUF_LOCKUP_FIX;
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) {
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762) {
val = TX_MODE_JMB_FRM_LEN | TX_MODE_CNT_DN_MODE;
tp->tx_mode &= ~val;
tp->tx_mode |= tr32(MAC_TX_MODE) & val;
@@ -12342,7 +12372,8 @@ static int tg3_test_memory(struct tg3 *tp)
if (tg3_flag(tp, 5717_PLUS))
mem_tbl = mem_tbl_5717;
- else if (tg3_flag(tp, 57765_CLASS))
+ else if (tg3_flag(tp, 57765_CLASS) ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
mem_tbl = mem_tbl_57765;
else if (tg3_flag(tp, 5755_PLUS))
mem_tbl = mem_tbl_5755;
@@ -14296,6 +14327,7 @@ static int tg3_phy_probe(struct tg3 *tp)
if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES) &&
(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762 ||
(tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 &&
tp->pci_chip_rev_id != CHIPREV_ID_5717_A0) ||
(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 &&
@@ -14785,7 +14817,10 @@ static void tg3_detect_asic_rev(struct tg3 *tp, u32 misc_ctrl_reg)
tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717_C ||
tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 ||
tp->pdev->device == TG3PCI_DEVICE_TIGON3_5719 ||
- tp->pdev->device == TG3PCI_DEVICE_TIGON3_5720)
+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5720 ||
+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5762 ||
+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5725 ||
+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5727)
reg = TG3PCI_GEN2_PRODID_ASICREV;
else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57781 ||
tp->pdev->device == TG3PCI_DEVICE_TIGON3_57785 ||
@@ -14822,7 +14857,8 @@ static void tg3_detect_asic_rev(struct tg3 *tp, u32 misc_ctrl_reg)
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57766)
tg3_flag_set(tp, 57765_CLASS);
- if (tg3_flag(tp, 57765_CLASS) || tg3_flag(tp, 5717_PLUS))
+ if (tg3_flag(tp, 57765_CLASS) || tg3_flag(tp, 5717_PLUS) ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
tg3_flag_set(tp, 57765_PLUS);
/* Intentionally exclude ASIC_REV_5906 */
@@ -15113,7 +15149,8 @@ static int tg3_get_invariants(struct tg3 *tp, const struct pci_device_id *ent)
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
tg3_flag_set(tp, LRG_PROD_RING_CAP);
if (tg3_flag(tp, 57765_PLUS) &&
@@ -15481,7 +15518,8 @@ static int tg3_get_invariants(struct tg3 *tp, const struct pci_device_id *ent)
/* Initialize data/descriptor byte/word swapping. */
val = tr32(GRC_MODE);
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
val &= (GRC_MODE_BYTE_SWAP_B2HRX_DATA |
GRC_MODE_WORD_SWAP_B2HRX_DATA |
GRC_MODE_B2HRX_ENABLE |
@@ -16238,6 +16276,7 @@ static char *tg3_phy_string(struct tg3 *tp)
case TG3_PHY_ID_BCM57765: return "57765";
case TG3_PHY_ID_BCM5719C: return "5719C";
case TG3_PHY_ID_BCM5720C: return "5720C";
+ case TG3_PHY_ID_BCM5762: return "5762C";
case TG3_PHY_ID_BCM8002: return "8002/serdes";
case 0: return "serdes";
default: return "unknown";
@@ -16413,7 +16452,10 @@ static int tg3_init_one(struct pci_dev *pdev,
tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717_C ||
tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 ||
tp->pdev->device == TG3PCI_DEVICE_TIGON3_5719 ||
- tp->pdev->device == TG3PCI_DEVICE_TIGON3_5720) {
+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5720 ||
+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5762 ||
+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5725 ||
+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5727) {
tg3_flag_set(tp, ENABLE_APE);
tp->aperegs = pci_ioremap_bar(pdev, BAR_2);
if (!tp->aperegs) {
@@ -16608,7 +16650,8 @@ static int tg3_init_one(struct pci_dev *pdev,
pci_set_drvdata(pdev, dev);
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
tg3_flag_set(tp, PTP_CAPABLE);
if (tg3_flag(tp, 5717_PLUS)) {
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h
index 247d954..46d43f7 100644
--- a/drivers/net/ethernet/broadcom/tg3.h
+++ b/drivers/net/ethernet/broadcom/tg3.h
@@ -65,6 +65,9 @@
#define TG3PCI_DEVICE_TIGON3_57766 0x1686
#define TG3PCI_DEVICE_TIGON3_57786 0x16b3
#define TG3PCI_DEVICE_TIGON3_57782 0x16b7
+#define TG3PCI_DEVICE_TIGON3_5762 0x1687
+#define TG3PCI_DEVICE_TIGON3_5725 0x1643
+#define TG3PCI_DEVICE_TIGON3_5727 0x16f3
/* 0x04 --> 0x2c unused */
#define TG3PCI_SUBVENDOR_ID_BROADCOM PCI_VENDOR_ID_BROADCOM
#define TG3PCI_SUBDEVICE_ID_BROADCOM_95700A6 0x1644
@@ -159,6 +162,7 @@
#define CHIPREV_ID_57765_A0 0x57785000
#define CHIPREV_ID_5719_A0 0x05719000
#define CHIPREV_ID_5720_A0 0x05720000
+#define CHIPREV_ID_5762_A0 0x05762000
#define GET_ASIC_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 12)
#define ASIC_REV_5700 0x07
#define ASIC_REV_5701 0x00
@@ -182,6 +186,7 @@
#define ASIC_REV_5719 0x5719
#define ASIC_REV_5720 0x5720
#define ASIC_REV_57766 0x57766
+#define ASIC_REV_5762 0x5762
#define GET_CHIP_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 8)
#define CHIPREV_5700_AX 0x70
#define CHIPREV_5700_BX 0x71
@@ -1178,6 +1183,7 @@
#define TG3_CPMU_EEE_LNKIDL_CTRL 0x000036bc
#define TG3_CPMU_EEE_LNKIDL_PCIE_NL0 0x01000000
#define TG3_CPMU_EEE_LNKIDL_UART_IDL 0x00000004
+#define TG3_CPMU_EEE_LNKIDL_APE_TX_MT 0x00000002
/* 0x36c0 --> 0x36d0 unused */
#define TG3_CPMU_EEE_CTRL 0x000036d0
@@ -1400,7 +1406,10 @@
#define RDMAC_STATUS_FIFOURUN 0x00000080
#define RDMAC_STATUS_FIFOOREAD 0x00000100
#define RDMAC_STATUS_LNGREAD 0x00000200
-/* 0x4808 --> 0x4900 unused */
+/* 0x4808 --> 0x4890 unused */
+
+#define TG3_RDMA_RSRVCTRL_REG2 0x00004890
+#define TG3_LSO_RD_DMA_CRPTEN_CTRL2 0x000048a0
#define TG3_RDMA_RSRVCTRL_REG 0x00004900
#define TG3_RDMA_RSRVCTRL_FIFO_OFLW_FIX 0x00000004
@@ -1910,6 +1919,8 @@
#define FLASH_5717VENDOR_ST_45USPT 0x03400001
#define FLASH_5720_EEPROM_HD 0x00000001
#define FLASH_5720_EEPROM_LD 0x00000003
+#define FLASH_5762_EEPROM_HD 0x02000001
+#define FLASH_5762_EEPROM_LD 0x02000003
#define FLASH_5720VENDOR_M_ATMEL_DB011D 0x01000000
#define FLASH_5720VENDOR_M_ATMEL_DB021D 0x01000002
#define FLASH_5720VENDOR_M_ATMEL_DB041D 0x01000001
@@ -3206,6 +3217,7 @@ struct tg3 {
#define TG3_PHY_ID_BCM57765 0x5c0d8a40
#define TG3_PHY_ID_BCM5719C 0x5c0d8a20
#define TG3_PHY_ID_BCM5720C 0x5c0d8b60
+#define TG3_PHY_ID_BCM5762 0x85803780
#define TG3_PHY_ID_BCM5906 0xdc00ac40
#define TG3_PHY_ID_BCM8002 0x60010140
#define TG3_PHY_ID_INVALID 0xffffffff
@@ -3230,6 +3242,7 @@ struct tg3 {
(X) == TG3_PHY_ID_BCM5906 || (X) == TG3_PHY_ID_BCM5761 || \
(X) == TG3_PHY_ID_BCM5718C || (X) == TG3_PHY_ID_BCM5718S || \
(X) == TG3_PHY_ID_BCM57765 || (X) == TG3_PHY_ID_BCM5719C || \
+ (X) == TG3_PHY_ID_BCM5720C || (X) == TG3_PHY_ID_BCM5762 || \
(X) == TG3_PHY_ID_BCM8002)
u32 phy_flags;
--
1.7.1
^ permalink raw reply related
* [PATCH 2/4 net-next] tg3: Add NVRAM support for 5762
From: Michael Chan @ 2013-01-06 22:51 UTC (permalink / raw)
To: davem; +Cc: netdev, nsujir
In-Reply-To: <1357512670-17636-1-git-send-email-mchan@broadcom.com>
Detect NVRAM types for 5762 and read OTP firmware version.
Signed-off-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/ethernet/broadcom/tg3.c | 96 ++++++++++++++++++++++++++++++++++-
drivers/net/ethernet/broadcom/tg3.h | 15 ++++++
2 files changed, 110 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 01e3201..6eab7d7 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -330,6 +330,9 @@ static DEFINE_PCI_DEVICE_TABLE(tg3_pci_tbl) = {
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5719)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5720)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57762)},
+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5762)},
+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5725)},
+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5727)},
{PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX)},
{PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX)},
{PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1000)},
@@ -13714,6 +13717,20 @@ static void tg3_get_5720_nvram_info(struct tg3 *tp)
nvcfg1 = tr32(NVRAM_CFG1);
nvmpinstrp = nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK;
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762) {
+ if (!(nvcfg1 & NVRAM_CFG1_5762VENDOR_MASK)) {
+ tg3_flag_set(tp, NO_NVRAM);
+ return;
+ }
+
+ switch (nvmpinstrp) {
+ case FLASH_5762_EEPROM_HD:
+ nvmpinstrp = FLASH_5720_EEPROM_HD;
+ case FLASH_5762_EEPROM_LD:
+ nvmpinstrp = FLASH_5720_EEPROM_LD;
+ }
+ }
+
switch (nvmpinstrp) {
case FLASH_5720_EEPROM_HD:
case FLASH_5720_EEPROM_LD:
@@ -13817,6 +13834,17 @@ static void tg3_get_5720_nvram_info(struct tg3 *tp)
tg3_nvram_get_pagesize(tp, nvcfg1);
if (tp->nvram_pagesize != 264 && tp->nvram_pagesize != 528)
tg3_flag_set(tp, NO_NVRAM_ADDR_TRANS);
+
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762) {
+ u32 val;
+
+ if (tg3_nvram_read(tp, 0, &val))
+ return;
+
+ if (val != TG3_EEPROM_MAGIC &&
+ (val & TG3_EEPROM_MAGIC_FW_MSK) != TG3_EEPROM_MAGIC_FW)
+ tg3_flag_set(tp, NO_NVRAM);
+ }
}
/* Chips other than 5700/5701 use the NVRAM for fetching info. */
@@ -13866,7 +13894,8 @@ static void tg3_nvram_init(struct tg3 *tp)
else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
tg3_get_5717_nvram_info(tp);
- else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+ else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
tg3_get_5720_nvram_info(tp);
else
tg3_get_nvram_info(tp);
@@ -14168,6 +14197,39 @@ done:
device_set_wakeup_capable(&tp->pdev->dev, false);
}
+static int tg3_ape_otp_read(struct tg3 *tp, u32 offset, u32 *val)
+{
+ int i, err;
+ u32 val2, off = offset * 8;
+
+ err = tg3_nvram_lock(tp);
+ if (err)
+ return err;
+
+ tg3_ape_write32(tp, TG3_APE_OTP_ADDR, off | APE_OTP_ADDR_CPU_ENABLE);
+ tg3_ape_write32(tp, TG3_APE_OTP_CTRL, APE_OTP_CTRL_PROG_EN |
+ APE_OTP_CTRL_CMD_RD | APE_OTP_CTRL_START);
+ tg3_ape_read32(tp, TG3_APE_OTP_CTRL);
+ udelay(10);
+
+ for (i = 0; i < 100; i++) {
+ val2 = tg3_ape_read32(tp, TG3_APE_OTP_STATUS);
+ if (val2 & APE_OTP_STATUS_CMD_DONE) {
+ *val = tg3_ape_read32(tp, TG3_APE_OTP_RD_DATA);
+ break;
+ }
+ udelay(10);
+ }
+
+ tg3_ape_write32(tp, TG3_APE_OTP_CTRL, 0);
+
+ tg3_nvram_unlock(tp);
+ if (val2 & APE_OTP_STATUS_CMD_DONE)
+ return 0;
+
+ return -EBUSY;
+}
+
static int tg3_issue_otp_command(struct tg3 *tp, u32 cmd)
{
int i;
@@ -14708,6 +14770,8 @@ static void tg3_read_dash_ver(struct tg3 *tp)
if (tg3_flag(tp, APE_HAS_NCSI))
fwtype = "NCSI";
+ else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5725)
+ fwtype = "SMASH";
else
fwtype = "DASH";
@@ -14721,6 +14785,31 @@ static void tg3_read_dash_ver(struct tg3 *tp)
(apedata & APE_FW_VERSION_BLDMSK));
}
+static void tg3_read_otp_ver(struct tg3 *tp)
+{
+ u32 val, val2;
+
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5762)
+ return;
+
+ if (!tg3_ape_otp_read(tp, OTP_ADDRESS_MAGIC0, &val) &&
+ !tg3_ape_otp_read(tp, OTP_ADDRESS_MAGIC0 + 4, &val2) &&
+ TG3_OTP_MAGIC0_VALID(val)) {
+ u64 val64 = (u64) val << 32 | val2;
+ u32 ver = 0;
+ int i, vlen;
+
+ for (i = 0; i < 7; i++) {
+ if ((val64 & 0xff) == 0)
+ break;
+ ver = val64 & 0xff;
+ val64 >>= 8;
+ }
+ vlen = strlen(tp->fw_ver);
+ snprintf(&tp->fw_ver[vlen], TG3_VER_SIZE - vlen, " .%02d", ver);
+ }
+}
+
static void tg3_read_fw_ver(struct tg3 *tp)
{
u32 val;
@@ -14731,6 +14820,7 @@ static void tg3_read_fw_ver(struct tg3 *tp)
if (tg3_flag(tp, NO_NVRAM)) {
strcat(tp->fw_ver, "sb");
+ tg3_read_otp_ver(tp);
return;
}
@@ -15428,6 +15518,10 @@ static int tg3_get_invariants(struct tg3 *tp, const struct pci_device_id *ent)
GRC_LCLCTRL_GPIO_OUTPUT0;
}
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
+ tp->grc_local_ctrl |=
+ tr32(GRC_LOCAL_CTRL) & GRC_LCLCTRL_GPIO_UART_SEL;
+
/* Switch out of Vaux if it is a NIC */
tg3_pwrsrc_switch_to_vmain(tp);
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h
index 46d43f7..39afc0e 100644
--- a/drivers/net/ethernet/broadcom/tg3.h
+++ b/drivers/net/ethernet/broadcom/tg3.h
@@ -1859,6 +1859,7 @@
#define FLASH_VENDOR_SST_SMALL 0x00000001
#define FLASH_VENDOR_SST_LARGE 0x02000001
#define NVRAM_CFG1_5752VENDOR_MASK 0x03c00003
+#define NVRAM_CFG1_5762VENDOR_MASK 0x03e00003
#define FLASH_5752VENDOR_ATMEL_EEPROM_64KHZ 0x00000000
#define FLASH_5752VENDOR_ATMEL_EEPROM_376KHZ 0x02000000
#define FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED 0x02000003
@@ -2376,6 +2377,20 @@
#define APE_LOCK_REQ_DRIVER 0x00001000
#define TG3_APE_LOCK_GRANT 0x004c
#define APE_LOCK_GRANT_DRIVER 0x00001000
+#define TG3_APE_OTP_CTRL 0x00e8
+#define APE_OTP_CTRL_PROG_EN 0x200000
+#define APE_OTP_CTRL_CMD_RD 0x000000
+#define APE_OTP_CTRL_START 0x000001
+#define TG3_APE_OTP_STATUS 0x00ec
+#define APE_OTP_STATUS_CMD_DONE 0x000001
+#define TG3_APE_OTP_ADDR 0x00f0
+#define APE_OTP_ADDR_CPU_ENABLE 0x80000000
+#define TG3_APE_OTP_RD_DATA 0x00f8
+
+#define OTP_ADDRESS_MAGIC0 0x00000050
+#define TG3_OTP_MAGIC0_VALID(val) \
+ ((((val) & 0xf0000000) == 0xa0000000) ||\
+ (((val) & 0x0f000000) == 0x0a000000))
/* APE shared memory. Accessible through BAR1 */
#define TG3_APE_SHMEM_BASE 0x4000
--
1.7.1
^ 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