Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH] net: qmi_wwan: Olivetti Olicard 200 support
From: Enrico Mioso @ 2013-10-15 16:07 UTC (permalink / raw)
  To: Dan Williams
  Cc: gregkh, davem, bjorn, christian.schmiedl, linux-usb, netdev,
	linux-kernel, Antonella Pellizzari
In-Reply-To: <1381848597.25397.4.camel@dcbw.foobar.com>

:) I'm very happy you got it working.
The firmware of our device seems so fragile still - and several QMI calls can 
bring it to a crashing state, especially when asking a network scan to the NAS 
service.


On Tue, 15 Oct 2013, Dan Williams wrote:

==Date: Tue, 15 Oct 2013 09:49:57 -0500
==From: Dan Williams <dcbw@redhat.com>
==To: Enrico Mioso <mrkiko.rs@gmail.com>
==Cc: gregkh@linuxfoundation.org, davem@davemloft.net, bjorn@mork.no,
==    christian.schmiedl@gemalto.com, linux-usb@vger.kernel.org,
==    netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
==    Antonella Pellizzari <anto.pellizzari83@gmail.com>
==Subject: Re: [PATCH] net: qmi_wwan: Olivetti Olicard 200 support
==
==On Tue, 2013-10-15 at 15:06 +0200, Enrico Mioso wrote:
==> This is a QMI device, manufactured by TCT Mobile Phones.
==> A companion patch blacklisting this device's QMI interface in the option.c
==> driver has been sent.
==> 
==> Signed-off-by: Enrico Mioso <mrkiko.rs@gmail.com>
==> Signed-off-by: Antonella Pellizzari <anto.pellizzari83@gmail.com>
==
==Good find.  For the record, mine has:
==
==PX1522E16X  1  [Oct 15 2010 02:00:00]
==
==	ctl (1.4)
==	wds (1.8)
==	dms (1.3)
==	nas (1.2)
==	qos (1.2)
==	wms (1.1)
==	pds (1.4)
==	auth (1.0)
==	voice (1.0)
==	cat2 (1.1)
==
==Tested-by: Dan Williams <dcbw@redhat.com>
==
==> diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
==> index 3d6aaf7..818ce90 100644
==> --- a/drivers/net/usb/qmi_wwan.c
==> +++ b/drivers/net/usb/qmi_wwan.c
==> @@ -714,6 +714,7 @@ static const struct usb_device_id products[] = {
==>  	{QMI_FIXED_INTF(0x2357, 0x0201, 4)},	/* TP-LINK HSUPA Modem MA180 */
==>  	{QMI_FIXED_INTF(0x2357, 0x9000, 4)},	/* TP-LINK MA260 */
==>  	{QMI_FIXED_INTF(0x1bc7, 0x1200, 5)},	/* Telit LE920 */
==> +	{QMI_FIXED_INTF(0x0b3c, 0xc005, 6)},    /* Olivetti Olicard 200 */
==>  	{QMI_FIXED_INTF(0x1e2d, 0x0060, 4)},	/* Cinterion PLxx */
==>  
==>  	/* 4. Gobi 1000 devices */
==
==
==

^ permalink raw reply

* getting lldp DCB_CMD_IEEE_GET after DCB_CMD_GCAP fails
From: Olaf Hering @ 2013-10-15 16:18 UTC (permalink / raw)
  To: netdev


If this list is the wrong place, please point me to the right direction.


In the example code below the part which grabs DCB_CMD_IEEE_GET fails,
unless the "hack" part is executed. What I see inside the kernel is that
__netlink_dump_start gets to the err=-EBUSY case because nlk->cb is
still set. The nl_ack_handler is executed, an "empty" error is returned.
I have compared my code with open-lldp-0.9.46/test/nltest.c and did not
spot the difference.


Is the code below supposed to work anyway? Thanks for any help.


Olaf


/* cc -lnl lldptest.c -o lldptest */
#include <stdio.h>
#include <netlink/msg.h>
#include <linux/dcbnl.h>

static int nl_dump_valid(struct nl_msg *msg, void *p)
{
	struct nlmsghdr *nlh = p;
	nlh = nlmsg_hdr(msg);
	printf("%s: %x\n", __func__, nlh->nlmsg_len);
	return NL_OK;
}

static int nl_ack_handler(struct nl_msg *msg, void *arg)
{
	arg = msg;
	printf("%s: %p\n", __func__, arg);
	return NL_STOP;
}

static int nl_error_handler(struct sockaddr_nl *sender, struct nlmsgerr *err, void *arg)
{
	char *s = arg;
	printf("%s: %p %s %x\n", __func__, sender, s, err->error);
	return NL_STOP;
}

int main(int argc, char *argv[])
{
	struct nl_handle *nl_handle;
	struct nl_cb *nl_cb, *tmp_cb;
	struct nl_msg *msg;
	struct nlattr *nla;
	struct dcbmsg dcb = {.dcb_family = AF_UNSPEC, };
	char *ifname;
	int hack;
	int protocol = 0;
	int ret = 1;

	if (argc < 2) {
		printf("Usage: %s <ifname> [hack]\n", argv[0]);
		goto out;
	}
	ifname = argv[1];
	hack = !!argv[2];

	nl_cb = nl_cb_alloc(NL_CB_DEFAULT);
	if (!nl_cb) {
		perror("nl_cb_alloc");
		goto out;
	}
	nl_handle = nl_handle_alloc_cb(nl_cb);
	if (nl_connect(nl_handle, protocol) < 0) {
		perror("nl_connect");
		goto out;
	}

	tmp_cb = nl_cb_clone(nl_cb);
	dcb.cmd = DCB_CMD_GCAP;
	nl_cb_err(tmp_cb, NL_CB_CUSTOM, nl_error_handler, "DCB_CMD_GCAP");
	nl_cb_set(tmp_cb, NL_CB_ACK, NL_CB_CUSTOM, nl_ack_handler, NULL);
	nl_cb_set(tmp_cb, NL_CB_VALID, NL_CB_CUSTOM, nl_dump_valid, NULL);

	msg = nlmsg_alloc_simple(RTM_GETDCB, NLM_F_REQUEST);
	if (!msg) {
		perror("nlmsg_alloc_simple");
		goto out;
	}
	if (nlmsg_append(msg, &dcb, sizeof(dcb), NLMSG_ALIGNTO) < 0) {
		perror("nlmsg_append");
		goto out;
	}

	NLA_PUT_STRING(msg, DCB_ATTR_IFNAME, ifname);
	nla = nla_nest_start(msg, DCB_ATTR_CAP);
	NLA_PUT_FLAG(msg, DCB_CAP_ATTR_ALL);
	nla_nest_end(msg, nla);

	if (nl_send_auto_complete(nl_handle, msg) < 0) {
		perror("nl_send_auto_complete");
		goto out;
	}

	if ((nl_recvmsgs(nl_handle, tmp_cb)) < 0) {
		perror("nl_recvmsgs");
		goto out;
	}

	nl_cb_put(tmp_cb);
	nlmsg_free(msg);

	if (hack) {
		nl_close(nl_handle);
		nl_handle = nl_handle_alloc_cb(nl_cb);
		if (nl_connect(nl_handle, protocol) < 0) {
			perror("nl_connect");
			goto out;
		}
	}

	tmp_cb = nl_cb_clone(nl_cb);
	dcb.cmd = DCB_CMD_IEEE_GET;
	nl_cb_err(tmp_cb, NL_CB_CUSTOM, nl_error_handler, "DCB_CMD_IEEE_GET");
	nl_cb_set(tmp_cb, NL_CB_ACK, NL_CB_CUSTOM, nl_ack_handler, NULL);
	nl_cb_set(tmp_cb, NL_CB_VALID, NL_CB_CUSTOM, nl_dump_valid, NULL);

	msg = nlmsg_alloc_simple(RTM_GETDCB, NLM_F_REQUEST);
	if (!msg) {
		perror("nlmsg_alloc_simple");
		goto out;
	}
	if (nlmsg_append(msg, &dcb, sizeof(dcb), NLMSG_ALIGNTO) < 0) {
		perror("nlmsg_append");
		goto out;
	}

	NLA_PUT_STRING(msg, DCB_ATTR_IFNAME, ifname);
	if (nl_send_auto_complete(nl_handle, msg) < 0) {
		perror("nl_send_auto_complete");
		goto out;
	}

	if ((nl_recvmsgs(nl_handle, tmp_cb)) < 0) {
		perror("nl_recvmsgs");
		goto out;
	}

	nl_cb_put(tmp_cb);
	nlmsg_free(msg);

	ret = 0;

      nla_put_failure:
      out:
	return ret;
}

^ permalink raw reply

* Re: DomU's network interface will hung when Dom0 running 32bit
From: jianhai luan @ 2013-10-15 16:23 UTC (permalink / raw)
  To: Wei Liu; +Cc: Ian Campbell, xen-devel, netdev, ANNIE LI
In-Reply-To: <20131015160336.GT11739@zion.uk.xensource.com>


On 2013-10-16 0:03, Wei Liu wrote:
> On Tue, Oct 15, 2013 at 11:19:42PM +0800, jianhai luan wrote:
> [...]
>>>>>> * time_after_eq(now, next_credit) -> false
>>>>>> * time_before(now, expires) -> false
>>>>> If now is placed in above environment, the result will be correct
>>>>> (Sending package will be not allowed until next_credit).
>>>> No, it is not necessarily correct. Keep in mind that "now" wraps around,
>>>> which is the issue you try to fix. You still have a window to stall your
>>>> frontend.
>>> Remember that time_after_eq is supposed to work even with wraparound
>>> occurring, so long as the two times are less than MAX_LONG/2 apart.
>> Sorry for my misunderstand explanation. I mean that
>>    * time_after_eq()/time_before_eq() fix the jiffies wraparound, so
>> please think about  jiffies in line increasing.
>>    * time_after_eq()/time_before_eq() have the range (0, MAX_LONG/2),
>> the judge will be wrong if out of the range.
>>
>> So please think about three kind environment
>>    -  expires        now        next_credit
>>       --------time increases this direction ---------->
>>
>>    -  expires        [next_credit        now next_credit+MAX_LONG/2
>>       --------time increase this direction ----------->
>>
>>    - expires        next_credit        next_credit+MAX_LONG/2 now
>>       --------time increadse this direction ---------->
>>
>> The first environment should be netfront consume all credit_byte
>> before next_credit, So we should pending one timer to calculator the
>> new credit_byte, and don't transmit until next_credit.
>>
>> the second environment should be calculator the credit_byte because
>> netfront don't consume all credit_byte before next_credit, and
>> time_after_eq() do correct judge.
>>
>> the third environment should be calculator in time because netfront
>> don't consume all credit_byte until next_credit.But time_after_eq do
>> error judge (time_after_eq(now, next_credit) is false), so the
>> remaining_byte isn't be increased.
>>
>> and I work on the third environment.  You know now >
>> next_credit+MAX_LONG/2, time_before(now, expire) should be
>> true(time_before(now, expire) is false in first environment)
> Thanks for staighten this out for me. I'm just too dumb for this, please
> be patient with me. :-)
>
> Could you prove that time_before(now, expire) is always true in third
> case? That's where my main cencern lies. Is it because msecs_to_jiffies
> always returns MAX_JIFFY_OFFSET (which is ((LONG_MAX >> 1)-1) ) at most?

I have wrong judge in third environment. If now large than expires + 
MAX_UNLONG, time_before(now, expires) will be false.
   expires    next_credit    next_credit+MAX_UNLONG/2    expires + 
MAX_UNLONG    now    next_credit+MAX_UNLONG
   --------------------------------------------------------- time 
increadse this direction  ---------------------------------->

   In the above environment, time_before(now, expires) will return 
false. But the jiffies elapsed more time and next_credit will be 
reachable in soon(time_after_eq(now, next_credit) will be true).
>
> Wei.

^ permalink raw reply

* Re: [PATCH 02/18] net: use wrapper functions of net_ratelimit() to simplify code
From: Joe Perches @ 2013-10-15 16:24 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-3-git-send-email-wangkefeng.wang@huawei.com>

On Tue, 2013-10-15 at 19:44 +0800, Kefeng Wang wrote:
> Wrapper functions net_ratelimited_function() and net_XXX_ratelimited()
> are called to simplify code.
[]
> diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
[]
> @@ -465,10 +465,8 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source,
>  	if (likely(fdb)) {
>  		/* attempt to update an entry for a local interface */
>  		if (unlikely(fdb->is_local)) {
> -			if (net_ratelimit())
> -				br_warn(br, "received packet on %s with "
> -					"own address as source address\n",
> -					source->dev->name);
> +			net_ratelimited_function(br_warn, br, "received packet on %s "
> +				"with own address as source address\n", source->dev->name);

Hello Kefeng.

When these types of lines are changed, please coalesce the
fragmented format pieces into a single string.

It makes grep a bit easier and 80 columns limits don't
apply to formats.

I think using net_ratelimited_function is not particularly
clarifying here.

Maybe net_ratelimited_function should be removed instead
of its use sites expanded.

Perhaps adding macros like #define br_warn_ratelimited()
would be better.

This comment applies to the whole series.

^ permalink raw reply

* Re: [PATCH] veth: Showing peer of veth type dev in ip link (kernel side)
From: Nicolas Dichtel @ 2013-10-15 16:44 UTC (permalink / raw)
  To: Eric W. Biederman, Stephen Hemminger; +Cc: David Miller, yamato, netdev
In-Reply-To: <87li22vv1w.fsf@xmission.com>

Le 10/10/2013 02:17, Eric W. Biederman a écrit :
> Stephen Hemminger <stephen@networkplumber.org> writes:
>
>> On Tue, 8 Oct 2013 14:13:37 -0700
>> Stephen Hemminger <stephen@networkplumber.org> wrote:
>>
>>> On Tue, 08 Oct 2013 15:23:49 -0400 (EDT)
>>> David Miller <davem@davemloft.net> wrote:
>>>
>>>> From: Masatake YAMATO <yamato@redhat.com>
>>>> Date: Fri,  4 Oct 2013 11:34:21 +0900
>>>>
>>>>> ip link has ability to show extra information of net work device if
>>>>> kernel provides sunh information. With this patch veth driver can
>>>>> provide its peer ifindex information to ip command via netlink
>>>>> interface.
>>>>>
>>>>> Signed-off-by: Masatake YAMATO <yamato@redhat.com>
>>>>
>>>> Applied to net-next, thank you.
>>>> --
>>>> 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
>>>
>>> Please revert this. It is incorrect.
>>> The info returned by any netlink message should be equal to the message
>>> for setting.
>>>
>>> I think the correct patch would be something like this (compile tested only).
>>>
>>> --- a/drivers/net/veth.c	2013-10-06 14:48:23.806461177 -0700
>>> +++ b/drivers/net/veth.c	2013-10-08 14:11:42.434074690 -0700
>>> @@ -434,6 +434,35 @@ static const struct nla_policy veth_poli
>>>   	[VETH_INFO_PEER]	= { .len = sizeof(struct ifinfomsg) },
>>>   };
>>>
>>> +static size_t veth_get_size(const struct net_device *dev)
>>> +{
>>> +	return nla_total_size(sizeof(struct ifinfomsg)) + /* VETH_INFO_PEER */
>>> +		0;
>>> +}
>>> +
>>> +static int veth_fill_info(struct sk_buff *skb, const struct net_device *dev)
>>> +{
>>> +	struct veth_priv *priv = netdev_priv(dev);
>>> +	struct net_device *peer = rtnl_dereference(priv->peer);
>>> +
>>> +	if (peer) {
>>> +		struct ifinfomsg ifi = {
>>> +			.ifi_family = AF_UNSPEC,
>>> +			.ifi_type = peer->type,
>>> +			.ifi_index = peer->ifindex,
>>> +			.ifi_flags = dev_get_flags(peer),
>>> +		};
>>> +
>>> +		if (nla_put(skb, VETH_INFO_PEER, sizeof(ifi), &ifi))
>>> +			goto nla_put_failure;
>>> +	}
>>> +
>>> +	return 0;
>>> +
>>> +nla_put_failure:
>>> +	return -EMSGSIZE;
>>> +}
>>> +
>>>   static struct rtnl_link_ops veth_link_ops = {
>>>   	.kind		= DRV_NAME,
>>>   	.priv_size	= sizeof(struct veth_priv),
>>> @@ -443,6 +472,8 @@ static struct rtnl_link_ops veth_link_op
>>>   	.dellink	= veth_dellink,
>>>   	.policy		= veth_policy,
>>>   	.maxtype	= VETH_INFO_MAX,
>>> +	.get_size	= veth_get_size,
>>> +	.fill_info	= veth_fill_info,
>>>   };
>>>
>>>   /*
>>>
>>>
>>
>> This patch is ok as RFC starting point but the full implementation needs to
>> add on IFLA_NAME and other attributes such that the full peer can be reconstructed.
>>
>> Ideally, the output of 'ip link' command can be in a format that can be used
>> to recreate the same veth pair.
>>
>> One issue is that veth has the ability to make a peer in a different namespace
>> and the network namespace code does not appear to have the ability to be invertable.
>> I.e it is not possible to construct IFLA_NET_NS_PID or IFLA_NET_NS_FD attributes
>> from an existing network device namespace.
>
> Right.
>
> IFLA_NET_NS_PID is not invertible as there may be no processes running
> in a pid namespace.
>
> IFLA_NET_NS_FD is in principle invertible.  We just need to add a file
> descriptor to the callers fd table.  I don't see IFLA_NET_NS_FD being
> invertible for broadcast messages, but for unicast it looks like a bit
> of a pain but there are no fundamental problems.
I'm not sure to understand why it is invertible only for unicast message.
Or are you saying that it is invertible only for the netns where the caller 
stands (and then not for the veth peer)?

>
> I don't know if we care enough yet to write the code for the
> IFLA_NET_NS_FD attribute but it is doable.
I care ;-)
Has somebody already started to write a patch?

^ permalink raw reply

* Re: [PATCH v3 net-next] openvswitch: fix vport-netdev unregister
From: Alexei Starovoitov @ 2013-10-15 16:53 UTC (permalink / raw)
  To: Jesse Gross
  Cc: David S. Miller, Pravin B Shelar, Jiri Pirko, Cong Wang,
	dev@openvswitch.org, netdev
In-Reply-To: <CAEP_g=-hkjjph8qO8MQL=BBA8MnaUdE2vTy3jN+m7Vh5skfa6g@mail.gmail.com>

On Tue, Oct 15, 2013 at 8:31 AM, Jesse Gross <jesse@nicira.com> wrote:
> On Sun, Oct 13, 2013 at 8:50 PM, Alexei Starovoitov <ast@plumgrid.com> wrote:
>> diff --git a/net/openvswitch/dp_notify.c b/net/openvswitch/dp_notify.c
>> index c323567..ffa429a 100644
>> --- a/net/openvswitch/dp_notify.c
>> +++ b/net/openvswitch/dp_notify.c
>> @@ -59,15 +59,9 @@ void ovs_dp_notify_wq(struct work_struct *work)
>>                         struct hlist_node *n;
>>
>>                         hlist_for_each_entry_safe(vport, n, &dp->ports[i], dp_hash_node) {
>> -                               struct netdev_vport *netdev_vport;
>> -
>>                                 if (vport->ops->type != OVS_VPORT_TYPE_NETDEV)
>>                                         continue;
>> -
>> -                               netdev_vport = netdev_vport_priv(vport);
>> -                               if (netdev_vport->dev->reg_state == NETREG_UNREGISTERED ||
>> -                                   netdev_vport->dev->reg_state == NETREG_UNREGISTERING)
>> -                                       dp_detach_port_notify(vport);
>> +                               dp_detach_port_notify(vport);
>
> Doesn't this free *all* ports of type OVS_VPORT_TYPE_NETDEV when any
> one of them is removed?

sorry. not sure what I was thinking on Sunday evening. will respin

^ permalink raw reply

* [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 Xiangzhong @ 2013-10-15 16:59 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 |  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;
 			}
 
 			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
-- 
1.7.9.5

^ permalink raw reply related

* Re: [PATCH] drivers: net: phy: marvell.c: removed checkpatch.pl warnings
From: Sergei Shtylyov @ 2013-10-15 17:12 UTC (permalink / raw)
  To: Avinash kumar; +Cc: davem, michal.simek, lars, RHoover, netdev
In-Reply-To: <1380514004-8701-1-git-send-email-avi.kp.137@gmail.com>

Hello.

On 09/30/2013 08:06 AM, Avinash kumar wrote:

> removes following warnings-
> drivers/net/phy/marvell.c:37: WARNING: Use #include <linux/io.h> instead of <asm/io.h>
> drivers/net/phy/marvell.c:39: WARNING: Use #include <linux/uaccess.h> instead of <asm/uaccess.h>

> Signed-off-by: Avinash Kumar <avi.kp.137@gmail.com>
> ---
>   drivers/net/phy/marvell.c |    4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)

> diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
> index 2e91477..2e3c778e 100644
> --- a/drivers/net/phy/marvell.c
> +++ b/drivers/net/phy/marvell.c
> @@ -34,9 +34,9 @@
>   #include <linux/marvell_phy.h>
>   #include <linux/of.h>
>
> -#include <asm/io.h>
> +#include <linux/io.h>
>   #include <asm/irq.h>
> -#include <asm/uaccess.h>
> +#include <linux/uaccess.h>

    You should move these #include's to the group of <linux/> #include's  now.

WBR, Sergei

^ permalink raw reply

* 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:25 UTC (permalink / raw)
  To: Chang Xiangzhong; +Cc: nhorman, davem, linux-sctp, netdev, linux-kernel
In-Reply-To: <1381856348-15503-1-git-send-email-changxiangzhong@gmail.com>

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?

@@ -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

* [PATCH net-next v3 4/9] qlcnic: Update ethtool standard pause settings.
From: Himanshu Madhani @ 2013-10-15 16:57 UTC (permalink / raw)
  To: davem; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Jitendra Kalsaria,
	himanshu.madhani
In-Reply-To: <cover.1381882600.git.himanshu.madhani@qlogic.com>

From: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>

Update ethtool standard pause parameter settings and display

Signed-off-by: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 18 +++++++++++++++---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h |  3 +++
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index c2df4ce..268fda6 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -3369,10 +3369,21 @@ void qlcnic_83xx_get_pauseparam(struct qlcnic_adapter *adapter,
 	}
 	config = ahw->port_config;
 	if (config & QLC_83XX_CFG_STD_PAUSE) {
-		if (config & QLC_83XX_CFG_STD_TX_PAUSE)
+		switch (MSW(config)) {
+		case QLC_83XX_TX_PAUSE:
+			pause->tx_pause = 1;
+			break;
+		case QLC_83XX_RX_PAUSE:
+			pause->rx_pause = 1;
+			break;
+		case QLC_83XX_TX_RX_PAUSE:
+		default:
+			/* Backward compatibility for existing
+			 * flash definitions
+			 */
 			pause->tx_pause = 1;
-		if (config & QLC_83XX_CFG_STD_RX_PAUSE)
 			pause->rx_pause = 1;
+		}
 	}
 
 	if (QLC_83XX_AUTONEG(config))
