* Re: [Ilw] drivers/net/wireless/iwlwifi/dvm/tx.c:456 iwlagn_tx_skb+0x6c5/0x883()
From: Sander Eikelenboom @ 2013-10-15 20:19 UTC (permalink / raw)
To: Grumbach, Emmanuel
Cc: John W. Linville, Berg, Johannes,
ilw-VuQAYsv1563Yd54FQh9/CA@public.gmane.org,
netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-wireless-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <0BA3FCBA62E2DC44AF3030971E174FB301DC4E24-yLYCJVCiOGwLt2AQoY/u9bfspsVTdybXVpNB7YpNyf8@public.gmane.org>
Tuesday, October 15, 2013, 9:11:36 PM, you wrote:
>> > Please apply this:
>> > diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c
>> b/drivers/net/wireless/iwlwifi/dvm/tx.c
>> > index d131f85..5968f19 100644
>> > --- a/drivers/net/wireless/iwlwifi/dvm/tx.c
>> > +++ b/drivers/net/wireless/iwlwifi/dvm/tx.c
>> > @@ -457,8 +457,8 @@ int iwlagn_tx_skb(struct iwl_priv *priv,
>> > WARN_ON_ONCE(is_agg &&
>> > priv->queue_to_mac80211[txq_id] != info->hw_queue);
>> >
>> > - IWL_DEBUG_TX(priv, "TX to [%d|%d] Q:%d - seq: 0x%x\n", sta_id, tid,
>> > - txq_id, seq_number);
>> > + IWL_DEBUG_TX(priv, "TX to [%d|%d] Q:%d info Q %d - seq: 0x%x\n",
>> sta_id, tid,
>> > + txq_id, info->hw_queue, seq_number);
>> >
>> > if (iwl_trans_tx(priv->trans, skb, dev_cmd, txq_id))
>> > goto drop_unlock_sta;
>>
>> > and send the output back to me
>>
>> > Thanks.
>>
> Can you please apply the patch attached (and remove the previous change)?
> Thanks.
That seems to make the warning go away :-)
[ 7.306696] iwlwifi 0000:02:00.0: L1 Disabled; Enabling L0S
[ 7.315790] iwlwifi 0000:02:00.0: Radio type=0x2-0x1-0x0
[ 7.362212] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 9 on FIFO 7 WrPtr: 0
[ 7.364973] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 0 on FIFO 3 WrPtr: 0
[ 7.365090] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 1 on FIFO 2 WrPtr: 0
[ 7.365208] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 2 on FIFO 1 WrPtr: 0
[ 7.365324] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 3 on FIFO 0 WrPtr: 0
[ 7.365440] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 4 on FIFO 0 WrPtr: 0
[ 7.365556] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 5 on FIFO 4 WrPtr: 0
[ 7.365672] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 6 on FIFO 2 WrPtr: 0
[ 7.365789] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 7 on FIFO 5 WrPtr: 0
[ 7.365905] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 8 on FIFO 4 WrPtr: 0
[ 7.366034] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 10 on FIFO 5 WrPtr: 0
[ 7.602726] iwlwifi 0000:02:00.0: L1 Disabled; Enabling L0S
[ 7.612133] iwlwifi 0000:02:00.0: Radio type=0x2-0x1-0x0
[ 7.658168] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 9 on FIFO 7 WrPtr: 0
[ 7.661021] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 0 on FIFO 3 WrPtr: 0
[ 7.663693] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 1 on FIFO 2 WrPtr: 0
[ 7.666341] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 2 on FIFO 1 WrPtr: 0
[ 7.668914] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 3 on FIFO 0 WrPtr: 0
[ 7.671464] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 4 on FIFO 0 WrPtr: 0
[ 7.673057] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 5 on FIFO 4 WrPtr: 0
[ 7.674631] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 6 on FIFO 2 WrPtr: 0
[ 7.676174] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 7 on FIFO 5 WrPtr: 0
[ 7.677657] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 8 on FIFO 4 WrPtr: 0
[ 7.679133] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 10 on FIFO 5 WrPtr: 0
[ 7.730037] device wlan0 entered promiscuous mode
[ 7.732390] xen_bridge: port 2(wlan0) entered forwarding state
[ 7.733984] xen_bridge: port 2(wlan0) entered forwarding state
[ 7.735692] cfg80211: Pending regulatory request, waiting for it to be processed...
[ 7.743541] iwlwifi 0000:02:00.0: I iwlagn_tx_skb TX to [14|8] Q:8 - seq: 0x0
[ 7.745347] device wlan0 left promiscuous mode
[ 7.747088] xen_bridge: port 2(wlan0) entered disabled state
[ 7.748034] iwlwifi 0000:02:00.0: I iwl_trans_pcie_reclaim [Q 8] 0 -> 1 (1)
[ 7.748039] iwlwifi 0000:02:00.0: I iwlagn_rx_reply_tx TXQ 8 status SUCCESS (0x00000201)
[ 7.748042] iwlwifi 0000:02:00.0: I iwlagn_rx_reply_tx initial_rate 0x820a retries 0, idx=0 ssn=1 seq_ctl=0x0
[ 7.769963] iwlwifi 0000:02:00.0: I iwl_pcie_txq_inc_wr_ptr Q:9 WR: 0x23
[ 7.821813] iwlwifi 0000:02:00.0: I iwl_pcie_txq_inc_wr_ptr Q:9 WR: 0x24
[ 7.824914] iwlwifi 0000:02:00.0: I iwl_pcie_txq_inc_wr_ptr Q:9 WR: 0x25
[ 7.828033] iwlwifi 0000:02:00.0: I iwl_pcie_txq_inc_wr_ptr Q:9 WR: 0x26
[ 7.831078] iwlwifi 0000:02:00.0: I iwl_pcie_txq_inc_wr_ptr Q:9 WR: 0x27
[ 7.834005] iwlwifi 0000:02:00.0: I iwl_pcie_txq_inc_wr_ptr Q:9 WR: 0x28
[ 7.836087] iwlwifi 0000:02:00.0: I iwl_pcie_txq_unmap Q 9 Free 39
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v4] net/hsr: Add support for the High-availability Seamless Redundancy protocol (HSRv0)
From: Arvid Brodin @ 2013-10-15 19:59 UTC (permalink / raw)
To: netdev
Cc: David Miller, shemminger, joe, jboticario, balferreira,
elias.molina, Arvid Brodin
In-Reply-To: <5249942F.3090504@xdin.com>
On 2013-09-30 17:09, Arvid Brodin wrote:
> On 2013-09-20 21:10, David Miller wrote:
>> From: Arvid Brodin <arvid.brodin@xdin.com>
>> Date: Thu, 19 Sep 2013 03:11:58 +0200
>>
>>> +#if !defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
>>> + /* We need to memmove the whole header to work around
>>> + * alignment problems caused by the 6-byte HSR tag.
>>> + */
>>> + memmove(skb_deliver->data - HSR_TAGLEN, skb_deliver->data,
>>> + skb_headlen(skb_deliver));
>>> + skb_deliver->data -= HSR_TAGLEN;
>>> + skb_deliver->tail -= HSR_TAGLEN;
>>> +#endif
>>
>> You can't do this.
>>
>> First of all, you have no idea if subtracting skb->data a given amount
>> will underflow the skb buffer start. You aren't even checking, all
>> of the standard skb_*() data adjustment interfaces do.
>
> (Shorter and more to the point than my previous replies:)
>
> I _do_ know: this can't possibly underflow since strip_hsr_tag() a
> few lines above pulled the same amount of data. I will rename
> strip_hsr_tag() to hsr_pull_tag() to make this clearer.
>
>
>> Secondly, everything after the header is now at the wrong offset from
>> the beginning of the packet.
>
> How does this matter? The memmove moves everything back (restores the
> changes made to the packet on the sending side) so that it is at the
> "normal" position for an ethernet packet.
>
Obviously, David is too busy to help me figure out what the problem is
(I know he reviews several thousand patches each year, so maybe that's
no wonder).
If anyone else has got an idea you are very welcome to chime in, and
perhaps we can solve this. I can't fix the problem if I don't understand
it.
On 2013-09-20 21:10, David Miller wrote:
> Secondly, everything after the header is now at the wrong offset from
> the beginning of the packet.
Maybe he's talking about systems with NET_SKBUFF_DATA_USES_OFFSET here?
This means the transport, network and mac headers are all relative to
skb->head, if I understand correctly. But at the point in the protocol
stack where this code is (the Ethernet protocol handler), the transport
and network headers have not been set yet, and the mac header is not
moved by the code. And tail is updated by the code. So that should not
be a problem?
--
Arvid Brodin | Consultant (Linux)
XDIN AB | Knarrarnäsgatan 7 | SE-164 40 Kista | Sweden | xdin.com
^ permalink raw reply
* Re: [PATCH 2/2] tcp: remove the sk_can_gso() check from tcp_set_skb_tso_segs()
From: Eric Dumazet @ 2013-10-15 19:44 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Neal Cardwell, Yuchung Cheng
In-Reply-To: <1381865094.2045.69.camel@edumazet-glaptop.roam.corp.google.com>
On Tue, 2013-10-15 at 12:24 -0700, Eric Dumazet wrote:
> From: Eric Dumazet <edumazet@google.com>
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Signed-off-by: Neal Cardwell <ncardwell@google.com>
> Signed-off-by: Yuchung Cheng <ycheng@google.com>
> ---
Reported-by: Maciej Żenczykowski <maze@google.com>
^ permalink raw reply
* Re: net/hsr Patch - Help
From: Arvid Brodin @ 2013-10-15 19:27 UTC (permalink / raw)
To: Elías Molina Muñoz
Cc: netdev@vger.kernel.org, Stephen Hemminger, Javier Boticario,
balferreira, Joe Perches
In-Reply-To: <525CF1F3.2050006@ehu.es>
On 2013-10-15 09:42, Elías Molina Muñoz wrote:
> El 09/09/2013 20:15, Arvid Brodin escribió:
>> On 2013-09-06 10:25, Elías Molina Muñoz wrote:
>>> Dear Mr. Brodin,
>>>
>>> I would like to introduce myself. My name is Elías Molina, PhD.
>>> Student at University of Basque Country (Spain). I am writing to
>>> enquire about your HSR patch.
>> Hi!
>>
>>> I have read "This is a patch against net-next (2013-08-21)" in
>>> its last version (v3) so I have tried with several kernel
>>> versions but I do not know which is the repo's correct version
>>> of
>>> http://git.kernel.org/cgit/linux/kernel/git/davem/net-next.git/
>>> .
>>>
>>> Could you tell me which is the kernel version to apply your
>>> patch?
>> I made an error when I sent that patch, so it won't apply to any
>> kernel version.
>>
>> The below patch should work (cd to the net-next directory and apply
>> with patch -Np1):
>>
[removed]
> Dear Mr. Brodin,
>
> Thanks for getting back to me and I apologize for being so late
> replying.
>
> I am writing to enquire if, once compiled the kernel with your patch,
> there is a sample application for verifying the correct operation of
> HSR, as you did in http://patchwork.ozlabs.org/patch/191165/ with
> Documentation/networking/hsr/hsr_genl.c
>
> Thank you very much. Best regards,
>
> Elías Molina
Hi again,
I'm CC:ing the netdev list and others who've shown interest in HSR, since
they might be interested as well.
Yes, I have patches for iproute2 (to make it possible to add HSR devices)
and also a "hsrinfo" program which can be used to query an HSR interface
for statistics, and to listen for any HSR errors detected. The hsrinfo
program is based on the hsr_genl program that you mention. It requires
the libnl3 library.
The hsrinfo program is below (the iproute2 patch was sent in a previous
message). This code is not of the same quality standards as you would
expect of a kernel/iproute2 patch. The idea is to re-write it so that it
becomes part of iproute2, but I won't spend time on that unless there is
some progress with the HSR kernel patch.
---
diff -Nurp hsrinfo-a/hsr_netlink.h hsrinfo-b/hsr_netlink.h
--- hsrinfo-a/hsr_netlink.h 1970-01-01 01:00:00.000000000 +0100
+++ hsrinfo-b/hsr_netlink.h 2013-10-15 21:21:09.058960618 +0200
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2011-2013 Autronica Fire and Security AS
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * Author(s):
+ * 2011-2013 Arvid Brodin, arvid.brodin@xdin.com
+ */
+
+#ifndef __HSR_NETLINK_H
+#define __HSR_NETLINK_H
+
+/* attributes */
+enum {
+ HSR_A_UNSPEC,
+ HSR_A_NODE_ADDR,
+ HSR_A_IFINDEX,
+ HSR_A_IF1_AGE,
+ HSR_A_IF2_AGE,
+ HSR_A_NODE_ADDR_B,
+ HSR_A_IF1_SEQ,
+ HSR_A_IF2_SEQ,
+ HSR_A_IF1_IFINDEX,
+ HSR_A_IF2_IFINDEX,
+ HSR_A_ADDR_B_IFINDEX,
+ __HSR_A_MAX,
+};
+#define HSR_A_MAX (__HSR_A_MAX - 1)
+
+
+#ifdef __KERNEL__
+
+#include <linux/if_ether.h>
+#include <linux/module.h>
+
+int __init hsr_netlink_init(void);
+void __exit hsr_netlink_exit(void);
+
+void hsr_nl_ringerror(unsigned char addr[ETH_ALEN], int dev_idx);
+void hsr_nl_nodedown(unsigned char addr[ETH_ALEN]);
+void hsr_nl_framedrop(int dropcount, int dev_idx);
+void hsr_nl_linkdown(int dev_idx);
+
+
+/*
+ * Generic Netlink HSR family definition
+ */
+
+
+#endif /* __KERNEL__ */
+
+
+
+/* commands */
+enum {
+ HSR_C_UNSPEC,
+ HSR_C_RING_ERROR,
+ HSR_C_NODE_DOWN,
+ HSR_C_GET_NODE_STATUS,
+ HSR_C_SET_NODE_STATUS,
+ HSR_C_GET_NODE_LIST,
+ HSR_C_SET_NODE_LIST,
+ __HSR_C_MAX,
+};
+#define HSR_C_MAX (__HSR_C_MAX - 1)
+
+
+
+#endif /* __HSR_NETLINK_H */
diff -Nurp hsrinfo-a/hsrinfo.c hsrinfo-b/hsrinfo.c
--- hsrinfo-a/hsrinfo.c 1970-01-01 01:00:00.000000000 +0100
+++ hsrinfo-b/hsrinfo.c 2013-10-15 21:23:32.983517217 +0200
@@ -0,0 +1,504 @@
+/*
+ * Copyright 2011-2013 Autronica Fire and Security AS
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * Author(s):
+ * 2011-2013 Arvid Brodin, arvid.brodin@xdin.com
+ *
+ * Userspace example of using Generic Netlink (through libnl-3) to get HSR
+ * ("High-availability Seamless Redundancy") link/network status.
+ */
+
+
+/*
+
+Manual static cross-build:
+
+$ PATH=[toolchain-path]/usr/bin/:${PATH} avr32-unknown-linux-uclibc-gcc -Wall -g -I[toolchain-path]/usr/include/libnl3 -static -L[toolchain-path]/usr/lib hsrinfo.c -o hsrinfo -lnl-genl-3 -lnl-3 -pthread -lm
+
+Native build:
+$ gcc -Wall -g -I /usr/include/libnl3/ -lnl-3 -lnl-genl-3 hsrinfo.c -o hsrinfo-x86
+
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <netlink/netlink.h>
+#include <netlink/socket.h>
+#include <netlink/attr.h>
+#include <netlink/genl/genl.h>
+#include <netlink/genl/ctrl.h>
+#include <net/if.h>
+#include <linux/if_ether.h>
+#include "hsr_netlink.h"
+
+struct node_item {
+ struct node_item *next;
+ unsigned char addr[ETH_ALEN];
+};
+
+static struct node_item *node_head = NULL;
+
+static int seq_nr = 10;
+
+
+static void nodelist_clear(struct node_item **ni)
+{
+ if (!*ni)
+ return;
+
+ nodelist_clear(&(*ni)->next);
+
+ free(*ni);
+ (*ni) = NULL;
+}
+
+static void nodelist_add(struct node_item **head, const char addr[ETH_ALEN])
+{
+ struct node_item **ni;
+
+ ni = head;
+ while (*ni)
+ ni = &(*ni)->next;
+
+ *ni = calloc(1, sizeof(struct node_item));
+ if (!*ni)
+ return; // No mem
+
+ memcpy((*ni)->addr, addr, ETH_ALEN);
+}
+
+
+static void print_mac(const unsigned char *addr)
+{
+ int i;
+
+ if (!addr) {
+ printf("(null) ");
+ return;
+ }
+
+ for (i = 0; i < ETH_ALEN - 1; i++)
+ printf("%02x:", addr[i]);
+ printf("%02x", addr[ETH_ALEN - 1]);
+}
+
+
+static void parse_ring_error(struct genlmsghdr *hdr)
+{
+ struct nlattr *attr;
+ unsigned char *AddrA;
+ int ifindex;
+ char ifname[IF_NAMESIZE];
+ char *nameptr;
+
+ printf("Ring error: ");
+
+ AddrA = NULL;
+ ifindex = -1;
+
+ attr = genlmsg_attrdata(hdr, 0);
+ int remaining = genlmsg_attrlen(hdr, 0);
+ while (nla_ok(attr, remaining)) {
+ switch (attr->nla_type) {
+ case HSR_A_NODE_ADDR:
+ AddrA = nla_data(attr);
+ break;
+ case HSR_A_IFINDEX:
+ ifindex = nla_get_u32(attr);
+ break;
+ default:
+ printf("unknown attribute type: %d\n", attr->nla_type);
+ }
+ attr = nla_next(attr, &remaining);
+ }
+
+ if (!AddrA) {
+ printf("Error: invalid HSR_C_RING_ERROR packet\n");
+ return;
+ }
+
+ nameptr = if_indextoname(ifindex, ifname);
+ if (!nameptr)
+ snprintf(ifname, IF_NAMESIZE, "if%d", ifindex);
+ printf("interface %s, node ", ifname);
+ print_mac(AddrA);
+ printf("\n");
+}
+
+static void parse_node_down(struct genlmsghdr *hdr)
+{
+ struct nlattr *attr;
+ unsigned char *AddrA;
+
+ printf("Node down: ");
+
+ AddrA = NULL;
+
+ attr = genlmsg_attrdata(hdr, 0);
+ int remaining = genlmsg_attrlen(hdr, 0);
+ while (nla_ok(attr, remaining)) {
+ switch (attr->nla_type) {
+ case HSR_A_NODE_ADDR:
+ AddrA = nla_data(attr);
+ break;
+ default:
+ printf("unknown attribute type: %d\n", attr->nla_type);
+ }
+ attr = nla_next(attr, &remaining);
+ }
+
+ if (!AddrA) {
+ printf("Error: invalid HSR_C_NODE_DOWN packet\n");
+ return;
+ }
+
+ print_mac(AddrA);
+ printf("\n");
+}
+
+static void parse_node_status(struct genlmsghdr *hdr)
+{
+ unsigned char *AddrA, *AddrB;
+ int if1_age, if2_age;
+ int if1_seq, if2_seq;
+ int if1_ifindex, if2_ifindex, addr_b_ifindex;
+ char if1_ifname[IF_NAMESIZE];
+ char if2_ifname[IF_NAMESIZE];
+ char addr_b_ifname[IF_NAMESIZE];
+ char *nameptr;
+ struct nlattr *attr;
+
+ AddrA = NULL;
+ AddrB = NULL;
+ if1_age = -1;
+ if2_age = -1;
+ if1_seq = -1;
+ if2_seq = -1;
+ if1_ifindex = -1;
+ if2_ifindex = -1;
+ addr_b_ifindex = -1;
+
+ attr = genlmsg_attrdata(hdr, 0);
+ int remaining = genlmsg_attrlen(hdr, 0);
+ while (nla_ok(attr, remaining)) {
+ switch (attr->nla_type) {
+ case HSR_A_NODE_ADDR:
+ if (AddrA)
+ printf("%s: Too many AddrA in message!\n", __func__);
+ AddrA = nla_data(attr);
+ break;
+ case HSR_A_NODE_ADDR_B:
+ if (AddrB)
+ printf("%s: Too many AddrB in message!\n", __func__);
+ AddrB = nla_data(attr);
+ break;
+ case HSR_A_IFINDEX:
+ break;
+ case HSR_A_IF1_AGE:
+ if1_age = (int) nla_get_u32(attr);
+ break;
+ case HSR_A_IF2_AGE:
+ if2_age = (int) nla_get_u32(attr);
+ break;
+ case HSR_A_IF1_SEQ:
+ if1_seq = nla_get_u16(attr);
+ break;
+ case HSR_A_IF2_SEQ:
+ if2_seq = nla_get_u16(attr);
+ break;
+ case HSR_A_IF1_IFINDEX:
+ if1_ifindex = nla_get_u32(attr);
+ break;
+ case HSR_A_IF2_IFINDEX:
+ if2_ifindex = nla_get_u32(attr);
+ break;
+ case HSR_A_ADDR_B_IFINDEX:
+ addr_b_ifindex = nla_get_u32(attr);
+ break;
+ default:
+ printf("%s: unknown attribute type: %d\n", __func__, attr->nla_type);
+ }
+ attr = nla_next(attr, &remaining);
+ }
+
+ if (!AddrA) {
+ printf("Error: invalid HSR_C_SET_NODE_STATUS packet\n");
+ return;
+ }
+
+ nameptr = if_indextoname(if1_ifindex, if1_ifname);
+ if (!nameptr)
+ snprintf(if1_ifname, IF_NAMESIZE, "if%d", if1_ifindex);
+ nameptr = if_indextoname(if2_ifindex, if2_ifname);
+ if (!nameptr)
+ snprintf(if2_ifname, IF_NAMESIZE, "if%d", if2_ifindex);
+ nameptr = if_indextoname(addr_b_ifindex, addr_b_ifname);
+ if (!nameptr)
+ snprintf(addr_b_ifname, IF_NAMESIZE, "if%d", addr_b_ifindex);
+
+ printf("Node: ");
+ print_mac(AddrA);
+ if (AddrB) {
+ printf(" AddrB: ");
+ print_mac(AddrB);
+ printf(" (over %s)", addr_b_ifname);
+ }
+ printf("\n Sequence nr (age): %s: %5d (%5d ms); %s: %5d (%5d ms)\n",
+ if1_ifname, if1_seq, if1_age,
+ if2_ifname, if2_seq, if2_age);
+}
+
+static void parse_node_list(struct genlmsghdr *hdr)
+{
+ struct nlattr *attr;
+
+ nodelist_clear(&node_head);
+
+ attr = genlmsg_attrdata(hdr, 0);
+ int remaining = genlmsg_attrlen(hdr, 0);
+ while (nla_ok(attr, remaining)) {
+ switch (attr->nla_type) {
+ case HSR_A_NODE_ADDR:
+ nodelist_add(&node_head, nla_data(attr));
+ break;
+ default:
+ printf("Unknown attribute type for HSR_C_SET_NODE_LIST: %d\n", attr->nla_type);
+ }
+ attr = nla_next(attr, &remaining);
+ }
+}
+
+
+static int parse_genlmsg(struct nl_msg *msg, void *arg)
+{
+ struct genlmsghdr *hdr;
+
+ /*
+ * Extract command ID from "message" -> "netlink header" ->
+ * "generic netlink header".
+ *
+ * These are the command enums used when creating a genl msg header
+ * in the kernel with genlmsg_put().
+ */
+ hdr = genlmsg_hdr(nlmsg_hdr(msg));
+
+// printf("%d: ", nlmsg_hdr(msg)->nlmsg_seq);
+ switch (hdr->cmd) {
+ case HSR_C_RING_ERROR:
+ parse_ring_error(hdr);
+ break;
+ case HSR_C_NODE_DOWN:
+ parse_node_down(hdr);
+ break;
+ case HSR_C_SET_NODE_STATUS:
+ parse_node_status(hdr);
+ break;
+ case HSR_C_SET_NODE_LIST:
+ parse_node_list(hdr);
+ break;
+ default:
+ printf("Unknown genl message received (%d)\n", hdr->cmd);
+ }
+
+ return 0;
+}
+
+
+static int query_get_node_status(struct nl_sock *nlsk, int family, int ifindex,
+ const unsigned char node_addr[ETH_ALEN])
+{
+ struct nl_msg *msg;
+ void *user_hdr;
+
+ msg = nlmsg_alloc();
+ if (!msg)
+ return -1;
+
+ user_hdr = genlmsg_put(msg, NL_AUTO_PORT, seq_nr++, family,
+ 0, NLM_F_REQUEST, HSR_C_GET_NODE_STATUS, 1);
+ if (!user_hdr)
+ goto nla_put_failure;
+
+ NLA_PUT_U32(msg, HSR_A_IFINDEX, ifindex);
+ NLA_PUT(msg, HSR_A_NODE_ADDR, ETH_ALEN, node_addr);
+
+/*
+ printf("Querying if %d for status of node ", ifindex);
+ print_mac(node_addr);
+ printf("\n");
+*/
+
+ return (nl_send_auto(nlsk, msg));
+
+nla_put_failure:
+ nlmsg_free(msg);
+ return -1;
+}
+
+
+static int query_get_node_list(struct nl_sock *nlsk, int family, int ifindex)
+{
+ struct nl_msg *msg;
+ void *user_hdr;
+
+ msg = nlmsg_alloc();
+ if (!msg)
+ return -1;
+
+ user_hdr = genlmsg_put(msg, NL_AUTO_PORT, seq_nr++, family,
+ 0, NLM_F_REQUEST, HSR_C_GET_NODE_LIST, 1);
+ if (!user_hdr)
+ goto nla_put_failure;
+
+ NLA_PUT_U32(msg, HSR_A_IFINDEX, ifindex);
+
+// printf("Querying if %d for node list\n", ifindex);
+
+ return (nl_send_auto(nlsk, msg));
+
+nla_put_failure:
+ nlmsg_free(msg);
+ return -1;
+}
+
+
+
+static void print_usage(const char *name)
+{
+ printf(
+"Usage: %s [-q] interface [node mac address]\n"
+"Display ring error messages for a HSR network interface, or\n"
+"(-q) query the interface node database. The node address parameter is only\n"
+"valid with -q, and limits the output to data about a specific node.\n", name);
+}
+
+
+static const char optstring[] = "+q";
+
+int main(int argc, char **argv)
+{
+ struct nl_sock *nlsk;
+ int hsr_mgroup;
+ int query;
+ int opt, rc;
+ int hsr_ifindex;
+ struct node_item *ni;
+
+ query = 0;
+ opt = getopt(argc, argv, optstring);
+ while (opt != -1) {
+ switch (opt) {
+ case 'q':
+ query = 1;
+ break;
+ default:
+ print_usage(argv[0]);
+ return EXIT_FAILURE;
+ }
+ opt = getopt(argc, argv, optstring);
+ }
+
+
+ nlsk = nl_socket_alloc();
+ if (!nlsk) {
+ printf("nl_socket_alloc() failed\n");
+ return EXIT_FAILURE;
+ }
+ nl_socket_modify_cb(nlsk, NL_CB_VALID, NL_CB_CUSTOM, parse_genlmsg, NULL);
+ genl_connect(nlsk);
+
+ /*
+ * Sign up for HSR messages
+ */
+ hsr_mgroup = genl_ctrl_resolve_grp(nlsk, "HSR", "hsr-network");
+ if (hsr_mgroup < 0) {
+ printf("genl_ctrl_resolve_grp() failed: %d\n", hsr_mgroup);
+ rc = EXIT_FAILURE;
+ goto out;
+ }
+
+ nl_socket_disable_seq_check(nlsk);
+
+ if (!query) {
+ if (argc - optind != 1) {
+ print_usage(argv[0]);
+ return EXIT_FAILURE;
+ }
+
+// printf("Registering for multicast group %d\n", hsr_mgroup);
+ rc = nl_socket_add_memberships(nlsk, hsr_mgroup, 0);
+ if (rc < 0) {
+ printf("nl_socket_add_memberships() failed: %d\n", rc);
+ goto out;
+ }
+
+ while (1)
+ nl_recvmsgs_default(nlsk);
+
+ /* Not reached */
+ }
+
+
+ if (argc - optind < 1) {
+ print_usage(argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ /* The hsr if we send the enquiry to (get it with e.g.
+ * 'cat /sys/class/net/hsr0/ifindex'): */
+ hsr_ifindex = if_nametoindex(argv[optind]);
+ if (hsr_ifindex == 0) {
+ printf("%s: %s\n", argv[optind], strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ /* Get node list */
+ int hsr_family;
+
+ hsr_family = genl_ctrl_resolve(nlsk, "HSR");
+ if (hsr_family < 0) {
+ printf("genl_ctrl_resolve() failed: %d\n", hsr_family);
+ goto out;
+ }
+
+ rc = query_get_node_list(nlsk, hsr_family, hsr_ifindex);
+// printf("query_get_node_list() returned %d\n", rc);
+
+ rc = nl_recvmsgs_default(nlsk);
+// printf("nl_recvmsgs_default() returned %d\n", rc);
+
+ ni = node_head;
+ while (ni) {
+ /*
+ * Send a query about the status of another node on the HSR network:
+ */
+ /* The node to enquire about: */
+ //const unsigned char node[ETH_ALEN] = {0x00, 0x24, 0x74, 0x00, 0x17, 0xAD};
+
+ rc = query_get_node_status(nlsk, hsr_family, hsr_ifindex, ni->addr);
+// printf("query_node_status() returned %d\n", rc);
+
+ ni = ni->next;
+ }
+
+ while (1) {
+ rc = nl_recvmsgs_default(nlsk);
+// printf("nl_recvmsgs_default() returned %d\n", rc);
+ }
+
+
+ rc = EXIT_SUCCESS;
+out:
+ nl_close(nlsk);
+ nl_socket_free(nlsk);
+ return rc;
+}
--
Arvid Brodin | Consultant (Linux)
XDIN AB | Knarrarnäsgatan 7 | SE-164 40 Kista | Sweden | xdin.com
^ permalink raw reply
* [PATCH 2/2] tcp: remove the sk_can_gso() check from tcp_set_skb_tso_segs()
From: Eric Dumazet @ 2013-10-15 19:24 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Neal Cardwell, Yuchung Cheng
From: Eric Dumazet <edumazet@google.com>
sk_can_gso() should only be used as a hint in tcp_sendmsg() to build GSO
packets in the first place. (As a performance hint)
Once we have GSO packets in write queue, we can not decide they are no
longer GSO only because flow now uses a route which doesn't handle
TSO/GSO.
Core networking stack handles the case very well for us, all we need
is keeping track of packet counts in MSS terms, regardless of
segmentation done later (in GSO or hardware)
Right now, if tcp_fragment() splits a GSO packet in two parts,
@left and @right, and route changed through a non GSO device,
both @left and @right have pcount set to 1, which is wrong,
and leads to incorrect packet_count tracking.
This problem was added in commit d5ac99a648 ("[TCP]: skb pcount with MTU
discovery")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Neal Cardwell <ncardwell@google.com>
Signed-off-by: Yuchung Cheng <ycheng@google.com>
---
net/ipv4/tcp_output.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 8fad1c1..d46f214 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -989,8 +989,7 @@ static void tcp_set_skb_tso_segs(const struct sock *sk, struct sk_buff *skb,
/* Make sure we own this skb before messing gso_size/gso_segs */
WARN_ON_ONCE(skb_cloned(skb));
- if (skb->len <= mss_now || !sk_can_gso(sk) ||
- skb->ip_summed == CHECKSUM_NONE) {
+ if (skb->len <= mss_now || skb->ip_summed == CHECKSUM_NONE) {
/* Avoid the costly divide in the normal
* non-TSO case.
*/
^ permalink raw reply related
* Re: [PATCH RFC 4/5] net: macb: Use devm_request_irq()
From: Sergei Shtylyov @ 2013-10-15 19:21 UTC (permalink / raw)
To: Soren Brinkmann; +Cc: Nicolas Ferre, netdev, linux-kernel, Michal Simek
In-Reply-To: <1381795140-10792-5-git-send-email-soren.brinkmann@xilinx.com>
Hello.
On 10/15/2013 03:58 AM, Soren Brinkmann wrote:
> Use the device managed interface to request the IRQ, simplifying error
> paths.
> Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com>
> ---
> drivers/net/ethernet/cadence/macb.c | 8 +++-----
> 1 file changed, 3 insertions(+), 5 deletions(-)
> diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
> index 436aecc31732..603844b1d483 100644
> --- a/drivers/net/ethernet/cadence/macb.c
> +++ b/drivers/net/ethernet/cadence/macb.c
> @@ -1825,7 +1825,8 @@ static int __init macb_probe(struct platform_device *pdev)
> }
>
> dev->irq = platform_get_irq(pdev, 0);
> - err = request_irq(dev->irq, macb_interrupt, 0, dev->name, dev);
> + err = devm_request_irq(&pdev->dev, dev->irq, macb_interrupt, 0,
> + dev->name, dev);
You should start the continuation line right under &.
WBR, Sergei
^ permalink raw reply
* Re: [PATCH] bridge: Correctly clamp MAX forward_delay when enabling STP
From: Veaceslav Falico @ 2013-10-15 19:17 UTC (permalink / raw)
To: Vlad Yasevich; +Cc: netdev, Herbert Xu, Stephen Hemminger
In-Reply-To: <1381863465-27304-1-git-send-email-vyasevic@redhat.com>
On Tue, Oct 15, 2013 at 02:57:45PM -0400, Vlad Yasevich wrote:
>Commit be4f154d5ef0ca147ab6bcd38857a774133f5450
> bridge: Clamp forward_delay when enabling STP
>had a typo when attempting to clamp maximum forward delay.
>
>It is possible to set bridge_forward_delay to be higher then
>permitted maximum when STP is off. When turning STP on, the
>higher then allowed delay has to be clamed down to max value.
>
>CC: Herbert Xu <herbert@gondor.apana.org.au>
>CC: Stephen Hemminger <shemminger@vyatta.com>
>Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
I think it should also be queued for stable, as it's present there also.
David, mind adding it?
As for the code - great catch!
Reviewed-by: Veaceslav Falico <vfalico@redhat.com>
>---
> net/bridge/br_stp_if.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
>diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c
>index 108084a..656a6f3 100644
>--- a/net/bridge/br_stp_if.c
>+++ b/net/bridge/br_stp_if.c
>@@ -134,7 +134,7 @@ static void br_stp_start(struct net_bridge *br)
>
> if (br->bridge_forward_delay < BR_MIN_FORWARD_DELAY)
> __br_set_forward_delay(br, BR_MIN_FORWARD_DELAY);
>- else if (br->bridge_forward_delay < BR_MAX_FORWARD_DELAY)
>+ else if (br->bridge_forward_delay > BR_MAX_FORWARD_DELAY)
> __br_set_forward_delay(br, BR_MAX_FORWARD_DELAY);
>
> if (r == 0) {
>--
>1.8.3.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
* RE: [Ilw] drivers/net/wireless/iwlwifi/dvm/tx.c:456 iwlagn_tx_skb+0x6c5/0x883()
From: Grumbach, Emmanuel @ 2013-10-15 19:11 UTC (permalink / raw)
To: Sander Eikelenboom
Cc: John W. Linville, Berg, Johannes, ilw@linux.intel.com,
netdev@vger.kernel.org, linux-wireless@vger.kernel.org
In-Reply-To: <1764863131.20131015210406@eikelenboom.it>
[-- Attachment #1: Type: text/plain, Size: 989 bytes --]
> > Please apply this:
> > diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c
> b/drivers/net/wireless/iwlwifi/dvm/tx.c
> > index d131f85..5968f19 100644
> > --- a/drivers/net/wireless/iwlwifi/dvm/tx.c
> > +++ b/drivers/net/wireless/iwlwifi/dvm/tx.c
> > @@ -457,8 +457,8 @@ int iwlagn_tx_skb(struct iwl_priv *priv,
> > WARN_ON_ONCE(is_agg &&
> > priv->queue_to_mac80211[txq_id] != info->hw_queue);
> >
> > - IWL_DEBUG_TX(priv, "TX to [%d|%d] Q:%d - seq: 0x%x\n", sta_id, tid,
> > - txq_id, seq_number);
> > + IWL_DEBUG_TX(priv, "TX to [%d|%d] Q:%d info Q %d - seq: 0x%x\n",
> sta_id, tid,
> > + txq_id, info->hw_queue, seq_number);
> >
> > if (iwl_trans_tx(priv->trans, skb, dev_cmd, txq_id))
> > goto drop_unlock_sta;
>
> > and send the output back to me
>
> > Thanks.
>
Can you please apply the patch attached (and remove the previous change)?
Thanks.
[-- Attachment #2: 0001-iwlwifi-dvm-don-t-override-mac80211-s-queue-setting.patch --]
[-- Type: application/octet-stream, Size: 1902 bytes --]
From fdda79b24213483034cd9a173bd1b078309cb4b9 Mon Sep 17 00:00:00 2001
From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Date: Tue, 15 Oct 2013 22:04:54 +0300
Subject: [PATCH] iwlwifi: dvm: don't override mac80211's queue setting
Since we set IEEE80211_HW_QUEUE_CONTROL, we can let
mac80211 do the queue assignement and don't need to
override its decisions.
This is true for offchannel packets, packets to be sent
after DTIM, but not for AMPDUs since we have a special
queue for them. So for AMPDU, we still override
info->hw_queue by the AMPDU queue.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
---
drivers/net/wireless/iwlwifi/dvm/tx.c | 14 +++-----------
1 file changed, 3 insertions(+), 11 deletions(-)
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c
index d131f85..86196a5 100644
--- a/drivers/net/wireless/iwlwifi/dvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/dvm/tx.c
@@ -433,27 +433,19 @@ int iwlagn_tx_skb(struct iwl_priv *priv,
/* Copy MAC header from skb into command buffer */
memcpy(tx_cmd->hdr, hdr, hdr_len);
+ txq_id = info->hw_queue;
+
if (is_agg)
txq_id = priv->tid_data[sta_id][tid].agg.txq_id;
else if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
/*
- * Send this frame after DTIM -- there's a special queue
- * reserved for this for contexts that support AP mode.
- */
- txq_id = ctx->mcast_queue;
-
- /*
* The microcode will clear the more data
* bit in the last frame it transmits.
*/
hdr->frame_control |=
cpu_to_le16(IEEE80211_FCTL_MOREDATA);
- } else if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN)
- txq_id = IWL_AUX_QUEUE;
- else
- txq_id = ctx->ac_to_queue[skb_get_queue_mapping(skb)];
+ }
- WARN_ON_ONCE(!is_agg && txq_id != info->hw_queue);
WARN_ON_ONCE(is_agg &&
priv->queue_to_mac80211[txq_id] != info->hw_queue);
--
1.8.1.msysgit.1
^ permalink raw reply related
* Re: net/hsr Patch - Help
From: Arvid Brodin @ 2013-10-15 19:09 UTC (permalink / raw)
To: Elías Molina Muñoz
Cc: netdev@vger.kernel.org, Stephen Hemminger, Javier Boticario,
balferreira, Joe Perches
In-Reply-To: <525CF1F3.2050006@ehu.es>
On 2013-10-15 09:42, Elías Molina Muñoz wrote:
> El 09/09/2013 20:15, Arvid Brodin escribió:
>> On 2013-09-06 10:25, Elías Molina Muñoz wrote:
>>> Dear Mr. Brodin,
>>>
>>> I would like to introduce myself. My name is Elías Molina, PhD.
>>> Student at University of Basque Country (Spain). I am writing to
>>> enquire about your HSR patch.
>> Hi!
>>
>>> I have read "This is a patch against net-next (2013-08-21)" in
>>> its last version (v3) so I have tried with several kernel
>>> versions but I do not know which is the repo's correct version
>>> of
>>> http://git.kernel.org/cgit/linux/kernel/git/davem/net-next.git/
>>> .
>>>
>>> Could you tell me which is the kernel version to apply your
>>> patch?
>> I made an error when I sent that patch, so it won't apply to any
>> kernel version.
>>
>> The below patch should work (cd to the net-next directory and apply
>> with patch -Np1):
>>
[removed]
> Dear Mr. Brodin,
>
> Thanks for getting back to me and I apologize for being so late
> replying.
>
> I am writing to enquire if, once compiled the kernel with your patch,
> there is a sample application for verifying the correct operation of
> HSR, as you did in http://patchwork.ozlabs.org/patch/191165/ with
> Documentation/networking/hsr/hsr_genl.c
>
> Thank you very much. Best regards,
>
> Elías Molina
Hi again,
I'm CC:ing the netdev list and others who've shown interest in HSR, since
they might be interested as well.
Yes, I have patches for iproute2 (to make it possible to add HSR devices)
and also a "hsrinfo" program which can be used to query an HSR interface
for statistics, and to listen for any HSR errors detected. The hsrinfo
program is based on the hsr_genl program that you mention. It requires
the libnl3 library.
The iproute patch is below (I'll send a separate message with the hsrinfo
code).
(I don't think the patch below will get accepted into iproute2 before
the HSR patch itself is accepted into the kernel - which I'm beginning to
doubt it ever will be, unfortunately.)
This patch adds support to iproute2 for adding High-Availability Seamless
Redundancy (HSR) network devices.
Signed-off-by: Arvid Brodin <arvid.brodin@xdin.com>
---
include/linux/if_link.h | 12 +++++++
ip/Makefile | 2 +-
ip/iplink_hsr.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 99 insertions(+), 1 deletion(-)
create mode 100644 ip/iplink_hsr.c
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index d07aeca..bab39e8 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -465,4 +465,16 @@ enum {
#define IFLA_IPOIB_MAX (__IFLA_IPOIB_MAX - 1)
+/* HSR section */
+
+enum {
+ IFLA_HSR_UNSPEC,
+ IFLA_HSR_SLAVE1,
+ IFLA_HSR_SLAVE2,
+ IFLA_HSR_MULTICAST_SPEC,
+ __IFLA_HSR_MAX,
+};
+
+#define IFLA_HSR_MAX (__IFLA_HSR_MAX - 1)
+
#endif /* _LINUX_IF_LINK_H */
diff --git a/ip/Makefile b/ip/Makefile
index 48bd4a1..5ef1562 100644
--- a/ip/Makefile
+++ b/ip/Makefile
@@ -5,7 +5,7 @@ IPOBJ=ip.o ipaddress.o ipaddrlabel.o iproute.o iprule.o ipnetns.o \
iplink_vlan.o link_veth.o link_gre.o iplink_can.o \
iplink_macvlan.o iplink_macvtap.o ipl2tp.o link_vti.o \
iplink_vxlan.o tcp_metrics.o iplink_ipoib.o ipnetconf.o link_ip6tnl.o \
- link_iptnl.o
+ link_iptnl.o iplink_hsr.o
RTMONOBJ=rtmon.o
diff --git a/ip/iplink_hsr.c b/ip/iplink_hsr.c
new file mode 100644
index 0000000..c7c00d6
--- /dev/null
+++ b/ip/iplink_hsr.c
@@ -0,0 +1,86 @@
+/*
+ * iplink_hsr.c HSR device support
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Authors: Arvid Brodin <arvid.brodin@xdin.com>
+ *
+ * Based on iplink_vlan.c by Patrick McHardy <kaber@trash.net>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h> /* Needed by linux/if.h for some reason */
+#include <linux/if.h>
+
+#include "utils.h"
+#include "ip_common.h"
+
+static void usage(void)
+{
+ fprintf(stderr,
+"Usage:\tip link add name NAME type hsr slave1 SLAVE1-IF slave2 SLAVE2-IF\n"
+"\t[ multicast ADDR-BYTE ]\n"
+"\n"
+"NAME\n"
+" name of new hsr device (e.g. hsr0)\n"
+"SLAVE1-IF, SLAVE2-IF\n"
+" the two slave devices bound to the HSR device\n"
+"ADDR-BYTE\n"
+" 0-255; the last byte of the multicast address used for HSR supervision\n"
+" frames (default = 0)\n");
+}
+
+static int hsr_parse_opt(struct link_util *lu, int argc, char **argv,
+ struct nlmsghdr *n)
+{
+ int ifindex;
+ unsigned char multicast_spec;
+
+ while (argc > 0) {
+ if (matches(*argv, "multicast") == 0) {
+ NEXT_ARG();
+ if (get_u8(&multicast_spec, *argv, 0))
+ invarg("ADDR-BYTE is invalid", *argv);
+ addattr_l(n, 1024, IFLA_HSR_MULTICAST_SPEC, &multicast_spec, 1);
+ } else if (matches(*argv, "slave1") == 0) {
+ NEXT_ARG();
+ ifindex = ll_name_to_index(*argv);
+ if (ifindex == 0)
+ invarg("No such interface", *argv);
+ addattr_l(n, 1024, IFLA_HSR_SLAVE1, &ifindex, 4);
+ } else if (matches(*argv, "slave2") == 0) {
+ NEXT_ARG();
+ ifindex = ll_name_to_index(*argv);
+ if (ifindex == 0)
+ invarg("No such interface", *argv);
+ addattr_l(n, 1024, IFLA_HSR_SLAVE2, &ifindex, 4);
+ } else if (matches(*argv, "help") == 0) {
+ usage();
+ return -1;
+ } else {
+ fprintf(stderr, "hsr: what is \"%s\"?\n", *argv);
+ usage();
+ return -1;
+ }
+ argc--, argv++;
+ }
+
+ return 0;
+}
+
+static void hsr_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
+{
+ fprintf(f, "hsr_print_opt() called\n");
+}
+
+struct link_util hsr_link_util = {
+ .id = "hsr",
+ .maxattr = IFLA_VLAN_MAX,
+ .parse_opt = hsr_parse_opt,
+ .print_opt = hsr_print_opt,
+};
--
1.8.1.5
--
Arvid Brodin | Consultant (Linux)
XDIN AB | Knarrarnäsgatan 7 | SE-164 40 Kista | Sweden | xdin.com
^ permalink raw reply related
* Re: [PATCH 14/18] net: usb: use wrapper functions of net_ratelimit() to simplify code
From: Sergei Shtylyov @ 2013-10-15 19:06 UTC (permalink / raw)
To: Kefeng Wang
Cc: linux-kernel, Greg Kroah-Hartman, David S. Miller,
Pablo Neira Ayuso, Stephen Hemminger, Johannes Berg,
John W. Linville, Stanislaw Gruszka, Johannes Berg,
Francois Romieu, Ben Hutchings, Chas Williams, Marc Kleine-Budde,
Samuel Ortiz, Paul Mackerras, Oliver Neukum,
Konrad Rzeszutek Wilk, Boris Ostrovsky, David Vrabel,
Rusty Russell, Michael S. Tsirkin, netfilter
In-Reply-To: <1381837514-50660-15-git-send-email-wangkefeng.wang@huawei.com>
Hello.
On 10/15/2013 03:45 PM, Kefeng Wang wrote:
> net_ratelimited_function() is called to simplify code.
> Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
> ---
> drivers/net/usb/usbnet.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
> diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
> index bf94e10..edf81de 100644
> --- a/drivers/net/usb/usbnet.c
> +++ b/drivers/net/usb/usbnet.c
> @@ -450,8 +450,8 @@ void usbnet_defer_kevent (struct usbnet *dev, int work)
> {
> set_bit (work, &dev->flags);
> if (!schedule_work (&dev->kevent)) {
> - if (net_ratelimit())
> - netdev_err(dev->net, "kevent %d may have been dropped\n", work);
> + net_ratelimited_function(netdev_err, dev->net,
> + "kevent %d may have been dropped\n", work);
The continuation line should start under 'netdev_err'. Same about the
other patches where you didn't change the indentation of the continuation
lines though you should have.
WBR, Sergei
^ permalink raw reply
* Re: [Ilw] drivers/net/wireless/iwlwifi/dvm/tx.c:456 iwlagn_tx_skb+0x6c5/0x883()
From: Sander Eikelenboom @ 2013-10-15 19:04 UTC (permalink / raw)
To: Grumbach, Emmanuel
Cc: John W. Linville, Berg, Johannes, ilw@linux.intel.com,
netdev@vger.kernel.org, linux-wireless@vger.kernel.org
In-Reply-To: <0BA3FCBA62E2DC44AF3030971E174FB301DC4AB7@HASMSX103.ger.corp.intel.com>
Tuesday, October 15, 2013, 3:35:30 PM, you wrote:
> Please apply this:
> diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c
> index d131f85..5968f19 100644
> --- a/drivers/net/wireless/iwlwifi/dvm/tx.c
> +++ b/drivers/net/wireless/iwlwifi/dvm/tx.c
> @@ -457,8 +457,8 @@ int iwlagn_tx_skb(struct iwl_priv *priv,
> WARN_ON_ONCE(is_agg &&
> priv->queue_to_mac80211[txq_id] != info->hw_queue);
>
> - IWL_DEBUG_TX(priv, "TX to [%d|%d] Q:%d - seq: 0x%x\n", sta_id, tid,
> - txq_id, seq_number);
> + IWL_DEBUG_TX(priv, "TX to [%d|%d] Q:%d info Q %d - seq: 0x%x\n", sta_id, tid,
> + txq_id, info->hw_queue, seq_number);
>
> if (iwl_trans_tx(priv->trans, skb, dev_cmd, txq_id))
> goto drop_unlock_sta;
> and send the output back to me
> Thanks.
With the patch i get:
That results in:
[ 7.154856] iwlwifi 0000:02:00.0: L1 Disabled; Enabling L0S
[ 7.163961] iwlwifi 0000:02:00.0: Radio type=0x2-0x1-0x0
[ 7.210395] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 9 on FIFO 7 WrPtr: 0
[ 7.213319] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 0 on FIFO 3 WrPtr: 0
[ 7.216195] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 1 on FIFO 2 WrPtr: 0
[ 7.218927] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 2 on FIFO 1 WrPtr: 0
[ 7.221531] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 3 on FIFO 0 WrPtr: 0
[ 7.224168] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 4 on FIFO 0 WrPtr: 0
[ 7.226768] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 5 on FIFO 4 WrPtr: 0
[ 7.229150] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 6 on FIFO 2 WrPtr: 0
[ 7.231449] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 7 on FIFO 5 WrPtr: 0
[ 7.235266] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 8 on FIFO 4 WrPtr: 0
[ 7.237399] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 10 on FIFO 5 WrPtr: 0
[ 7.474222] iwlwifi 0000:02:00.0: L1 Disabled; Enabling L0S
[ 7.485102] iwlwifi 0000:02:00.0: Radio type=0x2-0x1-0x0
[ 7.534296] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 9 on FIFO 7 WrPtr: 0
[ 7.538506] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 0 on FIFO 3 WrPtr: 0
[ 7.542438] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 1 on FIFO 2 WrPtr: 0
[ 7.546288] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 2 on FIFO 1 WrPtr: 0
[ 7.549720] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 3 on FIFO 0 WrPtr: 0
[ 7.553037] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 4 on FIFO 0 WrPtr: 0
[ 7.556308] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 5 on FIFO 4 WrPtr: 0
[ 7.559539] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 6 on FIFO 2 WrPtr: 0
[ 7.562506] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 7 on FIFO 5 WrPtr: 0
[ 7.565350] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 8 on FIFO 4 WrPtr: 0
[ 7.568098] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 10 on FIFO 5 WrPtr: 0
[ 7.614245] device wlan0 entered promiscuous mode
[ 7.616548] xen_bridge: port 2(wlan0) entered forwarding state
[ 7.618444] xen_bridge: port 2(wlan0) entered forwarding state
[ 7.620040] cfg80211: Pending regulatory request, waiting for it to be processed...
[ 7.630139] ------------[ cut here ]------------
[ 7.631729] WARNING: CPU: 2 PID: 2438 at drivers/net/wireless/iwlwifi/dvm/tx.c:456 iwlagn_tx_skb+0x776/0x981()
[ 7.633206] Modules linked in: acpi_cpufreq
[ 7.634693] CPU: 2 PID: 2438 Comm: hostapd Not tainted 3.12.0-rc5+ #1
[ 7.636529] Hardware name: /D53427RKE, BIOS RKPPT10H.86A.0017.2013.0425.1251 04/25/2013
[ 7.638385] 0000000000000000 0000000000000009 ffffffff818a8082 0000000000000000
[ 7.640163] ffffffff8105a4f2 0000000000000000 ffffffff815f440a ffff8800d736dec0
[ 7.641827] ffff8800d6cf9790 ffff8800d736dec0 0000000000000007 0000000000000000
[ 7.643295] Call Trace:
[ 7.644708] [<ffffffff818a8082>] ? dump_stack+0x41/0x51
[ 7.646187] [<ffffffff8105a4f2>] ? warn_slowpath_common+0x78/0x90
[ 7.647877] [<ffffffff815f440a>] ? iwlagn_tx_skb+0x776/0x981
[ 7.649587] [<ffffffff815f440a>] ? iwlagn_tx_skb+0x776/0x981
[ 7.651188] [<ffffffff815f2407>] ? iwlagn_mac_tx+0x19/0x30
[ 7.652993] [<ffffffff8187a261>] ? __ieee80211_tx+0x226/0x29b
[ 7.654661] [<ffffffff8187bcd9>] ? ieee80211_tx+0xa6/0xb5
[ 7.656409] [<ffffffff8187bfa7>] ? ieee80211_monitor_start_xmit+0x1e9/0x204
[ 7.658237] [<ffffffff8172e1f3>] ? dev_hard_start_xmit+0x271/0x3ec
[ 7.659800] [<ffffffff81746540>] ? sch_direct_xmit+0x66/0x164
[ 7.661362] [<ffffffff8172e553>] ? dev_queue_xmit+0x1e5/0x3c8
[ 7.663062] [<ffffffff8180bfee>] ? packet_sendmsg+0xac5/0xb3d
[ 7.664683] [<ffffffff8171ad9d>] ? sock_sendmsg+0x37/0x52
[ 7.664686] [<ffffffff810f9e0c>] ? __do_fault+0x338/0x36b
[ 7.664688] [<ffffffff81724bb4>] ? verify_iovec+0x44/0x94
[ 7.664690] [<ffffffff8171b1f7>] ? ___sys_sendmsg+0x1f1/0x283
[ 7.664693] [<ffffffff81140a73>] ? __inode_wait_for_writeback+0x67/0xae
[ 7.664694] [<ffffffff8111735e>] ? __cache_free.isra.46+0x178/0x187
[ 7.664696] [<ffffffff811173b1>] ? kmem_cache_free+0x44/0x84
[ 7.664698] [<ffffffff81132c22>] ? dentry_kill+0x13d/0x149
[ 7.664699] [<ffffffff81132f6f>] ? dput+0xe5/0xef
[ 7.664701] [<ffffffff81136e04>] ? fget_light+0x2e/0x7c
[ 7.664702] [<ffffffff8171c1f6>] ? __sys_sendmsg+0x39/0x57
[ 7.664705] [<ffffffff818b5e39>] ? system_call_fastpath+0x16/0x1b
[ 7.664707] ---[ end trace 6723715cfa72062a ]---
[ 7.664711] iwlwifi 0000:02:00.0: I iwlagn_tx_skb TX to [14|8] Q:7 info Q 8 - seq: 0x0
[ 7.665934] device wlan0 left promiscuous mode
[ 7.665941] xen_bridge: port 2(wlan0) entered disabled state
[ 7.667656] iwlwifi 0000:02:00.0: I iwl_trans_pcie_reclaim [Q 7] 0 -> 1 (1)
[ 7.667661] iwlwifi 0000:02:00.0: I iwlagn_rx_reply_tx TXQ 7 status SUCCESS (0x00000201)
[ 7.667664] iwlwifi 0000:02:00.0: I iwlagn_rx_reply_tx initial_rate 0x820a retries 0, idx=0 ssn=1 seq_ctl=0x0
[ 7.699446] iwlwifi 0000:02:00.0: I iwl_pcie_txq_inc_wr_ptr Q:9 WR: 0x23
[ 7.738105] iwlwifi 0000:02:00.0: I iwl_pcie_txq_inc_wr_ptr Q:9 WR: 0x24
[ 7.741555] iwlwifi 0000:02:00.0: I iwl_pcie_txq_inc_wr_ptr Q:9 WR: 0x25
[ 7.744882] iwlwifi 0000:02:00.0: I iwl_pcie_txq_inc_wr_ptr Q:9 WR: 0x26
[ 7.748108] iwlwifi 0000:02:00.0: I iwl_pcie_txq_inc_wr_ptr Q:9 WR: 0x27
[ 7.751367] iwlwifi 0000:02:00.0: I iwl_pcie_txq_inc_wr_ptr Q:9 WR: 0x28
[ 7.753309] iwlwifi 0000:02:00.0: I iwl_pcie_txq_unmap Q 9 Free 39
^ permalink raw reply
* [PATCH] bridge: Correctly clamp MAX forward_delay when enabling STP
From: Vlad Yasevich @ 2013-10-15 18:57 UTC (permalink / raw)
To: netdev; +Cc: Vlad Yasevich, Herbert Xu, Stephen Hemminger
Commit be4f154d5ef0ca147ab6bcd38857a774133f5450
bridge: Clamp forward_delay when enabling STP
had a typo when attempting to clamp maximum forward delay.
It is possible to set bridge_forward_delay to be higher then
permitted maximum when STP is off. When turning STP on, the
higher then allowed delay has to be clamed down to max value.
CC: Herbert Xu <herbert@gondor.apana.org.au>
CC: Stephen Hemminger <shemminger@vyatta.com>
Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
---
net/bridge/br_stp_if.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c
index 108084a..656a6f3 100644
--- a/net/bridge/br_stp_if.c
+++ b/net/bridge/br_stp_if.c
@@ -134,7 +134,7 @@ static void br_stp_start(struct net_bridge *br)
if (br->bridge_forward_delay < BR_MIN_FORWARD_DELAY)
__br_set_forward_delay(br, BR_MIN_FORWARD_DELAY);
- else if (br->bridge_forward_delay < BR_MAX_FORWARD_DELAY)
+ else if (br->bridge_forward_delay > BR_MAX_FORWARD_DELAY)
__br_set_forward_delay(br, BR_MAX_FORWARD_DELAY);
if (r == 0) {
--
1.8.3.1
^ permalink raw reply related
* [PATCH 1/2] tcp: must unclone packets before mangling them
From: Eric Dumazet @ 2013-10-15 18:54 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Neal Cardwell, Yuchung Cheng
From: Eric Dumazet <edumazet@google.com>
TCP stack should make sure it owns skbs before mangling them.
We had various crashes using bnx2x, and it turned out gso_size
was cleared right before bnx2x driver was populating TC descriptor
of the _previous_ packet send. TCP stack can sometime retransmit
packets that are still in Qdisc.
Of course we could make bnx2x driver more robust (using
ACCESS_ONCE(shinfo->gso_size) for example), but the bug is TCP stack.
We have identified two points where skb_unclone() was needed.
This patch adds a WARN_ON_ONCE() to warn us if we missed another
fix of this kind.
Kudos to Neal for finding the root cause of this bug. Its visible
using small MSS.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Neal Cardwell <ncardwell@google.com>
Cc: Yuchung Cheng <ycheng@google.com>
---
net/ipv4/tcp_output.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index c6f01f2..8fad1c1 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -986,6 +986,9 @@ static void tcp_queue_skb(struct sock *sk, struct sk_buff *skb)
static void tcp_set_skb_tso_segs(const struct sock *sk, struct sk_buff *skb,
unsigned int mss_now)
{
+ /* Make sure we own this skb before messing gso_size/gso_segs */
+ WARN_ON_ONCE(skb_cloned(skb));
+
if (skb->len <= mss_now || !sk_can_gso(sk) ||
skb->ip_summed == CHECKSUM_NONE) {
/* Avoid the costly divide in the normal
@@ -1067,9 +1070,7 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len,
if (nsize < 0)
nsize = 0;
- if (skb_cloned(skb) &&
- skb_is_nonlinear(skb) &&
- pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
+ if (skb_unclone(skb, GFP_ATOMIC))
return -ENOMEM;
/* Get a new skb... force flag on. */
@@ -2344,6 +2345,8 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
int oldpcount = tcp_skb_pcount(skb);
if (unlikely(oldpcount > 1)) {
+ if (skb_unclone(skb, GFP_ATOMIC))
+ return -ENOMEM;
tcp_init_tso_segs(sk, skb, cur_mss);
tcp_adjust_pcount(sk, skb, oldpcount - tcp_skb_pcount(skb));
}
^ permalink raw reply related
* [PATCH V2] For for each TSN t being newly acked (Not only cumulatively, but also SELECTIVELY) cacc_saw_newack should be set to 1.
From: Chang Xiangzhong @ 2013-10-15 18:13 UTC (permalink / raw)
To: vyasevich
Cc: nhorman, davem, linux-sctp, netdev, linux-kernel,
Chang Xiangzhong
Signed-off-by: Xiangzhong Chang <changxiangzhong@gmail.com>
---
net/sctp/outqueue.c | 76 ++++++++++++++++++++++++---------------------------
1 file changed, 35 insertions(+), 41 deletions(-)
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index 94df758..84ef3b8 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -1357,13 +1357,13 @@ static void sctp_check_transmitted(struct sctp_outq *q,
tsn = ntohl(tchunk->subh.data_hdr->tsn);
if (sctp_acked(sack, tsn)) {
- /* If this queue is the retransmit queue, the
- * retransmit timer has already reclaimed
- * the outstanding bytes for this chunk, so only
- * count bytes associated with a transport.
- */
- if (transport) {
- /* If this chunk is being used for RTT
+ if (!tchunk->tsn_gap_acked) {
+ /* If this queue is the retransmit queue, the
+ * retransmit timer has already reclaimed
+ * the outstanding bytes for this chunk, so only
+ * count bytes associated with a transport.
+ *
+ * If this chunk is being used for RTT
* measurement, calculate the RTT and update
* the RTO using this value.
*
@@ -1374,28 +1374,44 @@ static void sctp_check_transmitted(struct sctp_outq *q,
* first instance of the packet or a later
* instance).
*/
- if (!tchunk->tsn_gap_acked &&
- tchunk->rtt_in_progress) {
+ if (transport && tchunk->rtt_in_progress) {
tchunk->rtt_in_progress = 0;
rtt = jiffies - tchunk->sent_at;
sctp_transport_update_rto(transport,
- rtt);
+ rtt);
}
- }
- /* If the chunk hasn't been marked as ACKED,
- * mark it and account bytes_acked if the
- * chunk had a valid transport (it will not
- * have a transport if ASCONF had deleted it
- * while DATA was outstanding).
- */
- if (!tchunk->tsn_gap_acked) {
+ /* If the chunk hasn't been marked as ACKED,
+ * mark it and account bytes_acked if the
+ * chunk had a valid transport (it will not
+ * have a transport if ASCONF had deleted it
+ * while DATA was outstanding).
+ */
tchunk->tsn_gap_acked = 1;
*highest_new_tsn_in_sack = tsn;
bytes_acked += sctp_data_size(tchunk);
if (!tchunk->transport)
migrate_bytes += sctp_data_size(tchunk);
forward_progress = true;
+
+ /* SFR-CACC algorithm:
+ * 2) If the SACK contains gap acks
+ * and the flag CHANGEOVER_ACTIVE is
+ * set the receiver of the SACK MUST
+ * take the following action:
+ *
+ * B) For each TSN t being acked that
+ * has not been acked in any SACK so
+ * far, set cacc_saw_newack to 1 for
+ * the destination that the TSN was
+ * sent to.
+ */
+ if (transport &&
+ sack->num_gap_ack_blocks &&
+ q->asoc->peer.primary_path->cacc.
+ changeover_active
+ )
+ transport->cacc.cacc_saw_newack = 1;
}
if (TSN_lte(tsn, sack_ctsn)) {
@@ -1411,30 +1427,8 @@ static void sctp_check_transmitted(struct sctp_outq *q,
restart_timer = 1;
forward_progress = true;
- if (!tchunk->tsn_gap_acked) {
- /*
- * SFR-CACC algorithm:
- * 2) If the SACK contains gap acks
- * and the flag CHANGEOVER_ACTIVE is
- * set the receiver of the SACK MUST
- * take the following action:
- *
- * B) For each TSN t being acked that
- * has not been acked in any SACK so
- * far, set cacc_saw_newack to 1 for
- * the destination that the TSN was
- * sent to.
- */
- if (transport &&
- sack->num_gap_ack_blocks &&
- q->asoc->peer.primary_path->cacc.
- changeover_active)
- transport->cacc.cacc_saw_newack
- = 1;
- }
-
list_add_tail(&tchunk->transmitted_list,
- &q->sacked);
+ &q->sacked);
} else {
/* RFC2960 7.2.4, sctpimpguide-05 2.8.2
* M2) Each time a SACK arrives reporting
--
1.7.9.5
^ permalink raw reply related
* pull request: wireless 2013-10-15
From: John W. Linville @ 2013-10-15 17:56 UTC (permalink / raw)
To: davem; +Cc: linux-wireless, netdev, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 12907 bytes --]
(Sorry for the repost -- mistyped Dave's email address the first time...)
Dave,
Please pull this batch of fixes intended for the 3.12 stream!
For the mac80211 bits, Johannes says:
"Jouni fixes a remain-on-channel vs. scan bug, and Felix fixes client TX
probing on VLANs."
And also:
"This time I have two fixes from Emmanuel for RF-kill issues, and fixed
two issues reported by Evan Huus and Thomas Lindroth respectively."
On top of those...
Avinash Patil adds a couple of mwifiex fixes to properly inform cfg80211
about some different types of disconnects, avoiding WARNINGs.
Mark Cave-Ayland corrects a pointer arithmetic problem in rtlwifi,
avoiding incorrect automatic gain calculations.
Solomon Peachy sends a cw1200 fix for locking around calls to
cw1200_irq_handler, addressing "lost interrupt" problems.
Please let me know if there are problems!
Thanks,
John
---
The following changes since commit e9e4ea74f06635f2ffc1dffe5ef40c854faa0a90:
net: smc91x: dont't use SMC_outw for fixing up halfword-aligned data (2013-10-11 17:50:59 -0400)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git for-davem
for you to fetch changes up to 39c253ed7817bf477189a132b114303c9aa2c2d2:
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless into for-davem (2013-10-15 13:05:21 -0400)
----------------------------------------------------------------
Avinash Patil (2):
mwifiex: inform cfg80211 about disconnect if device is removed
mwifiex: inform cfg80211 about disconnect for P2P client interface
Emmanuel Grumbach (2):
mac80211: correctly close cancelled scans
cfg80211: don't add p2p device while in RFKILL
Felix Fietkau (2):
mac80211: use sta_info_get_bss() for nl80211 tx and client probing
mac80211: update sta->last_rx on acked tx frames
Johannes Berg (2):
wireless: radiotap: fix parsing buffer overrun
mac80211: fix crash if bitrate calculation goes wrong
John W. Linville (3):
Merge branch 'for-john' of git://git.kernel.org/.../jberg/mac80211
Merge branch 'for-john' of git://git.kernel.org/.../jberg/mac80211
Merge branch 'master' of git://git.kernel.org/.../linville/wireless into for-davem
Jouni Malinen (1):
mac80211: Run deferred scan if last roc_list item is not started
Mark Cave-Ayland (1):
rtlwifi: rtl8192cu: Fix error in pointer arithmetic
Solomon Peachy (1):
wireless: cw1200: acquire hwbus lock around cw1200_irq_handler() call.
drivers/net/wireless/cw1200/cw1200_spi.c | 2 ++
drivers/net/wireless/mwifiex/join.c | 10 ++++++++--
drivers/net/wireless/mwifiex/sta_event.c | 3 ++-
drivers/net/wireless/rtlwifi/rtl8192cu/trx.c | 3 ++-
net/mac80211/cfg.c | 2 +-
net/mac80211/ieee80211_i.h | 3 +++
net/mac80211/offchannel.c | 2 ++
net/mac80211/scan.c | 19 +++++++++++++++++++
net/mac80211/status.c | 3 +++
net/mac80211/tx.c | 3 ++-
net/mac80211/util.c | 4 ++++
net/wireless/core.c | 2 --
net/wireless/core.h | 3 +++
net/wireless/radiotap.c | 7 ++++++-
14 files changed, 57 insertions(+), 9 deletions(-)
diff --git a/drivers/net/wireless/cw1200/cw1200_spi.c b/drivers/net/wireless/cw1200/cw1200_spi.c
index 899cad3..755a0c8 100644
--- a/drivers/net/wireless/cw1200/cw1200_spi.c
+++ b/drivers/net/wireless/cw1200/cw1200_spi.c
@@ -237,7 +237,9 @@ static irqreturn_t cw1200_spi_irq_handler(int irq, void *dev_id)
struct hwbus_priv *self = dev_id;
if (self->core) {
+ cw1200_spi_lock(self);
cw1200_irq_handler(self->core);
+ cw1200_spi_unlock(self);
return IRQ_HANDLED;
} else {
return IRQ_NONE;
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c
index 9d7c0e6..37f873b 100644
--- a/drivers/net/wireless/mwifiex/join.c
+++ b/drivers/net/wireless/mwifiex/join.c
@@ -1422,13 +1422,19 @@ static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv, u8 *mac)
*/
int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac)
{
+ int ret = 0;
+
if (!priv->media_connected)
return 0;
switch (priv->bss_mode) {
case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_P2P_CLIENT:
- return mwifiex_deauthenticate_infra(priv, mac);
+ ret = mwifiex_deauthenticate_infra(priv, mac);
+ if (ret)
+ cfg80211_disconnected(priv->netdev, 0, NULL, 0,
+ GFP_KERNEL);
+ break;
case NL80211_IFTYPE_ADHOC:
return mwifiex_send_cmd_sync(priv,
HostCmd_CMD_802_11_AD_HOC_STOP,
@@ -1440,7 +1446,7 @@ int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac)
break;
}
- return 0;
+ return ret;
}
EXPORT_SYMBOL_GPL(mwifiex_deauthenticate);
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
index 8b05752..8c351f7 100644
--- a/drivers/net/wireless/mwifiex/sta_event.c
+++ b/drivers/net/wireless/mwifiex/sta_event.c
@@ -118,7 +118,8 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason_code)
dev_dbg(adapter->dev,
"info: successfully disconnected from %pM: reason code %d\n",
priv->cfg_bssid, reason_code);
- if (priv->bss_mode == NL80211_IFTYPE_STATION) {
+ if (priv->bss_mode == NL80211_IFTYPE_STATION ||
+ priv->bss_mode == NL80211_IFTYPE_P2P_CLIENT) {
cfg80211_disconnected(priv->netdev, reason_code, NULL, 0,
GFP_KERNEL);
}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
index 763cf1d..5a060e5 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
@@ -343,7 +343,8 @@ bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw,
(bool)GET_RX_DESC_PAGGR(pdesc));
rx_status->mactime = GET_RX_DESC_TSFL(pdesc);
if (phystatus) {
- p_drvinfo = (struct rx_fwinfo_92c *)(pdesc + RTL_RX_DESC_SIZE);
+ p_drvinfo = (struct rx_fwinfo_92c *)(skb->data +
+ stats->rx_bufshift);
rtl92c_translate_rx_signal_stuff(hw, skb, stats, pdesc,
p_drvinfo);
}
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 2e7855a..629dee7 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -3518,7 +3518,7 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
return -EINVAL;
}
band = chanctx_conf->def.chan->band;
- sta = sta_info_get(sdata, peer);
+ sta = sta_info_get_bss(sdata, peer);
if (sta) {
qos = test_sta_flag(sta, WLAN_STA_WME);
} else {
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index b618651..611abfc 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -893,6 +893,8 @@ struct tpt_led_trigger {
* that the scan completed.
* @SCAN_ABORTED: Set for our scan work function when the driver reported
* a scan complete for an aborted scan.
+ * @SCAN_HW_CANCELLED: Set for our scan work function when the scan is being
+ * cancelled.
*/
enum {
SCAN_SW_SCANNING,
@@ -900,6 +902,7 @@ enum {
SCAN_ONCHANNEL_SCANNING,
SCAN_COMPLETED,
SCAN_ABORTED,
+ SCAN_HW_CANCELLED,
};
/**
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index acd1f71..0c2a294 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -394,6 +394,8 @@ void ieee80211_sw_roc_work(struct work_struct *work)
if (started)
ieee80211_start_next_roc(local);
+ else if (list_empty(&local->roc_list))
+ ieee80211_run_deferred_scan(local);
}
out_unlock:
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 08afe74..d2d17a4 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -238,6 +238,9 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local)
enum ieee80211_band band;
int i, ielen, n_chans;
+ if (test_bit(SCAN_HW_CANCELLED, &local->scanning))
+ return false;
+
do {
if (local->hw_scan_band == IEEE80211_NUM_BANDS)
return false;
@@ -940,7 +943,23 @@ void ieee80211_scan_cancel(struct ieee80211_local *local)
if (!local->scan_req)
goto out;
+ /*
+ * We have a scan running and the driver already reported completion,
+ * but the worker hasn't run yet or is stuck on the mutex - mark it as
+ * cancelled.
+ */
+ if (test_bit(SCAN_HW_SCANNING, &local->scanning) &&
+ test_bit(SCAN_COMPLETED, &local->scanning)) {
+ set_bit(SCAN_HW_CANCELLED, &local->scanning);
+ goto out;
+ }
+
if (test_bit(SCAN_HW_SCANNING, &local->scanning)) {
+ /*
+ * Make sure that __ieee80211_scan_completed doesn't trigger a
+ * scan on another band.
+ */
+ set_bit(SCAN_HW_CANCELLED, &local->scanning);
if (local->ops->cancel_hw_scan)
drv_cancel_hw_scan(local,
rcu_dereference_protected(local->scan_sdata,
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 368837f..78dc2e9 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -180,6 +180,9 @@ static void ieee80211_frame_acked(struct sta_info *sta, struct sk_buff *skb)
struct ieee80211_local *local = sta->local;
struct ieee80211_sub_if_data *sdata = sta->sdata;
+ if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
+ sta->last_rx = jiffies;
+
if (ieee80211_is_data_qos(mgmt->frame_control)) {
struct ieee80211_hdr *hdr = (void *) skb->data;
u8 *qc = ieee80211_get_qos_ctl(hdr);
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 3456c04..70b5a05 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1120,7 +1120,8 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
tx->sta = rcu_dereference(sdata->u.vlan.sta);
if (!tx->sta && sdata->dev->ieee80211_ptr->use_4addr)
return TX_DROP;
- } else if (info->flags & IEEE80211_TX_CTL_INJECTED ||
+ } else if (info->flags & (IEEE80211_TX_CTL_INJECTED |
+ IEEE80211_TX_INTFL_NL80211_FRAME_TX) ||
tx->sdata->control_port_protocol == tx->skb->protocol) {
tx->sta = sta_info_get_bss(sdata, hdr->addr1);
}
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 9c3200b..69e4ef5 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -2238,6 +2238,10 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
}
rate = cfg80211_calculate_bitrate(&ri);
+ if (WARN_ONCE(!rate,
+ "Invalid bitrate: flags=0x%x, idx=%d, vht_nss=%d\n",
+ status->flag, status->rate_idx, status->vht_nss))
+ return 0;
/* rewind from end of MPDU */
if (status->flag & RX_FLAG_MACTIME_END)
diff --git a/net/wireless/core.c b/net/wireless/core.c
index fe8d4f2..aff959e 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -958,8 +958,6 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
case NETDEV_PRE_UP:
if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype)))
return notifier_from_errno(-EOPNOTSUPP);
- if (rfkill_blocked(rdev->rfkill))
- return notifier_from_errno(-ERFKILL);
ret = cfg80211_can_add_interface(rdev, wdev->iftype);
if (ret)
return notifier_from_errno(ret);
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 9ad43c6..3159e9c 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -411,6 +411,9 @@ static inline int
cfg80211_can_add_interface(struct cfg80211_registered_device *rdev,
enum nl80211_iftype iftype)
{
+ if (rfkill_blocked(rdev->rfkill))
+ return -ERFKILL;
+
return cfg80211_can_change_interface(rdev, NULL, iftype);
}
diff --git a/net/wireless/radiotap.c b/net/wireless/radiotap.c
index 7d604c0..a271c27 100644
--- a/net/wireless/radiotap.c
+++ b/net/wireless/radiotap.c
@@ -97,6 +97,10 @@ int ieee80211_radiotap_iterator_init(
struct ieee80211_radiotap_header *radiotap_header,
int max_length, const struct ieee80211_radiotap_vendor_namespaces *vns)
{
+ /* check the radiotap header can actually be present */
+ if (max_length < sizeof(struct ieee80211_radiotap_header))
+ return -EINVAL;
+
/* Linux only supports version 0 radiotap format */
if (radiotap_header->it_version)
return -EINVAL;
@@ -131,7 +135,8 @@ int ieee80211_radiotap_iterator_init(
*/
if ((unsigned long)iterator->_arg -
- (unsigned long)iterator->_rtheader >
+ (unsigned long)iterator->_rtheader +
+ sizeof(uint32_t) >
(unsigned long)iterator->_max_length)
return -EINVAL;
}
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply related
* Re: [PATCH] For for each TSN t being newly acked (Not only cumulatively, but also SELECTIVELY) cacc_saw_newack should be set to 1.
From: Vlad Yasevich @ 2013-10-15 17:48 UTC (permalink / raw)
To: Chang; +Cc: nhorman, davem, linux-sctp, netdev, linux-kernel
In-Reply-To: <525D7DD7.4070708@gmail.com>
On 10/15/2013 01:39 PM, Chang wrote:
>
> On 10/15/2013 07:25 PM, Vlad Yasevich wrote:
>> On 10/15/2013 12:59 PM, Chang Xiangzhong wrote:
>>> Signed-off-by: Xiangzhong Chang <changxiangzhong@gmail.com>
>>> ---
>>> net/sctp/outqueue.c | 142
>>> ++++++++++++++++++++++++---------------------------
>>> 1 file changed, 68 insertions(+), 74 deletions(-)
>>>
>>> diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
>>> index 94df758..f10d848 100644
>>> --- a/net/sctp/outqueue.c
>>> +++ b/net/sctp/outqueue.c
>>> @@ -1357,84 +1357,78 @@ static void sctp_check_transmitted(struct
>>> sctp_outq *q,
>>>
>>> tsn = ntohl(tchunk->subh.data_hdr->tsn);
>>> if (sctp_acked(sack, tsn)) {
>>> - /* If this queue is the retransmit queue, the
>>> - * retransmit timer has already reclaimed
>>> - * the outstanding bytes for this chunk, so only
>>> - * count bytes associated with a transport.
>>> - */
>>> - if (transport) {
>>> - /* If this chunk is being used for RTT
>>> - * measurement, calculate the RTT and update
>>> - * the RTO using this value.
>>> - *
>>> - * 6.3.1 C5) Karn's algorithm: RTT measurements
>>> - * MUST NOT be made using packets that were
>>> - * retransmitted (and thus for which it is
>>> - * ambiguous whether the reply was for the
>>> - * first instance of the packet or a later
>>> - * instance).
>>> - */
>>> - if (!tchunk->tsn_gap_acked &&
>>> - tchunk->rtt_in_progress) {
>>> - tchunk->rtt_in_progress = 0;
>>> - rtt = jiffies - tchunk->sent_at;
>>> - sctp_transport_update_rto(transport,
>>> - rtt);
>>> - }
>>> - }
>>> -
>>> - /* If the chunk hasn't been marked as ACKED,
>>> - * mark it and account bytes_acked if the
>>> - * chunk had a valid transport (it will not
>>> - * have a transport if ASCONF had deleted it
>>> - * while DATA was outstanding).
>>> - */
>>> if (!tchunk->tsn_gap_acked) {
>>> - tchunk->tsn_gap_acked = 1;
>>> - *highest_new_tsn_in_sack = tsn;
>>> - bytes_acked += sctp_data_size(tchunk);
>>> - if (!tchunk->transport)
>>> - migrate_bytes += sctp_data_size(tchunk);
>>> - forward_progress = true;
>>> + /* If this queue is the retransmit queue, the
>>> + * retransmit timer has already reclaimed
>>> + * the outstanding bytes for this chunk, so only
>>> + * count bytes associated with a transport.
>>> + *
>>> + * If this chunk is being used for RTT
>>> + * measurement, calculate the RTT and update
>>> + * the RTO using this value.
>>> + *
>>> + * 6.3.1 C5) Karn's algorithm: RTT measurements
>>> + * MUST NOT be made using packets that were
>>> + * retransmitted (and thus for which it is
>>> + * ambiguous whether the reply was for the
>>> + * first instance of the packet or a later
>>> + * instance).
>>> + */
>>> + if (transport && tchunk->rtt_in_progress) {
>>> + tchunk->rtt_in_progress = 0;
>>> + rtt = jiffies - tchunk->sent_at;
>>> + sctp_transport_update_rto(transport,
>>> + rtt);
>>> + }
>>> +
>>> + /* If the chunk hasn't been marked as ACKED,
>>> + * mark it and account bytes_acked if the
>>> + * chunk had a valid transport (it will not
>>> + * have a transport if ASCONF had deleted it
>>> + * while DATA was outstanding).
>>> + */
>>> + tchunk->tsn_gap_acked = 1;
>>> + *highest_new_tsn_in_sack = tsn;
>>> + bytes_acked += sctp_data_size(tchunk);
>>> + if (!tchunk->transport)
>>> + migrate_bytes += sctp_data_size(tchunk);
>>> + forward_progress = true;
>>> +
>>> + /*
>>> + * SFR-CACC algorithm:
>>> + * 2) If the SACK contains gap acks
>>> + * and the flag CHANGEOVER_ACTIVE is
>>> + * set the receiver of the SACK MUST
>>> + * take the following action:
>>> + *
>>> + * B) For each TSN t being acked that
>>> + * has not been acked in any SACK so
>>> + * far, set cacc_saw_newack to 1 for
>>> + * the destination that the TSN was
>>> + * sent to.
>>> + */
>>> + if (transport &&
>>> + sack->num_gap_ack_blocks &&
>>> + q->asoc->peer.primary_path->cacc.
>>> + changeover_active)
>>> + transport->cacc.cacc_saw_newack = 1;
>>> }
>>
>> Indents should be tab based.
>> This is a bit more of a re-write that is needed for the this
>> particualar patch. What's wrong with just doing this?
>>
> I'm pretty new of kernel dev. So I've make a new patch. What's the
> correct way of doing this? just attach the new patch to this email?
> -Chang
Send a [PATCH v2] with the same subject as before that contains the
updated patch.
-vlad
>
>> @@ -1396,6 +1396,25 @@ static void sctp_check_transmitted(struct
>> sctp_outq *q,
>> if (!tchunk->transport)
>> migrate_bytes +=
>> sctp_data_size(tchunk);
>> forward_progress = true;
>> +
>> + /*
>> + * SFR-CACC algorithm:
>> + * 2) If the SACK contains gap acks
>> + * and the flag CHANGEOVER_ACTIVE is
>> + * set the receiver of the SACK MUST
>> + * take the following action:
>> + *
>> + * B) For each TSN t being acked that
>> + * has not been acked in any SACK so
>> + * far, set cacc_saw_newack to 1 for
>> + * the destination that the TSN was
>> + * sent to.
>> + */
>> + if (transport &&
>> + sack->num_gap_ack_blocks &&
>> + q->asoc->peer.primary_path->cacc.
>> + changeover_active)
>> + transport->cacc.cacc_saw_newack = 1;
>> }
>>
>>
>> if (TSN_lte(tsn, sack_ctsn)) {
>>
>> -vlad
>>
>>>
>>> if (TSN_lte(tsn, sack_ctsn)) {
>>> - /* RFC 2960 6.3.2 Retransmission Timer Rules
>>> - *
>>> - * R3) Whenever a SACK is received
>>> - * that acknowledges the DATA chunk
>>> - * with the earliest outstanding TSN
>>> - * for that address, restart T3-rtx
>>> - * timer for that address with its
>>> - * current RTO.
>>> - */
>>> - restart_timer = 1;
>>> - forward_progress = true;
>>> -
>>> - if (!tchunk->tsn_gap_acked) {
>>> - /*
>>> - * SFR-CACC algorithm:
>>> - * 2) If the SACK contains gap acks
>>> - * and the flag CHANGEOVER_ACTIVE is
>>> - * set the receiver of the SACK MUST
>>> - * take the following action:
>>> - *
>>> - * B) For each TSN t being acked that
>>> - * has not been acked in any SACK so
>>> - * far, set cacc_saw_newack to 1 for
>>> - * the destination that the TSN was
>>> - * sent to.
>>> - */
>>> - if (transport &&
>>> - sack->num_gap_ack_blocks &&
>>> - q->asoc->peer.primary_path->cacc.
>>> - changeover_active)
>>> - transport->cacc.cacc_saw_newack
>>> - = 1;
>>> - }
>>> -
>>> - list_add_tail(&tchunk->transmitted_list,
>>> - &q->sacked);
>>> + /* RFC 2960 6.3.2 Retransmission Timer Rules
>>> + *
>>> + * R3) Whenever a SACK is received
>>> + * that acknowledges the DATA chunk
>>> + * with the earliest outstanding TSN
>>> + * for that address, restart T3-rtx
>>> + * timer for that address with its
>>> + * current RTO.
>>> + */
>>> + restart_timer = 1;
>>> + forward_progress = true;
>>> +
>>> + list_add_tail(&tchunk->transmitted_list,
>>> + &q->sacked);
>>> } else {
>>> /* RFC2960 7.2.4, sctpimpguide-05 2.8.2
>>> * M2) Each time a SACK arrives reporting
>>>
>>
>
^ permalink raw reply
* pull request: wireless 2013-10-15
From: John W. Linville @ 2013-10-15 17:46 UTC (permalink / raw)
To: dave; +Cc: linux-wireless, netdev, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 12830 bytes --]
Dave,
Please pull this batch of fixes intended for the 3.12 stream!
For the mac80211 bits, Johannes says:
"Jouni fixes a remain-on-channel vs. scan bug, and Felix fixes client TX
probing on VLANs."
And also:
"This time I have two fixes from Emmanuel for RF-kill issues, and fixed
two issues reported by Evan Huus and Thomas Lindroth respectively."
On top of those...
Avinash Patil adds a couple of mwifiex fixes to properly inform cfg80211
about some different types of disconnects, avoiding WARNINGs.
Mark Cave-Ayland corrects a pointer arithmetic problem in rtlwifi,
avoiding incorrect automatic gain calculations.
Solomon Peachy sends a cw1200 fix for locking around calls to
cw1200_irq_handler, addressing "lost interrupt" problems.
Please let me know if there are problems!
Thanks,
John
---
The following changes since commit e9e4ea74f06635f2ffc1dffe5ef40c854faa0a90:
net: smc91x: dont't use SMC_outw for fixing up halfword-aligned data (2013-10-11 17:50:59 -0400)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git for-davem
for you to fetch changes up to 39c253ed7817bf477189a132b114303c9aa2c2d2:
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless into for-davem (2013-10-15 13:05:21 -0400)
----------------------------------------------------------------
Avinash Patil (2):
mwifiex: inform cfg80211 about disconnect if device is removed
mwifiex: inform cfg80211 about disconnect for P2P client interface
Emmanuel Grumbach (2):
mac80211: correctly close cancelled scans
cfg80211: don't add p2p device while in RFKILL
Felix Fietkau (2):
mac80211: use sta_info_get_bss() for nl80211 tx and client probing
mac80211: update sta->last_rx on acked tx frames
Johannes Berg (2):
wireless: radiotap: fix parsing buffer overrun
mac80211: fix crash if bitrate calculation goes wrong
John W. Linville (3):
Merge branch 'for-john' of git://git.kernel.org/.../jberg/mac80211
Merge branch 'for-john' of git://git.kernel.org/.../jberg/mac80211
Merge branch 'master' of git://git.kernel.org/.../linville/wireless into for-davem
Jouni Malinen (1):
mac80211: Run deferred scan if last roc_list item is not started
Mark Cave-Ayland (1):
rtlwifi: rtl8192cu: Fix error in pointer arithmetic
Solomon Peachy (1):
wireless: cw1200: acquire hwbus lock around cw1200_irq_handler() call.
drivers/net/wireless/cw1200/cw1200_spi.c | 2 ++
drivers/net/wireless/mwifiex/join.c | 10 ++++++++--
drivers/net/wireless/mwifiex/sta_event.c | 3 ++-
drivers/net/wireless/rtlwifi/rtl8192cu/trx.c | 3 ++-
net/mac80211/cfg.c | 2 +-
net/mac80211/ieee80211_i.h | 3 +++
net/mac80211/offchannel.c | 2 ++
net/mac80211/scan.c | 19 +++++++++++++++++++
net/mac80211/status.c | 3 +++
net/mac80211/tx.c | 3 ++-
net/mac80211/util.c | 4 ++++
net/wireless/core.c | 2 --
net/wireless/core.h | 3 +++
net/wireless/radiotap.c | 7 ++++++-
14 files changed, 57 insertions(+), 9 deletions(-)
diff --git a/drivers/net/wireless/cw1200/cw1200_spi.c b/drivers/net/wireless/cw1200/cw1200_spi.c
index 899cad3..755a0c8 100644
--- a/drivers/net/wireless/cw1200/cw1200_spi.c
+++ b/drivers/net/wireless/cw1200/cw1200_spi.c
@@ -237,7 +237,9 @@ static irqreturn_t cw1200_spi_irq_handler(int irq, void *dev_id)
struct hwbus_priv *self = dev_id;
if (self->core) {
+ cw1200_spi_lock(self);
cw1200_irq_handler(self->core);
+ cw1200_spi_unlock(self);
return IRQ_HANDLED;
} else {
return IRQ_NONE;
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c
index 9d7c0e6..37f873b 100644
--- a/drivers/net/wireless/mwifiex/join.c
+++ b/drivers/net/wireless/mwifiex/join.c
@@ -1422,13 +1422,19 @@ static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv, u8 *mac)
*/
int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac)
{
+ int ret = 0;
+
if (!priv->media_connected)
return 0;
switch (priv->bss_mode) {
case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_P2P_CLIENT:
- return mwifiex_deauthenticate_infra(priv, mac);
+ ret = mwifiex_deauthenticate_infra(priv, mac);
+ if (ret)
+ cfg80211_disconnected(priv->netdev, 0, NULL, 0,
+ GFP_KERNEL);
+ break;
case NL80211_IFTYPE_ADHOC:
return mwifiex_send_cmd_sync(priv,
HostCmd_CMD_802_11_AD_HOC_STOP,
@@ -1440,7 +1446,7 @@ int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac)
break;
}
- return 0;
+ return ret;
}
EXPORT_SYMBOL_GPL(mwifiex_deauthenticate);
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
index 8b05752..8c351f7 100644
--- a/drivers/net/wireless/mwifiex/sta_event.c
+++ b/drivers/net/wireless/mwifiex/sta_event.c
@@ -118,7 +118,8 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason_code)
dev_dbg(adapter->dev,
"info: successfully disconnected from %pM: reason code %d\n",
priv->cfg_bssid, reason_code);
- if (priv->bss_mode == NL80211_IFTYPE_STATION) {
+ if (priv->bss_mode == NL80211_IFTYPE_STATION ||
+ priv->bss_mode == NL80211_IFTYPE_P2P_CLIENT) {
cfg80211_disconnected(priv->netdev, reason_code, NULL, 0,
GFP_KERNEL);
}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
index 763cf1d..5a060e5 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
@@ -343,7 +343,8 @@ bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw,
(bool)GET_RX_DESC_PAGGR(pdesc));
rx_status->mactime = GET_RX_DESC_TSFL(pdesc);
if (phystatus) {
- p_drvinfo = (struct rx_fwinfo_92c *)(pdesc + RTL_RX_DESC_SIZE);
+ p_drvinfo = (struct rx_fwinfo_92c *)(skb->data +
+ stats->rx_bufshift);
rtl92c_translate_rx_signal_stuff(hw, skb, stats, pdesc,
p_drvinfo);
}
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 2e7855a..629dee7 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -3518,7 +3518,7 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
return -EINVAL;
}
band = chanctx_conf->def.chan->band;
- sta = sta_info_get(sdata, peer);
+ sta = sta_info_get_bss(sdata, peer);
if (sta) {
qos = test_sta_flag(sta, WLAN_STA_WME);
} else {
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index b618651..611abfc 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -893,6 +893,8 @@ struct tpt_led_trigger {
* that the scan completed.
* @SCAN_ABORTED: Set for our scan work function when the driver reported
* a scan complete for an aborted scan.
+ * @SCAN_HW_CANCELLED: Set for our scan work function when the scan is being
+ * cancelled.
*/
enum {
SCAN_SW_SCANNING,
@@ -900,6 +902,7 @@ enum {
SCAN_ONCHANNEL_SCANNING,
SCAN_COMPLETED,
SCAN_ABORTED,
+ SCAN_HW_CANCELLED,
};
/**
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index acd1f71..0c2a294 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -394,6 +394,8 @@ void ieee80211_sw_roc_work(struct work_struct *work)
if (started)
ieee80211_start_next_roc(local);
+ else if (list_empty(&local->roc_list))
+ ieee80211_run_deferred_scan(local);
}
out_unlock:
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 08afe74..d2d17a4 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -238,6 +238,9 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local)
enum ieee80211_band band;
int i, ielen, n_chans;
+ if (test_bit(SCAN_HW_CANCELLED, &local->scanning))
+ return false;
+
do {
if (local->hw_scan_band == IEEE80211_NUM_BANDS)
return false;
@@ -940,7 +943,23 @@ void ieee80211_scan_cancel(struct ieee80211_local *local)
if (!local->scan_req)
goto out;
+ /*
+ * We have a scan running and the driver already reported completion,
+ * but the worker hasn't run yet or is stuck on the mutex - mark it as
+ * cancelled.
+ */
+ if (test_bit(SCAN_HW_SCANNING, &local->scanning) &&
+ test_bit(SCAN_COMPLETED, &local->scanning)) {
+ set_bit(SCAN_HW_CANCELLED, &local->scanning);
+ goto out;
+ }
+
if (test_bit(SCAN_HW_SCANNING, &local->scanning)) {
+ /*
+ * Make sure that __ieee80211_scan_completed doesn't trigger a
+ * scan on another band.
+ */
+ set_bit(SCAN_HW_CANCELLED, &local->scanning);
if (local->ops->cancel_hw_scan)
drv_cancel_hw_scan(local,
rcu_dereference_protected(local->scan_sdata,
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 368837f..78dc2e9 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -180,6 +180,9 @@ static void ieee80211_frame_acked(struct sta_info *sta, struct sk_buff *skb)
struct ieee80211_local *local = sta->local;
struct ieee80211_sub_if_data *sdata = sta->sdata;
+ if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
+ sta->last_rx = jiffies;
+
if (ieee80211_is_data_qos(mgmt->frame_control)) {
struct ieee80211_hdr *hdr = (void *) skb->data;
u8 *qc = ieee80211_get_qos_ctl(hdr);
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 3456c04..70b5a05 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1120,7 +1120,8 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
tx->sta = rcu_dereference(sdata->u.vlan.sta);
if (!tx->sta && sdata->dev->ieee80211_ptr->use_4addr)
return TX_DROP;
- } else if (info->flags & IEEE80211_TX_CTL_INJECTED ||
+ } else if (info->flags & (IEEE80211_TX_CTL_INJECTED |
+ IEEE80211_TX_INTFL_NL80211_FRAME_TX) ||
tx->sdata->control_port_protocol == tx->skb->protocol) {
tx->sta = sta_info_get_bss(sdata, hdr->addr1);
}
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 9c3200b..69e4ef5 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -2238,6 +2238,10 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
}
rate = cfg80211_calculate_bitrate(&ri);
+ if (WARN_ONCE(!rate,
+ "Invalid bitrate: flags=0x%x, idx=%d, vht_nss=%d\n",
+ status->flag, status->rate_idx, status->vht_nss))
+ return 0;
/* rewind from end of MPDU */
if (status->flag & RX_FLAG_MACTIME_END)
diff --git a/net/wireless/core.c b/net/wireless/core.c
index fe8d4f2..aff959e 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -958,8 +958,6 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
case NETDEV_PRE_UP:
if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype)))
return notifier_from_errno(-EOPNOTSUPP);
- if (rfkill_blocked(rdev->rfkill))
- return notifier_from_errno(-ERFKILL);
ret = cfg80211_can_add_interface(rdev, wdev->iftype);
if (ret)
return notifier_from_errno(ret);
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 9ad43c6..3159e9c 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -411,6 +411,9 @@ static inline int
cfg80211_can_add_interface(struct cfg80211_registered_device *rdev,
enum nl80211_iftype iftype)
{
+ if (rfkill_blocked(rdev->rfkill))
+ return -ERFKILL;
+
return cfg80211_can_change_interface(rdev, NULL, iftype);
}
diff --git a/net/wireless/radiotap.c b/net/wireless/radiotap.c
index 7d604c0..a271c27 100644
--- a/net/wireless/radiotap.c
+++ b/net/wireless/radiotap.c
@@ -97,6 +97,10 @@ int ieee80211_radiotap_iterator_init(
struct ieee80211_radiotap_header *radiotap_header,
int max_length, const struct ieee80211_radiotap_vendor_namespaces *vns)
{
+ /* check the radiotap header can actually be present */
+ if (max_length < sizeof(struct ieee80211_radiotap_header))
+ return -EINVAL;
+
/* Linux only supports version 0 radiotap format */
if (radiotap_header->it_version)
return -EINVAL;
@@ -131,7 +135,8 @@ int ieee80211_radiotap_iterator_init(
*/
if ((unsigned long)iterator->_arg -
- (unsigned long)iterator->_rtheader >
+ (unsigned long)iterator->_rtheader +
+ sizeof(uint32_t) >
(unsigned long)iterator->_max_length)
return -EINVAL;
}
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply related
* Re: [PATCH] For for each TSN t being newly acked (Not only cumulatively, but also SELECTIVELY) cacc_saw_newack should be set to 1.
From: Chang @ 2013-10-15 17:39 UTC (permalink / raw)
To: Vlad Yasevich; +Cc: nhorman, davem, linux-sctp, netdev, linux-kernel
In-Reply-To: <525D7A72.70200@gmail.com>
On 10/15/2013 07:25 PM, Vlad Yasevich wrote:
> On 10/15/2013 12:59 PM, Chang Xiangzhong wrote:
>> Signed-off-by: Xiangzhong Chang <changxiangzhong@gmail.com>
>> ---
>> net/sctp/outqueue.c | 142
>> ++++++++++++++++++++++++---------------------------
>> 1 file changed, 68 insertions(+), 74 deletions(-)
>>
>> diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
>> index 94df758..f10d848 100644
>> --- a/net/sctp/outqueue.c
>> +++ b/net/sctp/outqueue.c
>> @@ -1357,84 +1357,78 @@ static void sctp_check_transmitted(struct
>> sctp_outq *q,
>>
>> tsn = ntohl(tchunk->subh.data_hdr->tsn);
>> if (sctp_acked(sack, tsn)) {
>> - /* If this queue is the retransmit queue, the
>> - * retransmit timer has already reclaimed
>> - * the outstanding bytes for this chunk, so only
>> - * count bytes associated with a transport.
>> - */
>> - if (transport) {
>> - /* If this chunk is being used for RTT
>> - * measurement, calculate the RTT and update
>> - * the RTO using this value.
>> - *
>> - * 6.3.1 C5) Karn's algorithm: RTT measurements
>> - * MUST NOT be made using packets that were
>> - * retransmitted (and thus for which it is
>> - * ambiguous whether the reply was for the
>> - * first instance of the packet or a later
>> - * instance).
>> - */
>> - if (!tchunk->tsn_gap_acked &&
>> - tchunk->rtt_in_progress) {
>> - tchunk->rtt_in_progress = 0;
>> - rtt = jiffies - tchunk->sent_at;
>> - sctp_transport_update_rto(transport,
>> - rtt);
>> - }
>> - }
>> -
>> - /* If the chunk hasn't been marked as ACKED,
>> - * mark it and account bytes_acked if the
>> - * chunk had a valid transport (it will not
>> - * have a transport if ASCONF had deleted it
>> - * while DATA was outstanding).
>> - */
>> if (!tchunk->tsn_gap_acked) {
>> - tchunk->tsn_gap_acked = 1;
>> - *highest_new_tsn_in_sack = tsn;
>> - bytes_acked += sctp_data_size(tchunk);
>> - if (!tchunk->transport)
>> - migrate_bytes += sctp_data_size(tchunk);
>> - forward_progress = true;
>> + /* If this queue is the retransmit queue, the
>> + * retransmit timer has already reclaimed
>> + * the outstanding bytes for this chunk, so only
>> + * count bytes associated with a transport.
>> + *
>> + * If this chunk is being used for RTT
>> + * measurement, calculate the RTT and update
>> + * the RTO using this value.
>> + *
>> + * 6.3.1 C5) Karn's algorithm: RTT measurements
>> + * MUST NOT be made using packets that were
>> + * retransmitted (and thus for which it is
>> + * ambiguous whether the reply was for the
>> + * first instance of the packet or a later
>> + * instance).
>> + */
>> + if (transport && tchunk->rtt_in_progress) {
>> + tchunk->rtt_in_progress = 0;
>> + rtt = jiffies - tchunk->sent_at;
>> + sctp_transport_update_rto(transport,
>> + rtt);
>> + }
>> +
>> + /* If the chunk hasn't been marked as ACKED,
>> + * mark it and account bytes_acked if the
>> + * chunk had a valid transport (it will not
>> + * have a transport if ASCONF had deleted it
>> + * while DATA was outstanding).
>> + */
>> + tchunk->tsn_gap_acked = 1;
>> + *highest_new_tsn_in_sack = tsn;
>> + bytes_acked += sctp_data_size(tchunk);
>> + if (!tchunk->transport)
>> + migrate_bytes += sctp_data_size(tchunk);
>> + forward_progress = true;
>> +
>> + /*
>> + * SFR-CACC algorithm:
>> + * 2) If the SACK contains gap acks
>> + * and the flag CHANGEOVER_ACTIVE is
>> + * set the receiver of the SACK MUST
>> + * take the following action:
>> + *
>> + * B) For each TSN t being acked that
>> + * has not been acked in any SACK so
>> + * far, set cacc_saw_newack to 1 for
>> + * the destination that the TSN was
>> + * sent to.
>> + */
>> + if (transport &&
>> + sack->num_gap_ack_blocks &&
>> + q->asoc->peer.primary_path->cacc.
>> + changeover_active)
>> + transport->cacc.cacc_saw_newack = 1;
>> }
>
> Indents should be tab based.
> This is a bit more of a re-write that is needed for the this
> particualar patch. What's wrong with just doing this?
>
I'm pretty new of kernel dev. So I've make a new patch. What's the
correct way of doing this? just attach the new patch to this email?
-Chang
> @@ -1396,6 +1396,25 @@ static void sctp_check_transmitted(struct
> sctp_outq *q,
> if (!tchunk->transport)
> migrate_bytes +=
> sctp_data_size(tchunk);
> forward_progress = true;
> +
> + /*
> + * SFR-CACC algorithm:
> + * 2) If the SACK contains gap acks
> + * and the flag CHANGEOVER_ACTIVE is
> + * set the receiver of the SACK MUST
> + * take the following action:
> + *
> + * B) For each TSN t being acked that
> + * has not been acked in any SACK so
> + * far, set cacc_saw_newack to 1 for
> + * the destination that the TSN was
> + * sent to.
> + */
> + if (transport &&
> + sack->num_gap_ack_blocks &&
> + q->asoc->peer.primary_path->cacc.
> + changeover_active)
> + transport->cacc.cacc_saw_newack = 1;
> }
>
>
> if (TSN_lte(tsn, sack_ctsn)) {
>
> -vlad
>
>>
>> if (TSN_lte(tsn, sack_ctsn)) {
>> - /* RFC 2960 6.3.2 Retransmission Timer Rules
>> - *
>> - * R3) Whenever a SACK is received
>> - * that acknowledges the DATA chunk
>> - * with the earliest outstanding TSN
>> - * for that address, restart T3-rtx
>> - * timer for that address with its
>> - * current RTO.
>> - */
>> - restart_timer = 1;
>> - forward_progress = true;
>> -
>> - if (!tchunk->tsn_gap_acked) {
>> - /*
>> - * SFR-CACC algorithm:
>> - * 2) If the SACK contains gap acks
>> - * and the flag CHANGEOVER_ACTIVE is
>> - * set the receiver of the SACK MUST
>> - * take the following action:
>> - *
>> - * B) For each TSN t being acked that
>> - * has not been acked in any SACK so
>> - * far, set cacc_saw_newack to 1 for
>> - * the destination that the TSN was
>> - * sent to.
>> - */
>> - if (transport &&
>> - sack->num_gap_ack_blocks &&
>> - q->asoc->peer.primary_path->cacc.
>> - changeover_active)
>> - transport->cacc.cacc_saw_newack
>> - = 1;
>> - }
>> -
>> - list_add_tail(&tchunk->transmitted_list,
>> - &q->sacked);
>> + /* RFC 2960 6.3.2 Retransmission Timer Rules
>> + *
>> + * R3) Whenever a SACK is received
>> + * that acknowledges the DATA chunk
>> + * with the earliest outstanding TSN
>> + * for that address, restart T3-rtx
>> + * timer for that address with its
>> + * current RTO.
>> + */
>> + restart_timer = 1;
>> + forward_progress = true;
>> +
>> + list_add_tail(&tchunk->transmitted_list,
>> + &q->sacked);
>> } else {
>> /* RFC2960 7.2.4, sctpimpguide-05 2.8.2
>> * M2) Each time a SACK arrives reporting
>>
>
^ permalink raw reply
* Re: [PATCH] X.25: Fix address field length calculation
From: Joe Perches @ 2013-10-15 17:29 UTC (permalink / raw)
To: Kelleter, Günther
Cc: andrew.hendry@gmail.com, davem@davemloft.net,
linux-x25@vger.kernel.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <525D5131.9070007@datus.com>
On Tue, 2013-10-15 at 14:29 +0000, Kelleter, Günther wrote:
> Addresses are BCD encoded, not ASCII. x25_addr_ntoa got it right.
[]
> Wrong length calculation leads to rejection of CALL ACCEPT packets.
[]
> diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
[]
> @@ -98,7 +98,7 @@ int x25_parse_address_block(struct sk_buff *skb,
> }
> len = *skb->data;
> - needed = 1 + (len >> 4) + (len & 0x0f);
> + needed = 1 + ((len >> 4) + (len & 0x0f) + 1) / 2;
This calculation looks odd.
Perhaps use bcd.h instead?
^ permalink raw reply
* [PATCH net-next v3 9/9] qlcnic: update version to 5.3.51
From: Himanshu Madhani @ 2013-10-15 16:57 UTC (permalink / raw)
To: davem; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Himanshu Madhani
In-Reply-To: <cover.1381882600.git.himanshu.madhani@qlogic.com>
From: Himanshu Madhani <himanshu.madhani@qlogic.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
---
drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index 728bb88..0c2405d 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -38,8 +38,8 @@
#define _QLCNIC_LINUX_MAJOR 5
#define _QLCNIC_LINUX_MINOR 3
-#define _QLCNIC_LINUX_SUBVERSION 50
-#define QLCNIC_LINUX_VERSIONID "5.3.50"
+#define _QLCNIC_LINUX_SUBVERSION 51
+#define QLCNIC_LINUX_VERSIONID "5.3.51"
#define QLCNIC_DRV_IDC_VER 0x01
#define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\
(_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
--
1.8.1.4
^ permalink raw reply related
* [PATCH net-next v3 7/9] qlcnic: Validate Tx queue only for 82xx adapters.
From: Himanshu Madhani @ 2013-10-15 16:57 UTC (permalink / raw)
To: davem; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Himanshu Madhani
In-Reply-To: <cover.1381882600.git.himanshu.madhani@qlogic.com>
From: Himanshu Madhani <himanshu.madhani@qlogic.com>
o validate Tx queue only in case of adapters which supports
multi Tx queue.
This patch is to fix regression introduced in commit
aa4a1f7df7cbb98797c9f4edfde3c726e2b3841f
"qlcnic: Enable Tx queue changes using ethtool for 82xx Series adapter"
Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
---
drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | 2 +-
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 8 +-------
2 files changed, 2 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
index 66355b7..b2a8805 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
@@ -691,7 +691,7 @@ static int qlcnic_set_channels(struct net_device *dev,
return err;
}
- if (channel->tx_count) {
+ if (qlcnic_82xx_check(adapter) && channel->tx_count) {
err = qlcnic_validate_max_tx_rings(adapter, channel->tx_count);
if (err)
return err;
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 0274832..830c15f 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -3650,11 +3650,6 @@ int qlcnic_validate_max_tx_rings(struct qlcnic_adapter *adapter, u32 txq)
u8 max_hw = QLCNIC_MAX_TX_RINGS;
u32 max_allowed;
- if (!qlcnic_82xx_check(adapter)) {
- netdev_err(netdev, "No Multi TX-Q support\n");
- return -EINVAL;
- }
-
if (!qlcnic_use_msi_x && !qlcnic_use_msi) {
netdev_err(netdev, "No Multi TX-Q support in INT-x mode\n");
return -EINVAL;
@@ -3694,8 +3689,7 @@ int qlcnic_validate_max_rss(struct qlcnic_adapter *adapter,
u8 max_hw = adapter->ahw->max_rx_ques;
u32 max_allowed;
- if (qlcnic_82xx_check(adapter) && !qlcnic_use_msi_x &&
- !qlcnic_use_msi) {
+ if (!qlcnic_use_msi_x && !qlcnic_use_msi) {
netdev_err(netdev, "No RSS support in INT-x mode\n");
return -EINVAL;
}
--
1.8.1.4
^ permalink raw reply related
* [PATCH net-next v3 6/9] qlcnic: dcb code cleanup and refactoring.
From: Himanshu Madhani @ 2013-10-15 16:57 UTC (permalink / raw)
To: davem
Cc: netdev, Dept_NX_Linux_NIC_Driver, Sucheta Chakraborty,
himanshu.madhani
In-Reply-To: <cover.1381882600.git.himanshu.madhani@qlogic.com>
From: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
o Move dcb specific function definitions to dcb files.
o Move dcb specific variables to qlcnic_dcb structure.
Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
---
drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 96 -----------
.../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 2 +-
.../net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | 9 +-
drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c | 184 ++++++++++-----------
drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h | 109 ++++++++++--
drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c | 2 +-
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 24 +--
.../ethernet/qlogic/qlcnic/qlcnic_sriov_common.c | 9 +-
8 files changed, 207 insertions(+), 228 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index a3c4379..728bb88 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -961,8 +961,6 @@ struct qlcnic_ipaddr {
#define __QLCNIC_SRIOV_CAPABLE 11
#define __QLCNIC_MBX_POLL_ENABLE 12
#define __QLCNIC_DIAG_MODE 13
-#define __QLCNIC_DCB_STATE 14
-#define __QLCNIC_DCB_IN_AEN 15
#define QLCNIC_INTERRUPT_TEST 1
#define QLCNIC_LOOPBACK_TEST 2
@@ -2116,98 +2114,4 @@ static inline bool qlcnic_sriov_vf_check(struct qlcnic_adapter *adapter)
return status;
}
-
-static inline int qlcnic_dcb_get_hw_capability(struct qlcnic_adapter *adapter)
-{
- struct qlcnic_dcb *dcb = adapter->dcb;
-
- if (dcb && dcb->ops->get_hw_capability)
- return dcb->ops->get_hw_capability(adapter);
-
- return 0;
-}
-
-static inline void qlcnic_dcb_free(struct qlcnic_adapter *adapter)
-{
- struct qlcnic_dcb *dcb = adapter->dcb;
-
- if (dcb && dcb->ops->free)
- dcb->ops->free(adapter);
-}
-
-static inline int qlcnic_dcb_attach(struct qlcnic_adapter *adapter)
-{
- struct qlcnic_dcb *dcb = adapter->dcb;
-
- if (dcb && dcb->ops->attach)
- return dcb->ops->attach(adapter);
-
- return 0;
-}
-
-static inline int
-qlcnic_dcb_query_hw_capability(struct qlcnic_adapter *adapter, char *buf)
-{
- struct qlcnic_dcb *dcb = adapter->dcb;
-
- if (dcb && dcb->ops->query_hw_capability)
- return dcb->ops->query_hw_capability(adapter, buf);
-
- return 0;
-}
-
-static inline void qlcnic_dcb_get_info(struct qlcnic_adapter *adapter)
-{
- struct qlcnic_dcb *dcb = adapter->dcb;
-
- if (dcb && dcb->ops->get_info)
- dcb->ops->get_info(adapter);
-}
-
-static inline int
-qlcnic_dcb_query_cee_param(struct qlcnic_adapter *adapter, char *buf, u8 type)
-{
- struct qlcnic_dcb *dcb = adapter->dcb;
-
- if (dcb && dcb->ops->query_cee_param)
- return dcb->ops->query_cee_param(adapter, buf, type);
-
- return 0;
-}
-
-static inline int qlcnic_dcb_get_cee_cfg(struct qlcnic_adapter *adapter)
-{
- struct qlcnic_dcb *dcb = adapter->dcb;
-
- if (dcb && dcb->ops->get_cee_cfg)
- return dcb->ops->get_cee_cfg(adapter);
-
- return 0;
-}
-
-static inline void
-qlcnic_dcb_register_aen(struct qlcnic_adapter *adapter, u8 flag)
-{
- struct qlcnic_dcb *dcb = adapter->dcb;
-
- if (dcb && dcb->ops->register_aen)
- dcb->ops->register_aen(adapter, flag);
-}
-
-static inline void qlcnic_dcb_handle_aen(struct qlcnic_adapter *adapter,
- void *msg)
-{
- struct qlcnic_dcb *dcb = adapter->dcb;
-
- if (dcb && dcb->ops->handle_aen)
- dcb->ops->handle_aen(adapter, msg);
-}
-
-static inline void qlcnic_dcb_init_dcbnl_ops(struct qlcnic_adapter *adapter)
-{
- struct qlcnic_dcb *dcb = adapter->dcb;
-
- if (dcb && dcb->ops->init_dcbnl_ops)
- dcb->ops->init_dcbnl_ops(adapter);
-}
#endif /* __QLCNIC_H_ */
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index 268fda6..a126bdf 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -902,7 +902,7 @@ void __qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
QLCNIC_MBX_RSP(event[0]));
break;
case QLCNIC_MBX_DCBX_CONFIG_CHANGE_EVENT:
- qlcnic_dcb_handle_aen(adapter, (void *)&event[1]);
+ qlcnic_dcb_aen_handler(adapter->dcb, (void *)&event[1]);
break;
default:
dev_dbg(&adapter->pdev->dev, "Unsupported AEN:0x%x.\n",
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
index d303fab..e2cd484 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
@@ -636,7 +636,7 @@ int qlcnic_83xx_idc_reattach_driver(struct qlcnic_adapter *adapter)
if (adapter->portnum == 0)
qlcnic_set_drv_version(adapter);
- qlcnic_dcb_get_info(adapter);
+ qlcnic_dcb_get_info(adapter->dcb);
qlcnic_83xx_idc_attach_driver(adapter);
return 0;
@@ -2174,6 +2174,7 @@ static int qlcnic_83xx_get_fw_info(struct qlcnic_adapter *adapter)
int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac)
{
struct qlcnic_hardware_context *ahw = adapter->ahw;
+ struct qlcnic_dcb *dcb;
int err = 0;
ahw->msix_supported = !!qlcnic_use_msi_x;
@@ -2231,8 +2232,10 @@ int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac)
if (err)
goto disable_mbx_intr;
- if (adapter->dcb && qlcnic_dcb_attach(adapter))
- qlcnic_clear_dcb_ops(adapter);
+ dcb = adapter->dcb;
+
+ if (dcb && qlcnic_dcb_attach(dcb))
+ qlcnic_clear_dcb_ops(dcb);
/* Periodically monitor device status */
qlcnic_83xx_idc_poll_dev_state(&adapter->fw_work.work);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c
index d62d5ce..86bca7c 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c
@@ -57,22 +57,22 @@ static const struct dcbnl_rtnl_ops qlcnic_dcbnl_ops;
static void qlcnic_dcb_aen_work(struct work_struct *);
static void qlcnic_dcb_data_cee_param_map(struct qlcnic_adapter *);
-static inline void __qlcnic_init_dcbnl_ops(struct qlcnic_adapter *);
-static void __qlcnic_dcb_free(struct qlcnic_adapter *);
-static int __qlcnic_dcb_attach(struct qlcnic_adapter *);
-static int __qlcnic_dcb_query_hw_capability(struct qlcnic_adapter *, char *);
-static void __qlcnic_dcb_get_info(struct qlcnic_adapter *);
-
-static int qlcnic_82xx_dcb_get_hw_capability(struct qlcnic_adapter *);
-static int qlcnic_82xx_dcb_query_cee_param(struct qlcnic_adapter *, char *, u8);
-static int qlcnic_82xx_dcb_get_cee_cfg(struct qlcnic_adapter *);
-static void qlcnic_82xx_dcb_handle_aen(struct qlcnic_adapter *, void *);
-
-static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_adapter *);
-static int qlcnic_83xx_dcb_query_cee_param(struct qlcnic_adapter *, char *, u8);
-static int qlcnic_83xx_dcb_get_cee_cfg(struct qlcnic_adapter *);
-static int qlcnic_83xx_dcb_register_aen(struct qlcnic_adapter *, bool);
-static void qlcnic_83xx_dcb_handle_aen(struct qlcnic_adapter *, void *);
+static inline void __qlcnic_init_dcbnl_ops(struct qlcnic_dcb *);
+static void __qlcnic_dcb_free(struct qlcnic_dcb *);
+static int __qlcnic_dcb_attach(struct qlcnic_dcb *);
+static int __qlcnic_dcb_query_hw_capability(struct qlcnic_dcb *, char *);
+static void __qlcnic_dcb_get_info(struct qlcnic_dcb *);
+
+static int qlcnic_82xx_dcb_get_hw_capability(struct qlcnic_dcb *);
+static int qlcnic_82xx_dcb_query_cee_param(struct qlcnic_dcb *, char *, u8);
+static int qlcnic_82xx_dcb_get_cee_cfg(struct qlcnic_dcb *);
+static void qlcnic_82xx_dcb_aen_handler(struct qlcnic_dcb *, void *);
+
+static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_dcb *);
+static int qlcnic_83xx_dcb_query_cee_param(struct qlcnic_dcb *, char *, u8);
+static int qlcnic_83xx_dcb_get_cee_cfg(struct qlcnic_dcb *);
+static int qlcnic_83xx_dcb_register_aen(struct qlcnic_dcb *, bool);
+static void qlcnic_83xx_dcb_aen_handler(struct qlcnic_dcb *, void *);
struct qlcnic_dcb_capability {
bool tsa_capability;
@@ -180,7 +180,7 @@ static struct qlcnic_dcb_ops qlcnic_83xx_dcb_ops = {
.query_cee_param = qlcnic_83xx_dcb_query_cee_param,
.get_cee_cfg = qlcnic_83xx_dcb_get_cee_cfg,
.register_aen = qlcnic_83xx_dcb_register_aen,
- .handle_aen = qlcnic_83xx_dcb_handle_aen,
+ .aen_handler = qlcnic_83xx_dcb_aen_handler,
};
static struct qlcnic_dcb_ops qlcnic_82xx_dcb_ops = {
@@ -193,7 +193,7 @@ static struct qlcnic_dcb_ops qlcnic_82xx_dcb_ops = {
.get_hw_capability = qlcnic_82xx_dcb_get_hw_capability,
.query_cee_param = qlcnic_82xx_dcb_query_cee_param,
.get_cee_cfg = qlcnic_82xx_dcb_get_cee_cfg,
- .handle_aen = qlcnic_82xx_dcb_handle_aen,
+ .aen_handler = qlcnic_82xx_dcb_aen_handler,
};
static u8 qlcnic_dcb_get_num_app(struct qlcnic_adapter *adapter, u32 val)
@@ -242,10 +242,10 @@ static int qlcnic_dcb_prio_count(u8 up_tc_map)
return j;
}
-static inline void __qlcnic_init_dcbnl_ops(struct qlcnic_adapter *adapter)
+static inline void __qlcnic_init_dcbnl_ops(struct qlcnic_dcb *dcb)
{
- if (test_bit(__QLCNIC_DCB_STATE, &adapter->state))
- adapter->netdev->dcbnl_ops = &qlcnic_dcbnl_ops;
+ if (test_bit(QLCNIC_DCB_STATE, &dcb->state))
+ dcb->adapter->netdev->dcbnl_ops = &qlcnic_dcbnl_ops;
}
static void qlcnic_set_dcb_ops(struct qlcnic_adapter *adapter)
@@ -256,7 +256,7 @@ static void qlcnic_set_dcb_ops(struct qlcnic_adapter *adapter)
adapter->dcb->ops = &qlcnic_83xx_dcb_ops;
}
-int __qlcnic_register_dcb(struct qlcnic_adapter *adapter)
+int qlcnic_register_dcb(struct qlcnic_adapter *adapter)
{
struct qlcnic_dcb *dcb;
@@ -267,20 +267,22 @@ int __qlcnic_register_dcb(struct qlcnic_adapter *adapter)
adapter->dcb = dcb;
dcb->adapter = adapter;
qlcnic_set_dcb_ops(adapter);
+ dcb->state = 0;
return 0;
}
-static void __qlcnic_dcb_free(struct qlcnic_adapter *adapter)
+static void __qlcnic_dcb_free(struct qlcnic_dcb *dcb)
{
- struct qlcnic_dcb *dcb = adapter->dcb;
+ struct qlcnic_adapter *adapter;
if (!dcb)
return;
- qlcnic_dcb_register_aen(adapter, 0);
+ adapter = dcb->adapter;
+ qlcnic_dcb_register_aen(dcb, 0);
- while (test_bit(__QLCNIC_DCB_IN_AEN, &adapter->state))
+ while (test_bit(QLCNIC_DCB_AEN_MODE, &dcb->state))
usleep_range(10000, 11000);
cancel_delayed_work_sync(&dcb->aen_work);
@@ -298,23 +300,22 @@ static void __qlcnic_dcb_free(struct qlcnic_adapter *adapter)
adapter->dcb = NULL;
}
-static void __qlcnic_dcb_get_info(struct qlcnic_adapter *adapter)
+static void __qlcnic_dcb_get_info(struct qlcnic_dcb *dcb)
{
- qlcnic_dcb_get_hw_capability(adapter);
- qlcnic_dcb_get_cee_cfg(adapter);
- qlcnic_dcb_register_aen(adapter, 1);
+ qlcnic_dcb_get_hw_capability(dcb);
+ qlcnic_dcb_get_cee_cfg(dcb);
+ qlcnic_dcb_register_aen(dcb, 1);
}
-static int __qlcnic_dcb_attach(struct qlcnic_adapter *adapter)
+static int __qlcnic_dcb_attach(struct qlcnic_dcb *dcb)
{
- struct qlcnic_dcb *dcb = adapter->dcb;
int err = 0;
INIT_DELAYED_WORK(&dcb->aen_work, qlcnic_dcb_aen_work);
dcb->wq = create_singlethread_workqueue("qlcnic-dcb");
if (!dcb->wq) {
- dev_err(&adapter->pdev->dev,
+ dev_err(&dcb->adapter->pdev->dev,
"DCB workqueue allocation failed. DCB will be disabled\n");
return -1;
}
@@ -331,7 +332,7 @@ static int __qlcnic_dcb_attach(struct qlcnic_adapter *adapter)
goto out_free_cfg;
}
- qlcnic_dcb_get_info(adapter);
+ qlcnic_dcb_get_info(dcb);
return 0;
out_free_cfg:
@@ -345,9 +346,9 @@ out_free_wq:
return err;
}
-static int __qlcnic_dcb_query_hw_capability(struct qlcnic_adapter *adapter,
- char *buf)
+static int __qlcnic_dcb_query_hw_capability(struct qlcnic_dcb *dcb, char *buf)
{
+ struct qlcnic_adapter *adapter = dcb->adapter;
struct qlcnic_cmd_args cmd;
u32 mbx_out;
int err;
@@ -371,15 +372,15 @@ static int __qlcnic_dcb_query_hw_capability(struct qlcnic_adapter *adapter,
return err;
}
-static int __qlcnic_dcb_get_capability(struct qlcnic_adapter *adapter, u32 *val)
+static int __qlcnic_dcb_get_capability(struct qlcnic_dcb *dcb, u32 *val)
{
- struct qlcnic_dcb_capability *cap = &adapter->dcb->cfg->capability;
+ struct qlcnic_dcb_capability *cap = &dcb->cfg->capability;
u32 mbx_out;
int err;
memset(cap, 0, sizeof(struct qlcnic_dcb_capability));
- err = qlcnic_dcb_query_hw_capability(adapter, (char *)val);
+ err = qlcnic_dcb_query_hw_capability(dcb, (char *)val);
if (err)
return err;
@@ -397,21 +398,21 @@ static int __qlcnic_dcb_get_capability(struct qlcnic_adapter *adapter, u32 *val)
if (cap->max_num_tc > QLC_DCB_MAX_TC ||
cap->max_ets_tc > cap->max_num_tc ||
cap->max_pfc_tc > cap->max_num_tc) {
- dev_err(&adapter->pdev->dev, "Invalid DCB configuration\n");
+ dev_err(&dcb->adapter->pdev->dev, "Invalid DCB configuration\n");
return -EINVAL;
}
return err;
}
-static int qlcnic_82xx_dcb_get_hw_capability(struct qlcnic_adapter *adapter)
+static int qlcnic_82xx_dcb_get_hw_capability(struct qlcnic_dcb *dcb)
{
- struct qlcnic_dcb_cfg *cfg = adapter->dcb->cfg;
+ struct qlcnic_dcb_cfg *cfg = dcb->cfg;
struct qlcnic_dcb_capability *cap;
u32 mbx_out;
int err;
- err = __qlcnic_dcb_get_capability(adapter, &mbx_out);
+ err = __qlcnic_dcb_get_capability(dcb, &mbx_out);
if (err)
return err;
@@ -419,15 +420,16 @@ static int qlcnic_82xx_dcb_get_hw_capability(struct qlcnic_adapter *adapter)
cap->dcb_capability = DCB_CAP_DCBX_VER_CEE | DCB_CAP_DCBX_LLD_MANAGED;
if (cap->dcb_capability && cap->tsa_capability && cap->ets_capability)
- set_bit(__QLCNIC_DCB_STATE, &adapter->state);
+ set_bit(QLCNIC_DCB_STATE, &dcb->state);
return err;
}
-static int qlcnic_82xx_dcb_query_cee_param(struct qlcnic_adapter *adapter,
+static int qlcnic_82xx_dcb_query_cee_param(struct qlcnic_dcb *dcb,
char *buf, u8 type)
{
u16 size = sizeof(struct qlcnic_82xx_dcb_param_mbx_le);
+ struct qlcnic_adapter *adapter = dcb->adapter;
struct qlcnic_82xx_dcb_param_mbx_le *prsp_le;
struct device *dev = &adapter->pdev->dev;
dma_addr_t cardrsp_phys_addr;
@@ -447,8 +449,7 @@ static int qlcnic_82xx_dcb_query_cee_param(struct qlcnic_adapter *adapter,
return -EINVAL;
}
- addr = dma_alloc_coherent(&adapter->pdev->dev, size, &cardrsp_phys_addr,
- GFP_KERNEL);
+ addr = dma_alloc_coherent(dev, size, &cardrsp_phys_addr, GFP_KERNEL);
if (addr == NULL)
return -ENOMEM;
@@ -488,72 +489,67 @@ out:
qlcnic_free_mbx_args(&cmd);
out_free_rsp:
- dma_free_coherent(&adapter->pdev->dev, size, addr, cardrsp_phys_addr);
+ dma_free_coherent(dev, size, addr, cardrsp_phys_addr);
return err;
}
-static int qlcnic_82xx_dcb_get_cee_cfg(struct qlcnic_adapter *adapter)
+static int qlcnic_82xx_dcb_get_cee_cfg(struct qlcnic_dcb *dcb)
{
struct qlcnic_dcb_mbx_params *mbx;
int err;
- mbx = adapter->dcb->param;
+ mbx = dcb->param;
if (!mbx)
return 0;
- err = qlcnic_dcb_query_cee_param(adapter, (char *)&mbx->type[0],
+ err = qlcnic_dcb_query_cee_param(dcb, (char *)&mbx->type[0],
QLC_DCB_LOCAL_PARAM_FWID);
if (err)
return err;
- err = qlcnic_dcb_query_cee_param(adapter, (char *)&mbx->type[1],
+ err = qlcnic_dcb_query_cee_param(dcb, (char *)&mbx->type[1],
QLC_DCB_OPER_PARAM_FWID);
if (err)
return err;
- err = qlcnic_dcb_query_cee_param(adapter, (char *)&mbx->type[2],
+ err = qlcnic_dcb_query_cee_param(dcb, (char *)&mbx->type[2],
QLC_DCB_PEER_PARAM_FWID);
if (err)
return err;
mbx->prio_tc_map = QLC_82XX_DCB_PRIO_TC_MAP;
- qlcnic_dcb_data_cee_param_map(adapter);
+ qlcnic_dcb_data_cee_param_map(dcb->adapter);
return err;
}
static void qlcnic_dcb_aen_work(struct work_struct *work)
{
- struct qlcnic_adapter *adapter;
struct qlcnic_dcb *dcb;
dcb = container_of(work, struct qlcnic_dcb, aen_work.work);
- adapter = dcb->adapter;
- qlcnic_dcb_get_cee_cfg(adapter);
- clear_bit(__QLCNIC_DCB_IN_AEN, &adapter->state);
+ qlcnic_dcb_get_cee_cfg(dcb);
+ clear_bit(QLCNIC_DCB_AEN_MODE, &dcb->state);
}
-static void qlcnic_82xx_dcb_handle_aen(struct qlcnic_adapter *adapter,
- void *data)
+static void qlcnic_82xx_dcb_aen_handler(struct qlcnic_dcb *dcb, void *data)
{
- struct qlcnic_dcb *dcb = adapter->dcb;
-
- if (test_and_set_bit(__QLCNIC_DCB_IN_AEN, &adapter->state))
+ if (test_and_set_bit(QLCNIC_DCB_AEN_MODE, &dcb->state))
return;
queue_delayed_work(dcb->wq, &dcb->aen_work, 0);
}
-static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_adapter *adapter)
+static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_dcb *dcb)
{
- struct qlcnic_dcb_capability *cap = &adapter->dcb->cfg->capability;
+ struct qlcnic_dcb_capability *cap = &dcb->cfg->capability;
u32 mbx_out;
int err;
- err = __qlcnic_dcb_get_capability(adapter, &mbx_out);
+ err = __qlcnic_dcb_get_capability(dcb, &mbx_out);
if (err)
return err;
@@ -565,14 +561,15 @@ static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_adapter *adapter)
cap->dcb_capability |= DCB_CAP_DCBX_LLD_MANAGED;
if (cap->dcb_capability && cap->tsa_capability && cap->ets_capability)
- set_bit(__QLCNIC_DCB_STATE, &adapter->state);
+ set_bit(QLCNIC_DCB_STATE, &dcb->state);
return err;
}
-static int qlcnic_83xx_dcb_query_cee_param(struct qlcnic_adapter *adapter,
+static int qlcnic_83xx_dcb_query_cee_param(struct qlcnic_dcb *dcb,
char *buf, u8 idx)
{
+ struct qlcnic_adapter *adapter = dcb->adapter;
struct qlcnic_dcb_mbx_params mbx_out;
int err, i, j, k, max_app, size;
struct qlcnic_dcb_param *each;
@@ -632,24 +629,23 @@ out:
return err;
}
-static int qlcnic_83xx_dcb_get_cee_cfg(struct qlcnic_adapter *adapter)
+static int qlcnic_83xx_dcb_get_cee_cfg(struct qlcnic_dcb *dcb)
{
- struct qlcnic_dcb *dcb = adapter->dcb;
int err;
- err = qlcnic_dcb_query_cee_param(adapter, (char *)dcb->param, 0);
+ err = qlcnic_dcb_query_cee_param(dcb, (char *)dcb->param, 0);
if (err)
return err;
- qlcnic_dcb_data_cee_param_map(adapter);
+ qlcnic_dcb_data_cee_param_map(dcb->adapter);
return err;
}
-static int qlcnic_83xx_dcb_register_aen(struct qlcnic_adapter *adapter,
- bool flag)
+static int qlcnic_83xx_dcb_register_aen(struct qlcnic_dcb *dcb, bool flag)
{
u8 val = (flag ? QLCNIC_CMD_INIT_NIC_FUNC : QLCNIC_CMD_STOP_NIC_FUNC);
+ struct qlcnic_adapter *adapter = dcb->adapter;
struct qlcnic_cmd_args cmd;
int err;
@@ -669,19 +665,17 @@ static int qlcnic_83xx_dcb_register_aen(struct qlcnic_adapter *adapter,
return err;
}
-static void qlcnic_83xx_dcb_handle_aen(struct qlcnic_adapter *adapter,
- void *data)
+static void qlcnic_83xx_dcb_aen_handler(struct qlcnic_dcb *dcb, void *data)
{
- struct qlcnic_dcb *dcb = adapter->dcb;
u32 *val = data;
- if (test_and_set_bit(__QLCNIC_DCB_IN_AEN, &adapter->state))
+ if (test_and_set_bit(QLCNIC_DCB_AEN_MODE, &dcb->state))
return;
if (*val & BIT_8)
- set_bit(__QLCNIC_DCB_STATE, &adapter->state);
+ set_bit(QLCNIC_DCB_STATE, &dcb->state);
else
- clear_bit(__QLCNIC_DCB_STATE, &adapter->state);
+ clear_bit(QLCNIC_DCB_STATE, &dcb->state);
queue_delayed_work(dcb->wq, &dcb->aen_work, 0);
}
@@ -814,12 +808,12 @@ static u8 qlcnic_dcb_get_state(struct net_device *netdev)
{
struct qlcnic_adapter *adapter = netdev_priv(netdev);
- return test_bit(__QLCNIC_DCB_STATE, &adapter->state);
+ return test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state);
}
static void qlcnic_dcb_get_perm_hw_addr(struct net_device *netdev, u8 *addr)
{
- memcpy(addr, netdev->dev_addr, netdev->addr_len);
+ memcpy(addr, netdev->perm_addr, netdev->addr_len);
}
static void
@@ -834,7 +828,7 @@ qlcnic_dcb_get_pg_tc_cfg_tx(struct net_device *netdev, int tc, u8 *prio,
type = &adapter->dcb->cfg->type[QLC_DCB_OPER_IDX];
*prio = *pgid = *bw_per = *up_tc_map = 0;
- if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state) ||
+ if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state) ||
!type->tc_param_valid)
return;
@@ -870,7 +864,7 @@ static void qlcnic_dcb_get_pg_bwg_cfg_tx(struct net_device *netdev, int pgid,
*bw_pct = 0;
type = &adapter->dcb->cfg->type[QLC_DCB_OPER_IDX];
- if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state) ||
+ if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state) ||
!type->tc_param_valid)
return;
@@ -896,7 +890,7 @@ static void qlcnic_dcb_get_pfc_cfg(struct net_device *netdev, int prio,
*setting = 0;
type = &adapter->dcb->cfg->type[QLC_DCB_OPER_IDX];
- if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state) ||
+ if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state) ||
!type->pfc_mode_enable)
return;
@@ -915,7 +909,7 @@ static u8 qlcnic_dcb_get_capability(struct net_device *netdev, int capid,
{
struct qlcnic_adapter *adapter = netdev_priv(netdev);
- if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
+ if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
return 0;
switch (capid) {
@@ -944,7 +938,7 @@ static int qlcnic_dcb_get_num_tcs(struct net_device *netdev, int attr, u8 *num)
struct qlcnic_adapter *adapter = netdev_priv(netdev);
struct qlcnic_dcb_cfg *cfg = adapter->dcb->cfg;
- if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
+ if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
return -EINVAL;
switch (attr) {
@@ -967,7 +961,7 @@ static u8 qlcnic_dcb_get_app(struct net_device *netdev, u8 idtype, u16 id)
.protocol = id,
};
- if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
+ if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
return 0;
return dcb_getapp(netdev, &app);
@@ -978,7 +972,7 @@ static u8 qlcnic_dcb_get_pfc_state(struct net_device *netdev)
struct qlcnic_adapter *adapter = netdev_priv(netdev);
struct qlcnic_dcb *dcb = adapter->dcb;
- if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
+ if (!test_bit(QLCNIC_DCB_STATE, &dcb->state))
return 0;
return dcb->cfg->type[QLC_DCB_OPER_IDX].pfc_mode_enable;
@@ -989,7 +983,7 @@ static u8 qlcnic_dcb_get_dcbx(struct net_device *netdev)
struct qlcnic_adapter *adapter = netdev_priv(netdev);
struct qlcnic_dcb_cfg *cfg = adapter->dcb->cfg;
- if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
+ if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
return 0;
return cfg->capability.dcb_capability;
@@ -1000,7 +994,7 @@ static u8 qlcnic_dcb_get_feat_cfg(struct net_device *netdev, int fid, u8 *flag)
struct qlcnic_adapter *adapter = netdev_priv(netdev);
struct qlcnic_dcb_cee *type;
- if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
+ if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
return 1;
type = &adapter->dcb->cfg->type[QLC_DCB_OPER_IDX];
@@ -1055,7 +1049,7 @@ static int qlcnic_dcb_peer_app_info(struct net_device *netdev,
*app_count = 0;
- if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
+ if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
return 0;
peer = &adapter->dcb->cfg->type[QLC_DCB_PEER_IDX];
@@ -1076,7 +1070,7 @@ static int qlcnic_dcb_peer_app_table(struct net_device *netdev,
struct qlcnic_dcb_app *app;
int i, j;
- if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
+ if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
return 0;
peer = &adapter->dcb->cfg->type[QLC_DCB_PEER_IDX];
@@ -1101,7 +1095,7 @@ static int qlcnic_dcb_cee_peer_get_pg(struct net_device *netdev,
struct qlcnic_dcb_cee *peer;
u8 i, j, k, map;
- if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
+ if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
return 0;
peer = &adapter->dcb->cfg->type[QLC_DCB_PEER_IDX];
@@ -1136,7 +1130,7 @@ static int qlcnic_dcb_cee_peer_get_pfc(struct net_device *netdev,
pfc->pfc_en = 0;
- if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
+ if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
return 0;
peer = &cfg->type[QLC_DCB_PEER_IDX];
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h
index b87ce9f..c04ae0c 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h
@@ -8,26 +8,29 @@
#ifndef __QLCNIC_DCBX_H
#define __QLCNIC_DCBX_H
-void qlcnic_clear_dcb_ops(struct qlcnic_adapter *);
+#define QLCNIC_DCB_STATE 0
+#define QLCNIC_DCB_AEN_MODE 1
#ifdef CONFIG_QLCNIC_DCB
-int __qlcnic_register_dcb(struct qlcnic_adapter *);
+int qlcnic_register_dcb(struct qlcnic_adapter *);
#else
-static inline int __qlcnic_register_dcb(struct qlcnic_adapter *adapter)
+static inline int qlcnic_register_dcb(struct qlcnic_adapter *adapter)
{ return 0; }
#endif
+struct qlcnic_dcb;
+
struct qlcnic_dcb_ops {
- void (*init_dcbnl_ops) (struct qlcnic_adapter *);
- void (*free) (struct qlcnic_adapter *);
- int (*attach) (struct qlcnic_adapter *);
- int (*query_hw_capability) (struct qlcnic_adapter *, char *);
- int (*get_hw_capability) (struct qlcnic_adapter *);
- void (*get_info) (struct qlcnic_adapter *);
- int (*query_cee_param) (struct qlcnic_adapter *, char *, u8);
- int (*get_cee_cfg) (struct qlcnic_adapter *);
- int (*register_aen) (struct qlcnic_adapter *, bool);
- void (*handle_aen) (struct qlcnic_adapter *, void *);
+ int (*query_hw_capability) (struct qlcnic_dcb *, char *);
+ int (*get_hw_capability) (struct qlcnic_dcb *);
+ int (*query_cee_param) (struct qlcnic_dcb *, char *, u8);
+ void (*init_dcbnl_ops) (struct qlcnic_dcb *);
+ int (*register_aen) (struct qlcnic_dcb *, bool);
+ void (*aen_handler) (struct qlcnic_dcb *, void *);
+ int (*get_cee_cfg) (struct qlcnic_dcb *);
+ void (*get_info) (struct qlcnic_dcb *);
+ int (*attach) (struct qlcnic_dcb *);
+ void (*free) (struct qlcnic_dcb *);
};
struct qlcnic_dcb {
@@ -37,5 +40,85 @@ struct qlcnic_dcb {
struct workqueue_struct *wq;
struct qlcnic_dcb_ops *ops;
struct qlcnic_dcb_cfg *cfg;
+ unsigned long state;
};
+
+static inline void qlcnic_clear_dcb_ops(struct qlcnic_dcb *dcb)
+{
+ kfree(dcb);
+ dcb = NULL;
+}
+
+static inline int qlcnic_dcb_get_hw_capability(struct qlcnic_dcb *dcb)
+{
+ if (dcb && dcb->ops->get_hw_capability)
+ return dcb->ops->get_hw_capability(dcb);
+
+ return 0;
+}
+
+static inline void qlcnic_dcb_free(struct qlcnic_dcb *dcb)
+{
+ if (dcb && dcb->ops->free)
+ dcb->ops->free(dcb);
+}
+
+static inline int qlcnic_dcb_attach(struct qlcnic_dcb *dcb)
+{
+ if (dcb && dcb->ops->attach)
+ return dcb->ops->attach(dcb);
+
+ return 0;
+}
+
+static inline int
+qlcnic_dcb_query_hw_capability(struct qlcnic_dcb *dcb, char *buf)
+{
+ if (dcb && dcb->ops->query_hw_capability)
+ return dcb->ops->query_hw_capability(dcb, buf);
+
+ return 0;
+}
+
+static inline void qlcnic_dcb_get_info(struct qlcnic_dcb *dcb)
+{
+ if (dcb && dcb->ops->get_info)
+ dcb->ops->get_info(dcb);
+}
+
+static inline int
+qlcnic_dcb_query_cee_param(struct qlcnic_dcb *dcb, char *buf, u8 type)
+{
+ if (dcb && dcb->ops->query_cee_param)
+ return dcb->ops->query_cee_param(dcb, buf, type);
+
+ return 0;
+}
+
+static inline int qlcnic_dcb_get_cee_cfg(struct qlcnic_dcb *dcb)
+{
+ if (dcb && dcb->ops->get_cee_cfg)
+ return dcb->ops->get_cee_cfg(dcb);
+
+ return 0;
+}
+
+static inline void
+qlcnic_dcb_register_aen(struct qlcnic_dcb *dcb, u8 flag)
+{
+ if (dcb && dcb->ops->register_aen)
+ dcb->ops->register_aen(dcb, flag);
+}
+
+static inline void qlcnic_dcb_aen_handler(struct qlcnic_dcb *dcb, void *msg)
+{
+ if (dcb && dcb->ops->aen_handler)
+ dcb->ops->aen_handler(dcb, msg);
+}
+
+static inline void qlcnic_dcb_init_dcbnl_ops(struct qlcnic_dcb *dcb)
+{
+ if (dcb && dcb->ops->init_dcbnl_ops)
+ dcb->ops->init_dcbnl_ops(dcb);
+}
#endif
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
index 11b4bb8..897627d 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
@@ -1011,7 +1011,7 @@ static void qlcnic_handle_fw_message(int desc_cnt, int index,
}
break;
case QLCNIC_C2H_OPCODE_GET_DCB_AEN:
- qlcnic_dcb_handle_aen(adapter, (void *)&msg);
+ qlcnic_dcb_aen_handler(adapter->dcb, (void *)&msg);
break;
default:
break;
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 725d76f..0274832 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -2071,7 +2071,7 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev,
return err;
}
- qlcnic_dcb_init_dcbnl_ops(adapter);
+ qlcnic_dcb_init_dcbnl_ops(adapter->dcb);
return 0;
}
@@ -2166,17 +2166,6 @@ void qlcnic_set_drv_version(struct qlcnic_adapter *adapter)
qlcnic_fw_cmd_set_drv_version(adapter, fw_cmd);
}
-static int qlcnic_register_dcb(struct qlcnic_adapter *adapter)
-{
- return __qlcnic_register_dcb(adapter);
-}
-
-void qlcnic_clear_dcb_ops(struct qlcnic_adapter *adapter)
-{
- kfree(adapter->dcb);
- adapter->dcb = NULL;
-}
-
static int
qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
@@ -2185,6 +2174,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
struct qlcnic_hardware_context *ahw;
int err, pci_using_dac = -1;
char board_name[QLCNIC_MAX_BOARD_NAME_LEN + 19]; /* MAC + ": " + name */
+ struct qlcnic_dcb *dcb;
if (pdev->is_virtfn)
return -ENODEV;
@@ -2305,8 +2295,10 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
adapter->flags |= QLCNIC_NEED_FLR;
- if (adapter->dcb && qlcnic_dcb_attach(adapter))
- qlcnic_clear_dcb_ops(adapter);
+ dcb = adapter->dcb;
+
+ if (dcb && qlcnic_dcb_attach(dcb))
+ qlcnic_clear_dcb_ops(dcb);
} else if (qlcnic_83xx_check(adapter)) {
adapter->max_drv_tx_rings = 1;
@@ -2451,7 +2443,7 @@ static void qlcnic_remove(struct pci_dev *pdev)
qlcnic_cancel_idc_work(adapter);
ahw = adapter->ahw;
- qlcnic_dcb_free(adapter);
+ qlcnic_dcb_free(adapter->dcb);
unregister_netdev(netdev);
qlcnic_sriov_cleanup(adapter);
@@ -3329,7 +3321,7 @@ qlcnic_attach_work(struct work_struct *work)
return;
}
attach:
- qlcnic_dcb_get_info(adapter);
+ qlcnic_dcb_get_info(adapter->dcb);
if (netif_running(netdev)) {
if (qlcnic_up(adapter, netdev))
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
index 392b9bd..8b96e29 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
@@ -500,6 +500,7 @@ static int qlcnic_sriov_vf_init_driver(struct qlcnic_adapter *adapter)
static int qlcnic_sriov_setup_vf(struct qlcnic_adapter *adapter,
int pci_using_dac)
{
+ struct qlcnic_dcb *dcb;
int err;
INIT_LIST_HEAD(&adapter->vf_mc_list);
@@ -533,8 +534,10 @@ static int qlcnic_sriov_setup_vf(struct qlcnic_adapter *adapter,
if (err)
goto err_out_send_channel_term;
- if (adapter->dcb && qlcnic_dcb_attach(adapter))
- qlcnic_clear_dcb_ops(adapter);
+ dcb = adapter->dcb;
+
+ if (dcb && qlcnic_dcb_attach(dcb))
+ qlcnic_clear_dcb_ops(dcb);
err = qlcnic_setup_netdev(adapter, adapter->netdev, pci_using_dac);
if (err)
@@ -1577,7 +1580,7 @@ static int qlcnic_sriov_vf_reinit_driver(struct qlcnic_adapter *adapter)
if (err)
goto err_out_term_channel;
- qlcnic_dcb_get_info(adapter);
+ qlcnic_dcb_get_info(adapter->dcb);
return 0;
--
1.8.1.4
^ permalink raw reply related
* [PATCH net-next v3 1/9] qlcnic: Print informational messages only once during driver load.
From: Himanshu Madhani @ 2013-10-15 16:57 UTC (permalink / raw)
To: davem
Cc: netdev, Dept_NX_Linux_NIC_Driver, Sucheta Chakraborty,
himanshu.madhani
In-Reply-To: <cover.1381882600.git.himanshu.madhani@qlogic.com>
From: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
---
drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 1 +
.../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 12 -----------
.../net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c | 24 ++++++++++++++++++----
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 1 +
4 files changed, 22 insertions(+), 16 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index 81bf836..a3c4379 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -1199,6 +1199,7 @@ struct qlcnic_npar_info {
u8 promisc_mode;
u8 offload_flags;
u8 pci_func;
+ u8 mac[ETH_ALEN];
};
struct qlcnic_eswitch {
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index 3ca00e0..66e94dc 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -2321,19 +2321,7 @@ int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *adapter,
i++;
memcpy(pci_info->mac + sizeof(u32), &cmd.rsp.arg[i], 2);
i = i + 3;
- if (ahw->op_mode == QLCNIC_MGMT_FUNC)
- dev_info(dev, "id = %d active = %d type = %d\n"
- "\tport = %d min bw = %d max bw = %d\n"
- "\tmac_addr = %pM\n", pci_info->id,
- pci_info->active, pci_info->type,
- pci_info->default_port,
- pci_info->tx_min_bw,
- pci_info->tx_max_bw, pci_info->mac);
}
- if (ahw->op_mode == QLCNIC_MGMT_FUNC)
- dev_info(dev, "Max functions = %d, active functions = %d\n",
- ahw->max_pci_func, ahw->act_pci_func);
-
} else {
dev_err(dev, "Failed to get PCI Info, error = %d\n", err);
err = -EIO;
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c
index 0248a4c..60a477f 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c
@@ -94,13 +94,29 @@ qlcnic_83xx_config_vnic_buff_descriptors(struct qlcnic_adapter *adapter)
**/
static int qlcnic_83xx_init_mgmt_vnic(struct qlcnic_adapter *adapter)
{
- int err = -EIO;
+ struct qlcnic_hardware_context *ahw = adapter->ahw;
+ struct device *dev = &adapter->pdev->dev;
+ struct qlcnic_npar_info *npar;
+ int i, err = -EIO;
qlcnic_83xx_get_minidump_template(adapter);
+
if (!(adapter->flags & QLCNIC_ADAPTER_INITIALIZED)) {
if (qlcnic_init_pci_info(adapter))
return err;
+ npar = adapter->npars;
+
+ for (i = 0; i < ahw->act_pci_func; i++, npar++) {
+ dev_info(dev, "id:%d active:%d type:%d port:%d min_bw:%d max_bw:%d mac_addr:%pM\n",
+ npar->pci_func, npar->active, npar->type,
+ npar->phy_port, npar->min_bw, npar->max_bw,
+ npar->mac);
+ }
+
+ dev_info(dev, "Max functions = %d, active functions = %d\n",
+ ahw->max_pci_func, ahw->act_pci_func);
+
if (qlcnic_83xx_set_vnic_opmode(adapter))
return err;
@@ -115,12 +131,12 @@ static int qlcnic_83xx_init_mgmt_vnic(struct qlcnic_adapter *adapter)
return err;
qlcnic_83xx_config_vnic_buff_descriptors(adapter);
- adapter->ahw->msix_supported = !!qlcnic_use_msi_x;
+ ahw->msix_supported = qlcnic_use_msi_x ? 1 : 0;
adapter->flags |= QLCNIC_ADAPTER_INITIALIZED;
qlcnic_83xx_enable_vnic_mode(adapter, 1);
- dev_info(&adapter->pdev->dev, "HAL Version: %d, Management function\n",
- adapter->ahw->fw_hal_version);
+ dev_info(dev, "HAL Version: %d, Management function\n",
+ ahw->fw_hal_version);
return 0;
}
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index f07f2b0..55e8b23 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -875,6 +875,7 @@ int qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
adapter->npars[j].min_bw = pci_info[i].tx_min_bw;
adapter->npars[j].max_bw = pci_info[i].tx_max_bw;
+ memcpy(&adapter->npars[j].mac, &pci_info[i].mac, ETH_ALEN);
j++;
}
--
1.8.1.4
^ permalink raw reply related
* [PATCH net-next v3 5/9] qlcnic: Remove redundant eSwitch enable commands
From: Himanshu Madhani @ 2013-10-15 16:57 UTC (permalink / raw)
To: davem; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Sony Chacko, himanshu.madhani
In-Reply-To: <cover.1381882600.git.himanshu.madhani@qlogic.com>
From: Sony Chacko <sony.chacko@qlogic.com>
When more than one NIC physical functions are enabled on a port,
eSwitch on that port gets enabled automatically. Driver
need not explicitly enable the eSwitch.
Signed-off-by: Sony Chacko <sony.chacko@qlogic.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
---
.../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h | 2 +-
.../net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c | 23 ++++------------------
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 13 ++++++------
3 files changed, 12 insertions(+), 26 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
index 2883b57..9f4e4c4 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
@@ -629,7 +629,7 @@ int qlcnic_83xx_config_vnic_opmode(struct qlcnic_adapter *);
int qlcnic_83xx_get_vnic_vport_info(struct qlcnic_adapter *,
struct qlcnic_info *, u8);
int qlcnic_83xx_get_vnic_pf_info(struct qlcnic_adapter *, struct qlcnic_info *);
-int qlcnic_83xx_enable_port_eswitch(struct qlcnic_adapter *, int);
+int qlcnic_83xx_set_port_eswitch_status(struct qlcnic_adapter *, int, int *);
void qlcnic_83xx_get_minidump_template(struct qlcnic_adapter *);
void qlcnic_83xx_get_stats(struct qlcnic_adapter *adapter, u64 *data);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c
index 60a477f..734d286 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c
@@ -256,8 +256,8 @@ int qlcnic_83xx_check_vnic_state(struct qlcnic_adapter *adapter)
return 0;
}
-static int qlcnic_83xx_get_eswitch_port_info(struct qlcnic_adapter *adapter,
- int func, int *port_id)
+int qlcnic_83xx_set_port_eswitch_status(struct qlcnic_adapter *adapter,
+ int func, int *port_id)
{
struct qlcnic_info nic_info;
int err = 0;
@@ -273,23 +273,8 @@ static int qlcnic_83xx_get_eswitch_port_info(struct qlcnic_adapter *adapter,
else
err = -EIO;
- return err;
-}
-
-int qlcnic_83xx_enable_port_eswitch(struct qlcnic_adapter *adapter, int func)
-{
- int id, err = 0;
-
- err = qlcnic_83xx_get_eswitch_port_info(adapter, func, &id);
- if (err)
- return err;
-
- if (!(adapter->eswitch[id].flags & QLCNIC_SWITCH_ENABLE)) {
- if (!qlcnic_enable_eswitch(adapter, id, 1))
- adapter->eswitch[id].flags |= QLCNIC_SWITCH_ENABLE;
- else
- err = -EIO;
- }
+ if (!err)
+ adapter->eswitch[*port_id].flags |= QLCNIC_SWITCH_ENABLE;
return err;
}
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 5195972..725d76f 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -819,7 +819,7 @@ static bool qlcnic_port_eswitch_cfg_capability(struct qlcnic_adapter *adapter)
int qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
{
struct qlcnic_pci_info *pci_info;
- int i, ret = 0, j = 0;
+ int i, id = 0, ret = 0, j = 0;
u16 act_pci_func;
u8 pfn;
@@ -860,7 +860,8 @@ int qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
continue;
if (qlcnic_port_eswitch_cfg_capability(adapter)) {
- if (!qlcnic_83xx_enable_port_eswitch(adapter, pfn))
+ if (!qlcnic_83xx_set_port_eswitch_status(adapter, pfn,
+ &id))
adapter->npars[j].eswitch_status = true;
else
continue;
@@ -879,12 +880,12 @@ int qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
j++;
}
- if (qlcnic_82xx_check(adapter)) {
+ /* Update eSwitch status for adapters without per port eSwitch
+ * configuration capability
+ */
+ if (!qlcnic_port_eswitch_cfg_capability(adapter)) {
for (i = 0; i < QLCNIC_NIU_MAX_XG_PORTS; i++)
adapter->eswitch[i].flags |= QLCNIC_SWITCH_ENABLE;
- } else if (!qlcnic_port_eswitch_cfg_capability(adapter)) {
- for (i = 0; i < QLCNIC_NIU_MAX_XG_PORTS; i++)
- qlcnic_enable_eswitch(adapter, i, 1);
}
kfree(pci_info);
--
1.8.1.4
^ permalink raw reply related
* [PATCH net-next v3 2/9] qlcnic: Enhance ethtool to display ring indices and interrupt mask
From: Himanshu Madhani @ 2013-10-15 16:57 UTC (permalink / raw)
To: davem; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Pratik Pujar, himanshu.madhani
In-Reply-To: <cover.1381882600.git.himanshu.madhani@qlogic.com>
From: Pratik Pujar <pratik.pujar@qlogic.com>
o Updated ethtool -d <ethX> option to display ring indices for Transmit(Tx),
Receive(Rx), and Status(St) rings.
o Updated ethtool -d <ethX> option to display ring interrupt mask for Transmit(Tx),
and Status(St) rings.
Signed-off-by: Pratik Pujar <pratik.pujar@qlogic.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
---
.../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 8 ++--
.../net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | 54 ++++++++++++++++------
2 files changed, 44 insertions(+), 18 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index 66e94dc..c2df4ce 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -3267,12 +3267,12 @@ int qlcnic_83xx_reg_test(struct qlcnic_adapter *adapter)
return 0;
}
-int qlcnic_83xx_get_regs_len(struct qlcnic_adapter *adapter)
+inline int qlcnic_83xx_get_regs_len(struct qlcnic_adapter *adapter)
{
return (ARRAY_SIZE(qlcnic_83xx_ext_reg_tbl) *
- sizeof(adapter->ahw->ext_reg_tbl)) +
- (ARRAY_SIZE(qlcnic_83xx_reg_tbl) +
- sizeof(adapter->ahw->reg_tbl));
+ sizeof(*adapter->ahw->ext_reg_tbl)) +
+ (ARRAY_SIZE(qlcnic_83xx_reg_tbl) *
+ sizeof(*adapter->ahw->reg_tbl));
}
int qlcnic_83xx_get_registers(struct qlcnic_adapter *adapter, u32 *regs_buff)
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
index ebe4c86..66355b7 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
@@ -187,8 +187,8 @@ static int qlcnic_dev_statistics_len(struct qlcnic_adapter *adapter)
return -1;
}
-#define QLCNIC_RING_REGS_COUNT 20
-#define QLCNIC_RING_REGS_LEN (QLCNIC_RING_REGS_COUNT * sizeof(u32))
+#define QLCNIC_TX_INTR_NOT_CONFIGURED 0X78563412
+
#define QLCNIC_MAX_EEPROM_LEN 1024
static const u32 diag_registers[] = {
@@ -219,7 +219,15 @@ static const u32 ext_diag_registers[] = {
};
#define QLCNIC_MGMT_API_VERSION 2
-#define QLCNIC_ETHTOOL_REGS_VER 3
+#define QLCNIC_ETHTOOL_REGS_VER 4
+
+static inline int qlcnic_get_ring_regs_len(struct qlcnic_adapter *adapter)
+{
+ int ring_regs_cnt = (adapter->max_drv_tx_rings * 5) +
+ (adapter->max_rds_rings * 2) +
+ (adapter->max_sds_rings * 3) + 5;
+ return ring_regs_cnt * sizeof(u32);
+}
static int qlcnic_get_regs_len(struct net_device *dev)
{
@@ -231,7 +239,9 @@ static int qlcnic_get_regs_len(struct net_device *dev)
else
len = sizeof(ext_diag_registers) + sizeof(diag_registers);
- return QLCNIC_RING_REGS_LEN + len + QLCNIC_DEV_INFO_SIZE + 1;
+ len += ((QLCNIC_DEV_INFO_SIZE + 2) * sizeof(u32));
+ len += qlcnic_get_ring_regs_len(adapter);
+ return len;
}
static int qlcnic_get_eeprom_len(struct net_device *dev)
@@ -493,6 +503,8 @@ qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
struct qlcnic_adapter *adapter = netdev_priv(dev);
struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
struct qlcnic_host_sds_ring *sds_ring;
+ struct qlcnic_host_rds_ring *rds_rings;
+ struct qlcnic_host_tx_ring *tx_ring;
u32 *regs_buff = p;
int ring, i = 0;
@@ -512,21 +524,35 @@ qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
return;
- regs_buff[i++] = 0xFFEFCDAB; /* Marker btw regs and ring count*/
-
- regs_buff[i++] = 1; /* No. of tx ring */
- regs_buff[i++] = le32_to_cpu(*(adapter->tx_ring->hw_consumer));
- regs_buff[i++] = readl(adapter->tx_ring->crb_cmd_producer);
-
- regs_buff[i++] = 2; /* No. of rx ring */
- regs_buff[i++] = readl(recv_ctx->rds_rings[0].crb_rcv_producer);
- regs_buff[i++] = readl(recv_ctx->rds_rings[1].crb_rcv_producer);
+ /* Marker btw regs and TX ring count */
+ regs_buff[i++] = 0xFFEFCDAB;
+
+ regs_buff[i++] = adapter->max_drv_tx_rings; /* No. of TX ring */
+ for (ring = 0; ring < adapter->max_drv_tx_rings; ring++) {
+ tx_ring = &adapter->tx_ring[ring];
+ regs_buff[i++] = le32_to_cpu(*(tx_ring->hw_consumer));
+ regs_buff[i++] = tx_ring->sw_consumer;
+ regs_buff[i++] = readl(tx_ring->crb_cmd_producer);
+ regs_buff[i++] = tx_ring->producer;
+ if (tx_ring->crb_intr_mask)
+ regs_buff[i++] = readl(tx_ring->crb_intr_mask);
+ else
+ regs_buff[i++] = QLCNIC_TX_INTR_NOT_CONFIGURED;
+ }
- regs_buff[i++] = adapter->max_sds_rings;
+ regs_buff[i++] = adapter->max_rds_rings; /* No. of RX ring */
+ for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+ rds_rings = &recv_ctx->rds_rings[ring];
+ regs_buff[i++] = readl(rds_rings->crb_rcv_producer);
+ regs_buff[i++] = rds_rings->producer;
+ }
+ regs_buff[i++] = adapter->max_sds_rings; /* No. of SDS ring */
for (ring = 0; ring < adapter->max_sds_rings; ring++) {
sds_ring = &(recv_ctx->sds_rings[ring]);
regs_buff[i++] = readl(sds_ring->crb_sts_consumer);
+ regs_buff[i++] = sds_ring->consumer;
+ regs_buff[i++] = readl(sds_ring->crb_intr_mask);
}
}
--
1.8.1.4
^ 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