@@ -3415,7 +3426,8 @@ int qlcnic_83xx_set_pauseparam(struct qlcnic_adapter *adapter,
 		ahw->port_config &= ~QLC_83XX_CFG_STD_RX_PAUSE;
 		ahw->port_config |= QLC_83XX_CFG_STD_TX_PAUSE;
 	} else if (!pause->rx_pause && !pause->tx_pause) {
-		ahw->port_config &= ~QLC_83XX_CFG_STD_TX_RX_PAUSE;
+		ahw->port_config &= ~(QLC_83XX_CFG_STD_TX_RX_PAUSE |
+				      QLC_83XX_CFG_STD_PAUSE);
 	}
 	status = qlcnic_83xx_set_port_config(adapter);
 	if (status) {
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
index 533e150..2883b57 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
@@ -363,6 +363,9 @@ enum qlcnic_83xx_states {
 #define QLC_83XX_LINK_EEE(data)		((data) & BIT_13)
 #define QLC_83XX_DCBX(data)			(((data) >> 28) & 7)
 #define QLC_83XX_AUTONEG(data)			((data) & BIT_15)
+#define QLC_83XX_TX_PAUSE			0x10
+#define QLC_83XX_RX_PAUSE			0x20
+#define QLC_83XX_TX_RX_PAUSE			0x30
 #define QLC_83XX_CFG_STD_PAUSE			(1 << 5)
 #define QLC_83XX_CFG_STD_TX_PAUSE		(1 << 20)
 #define QLC_83XX_CFG_STD_RX_PAUSE		(2 << 20)
-- 
1.8.1.4

^ permalink raw reply related

* [PATCH net-next v3 0/9] qlcnic: fixes and ethtool enhancements.
From: Himanshu Madhani @ 2013-10-15 16:57 UTC (permalink / raw)
  To: davem; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Himanshu Madhani

From: Himanshu Madhani <himanshu.madhani@qlogic.com>

This patch series contains

o patch to fix regression introduced by commit
  aa4a1f7df7cbb98797c9f4edfde3c726e2b3841f.
o updates to ethtool for pause settings and enhance
  register dump to display mask and ring indices.
o cleanup in DCB code and remove redundant eSwitch enablement command.
o fixed firmware dump collection logic to skip unknown entries.

Changes from v2 -> v3

o Updated patch to print informational messages as per Joe Perches's comment.

Changes from v1 -> v2

o Dropped patch to register device if adapter is in FAILED state for more rework.
o Updated patch to display ring indices via ethtool per Ben Hutchings's comment.
o Update patch for DCB cleanup per Stephen Hemminger's comment.

Please apply to net-next.

Thanks,
Himanshu

Himanshu Madhani (2):
  qlcnic: Validate Tx queue only for 82xx adapters.
  qlcnic: update version to 5.3.51

Jitendra Kalsaria (1):
  qlcnic: Update ethtool standard pause settings.

Pratik Pujar (2):
  qlcnic: Enhance ethtool to display ring indices and interrupt mask
  qlcnic: Firmware dump collection when auto recovery is disabled.

Shahed Shaikh (1):
  qlcnic: Skip unknown entry type while collecting firmware dump

Sony Chacko (1):
  qlcnic: Remove redundant eSwitch enable commands

Sucheta Chakraborty (2):
  qlcnic: Print informational messages only once during driver load.
  qlcnic: dcb code cleanup and refactoring.

 drivers/net/ethernet/qlogic/qlcnic/qlcnic.h        | 101 +----------
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c    |  40 ++---
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h    |   5 +-
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c  |  20 ++-
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c  |  47 +++---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c    | 184 ++++++++++-----------
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h    | 109 ++++++++++--
 .../net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c    |  56 +++++--
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c     |   2 +-
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c   |  53 +++---
 .../net/ethernet/qlogic/qlcnic/qlcnic_minidump.c   |  41 +++--
 .../ethernet/qlogic/qlcnic/qlcnic_sriov_common.c   |   9 +-
 12 files changed, 343 insertions(+), 324 deletions(-)

-- 
1.8.1.4

^ permalink raw reply

* [PATCH net-next v3 3/9] qlcnic: Firmware dump collection when auto recovery is disabled.
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 Allow collecting the firmware dump of halted firmware when auto
  recovery is disabled.

Signed-off-by: Pratik Pujar <pratik.pujar@qlogic.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | 11 +++++++++++
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c      |  7 ++++++-
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
index f09e787..d303fab 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
@@ -818,6 +818,7 @@ static int qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter)
 	struct qlcnic_hardware_context *ahw = adapter->ahw;
 	struct qlcnic_mailbox *mbx = ahw->mailbox;
 	int ret = 0;
+	u32 owner;
 	u32 val;
 
 	/* Perform NIC configuration based ready state entry actions */
@@ -846,6 +847,10 @@ static int qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter)
 			clear_bit(QLC_83XX_MBX_READY, &mbx->status);
 			set_bit(__QLCNIC_RESETTING, &adapter->state);
 			qlcnic_83xx_idc_enter_need_reset_state(adapter, 1);
+		}  else {
+			owner = qlcnic_83xx_idc_find_reset_owner_id(adapter);
+			if (ahw->pci_func == owner)
+				qlcnic_dump_fw(adapter);
 		}
 		return -EIO;
 	}
@@ -1058,6 +1063,12 @@ void qlcnic_83xx_idc_poll_dev_state(struct work_struct *work)
 	adapter->ahw->idc.prev_state = adapter->ahw->idc.curr_state;
 	qlcnic_83xx_periodic_tasks(adapter);
 
+	/* Do not reschedule if firmaware is in hanged state and auto
+	 * recovery is disabled
+	 */
+	if ((adapter->flags & QLCNIC_FW_HANG) && !qlcnic_auto_fw_reset)
+		return;
+
 	/* Re-schedule the function */
 	if (test_bit(QLC_83XX_MODULE_LOADED, &adapter->ahw->idc.status))
 		qlcnic_schedule_work(adapter, qlcnic_83xx_idc_poll_dev_state,
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 55e8b23..5195972 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -3353,6 +3353,8 @@ done:
 static int
 qlcnic_check_health(struct qlcnic_adapter *adapter)
 {
+	struct qlcnic_hardware_context *ahw = adapter->ahw;
+	struct qlcnic_fw_dump *fw_dump = &ahw->fw_dump;
 	u32 state = 0, heartbeat;
 	u32 peg_status;
 	int err = 0;
@@ -3377,7 +3379,7 @@ qlcnic_check_health(struct qlcnic_adapter *adapter)
 		if (adapter->need_fw_reset)
 			goto detach;
 
-		if (adapter->ahw->reset_context && qlcnic_auto_fw_reset)
+		if (ahw->reset_context && qlcnic_auto_fw_reset)
 			qlcnic_reset_hw_context(adapter);
 
 		return 0;
@@ -3420,6 +3422,9 @@ detach:
 
 		qlcnic_schedule_work(adapter, qlcnic_detach_work, 0);
 		QLCDB(adapter, DRV, "fw recovery scheduled.\n");
+	} else if (!qlcnic_auto_fw_reset && fw_dump->enable &&
+		   adapter->flags & QLCNIC_FW_RESET_OWNER) {
+		qlcnic_dump_fw(adapter);
 	}
 
 	return 1;
-- 
1.8.1.4

^ permalink raw reply related

* [PATCH net-next v3 8/9] qlcnic: Skip unknown entry type while collecting firmware dump
From: Himanshu Madhani @ 2013-10-15 16:57 UTC (permalink / raw)
  To: davem; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Shahed Shaikh, himanshu.madhani
In-Reply-To: <cover.1381882600.git.himanshu.madhani@qlogic.com>

From: Shahed Shaikh <shahed.shaikh@qlogic.com>

o Driver aborts the minidump collection operation when it finds
  an unknown entry opcode. This patch skips unknown entry type
  and resumes the minidump collection operation.
o Removed a comparision of collected dump size with expected dump size.
  Size may differ when driver decides to skip an entry.

Signed-off-by: Shahed Shaikh <shahed.shaikh@qlogic.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
---
 .../net/ethernet/qlogic/qlcnic/qlcnic_minidump.c   | 41 ++++++++++------------
 1 file changed, 19 insertions(+), 22 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c
index 1551360..7763962 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c
@@ -1187,41 +1187,38 @@ int qlcnic_dump_fw(struct qlcnic_adapter *adapter)
 		}
 
 		if (ops_index == ops_cnt) {
-			dev_info(&adapter->pdev->dev,
-				 "Invalid entry type %d, exiting dump\n",
+			dev_info(dev, "Skipping unknown entry opcode %d\n",
 				 entry->hdr.type);
-			goto error;
+			entry->hdr.flags |= QLCNIC_DUMP_SKIP;
+			entry_offset += entry->hdr.offset;
+			continue;
 		}
 
 		/* Collect dump for this entry */
 		dump = fw_dump_ops[ops_index].handler(adapter, entry, buffer);
-		if (!qlcnic_valid_dump_entry(&adapter->pdev->dev, entry, dump))
+		if (!qlcnic_valid_dump_entry(dev, entry, dump)) {
 			entry->hdr.flags |= QLCNIC_DUMP_SKIP;
+			entry_offset += entry->hdr.offset;
+			continue;
+		}
+
 		buf_offset += entry->hdr.cap_size;
 		entry_offset += entry->hdr.offset;
 		buffer = fw_dump->data + buf_offset;
 	}
-	if (dump_size != buf_offset) {
-		dev_info(&adapter->pdev->dev,
-			 "Captured(%d) and expected size(%d) do not match\n",
-			 buf_offset, dump_size);
-		goto error;
-	} else {
-		fw_dump->clr = 1;
-		snprintf(mesg, sizeof(mesg), "FW_DUMP=%s",
-			 adapter->netdev->name);
-		dev_info(&adapter->pdev->dev, "%s: Dump data, %d bytes captured\n",
-			 adapter->netdev->name, fw_dump->size);
-		/* Send a udev event to notify availability of FW dump */
-		kobject_uevent_env(&adapter->pdev->dev.kobj, KOBJ_CHANGE, msg);
-		return 0;
-	}
-error:
+
+	fw_dump->clr = 1;
+	snprintf(mesg, sizeof(mesg), "FW_DUMP=%s", adapter->netdev->name);
+	dev_info(dev, "%s: Dump data %d bytes captured, template header size %d bytes\n",
+		 adapter->netdev->name, fw_dump->size, tmpl_hdr->size);
+	/* Send a udev event to notify availability of FW dump */
+	kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, msg);
+
 	if (fw_dump->use_pex_dma)
 		dma_free_coherent(dev, QLC_PEX_DMA_READ_SIZE,
 				  fw_dump->dma_buffer, fw_dump->phys_addr);
-	vfree(fw_dump->data);
-	return -EINVAL;
+
+	return 0;
 }
 
 void qlcnic_83xx_get_minidump_template(struct qlcnic_adapter *adapter)
-- 
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

* [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 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 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 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 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

* 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

* 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

* 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: 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: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

* [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


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox