* [PATCH net-next] netxen: explicity handle pause autoneg parameter
From: Flavio Leitner @ 2012-10-26 17:17 UTC (permalink / raw)
To: netdev; +Cc: Sony Chacko, Rajesh Borundia, Flavio Leitner
The hardware doesn't support controlling pause frames autoneg, so
report that back correctly to userspace.
Signed-off-by: Flavio Leitner <fbl@redhat.com>
---
drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c | 6 ++++++
1 file changed, 6 insertions(+)
I don't have the hardware handy to test this, so I appreciate
if someone could do it.
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c
index 10468e7..b4b46f9 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c
@@ -488,6 +488,8 @@ netxen_nic_get_pauseparam(struct net_device *dev,
__u32 val;
int port = adapter->physical_port;
+ pause->autoneg = AUTONEG_DISABLE;
+
if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
if ((port < 0) || (port >= NETXEN_NIU_MAX_GBE_PORTS))
return;
@@ -532,6 +534,10 @@ netxen_nic_set_pauseparam(struct net_device *dev,
struct netxen_adapter *adapter = netdev_priv(dev);
__u32 val;
int port = adapter->physical_port;
+
+ if (pause->autoneg)
+ return -EOPNOTSUPP;
+
/* read mode */
if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
if ((port < 0) || (port >= NETXEN_NIU_MAX_GBE_PORTS))
--
1.7.11.4
^ permalink raw reply related
* [PATCH net-next] sk-filter: Add ability to get socket filter program
From: Pavel Emelyanov @ 2012-10-26 17:15 UTC (permalink / raw)
To: Linux Netdev List, David Miller
The SO_ATTACH_FILTER option is set only. I propose to add the get
ability by using SO_ATTACH_FILTER in getsockopt. To be less irritating
to eyes the SO_GET_FILTER alias to it is declared.
There are two issues with getting filter back.
First, kernel modifies the sock_filter->code on filter load, thus in
order to return the filter element back to user we have to decode it
into user-visible constants. Fortunately the modification in question
is interconvertible.
Second, the BPF_S_ALU_DIV_K code modifies the command argument k to
speed up the run-time division by doing kernel_k = reciprocal(user_k).
Bad news is that different user_k may result in same kernel_k, so we
can't get the original user_k back. Good news is that we don't have
to do it. What we need to is calculate a user2_k so, that
reciprocal(user2_k) == reciprocal(user_k) == kernel_k
i.e. if it's re-loaded back the compiled again value will be exactly
the same as it was. That said, the user2_k can be calculated like this
user2_k = reciprocal(kernel_k)
with an exception, that if kernel_k == 0, then user2_k == 1.
The optlen argument is treated like this -- when zero, kernel returns
the amount of sock_fprog elements in filter, otherwise it should be
large enough for the sock_fprog array.
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
---
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 24d251f..6ca0085 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -45,6 +45,7 @@ extern void sk_unattached_filter_destroy(struct sk_filter *fp);
extern int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk);
extern int sk_detach_filter(struct sock *sk);
extern int sk_chk_filter(struct sock_filter *filter, unsigned int flen);
+extern int sk_get_filter(struct sock *sk, struct sock_filter __user *filter, unsigned len);
#ifdef CONFIG_BPF_JIT
extern void bpf_jit_compile(struct sk_filter *fp);
diff --git a/include/uapi/asm-generic/socket.h b/include/uapi/asm-generic/socket.h
index b1bea03..2d32d07 100644
--- a/include/uapi/asm-generic/socket.h
+++ b/include/uapi/asm-generic/socket.h
@@ -43,6 +43,7 @@
/* Socket filtering */
#define SO_ATTACH_FILTER 26
#define SO_DETACH_FILTER 27
+#define SO_GET_FILTER SO_ATTACH_FILTER
#define SO_PEERNAME 28
#define SO_TIMESTAMP 29
diff --git a/net/core/filter.c b/net/core/filter.c
index 3d92ebb..0a8cb99 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -751,3 +751,131 @@ int sk_detach_filter(struct sock *sk)
return ret;
}
EXPORT_SYMBOL_GPL(sk_detach_filter);
+
+static void sk_decode_filter(struct sock_filter *filt, struct sock_filter *to)
+{
+ static const u16 decodes[] = {
+ [BPF_S_ALU_ADD_K] = BPF_ALU|BPF_ADD|BPF_K,
+ [BPF_S_ALU_ADD_X] = BPF_ALU|BPF_ADD|BPF_X,
+ [BPF_S_ALU_SUB_K] = BPF_ALU|BPF_SUB|BPF_K,
+ [BPF_S_ALU_SUB_X] = BPF_ALU|BPF_SUB|BPF_X,
+ [BPF_S_ALU_MUL_K] = BPF_ALU|BPF_MUL|BPF_K,
+ [BPF_S_ALU_MUL_X] = BPF_ALU|BPF_MUL|BPF_X,
+ [BPF_S_ALU_DIV_X] = BPF_ALU|BPF_DIV|BPF_X,
+ [BPF_S_ALU_MOD_K] = BPF_ALU|BPF_MOD|BPF_K,
+ [BPF_S_ALU_MOD_X] = BPF_ALU|BPF_MOD|BPF_X,
+ [BPF_S_ALU_AND_K] = BPF_ALU|BPF_AND|BPF_K,
+ [BPF_S_ALU_AND_X] = BPF_ALU|BPF_AND|BPF_X,
+ [BPF_S_ALU_OR_K] = BPF_ALU|BPF_OR|BPF_K,
+ [BPF_S_ALU_OR_X] = BPF_ALU|BPF_OR|BPF_X,
+ [BPF_S_ALU_XOR_K] = BPF_ALU|BPF_XOR|BPF_K,
+ [BPF_S_ALU_XOR_X] = BPF_ALU|BPF_XOR|BPF_X,
+ [BPF_S_ALU_LSH_K] = BPF_ALU|BPF_LSH|BPF_K,
+ [BPF_S_ALU_LSH_X] = BPF_ALU|BPF_LSH|BPF_X,
+ [BPF_S_ALU_RSH_K] = BPF_ALU|BPF_RSH|BPF_K,
+ [BPF_S_ALU_RSH_X] = BPF_ALU|BPF_RSH|BPF_X,
+ [BPF_S_ALU_NEG] = BPF_ALU|BPF_NEG,
+ [BPF_S_LD_W_ABS] = BPF_LD|BPF_W|BPF_ABS,
+ [BPF_S_LD_H_ABS] = BPF_LD|BPF_H|BPF_ABS,
+ [BPF_S_LD_B_ABS] = BPF_LD|BPF_B|BPF_ABS,
+ [BPF_S_ANC_PROTOCOL] = BPF_LD|BPF_B|BPF_ABS,
+ [BPF_S_ANC_PKTTYPE] = BPF_LD|BPF_B|BPF_ABS,
+ [BPF_S_ANC_IFINDEX] = BPF_LD|BPF_B|BPF_ABS,
+ [BPF_S_ANC_NLATTR] = BPF_LD|BPF_B|BPF_ABS,
+ [BPF_S_ANC_NLATTR_NEST] = BPF_LD|BPF_B|BPF_ABS,
+ [BPF_S_ANC_MARK] = BPF_LD|BPF_B|BPF_ABS,
+ [BPF_S_ANC_QUEUE] = BPF_LD|BPF_B|BPF_ABS,
+ [BPF_S_ANC_HATYPE] = BPF_LD|BPF_B|BPF_ABS,
+ [BPF_S_ANC_RXHASH] = BPF_LD|BPF_B|BPF_ABS,
+ [BPF_S_ANC_CPU] = BPF_LD|BPF_B|BPF_ABS,
+ [BPF_S_ANC_ALU_XOR_X] = BPF_LD|BPF_B|BPF_ABS,
+ [BPF_S_ANC_SECCOMP_LD_W] = BPF_LD|BPF_B|BPF_ABS,
+ [BPF_S_LD_W_LEN] = BPF_LD|BPF_W|BPF_LEN,
+ [BPF_S_LD_W_IND] = BPF_LD|BPF_W|BPF_IND,
+ [BPF_S_LD_H_IND] = BPF_LD|BPF_H|BPF_IND,
+ [BPF_S_LD_B_IND] = BPF_LD|BPF_B|BPF_IND,
+ [BPF_S_LD_IMM] = BPF_LD|BPF_IMM,
+ [BPF_S_LDX_W_LEN] = BPF_LDX|BPF_W|BPF_LEN,
+ [BPF_S_LDX_B_MSH] = BPF_LDX|BPF_B|BPF_MSH,
+ [BPF_S_LDX_IMM] = BPF_LDX|BPF_IMM,
+ [BPF_S_MISC_TAX] = BPF_MISC|BPF_TAX,
+ [BPF_S_MISC_TXA] = BPF_MISC|BPF_TXA,
+ [BPF_S_RET_K] = BPF_RET|BPF_K,
+ [BPF_S_RET_A] = BPF_RET|BPF_A,
+ [BPF_S_ALU_DIV_K] = BPF_ALU|BPF_DIV|BPF_K,
+ [BPF_S_LD_MEM] = BPF_LD|BPF_MEM,
+ [BPF_S_LDX_MEM] = BPF_LDX|BPF_MEM,
+ [BPF_S_ST] = BPF_ST,
+ [BPF_S_STX] = BPF_STX,
+ [BPF_S_JMP_JA] = BPF_JMP|BPF_JA,
+ [BPF_S_JMP_JEQ_K] = BPF_JMP|BPF_JEQ|BPF_K,
+ [BPF_S_JMP_JEQ_X] = BPF_JMP|BPF_JEQ|BPF_X,
+ [BPF_S_JMP_JGE_K] = BPF_JMP|BPF_JGE|BPF_K,
+ [BPF_S_JMP_JGE_X] = BPF_JMP|BPF_JGE|BPF_X,
+ [BPF_S_JMP_JGT_K] = BPF_JMP|BPF_JGT|BPF_K,
+ [BPF_S_JMP_JGT_X] = BPF_JMP|BPF_JGT|BPF_X,
+ [BPF_S_JMP_JSET_K] = BPF_JMP|BPF_JSET|BPF_K,
+ [BPF_S_JMP_JSET_X] = BPF_JMP|BPF_JSET|BPF_X,
+ };
+ u16 code;
+
+ code = filt->code;
+
+ to->code = decodes[code];
+ to->jt = filt->jt;
+ to->jf = filt->jf;
+
+ if (code == BPF_S_ALU_DIV_K) {
+ /*
+ * When loaded this rule user gave us X, which was
+ * translated into R = r(X). Now we calculate the
+ * RR = r(R) and report it back. If next time this
+ * value is loaded and RRR = r(RR) is calculated
+ * then the R == RRR will be true.
+ *
+ * One exception. X == 1 translates into R == 0 and
+ * we can't calculate RR out of it with r().
+ */
+
+ if (filt->k == 0)
+ to->k = 1;
+ else
+ to->k = reciprocal_value(filt->k);
+
+ BUG_ON(reciprocal_value(to->k) != filt->k);
+ } else
+ to->k = filt->k;
+}
+
+int sk_get_filter(struct sock *sk, struct sock_filter __user *ubuf, unsigned int len)
+{
+ struct sk_filter *filter;
+ int i, ret;
+
+ lock_sock(sk);
+ filter = rcu_dereference_protected(sk->sk_filter,
+ sock_owned_by_user(sk));
+ ret = 0;
+ if (!filter)
+ goto out;
+ ret = filter->len;
+ if (!len)
+ goto out;
+ ret = -EINVAL;
+ if (len < filter->len)
+ goto out;
+
+ ret = -EFAULT;
+ for (i = 0; i < filter->len; i++) {
+ struct sock_filter fb;
+
+ sk_decode_filter(&filter->insns[i], &fb);
+ if (copy_to_user(&ubuf[i], &fb, sizeof(fb)))
+ goto out;
+ }
+
+ ret = filter->len;
+out:
+ release_sock(sk);
+ return ret;
+}
diff --git a/net/core/sock.c b/net/core/sock.c
index 0a023b8..0628600 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1077,6 +1077,12 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
case SO_BINDTODEVICE:
v.val = sk->sk_bound_dev_if;
break;
+ case SO_GET_FILTER:
+ len = sk_get_filter(sk, (struct sock_filter __user *)optval, len);
+ if (len < 0)
+ return len;
+
+ goto lenout;
default:
return -ENOPROTOOPT;
}
^ permalink raw reply related
* Re: [RFC PATCH net-next] qfq: handle the case that front slot is empty
From: Paolo Valente @ 2012-10-26 16:51 UTC (permalink / raw)
To: Cong Wang; +Cc: netdev, Stephen Hemminger, Eric Dumazet, Fabio Checconi
In-Reply-To: <1350982432.26308.8.camel@cr0>
Il 23/10/2012 10:53, Cong Wang ha scritto:
> On Tue, 2012-10-23 at 09:09 +0200, Paolo Valente wrote:
>> The crash you reported is one of the problems I tried to solve with my last fixes.
>> After those fixes I could not reproduce this crash (and other crashes) any more, but of course I am still missing something.
>
> I am using the latest net-next, so if your patches are in net-next,
> then the problem of course still exists.
>
>>
>> Il giorno 23/ott/2012, alle ore 06:15, Cong Wang ha scritto:
>>
>>> I am not sure if this patch fixes the real problem or just workarounds
>>> it. At least, after this patch I don't see the crash I reported any more.
>>
>> It is actually a workaround: if the condition that triggers your workaround holds true, then the group data structure is already inconstent, and qfq is likely not to schedule classes correctly.
>> I will try to reproduce the crash with the steps you suggest, and try to understand what is still wrong as soon as I can.
>>
>
> OK, I don't pretend I understand qfq. And I can help you to test
> patches.
Here is a possible patch. Could you please give me a feedback?
If this patch actually works, there are some issues related to it that I would
like to point out after your (and/or anyone else's) tests.
>
> Thanks!
>
>
---
net/sched/sch_qfq.c | 84 +++++++++++++++++++++++++++++++++------------------
1 file changed, 55 insertions(+), 29 deletions(-)
diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c
index f0dd83c..1fef61a 100644
--- a/net/sched/sch_qfq.c
+++ b/net/sched/sch_qfq.c
@@ -84,18 +84,19 @@
* grp->index is the index of the group; and grp->slot_shift
* is the shift for the corresponding (scaled) sigma_i.
*/
-#define QFQ_MAX_INDEX 19
-#define QFQ_MAX_WSHIFT 16
+#define QFQ_MAX_INDEX 24
+#define QFQ_MAX_WSHIFT 12
#define QFQ_MAX_WEIGHT (1<<QFQ_MAX_WSHIFT)
-#define QFQ_MAX_WSUM (2*QFQ_MAX_WEIGHT)
+#define QFQ_MAX_WSUM (16*QFQ_MAX_WEIGHT)
#define FRAC_BITS 30 /* fixed point arithmetic */
#define ONE_FP (1UL << FRAC_BITS)
#define IWSUM (ONE_FP/QFQ_MAX_WSUM)
-#define QFQ_MTU_SHIFT 11
+#define QFQ_MTU_SHIFT 16 /* because of TSO/GSP */
#define QFQ_MIN_SLOT_SHIFT (FRAC_BITS + QFQ_MTU_SHIFT - QFQ_MAX_INDEX)
+#define QFQ_MIN_LMAX 256 /* min possible lmax for a class */
/*
* Possible group states. These values are used as indexes for the bitmaps
@@ -231,6 +232,32 @@ static void qfq_update_class_params(struct qfq_sched *q, struct qfq_class *cl,
q->wsum += delta_w;
}
+static void qfq_update_reactivate_class(struct qfq_sched *q,
+ struct qfq_class *cl,
+ u32 inv_w, u32 lmax, int delta_w)
+{
+ bool need_reactivation = false;
+ int i = qfq_calc_index(inv_w, lmax);
+
+ if (&q->groups[i] != cl->grp && cl->qdisc->q.qlen > 0) {
+ /*
+ * shift cl->F back, to not charge the
+ * class for the not-yet-served head
+ * packet
+ */
+ cl->F = cl->S;
+ /* remove class from its slot in the old group */
+ qfq_deactivate_class(q, cl);
+ need_reactivation = true;
+ }
+
+ qfq_update_class_params(q, cl, lmax, inv_w, delta_w);
+
+ if (need_reactivation) /* activate in new group */
+ qfq_activate_class(q, cl, qdisc_peek_len(cl->qdisc));
+}
+
+
static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
struct nlattr **tca, unsigned long *arg)
{
@@ -238,7 +265,7 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
struct qfq_class *cl = (struct qfq_class *)*arg;
struct nlattr *tb[TCA_QFQ_MAX + 1];
u32 weight, lmax, inv_w;
- int i, err;
+ int err;
int delta_w;
if (tca[TCA_OPTIONS] == NULL) {
@@ -270,16 +297,14 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
if (tb[TCA_QFQ_LMAX]) {
lmax = nla_get_u32(tb[TCA_QFQ_LMAX]);
- if (!lmax || lmax > (1UL << QFQ_MTU_SHIFT)) {
+ if (lmax < QFQ_MIN_LMAX || lmax > (1UL << QFQ_MTU_SHIFT)) {
pr_notice("qfq: invalid max length %u\n", lmax);
return -EINVAL;
}
} else
- lmax = 1UL << QFQ_MTU_SHIFT;
+ lmax = psched_mtu(qdisc_dev(sch));
if (cl != NULL) {
- bool need_reactivation = false;
-
if (tca[TCA_RATE]) {
err = gen_replace_estimator(&cl->bstats, &cl->rate_est,
qdisc_root_sleeping_lock(sch),
@@ -291,24 +316,8 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
if (lmax == cl->lmax && inv_w == cl->inv_w)
return 0; /* nothing to update */
- i = qfq_calc_index(inv_w, lmax);
sch_tree_lock(sch);
- if (&q->groups[i] != cl->grp && cl->qdisc->q.qlen > 0) {
- /*
- * shift cl->F back, to not charge the
- * class for the not-yet-served head
- * packet
- */
- cl->F = cl->S;
- /* remove class from its slot in the old group */
- qfq_deactivate_class(q, cl);
- need_reactivation = true;
- }
-
- qfq_update_class_params(q, cl, lmax, inv_w, delta_w);
-
- if (need_reactivation) /* activate in new group */
- qfq_activate_class(q, cl, qdisc_peek_len(cl->qdisc));
+ qfq_update_reactivate_class(q, cl, inv_w, lmax, delta_w);
sch_tree_unlock(sch);
return 0;
@@ -663,9 +672,17 @@ static void qfq_make_eligible(struct qfq_sched *q, u64 old_V)
/*
- * XXX we should make sure that slot becomes less than 32.
- * This is guaranteed by the input values.
- * roundedS is always cl->S rounded on grp->slot_shift bits.
+ * If the weight and lmax (max_pkt_size) of the classes do not change,
+ * then QFQ guarantees that the slot index is never higher than 2 +
+ * ((1<<QFQ_MTU_SHIFT)/QFQ_MIN_LMAX) * (QFQ_MAX_WEIGHT/QFQ_MAX_WSUM).
+ *
+ * With the current values of the above constants, the index is
+ * then guaranteed to never be higher than 2 + 256 * (1 / 16) = 18.
+ *
+ * Even if the weight and/or lmax of some class change, the index
+ * should not, however, happen to be higher than 30, which is the
+ * critical threshold above which the full_slots bitmap my get
+ * corrupted.
*/
static void qfq_slot_insert(struct qfq_group *grp, struct qfq_class *cl,
u64 roundedS)
@@ -673,6 +690,8 @@ static void qfq_slot_insert(struct qfq_group *grp, struct qfq_class *cl,
u64 slot = (roundedS - grp->S) >> grp->slot_shift;
unsigned int i = (grp->front + slot) % QFQ_MAX_SLOTS;
+ BUG_ON(slot > 30);
+
hlist_add_head(&cl->next, &grp->slots[i]);
__set_bit(slot, &grp->full_slots);
}
@@ -892,6 +911,13 @@ static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
}
pr_debug("qfq_enqueue: cl = %x\n", cl->common.classid);
+ if (unlikely(cl->lmax < qdisc_pkt_len(skb))) {
+ pr_notice("qfq: increasing class max_pkt_size from %u to %u\n",
+ cl->lmax, qdisc_pkt_len(skb));
+ qfq_update_reactivate_class(q, cl, cl->inv_w,
+ qdisc_pkt_len(skb), 0);
+ }
+
err = qdisc_enqueue(skb, cl->qdisc);
if (unlikely(err != NET_XMIT_SUCCESS)) {
pr_debug("qfq_enqueue: enqueue failed %d\n", err);
--
1.7.9.5
^ permalink raw reply related
* RE: [PATCH -next] qla3xxx: remove unused variable in ql_process_mac_tx_intr()
From: Jitendra Kalsaria @ 2012-10-26 16:35 UTC (permalink / raw)
To: Wei Yongjun, Ron Mercer
Cc: yongjun_wei@trendmicro.com.cn, Dept-Eng Linux Driver, netdev
In-Reply-To: <CAPgLHd-rHiLuMR45R7uDWx=BVNr01XpcG6XG0_uMwjbhUGyKEw@mail.gmail.com>
>From: Wei Yongjun [mailto:weiyj.lk@gmail.com]
>Sent: Friday, October 26, 2012 8:31 AM
>To: Jitendra Kalsaria; Ron Mercer
>Cc: yongjun_wei@trendmicro.com.cn; Dept-Eng Linux Driver; netdev
>Subject: [PATCH -next] qla3xxx: remove unused variable in ql_process_mac_tx_intr()
>
>From: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
>
>The variable retval is initialized but never used
>otherwise, so remove the unused variable.
>
>dpatch engine is used to auto generate this patch.
>(https://github.com/weiyj/dpatch)
>
>Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
Acked-by: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>
^ permalink raw reply
* RE: [PATCH -next] qla3xxx: use module_pci_driver to simplify the code
From: Jitendra Kalsaria @ 2012-10-26 16:32 UTC (permalink / raw)
To: Wei Yongjun, Ron Mercer
Cc: yongjun_wei@trendmicro.com.cn, Dept-Eng Linux Driver, netdev
In-Reply-To: <CAPgLHd_Xu7TKZ_mqQ2r7A2GVCo+Us6kEggHc5d+hhg4Hh6cukA@mail.gmail.com>
>From: Wei Yongjun [mailto:weiyj.lk@gmail.com]
>Sent: Friday, October 26, 2012 8:03 AM
>To: Jitendra Kalsaria; Ron Mercer
>Cc: yongjun_wei@trendmicro.com.cn; Dept-Eng Linux Driver; netdev
>Subject: [PATCH -next] qla3xxx: use module_pci_driver to simplify the code
>
>From: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
>
>Use the module_pci_driver() macro to make the code simpler
>by eliminating module_init and module_exit calls.
>
>dpatch engine is used to auto generate this patch.
>(https://github.com/weiyj/dpatch)
>
>Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
Acked-by: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>
^ permalink raw reply
* Re: [net-next 10/14] ixgbevf: make sure probe fails on MSI-X enable error
From: Greg Rose @ 2012-10-26 16:32 UTC (permalink / raw)
To: Kicinski, Jakub
Cc: Kirsher, Jeffrey T, davem@davemloft.net, netdev@vger.kernel.org,
gospo@redhat.com, sassmann@redhat.com
In-Reply-To: <4F2EF616F787D840B1215485A0B91D1E5EF3AD@IRSMSX103.ger.corp.intel.com>
On Fri, 26 Oct 2012 12:43:12 +0000
"Kicinski, Jakub" <jakub.kicinski@intel.com> wrote:
> > From: Jakub Kicinski <jakub.kicinski@intel.com>
> >
> > This driver cannot work without MSI-X interrupts so there is no
> > mechanism to fall back to.
> >
> > Signed-off-by: Jakub Kicinski <jakub.kicinski@intel.com>
> > Acked-by: Greg Rose <gregory.v.rose@intel.com>
> > Tested-by: Sibai Li <sibai.li@intel.com>
> > Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> > ---
> > drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 24
> > +++++++++++------------ 1 file changed, 11 insertions(+), 13
> > deletions(-)
> >
> > diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
> > b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
> > index b5979ba..7ceccff 100644
> > --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
> > +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
> [...]
> > @@ -1858,7 +1856,7 @@ static int
> > ixgbevf_set_interrupt_capability(struct ixgbevf_adapter *adapter)
> > for (vector = 0; vector < v_budget; vector++)
> > adapter->msix_entries[vector].entry = vector;
> >
> > - ixgbevf_acquire_msix_vectors(adapter, v_budget);
> > + err = ixgbevf_acquire_msix_vectors(adapter, v_budget);
> >
> > err = netif_set_real_num_tx_queues(netdev,
> > adapter->num_tx_queues); if (err)
>
> This is clearly wrong. My change was overtaken by:
>
> commit 91e2b89b04d3f568dc4ec99f242a4a742061e399
> Author: Greg Rose <gregory.v.rose@intel.com>
> Date: Wed Oct 3 00:57:23 2012 +0000
>
> ixgbevf: Set the netdev number of Tx queues
>
> Please drop this patch, I'll resend a fixed version to Greg.
Yikes! Yeah, that patch got munged somehow. Thanks!
- Greg
^ permalink raw reply
* [PATCH] vxlan: don't expire permanent entries
From: Stephen Hemminger @ 2012-10-26 16:24 UTC (permalink / raw)
To: David Miller, John Southworth; +Cc: netdev
VXLAN confused flag versus bitmap on state.
Based on part of a earlier patch by David Stevens.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
---
Applies to 3.7.0-rc2. Needs to be fixed in 3.7 series
--- a/drivers/net/vxlan.c 2012-10-11 11:06:10.032585615 -0700
+++ b/drivers/net/vxlan.c 2012-10-26 09:19:30.734585097 -0700
@@ -816,7 +816,7 @@ static void vxlan_cleanup(unsigned long
= container_of(p, struct vxlan_fdb, hlist);
unsigned long timeout;
- if (f->state == NUD_PERMANENT)
+ if (f->state & NUD_PERMANENT)
continue;
timeout = f->used + vxlan->age_interval * HZ;
^ permalink raw reply
* Re: Regarding bottlenecks for high speed packet generation
From: Ben Hutchings @ 2012-10-26 16:15 UTC (permalink / raw)
To: Ajith Adapa; +Cc: David Miller, danborkmann, netdev
In-Reply-To: <CADAe=+LSeTWTnDk3o46EiLMQqJ6q93yVP_D3J2Ufcfy-_cv6RA@mail.gmail.com>
On Fri, 2012-10-26 at 11:42 +0530, Ajith Adapa wrote:
> > >
> > > But does NAPI comes into picture in case of transmission of packets ?
> >
> > Reclaim of TX descriptors occurs via NAPI.
>
> You mean for every packet sent by the NIC card it drops a interrupt to
> reclaim the TX buffers used ?
Not necessarily; completions may be batched in some way.
> I am not able to understand why does NIC has to interrupt back instead
> of freeing the memory in background.
>
> Might be it does add some bottleneck in my case of transmitting traffic bursts.
The network core needs to account and limit how much memory is allocated
to socket buffers. Completed TX buffers should therefore be freed
promptly, to avoid blocking the sending socket unnecessarily. It
doesn't strictly matter whether this is triggered by an IRQ from the NIC
or by a timer, but it certainly must not be triggered by the next TX
initiation as this may result in a kind of deadlock.
Ben.
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* [PATCH -next] qla3xxx: remove unused variable in ql_process_mac_tx_intr()
From: Wei Yongjun @ 2012-10-26 15:30 UTC (permalink / raw)
To: jitendra.kalsaria, ron.mercer; +Cc: yongjun_wei, linux-driver, netdev
From: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
The variable retval is initialized but never used
otherwise, so remove the unused variable.
dpatch engine is used to auto generate this patch.
(https://github.com/weiyj/dpatch)
Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
---
drivers/net/ethernet/qlogic/qla3xxx.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c
index 6407d0d..dd4d864a 100644
--- a/drivers/net/ethernet/qlogic/qla3xxx.c
+++ b/drivers/net/ethernet/qlogic/qla3xxx.c
@@ -1920,7 +1920,6 @@ static void ql_process_mac_tx_intr(struct ql3_adapter *qdev,
{
struct ql_tx_buf_cb *tx_cb;
int i;
- int retval = 0;
if (mac_rsp->flags & OB_MAC_IOCB_RSP_S) {
netdev_warn(qdev->ndev,
@@ -1935,7 +1934,6 @@ static void ql_process_mac_tx_intr(struct ql3_adapter *qdev,
"Frame too short to be legal, frame not sent\n");
qdev->ndev->stats.tx_errors++;
- retval = -EIO;
goto frame_not_sent;
}
@@ -1944,7 +1942,6 @@ static void ql_process_mac_tx_intr(struct ql3_adapter *qdev,
mac_rsp->transaction_id);
qdev->ndev->stats.tx_errors++;
- retval = -EIO;
goto invalid_seg_count;
}
^ permalink raw reply related
* Re: [PATCH v2 0/9] net/macb: driver enhancement concerning GEM support, ring logic and cleanup
From: Nicolas Ferre @ 2012-10-26 15:25 UTC (permalink / raw)
To: davem, Joachim Eastwood
Cc: netdev, havard, bhutchings, linux-arm-kernel, plagnioj,
patrice.vilchez, linux-kernel
In-Reply-To: <cover.1348055112.git.nicolas.ferre@atmel.com>
David,
On 09/19/2012 01:55 PM, Nicolas Ferre :
> This is an enhancement work that began several years ago. I try to catchup with
> some performance improvement that has been implemented then by Havard.
> The ring index logic and the TX error path modification are the biggest changes
> but some cleanup/debugging have been added along the way.
> The GEM revision will benefit from the Gigabit support.
>
> The series has been tested on several Atmel AT91 SoC with the two MACB/GEM
> flavors.
>
> v2: - modify the tx error handling: now uses a workqueue
> - information provided by ethtool -i were not accurate: removed
I am about to re-send this patch series. Should I rebase it on top of
Joachim's recent modifications? I mean, I plan to rebase them on top of
net-next, is it the proper thing to do?
> Havard Skinnemoen (4):
> net/macb: memory barriers cleanup
> net/macb: change debugging messages
> net/macb: clean up ring buffer logic
> net/macb: Offset first RX buffer by two bytes
>
> Nicolas Ferre (4):
> net/macb: remove macb_get_drvinfo()
> net/macb: tx status is more than 8 bits now
> net/macb: ethtool interface: add register dump feature
> net/macb: better manage tx errors
>
> Patrice Vilchez (1):
> net/macb: Add support for Gigabit Ethernet mode
>
> drivers/net/ethernet/cadence/macb.c | 433 +++++++++++++++++++++++++-----------
> drivers/net/ethernet/cadence/macb.h | 30 ++-
> 2 files changed, 321 insertions(+), 142 deletions(-)
Best regards,
--
Nicolas Ferre
^ permalink raw reply
* pull request: wireless 2012-10-26
From: John W. Linville @ 2012-10-26 15:21 UTC (permalink / raw)
To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
[-- Attachment #1: Type: text/plain, Size: 21402 bytes --]
commit 330ee00412bbaefa7d0597a1bed7804e818ba91c
Dave,
This is a batch of fixes intended for the 3.7 stream.
Bing Zhao brings two mwifiex fixes, both continuing to fix some scanning
failure cases.
Christian Lamparter provides an rtlwifi fix to properly propogate an
error code.
Felix Fietkau reverts a previous fix that was improperly reducing Tx
power for some devices. This one looks big, but it is mostly just
changes to a table of initialization values.
Larry Finger provides a b43 version of an earlier b43legacy fix to
avoid and oops when removing the modules after failing to load firmware.
Mohammed Shafi Shajakhan provides a new device ID for ath9k_htc.
Stanislaw Gruszka gives us an rt2x00 fix to avoide a WARNING during
resume, as described in kernel.org bug 48041.
Yuanhan Liu fixes a potential NULL dereference in brcmfmac.
Please let me know if there are problems!
Thanks,
John
---
The following changes since commit 3da3fff8006c608f19a51859d44ba47ca8b41461:
tilegx: fix some issues in the SW TSO support (2012-10-26 03:50:08 -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 330ee00412bbaefa7d0597a1bed7804e818ba91c:
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless into for-davem (2012-10-26 10:32:13 -0400)
----------------------------------------------------------------
Bing Zhao (2):
mwifiex: return -EBUSY if specific scan request cannot be honored
mwifiex: clean up scan state on error
Christian Lamparter (1):
rtlwifi: pass rx setup error code to caller
Felix Fietkau (1):
Revert "ath9k_hw: Updated AR9003 tx gain table for 5GHz"
John W. Linville (1):
Merge branch 'master' of git://git.kernel.org/.../linville/wireless into for-davem
Larry Finger (1):
b43: Fix oops on unload when firmware not found
Mohammed Shafi Shajakhan (1):
ath9k_htc: Add PID/VID for a Ubiquiti WiFiStation
Stanislaw Gruszka (1):
rt2x00: usb: fix reset resume
Yuanhan Liu (1):
brcmfmac: fix potential NULL dereference
.../net/wireless/ath/ath9k/ar9003_2p2_initvals.h | 164 ++++++++++-----------
drivers/net/wireless/ath/ath9k/hif_usb.c | 1 +
drivers/net/wireless/b43/main.c | 4 +
.../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 2 +-
drivers/net/wireless/mwifiex/cfg80211.c | 7 +-
drivers/net/wireless/mwifiex/scan.c | 13 +-
drivers/net/wireless/rt2x00/rt2500usb.c | 1 +
drivers/net/wireless/rt2x00/rt2800usb.c | 1 +
drivers/net/wireless/rt2x00/rt73usb.c | 1 +
drivers/net/wireless/rtlwifi/usb.c | 2 +-
10 files changed, 102 insertions(+), 94 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
index 89bf94d..6f7cf49 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
@@ -534,107 +534,107 @@ static const u32 ar9300_2p2_baseband_core[][2] = {
static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = {
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
- {0x0000a2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
- {0x0000a2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
- {0x0000a2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
+ {0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
+ {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
+ {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
{0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
{0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
{0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
{0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
{0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
- {0x0000a510, 0x15000028, 0x15000028, 0x0f000202, 0x0f000202},
- {0x0000a514, 0x1b00002b, 0x1b00002b, 0x12000400, 0x12000400},
- {0x0000a518, 0x1f020028, 0x1f020028, 0x16000402, 0x16000402},
- {0x0000a51c, 0x2502002b, 0x2502002b, 0x19000404, 0x19000404},
- {0x0000a520, 0x2a04002a, 0x2a04002a, 0x1c000603, 0x1c000603},
- {0x0000a524, 0x2e06002a, 0x2e06002a, 0x21000a02, 0x21000a02},
- {0x0000a528, 0x3302202d, 0x3302202d, 0x25000a04, 0x25000a04},
- {0x0000a52c, 0x3804202c, 0x3804202c, 0x28000a20, 0x28000a20},
- {0x0000a530, 0x3c06202c, 0x3c06202c, 0x2c000e20, 0x2c000e20},
- {0x0000a534, 0x4108202d, 0x4108202d, 0x30000e22, 0x30000e22},
- {0x0000a538, 0x4506402d, 0x4506402d, 0x34000e24, 0x34000e24},
- {0x0000a53c, 0x4906222d, 0x4906222d, 0x38001640, 0x38001640},
- {0x0000a540, 0x4d062231, 0x4d062231, 0x3c001660, 0x3c001660},
- {0x0000a544, 0x50082231, 0x50082231, 0x3f001861, 0x3f001861},
- {0x0000a548, 0x5608422e, 0x5608422e, 0x43001a81, 0x43001a81},
- {0x0000a54c, 0x5a08442e, 0x5a08442e, 0x47001a83, 0x47001a83},
- {0x0000a550, 0x5e0a4431, 0x5e0a4431, 0x4a001c84, 0x4a001c84},
- {0x0000a554, 0x640a4432, 0x640a4432, 0x4e001ce3, 0x4e001ce3},
- {0x0000a558, 0x680a4434, 0x680a4434, 0x52001ce5, 0x52001ce5},
- {0x0000a55c, 0x6c0a6434, 0x6c0a6434, 0x56001ce9, 0x56001ce9},
- {0x0000a560, 0x6f0a6633, 0x6f0a6633, 0x5a001ceb, 0x5a001ceb},
- {0x0000a564, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
- {0x0000a568, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
- {0x0000a56c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
- {0x0000a570, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
- {0x0000a574, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
- {0x0000a578, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
- {0x0000a57c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
+ {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
+ {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400},
+ {0x0000a518, 0x21002220, 0x21002220, 0x16000402, 0x16000402},
+ {0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404},
+ {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603},
+ {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02},
+ {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04},
+ {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20},
+ {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20},
+ {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22},
+ {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
+ {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
+ {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
+ {0x0000a544, 0x52022470, 0x52022470, 0x3f001861, 0x3f001861},
+ {0x0000a548, 0x55022490, 0x55022490, 0x43001a81, 0x43001a81},
+ {0x0000a54c, 0x59022492, 0x59022492, 0x47001a83, 0x47001a83},
+ {0x0000a550, 0x5d022692, 0x5d022692, 0x4a001c84, 0x4a001c84},
+ {0x0000a554, 0x61022892, 0x61022892, 0x4e001ce3, 0x4e001ce3},
+ {0x0000a558, 0x65024890, 0x65024890, 0x52001ce5, 0x52001ce5},
+ {0x0000a55c, 0x69024892, 0x69024892, 0x56001ce9, 0x56001ce9},
+ {0x0000a560, 0x6e024c92, 0x6e024c92, 0x5a001ceb, 0x5a001ceb},
+ {0x0000a564, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+ {0x0000a568, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+ {0x0000a56c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+ {0x0000a570, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+ {0x0000a574, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+ {0x0000a578, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+ {0x0000a57c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
{0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
{0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
{0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
{0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
- {0x0000a590, 0x15800028, 0x15800028, 0x0f800202, 0x0f800202},
- {0x0000a594, 0x1b80002b, 0x1b80002b, 0x12800400, 0x12800400},
- {0x0000a598, 0x1f820028, 0x1f820028, 0x16800402, 0x16800402},
- {0x0000a59c, 0x2582002b, 0x2582002b, 0x19800404, 0x19800404},
- {0x0000a5a0, 0x2a84002a, 0x2a84002a, 0x1c800603, 0x1c800603},
- {0x0000a5a4, 0x2e86002a, 0x2e86002a, 0x21800a02, 0x21800a02},
- {0x0000a5a8, 0x3382202d, 0x3382202d, 0x25800a04, 0x25800a04},
- {0x0000a5ac, 0x3884202c, 0x3884202c, 0x28800a20, 0x28800a20},
- {0x0000a5b0, 0x3c86202c, 0x3c86202c, 0x2c800e20, 0x2c800e20},
- {0x0000a5b4, 0x4188202d, 0x4188202d, 0x30800e22, 0x30800e22},
- {0x0000a5b8, 0x4586402d, 0x4586402d, 0x34800e24, 0x34800e24},
- {0x0000a5bc, 0x4986222d, 0x4986222d, 0x38801640, 0x38801640},
- {0x0000a5c0, 0x4d862231, 0x4d862231, 0x3c801660, 0x3c801660},
- {0x0000a5c4, 0x50882231, 0x50882231, 0x3f801861, 0x3f801861},
- {0x0000a5c8, 0x5688422e, 0x5688422e, 0x43801a81, 0x43801a81},
- {0x0000a5cc, 0x5a88442e, 0x5a88442e, 0x47801a83, 0x47801a83},
- {0x0000a5d0, 0x5e8a4431, 0x5e8a4431, 0x4a801c84, 0x4a801c84},
- {0x0000a5d4, 0x648a4432, 0x648a4432, 0x4e801ce3, 0x4e801ce3},
- {0x0000a5d8, 0x688a4434, 0x688a4434, 0x52801ce5, 0x52801ce5},
- {0x0000a5dc, 0x6c8a6434, 0x6c8a6434, 0x56801ce9, 0x56801ce9},
- {0x0000a5e0, 0x6f8a6633, 0x6f8a6633, 0x5a801ceb, 0x5a801ceb},
- {0x0000a5e4, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
- {0x0000a5e8, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
- {0x0000a5ec, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
- {0x0000a5f0, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
- {0x0000a5f4, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
- {0x0000a5f8, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
- {0x0000a5fc, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
+ {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
+ {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400},
+ {0x0000a598, 0x21802220, 0x21802220, 0x16800402, 0x16800402},
+ {0x0000a59c, 0x27802223, 0x27802223, 0x19800404, 0x19800404},
+ {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603},
+ {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02},
+ {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04},
+ {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20},
+ {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20},
+ {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22},
+ {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24},
+ {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640},
+ {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660},
+ {0x0000a5c4, 0x52822470, 0x52822470, 0x3f801861, 0x3f801861},
+ {0x0000a5c8, 0x55822490, 0x55822490, 0x43801a81, 0x43801a81},
+ {0x0000a5cc, 0x59822492, 0x59822492, 0x47801a83, 0x47801a83},
+ {0x0000a5d0, 0x5d822692, 0x5d822692, 0x4a801c84, 0x4a801c84},
+ {0x0000a5d4, 0x61822892, 0x61822892, 0x4e801ce3, 0x4e801ce3},
+ {0x0000a5d8, 0x65824890, 0x65824890, 0x52801ce5, 0x52801ce5},
+ {0x0000a5dc, 0x69824892, 0x69824892, 0x56801ce9, 0x56801ce9},
+ {0x0000a5e0, 0x6e824c92, 0x6e824c92, 0x5a801ceb, 0x5a801ceb},
+ {0x0000a5e4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+ {0x0000a5e8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+ {0x0000a5ec, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+ {0x0000a5f0, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+ {0x0000a5f4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+ {0x0000a5f8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+ {0x0000a5fc, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
{0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
- {0x0000a608, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
- {0x0000a60c, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
- {0x0000a610, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
- {0x0000a614, 0x01804601, 0x01804601, 0x01404000, 0x01404000},
- {0x0000a618, 0x01804601, 0x01804601, 0x01404501, 0x01404501},
- {0x0000a61c, 0x01804601, 0x01804601, 0x02008501, 0x02008501},
- {0x0000a620, 0x03408d02, 0x03408d02, 0x0280ca03, 0x0280ca03},
- {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04},
- {0x0000a628, 0x03410d04, 0x03410d04, 0x04014c04, 0x04014c04},
- {0x0000a62c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
- {0x0000a630, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
- {0x0000a634, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
- {0x0000a638, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
- {0x0000a63c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
- {0x0000b2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
- {0x0000b2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
- {0x0000b2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
+ {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x0000a614, 0x02004000, 0x02004000, 0x01404000, 0x01404000},
+ {0x0000a618, 0x02004801, 0x02004801, 0x01404501, 0x01404501},
+ {0x0000a61c, 0x02808a02, 0x02808a02, 0x02008501, 0x02008501},
+ {0x0000a620, 0x0380ce03, 0x0380ce03, 0x0280ca03, 0x0280ca03},
+ {0x0000a624, 0x04411104, 0x04411104, 0x03010c04, 0x03010c04},
+ {0x0000a628, 0x04411104, 0x04411104, 0x04014c04, 0x04014c04},
+ {0x0000a62c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+ {0x0000a630, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+ {0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+ {0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+ {0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+ {0x0000b2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
+ {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
+ {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
{0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
- {0x0000c2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
- {0x0000c2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
- {0x0000c2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
+ {0x0000c2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
+ {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
+ {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
{0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
{0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
- {0x00016048, 0x61200001, 0x61200001, 0x66480001, 0x66480001},
+ {0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001},
{0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
{0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
- {0x00016448, 0x61200001, 0x61200001, 0x66480001, 0x66480001},
+ {0x00016448, 0x66480001, 0x66480001, 0x66480001, 0x66480001},
{0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
{0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
- {0x00016848, 0x61200001, 0x61200001, 0x66480001, 0x66480001},
+ {0x00016848, 0x66480001, 0x66480001, 0x66480001, 0x66480001},
{0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
};
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index 924c461..f5dda84 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -38,6 +38,7 @@ static struct usb_device_id ath9k_hif_usb_ids[] = {
{ USB_DEVICE(0x04CA, 0x4605) }, /* Liteon */
{ USB_DEVICE(0x040D, 0x3801) }, /* VIA */
{ USB_DEVICE(0x0cf3, 0xb003) }, /* Ubiquiti WifiStation Ext */
+ { USB_DEVICE(0x0cf3, 0xb002) }, /* Ubiquiti WifiStation */
{ USB_DEVICE(0x057c, 0x8403) }, /* AVM FRITZ!WLAN 11N v2 USB */
{ USB_DEVICE(0x0cf3, 0x7015),
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 73730e9..c5a99c8 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -5404,6 +5404,8 @@ static void b43_bcma_remove(struct bcma_device *core)
cancel_work_sync(&wldev->restart_work);
B43_WARN_ON(!wl);
+ if (!wldev->fw.ucode.data)
+ return; /* NULL if firmware never loaded */
if (wl->current_dev == wldev && wl->hw_registred) {
b43_leds_stop(wldev);
ieee80211_unregister_hw(wl->hw);
@@ -5478,6 +5480,8 @@ static void b43_ssb_remove(struct ssb_device *sdev)
cancel_work_sync(&wldev->restart_work);
B43_WARN_ON(!wl);
+ if (!wldev->fw.ucode.data)
+ return; /* NULL if firmware never loaded */
if (wl->current_dev == wldev && wl->hw_registred) {
b43_leds_stop(wldev);
ieee80211_unregister_hw(wl->hw);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 411dfe7..a6f1e81 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -3569,7 +3569,7 @@ brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
if (!request || !request->n_ssids || !request->n_match_sets) {
WL_ERR("Invalid sched scan req!! n_ssids:%d\n",
- request->n_ssids);
+ request ? request->n_ssids : 0);
return -EINVAL;
}
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 0679458..780d3e1 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1825,8 +1825,6 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
return -EBUSY;
}
- priv->scan_request = request;
-
priv->user_scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg),
GFP_KERNEL);
if (!priv->user_scan_cfg) {
@@ -1834,6 +1832,8 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
return -ENOMEM;
}
+ priv->scan_request = request;
+
priv->user_scan_cfg->num_ssids = request->n_ssids;
priv->user_scan_cfg->ssid_list = request->ssids;
@@ -1870,6 +1870,9 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
ret = mwifiex_scan_networks(priv, priv->user_scan_cfg);
if (ret) {
dev_err(priv->adapter->dev, "scan failed: %d\n", ret);
+ priv->scan_request = NULL;
+ kfree(priv->user_scan_cfg);
+ priv->user_scan_cfg = NULL;
return ret;
}
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index 00b658d..9171aae 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -1843,21 +1843,18 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv,
struct cfg80211_ssid *req_ssid)
{
struct mwifiex_adapter *adapter = priv->adapter;
- int ret = 0;
+ int ret;
struct mwifiex_user_scan_cfg *scan_cfg;
- if (!req_ssid)
- return -1;
-
if (adapter->scan_processing) {
- dev_dbg(adapter->dev, "cmd: Scan already in process...\n");
- return ret;
+ dev_err(adapter->dev, "cmd: Scan already in process...\n");
+ return -EBUSY;
}
if (priv->scan_block) {
- dev_dbg(adapter->dev,
+ dev_err(adapter->dev,
"cmd: Scan is blocked during association...\n");
- return ret;
+ return -EBUSY;
}
scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), GFP_KERNEL);
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index a12e84f..6b2e1e43 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1988,6 +1988,7 @@ static struct usb_driver rt2500usb_driver = {
.disconnect = rt2x00usb_disconnect,
.suspend = rt2x00usb_suspend,
.resume = rt2x00usb_resume,
+ .reset_resume = rt2x00usb_resume,
.disable_hub_initiated_lpm = 1,
};
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index c9e9370..3b8fb5a 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -1282,6 +1282,7 @@ static struct usb_driver rt2800usb_driver = {
.disconnect = rt2x00usb_disconnect,
.suspend = rt2x00usb_suspend,
.resume = rt2x00usb_resume,
+ .reset_resume = rt2x00usb_resume,
.disable_hub_initiated_lpm = 1,
};
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index e5eb43b..24eec66 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -2535,6 +2535,7 @@ static struct usb_driver rt73usb_driver = {
.disconnect = rt2x00usb_disconnect,
.suspend = rt2x00usb_suspend,
.resume = rt2x00usb_resume,
+ .reset_resume = rt2x00usb_resume,
.disable_hub_initiated_lpm = 1,
};
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c
index 030beb4..e3ea4b3 100644
--- a/drivers/net/wireless/rtlwifi/usb.c
+++ b/drivers/net/wireless/rtlwifi/usb.c
@@ -673,7 +673,7 @@ static int rtl_usb_start(struct ieee80211_hw *hw)
set_hal_start(rtlhal);
/* Start bulk IN */
- _rtl_usb_receive(hw);
+ err = _rtl_usb_receive(hw);
}
return err;
--
John W. Linville Someday the world will need a hero, and you
linville-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org might be all we have. Be ready.
[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply related
* [PATCH -next] qla3xxx: use module_pci_driver to simplify the code
From: Wei Yongjun @ 2012-10-26 15:02 UTC (permalink / raw)
To: jitendra.kalsaria, ron.mercer; +Cc: yongjun_wei, linux-driver, netdev
From: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
Use the module_pci_driver() macro to make the code simpler
by eliminating module_init and module_exit calls.
dpatch engine is used to auto generate this patch.
(https://github.com/weiyj/dpatch)
Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
---
drivers/net/ethernet/qlogic/qla3xxx.c | 13 +------------
1 file changed, 1 insertion(+), 12 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c
index 6407d0d..232a115 100644
--- a/drivers/net/ethernet/qlogic/qla3xxx.c
+++ b/drivers/net/ethernet/qlogic/qla3xxx.c
@@ -3958,15 +3958,4 @@ static struct pci_driver ql3xxx_driver = {
.remove = __devexit_p(ql3xxx_remove),
};
-static int __init ql3xxx_init_module(void)
-{
- return pci_register_driver(&ql3xxx_driver);
-}
-
-static void __exit ql3xxx_exit(void)
-{
- pci_unregister_driver(&ql3xxx_driver);
-}
-
-module_init(ql3xxx_init_module);
-module_exit(ql3xxx_exit);
+module_pci_driver(ql3xxx_driver);
^ permalink raw reply related
* Re: [PATCH net-next] sctp: support per-association stats via a new SCTP_GET_ASSOC_STATS call
From: Neil Horman @ 2012-10-26 14:37 UTC (permalink / raw)
To: Michele Baldessari
Cc: linux-sctp, Vlad Yasevich, David S. Miller, netdev, Thomas Graf
In-Reply-To: <1351258973-17227-1-git-send-email-michele@acksyn.org>
On Fri, Oct 26, 2012 at 03:42:53PM +0200, Michele Baldessari wrote:
> The current SCTP stack is lacking an API to have per association
> statistics. This is a kernel implementation modeled after OpenSolaris'
> SCTP_GET_ASSOC_STATS.
>
> Userspace part will follow on lksctp if/when there is a general ACK on this.
>
> Signed-off-by: Michele Baldessari <michele@acksyn.org>
> Acked-by: Thomas Graf <tgraf@suug.ch>
> ---
> include/net/sctp/sctp.h | 3 +++
> include/net/sctp/structs.h | 39 +++++++++++++++++++++++++++
> include/net/sctp/user.h | 26 ++++++++++++++++++
> net/sctp/associola.c | 20 ++++++++++++++
> net/sctp/endpointola.c | 5 +++-
> net/sctp/input.c | 5 ++--
> net/sctp/output.c | 5 ++++
> net/sctp/outqueue.c | 12 +++++++++
> net/sctp/sm_sideeffect.c | 2 ++
> net/sctp/sm_statefuns.c | 12 +++++++--
> net/sctp/socket.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++
> net/sctp/transport.c | 2 ++
> 12 files changed, 193 insertions(+), 5 deletions(-)
>
We already have files in /proc/net/sctp to count snmp system-wide totals,
per-endpoint totals, and per association totals. Why do these stats differently
instead of just adding them the per-association file? I get that solaris does
this, but its not codified in any of the RFC's or other standards. I would
really rather see something like this go into the interfaces we have, rather
than creating a new one.
I also am a bit confused regarding the stats themselves. Most are fairly clear,
but some seem lacking (you count most things sent and received, but only count
received gap acks). Others seems vague and or confusing (when counting
retransmitted chunks and packets, how do you count a packet that has both new
and retransmitted chunks)? And the max observed rto stat is just odd. Each
transport has an rto value, not each association, and you cal already see the
individual transport rto values in /proc/net/sctp/remaddr.
> +
> + /* Gap Ack Blocks received */
> + __u64 gapcnt;
> +
No gapcnt for sent gap ack blocks?
> unsigned long timeout;
> diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
> index 1b4a7f8..569ee3a 100644
> --- a/net/sctp/outqueue.c
> +++ b/net/sctp/outqueue.c
> @@ -667,6 +667,8 @@ redo:
> chunk->fast_retransmit = SCTP_DONT_FRTX;
>
> q->empty = 0;
> + if (q->asoc)
> + q->asoc->rtxchunks++;
> break;
> }
>
> @@ -678,6 +680,10 @@ redo:
> break;
> }
>
> + if (q->asoc)
> + q->asoc->rtxpackets++;
> +
> +
This seems incorrect to me. The packet being assembled here may have new chunks
in it (either control or data). Counting a packet as being retransmitted just
because it has a retransmitted chunk in it seems wrong. At the very least its a
misleading/vague statistic.
> break;
> diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
> index b6adef8..4f94432 100644
> --- a/net/sctp/sm_statefuns.c
> +++ b/net/sctp/sm_statefuns.c
> @@ -6127,9 +6127,13 @@ static int sctp_eat_data(const struct sctp_association *asoc,
> /* The TSN is too high--silently discard the chunk and
> * count on it getting retransmitted later.
> */
> + if (chunk->asoc)
> + chunk->asoc->outseqtsns++;
This just seems wrong. The definition states that this is counting the last TSN
recevied (despite being name outseqtsns), yet this looks like you're:
1) just incrementing a counter, rather than recording the TSN value itself
(which may or may not be what you meant, but seems to contradict what the
comments at the definition)
2) Only incremanting it if the TSN is out of range, which makes very little
sense to me.
>
^ permalink raw reply
* [PATCH net-next] sctp: support per-association stats via a new SCTP_GET_ASSOC_STATS call
From: Michele Baldessari @ 2012-10-26 13:42 UTC (permalink / raw)
To: linux-sctp
Cc: Michele Baldessari, Neil Horman, Vlad Yasevich, David S. Miller,
netdev, Thomas Graf
The current SCTP stack is lacking an API to have per association
statistics. This is a kernel implementation modeled after OpenSolaris'
SCTP_GET_ASSOC_STATS.
Userspace part will follow on lksctp if/when there is a general ACK on this.
Signed-off-by: Michele Baldessari <michele@acksyn.org>
Acked-by: Thomas Graf <tgraf@suug.ch>
---
include/net/sctp/sctp.h | 3 +++
include/net/sctp/structs.h | 39 +++++++++++++++++++++++++++
include/net/sctp/user.h | 26 ++++++++++++++++++
net/sctp/associola.c | 20 ++++++++++++++
net/sctp/endpointola.c | 5 +++-
net/sctp/input.c | 5 ++--
net/sctp/output.c | 5 ++++
net/sctp/outqueue.c | 12 +++++++++
net/sctp/sm_sideeffect.c | 2 ++
net/sctp/sm_statefuns.c | 12 +++++++--
net/sctp/socket.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++
net/sctp/transport.c | 2 ++
12 files changed, 193 insertions(+), 5 deletions(-)
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index 9c6414f..e2248de 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -272,6 +272,9 @@ struct sctp_mib {
unsigned long mibs[SCTP_MIB_MAX];
};
+#define SCTP_MAX_RTO(asoc, transport) \
+ (asoc)->max_obs_rto = max((__u64)(transport)->rto, \
+ (asoc)->max_obs_rto);
/* Print debugging messages. */
#if SCTP_DEBUG
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 64158aa..8afcb57 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -1829,6 +1829,45 @@ struct sctp_association {
__u8 need_ecne:1, /* Need to send an ECNE Chunk? */
temp:1; /* Is it a temporary association? */
+
+ /* Total In and Out SACKs received and sent */
+ __u64 isacks;
+ __u64 osacks;
+
+ /* Total In and Out packets received and sent */
+ __u64 opackets;
+ __u64 ipackets;
+
+ /* Total retransmitted chunks and packets */
+ __u64 rtxchunks;
+ __u64 rtxpackets;
+
+ /* TSN received > next expected */
+ __u64 outseqtsns;
+
+ /* Duplicate Chunks received */
+ __u64 idupchunks;
+
+ /* Gap Ack Blocks received */
+ __u64 gapcnt;
+
+ /* Unordered data chunks sent and received */
+ __u64 ouodchunks;
+ __u64 iuodchunks;
+
+ /* Ordered data chunks sent and received */
+ __u64 oodchunks;
+ __u64 iodchunks;
+
+ /* Control chunks sent and received */
+ __u64 octrlchunks;
+ __u64 ictrlchunks;
+
+ /* Maximum observed rto in the association. Value is unchanged
+ * when read and the max rto did not change
+ */
+ __u64 max_obs_rto;
+ __u64 max_prev_obs_rto;
};
diff --git a/include/net/sctp/user.h b/include/net/sctp/user.h
index 1b02d7a..c1715e2 100644
--- a/include/net/sctp/user.h
+++ b/include/net/sctp/user.h
@@ -94,6 +94,7 @@ typedef __s32 sctp_assoc_t;
#define SCTP_GET_ASSOC_ID_LIST 29 /* Read only */
#define SCTP_AUTO_ASCONF 30
#define SCTP_PEER_ADDR_THLDS 31
+#define SCTP_GET_ASSOC_STATS 32 /* Read only */
/* Internal Socket Options. Some of the sctp library functions are
* implemented using these socket options.
@@ -719,6 +720,31 @@ struct sctp_getaddrs {
__u8 addrs[0]; /*output, variable size*/
};
+/* A socket user request obtained via SCTP_GET_ASSOC_STATS that retrieves
+ * local per endpoint association stats. All stats are counts except
+ * sas_maxrto, which is the max value since the last user request for
+ * stats on this endpoint.
+ */
+struct sctp_assoc_stats {
+ sctp_assoc_t sas_assoc_id; /* Input */
+ __u64 sas_rtxchunks; /* Retransmitted Chunks */
+ __u64 sas_gapcnt; /* Gap Acknowledgements Received */
+ __u64 sas_outseqtsns; /* TSN received > next expected */
+ __u64 sas_osacks; /* SACKs sent */
+ __u64 sas_isacks; /* SACKs received */
+ __u64 sas_octrlchunks; /* Control chunks sent */
+ __u64 sas_ictrlchunks; /* Control chunks received */
+ __u64 sas_oodchunks; /* Ordered data chunks sent */
+ __u64 sas_iodchunks; /* Ordered data chunks received */
+ __u64 sas_ouodchunks; /* Unordered data chunks sent */
+ __u64 sas_iuodchunks; /* Unordered data chunks received */
+ __u64 sas_idupchunks; /* Dups received (ordered+unordered) */
+ __u64 sas_opackets; /* Packets sent */
+ __u64 sas_ipackets; /* Packets received */
+ __u64 sas_rtxpackets; /* Packets retransmitted */
+ __u64 sas_maxrto; /* Maximum Observed RTO for period */
+};
+
/* These are bit fields for msghdr->msg_flags. See section 5.1. */
/* On user space Linux, these live in <bits/socket.h> as an enum. */
enum sctp_msg_flags {
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index b1ef3bc..8560048 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -321,6 +321,25 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
asoc->default_timetolive = sp->default_timetolive;
asoc->default_rcv_context = sp->default_rcv_context;
+ /* SCTP_GET_ASSOC_STATS COUNTERS */
+ asoc->isacks = 0;
+ asoc->osacks = 0;
+ asoc->opackets = 0;
+ asoc->ipackets = 0;
+ asoc->rtxpackets = 0;
+ asoc->rtxchunks = 0;
+ asoc->outseqtsns = 0;
+ asoc->idupchunks = 0;
+ asoc->gapcnt = 0;
+ asoc->ouodchunks = 0;
+ asoc->iuodchunks = 0;
+ asoc->oodchunks = 0;
+ asoc->iodchunks = 0;
+ asoc->octrlchunks = 0;
+ asoc->ictrlchunks = 0;
+ asoc->max_obs_rto = 0;
+ asoc->max_prev_obs_rto = 0;
+
/* AUTH related initializations */
INIT_LIST_HEAD(&asoc->endpoint_shared_keys);
err = sctp_auth_asoc_copy_shkeys(ep, asoc, gfp);
@@ -760,6 +779,7 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
/* Set the transport's RTO.initial value */
peer->rto = asoc->rto_initial;
+ SCTP_MAX_RTO(asoc, peer);
/* Set the peer's active state. */
peer->state = peer_state;
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index 1859e2b..b89731e 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -480,8 +480,11 @@ normal:
*/
if (asoc && sctp_chunk_is_data(chunk))
asoc->peer.last_data_from = chunk->transport;
- else
+ else {
SCTP_INC_STATS(sock_net(ep->base.sk), SCTP_MIB_INCTRLCHUNKS);
+ if (asoc)
+ asoc->ictrlchunks++;
+ }
if (chunk->transport)
chunk->transport->last_time_heard = jiffies;
diff --git a/net/sctp/input.c b/net/sctp/input.c
index 8bd3c27..3c32ca5 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -285,9 +285,10 @@ int sctp_rcv(struct sk_buff *skb)
sctp_bh_unlock_sock(sk);
/* Release the asoc/ep ref we took in the lookup calls. */
- if (asoc)
+ if (asoc) {
+ asoc->ipackets++;
sctp_association_put(asoc);
- else
+ } else
sctp_endpoint_put(ep);
return 0;
diff --git a/net/sctp/output.c b/net/sctp/output.c
index 4e90188bf..ca5ce50 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -311,6 +311,8 @@ static sctp_xmit_t __sctp_packet_append_chunk(struct sctp_packet *packet,
case SCTP_CID_SACK:
packet->has_sack = 1;
+ if (chunk->asoc)
+ chunk->asoc->osacks++;
break;
case SCTP_CID_AUTH:
@@ -591,6 +593,9 @@ int sctp_packet_transmit(struct sctp_packet *packet)
asoc->peer.last_sent_to = tp;
}
+ if (asoc)
+ asoc->opackets++;
+
if (has_data) {
struct timer_list *timer;
unsigned long timeout;
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index 1b4a7f8..569ee3a 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -667,6 +667,8 @@ redo:
chunk->fast_retransmit = SCTP_DONT_FRTX;
q->empty = 0;
+ if (q->asoc)
+ q->asoc->rtxchunks++;
break;
}
@@ -678,6 +680,10 @@ redo:
break;
}
+ if (q->asoc)
+ q->asoc->rtxpackets++;
+
+
/* If we are here due to a retransmit timeout or a fast
* retransmit and if there are any chunks left in the retransmit
* queue that could not fit in the PMTU sized packet, they need
@@ -883,6 +889,7 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
*/
sctp_transport_reset_timers(transport);
}
+ asoc->octrlchunks++;
break;
default:
@@ -1055,6 +1062,10 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
*/
if (asoc->state == SCTP_STATE_SHUTDOWN_PENDING)
chunk->chunk_hdr->flags |= SCTP_DATA_SACK_IMM;
+ if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED)
+ asoc->ouodchunks++;
+ else
+ asoc->oodchunks++;
break;
@@ -1162,6 +1173,7 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_chunk *chunk)
sack_ctsn = ntohl(sack->cum_tsn_ack);
gap_ack_blocks = ntohs(sack->num_gap_ack_blocks);
+ asoc->gapcnt += gap_ack_blocks;
/*
* SFR-CACC algorithm:
* On receipt of a SACK the sender SHOULD execute the
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 6773d78..ed49431 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -542,6 +542,7 @@ static void sctp_do_8_2_transport_strike(sctp_cmd_seq_t *commands,
*/
if (!is_hb || transport->hb_sent) {
transport->rto = min((transport->rto * 2), transport->asoc->rto_max);
+ SCTP_MAX_RTO(asoc, transport);
}
}
@@ -1330,6 +1331,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
case SCTP_CMD_PROCESS_SACK:
/* Process an inbound SACK. */
+ asoc->isacks++;
error = sctp_cmd_process_sack(commands, asoc,
cmd->obj.ptr);
break;
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index b6adef8..4f94432 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -6127,9 +6127,13 @@ static int sctp_eat_data(const struct sctp_association *asoc,
/* The TSN is too high--silently discard the chunk and
* count on it getting retransmitted later.
*/
+ if (chunk->asoc)
+ chunk->asoc->outseqtsns++;
return SCTP_IERROR_HIGH_TSN;
} else if (tmp > 0) {
/* This is a duplicate. Record it. */
+ if (chunk->asoc)
+ chunk->asoc->idupchunks++;
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_DUP, SCTP_U32(tsn));
return SCTP_IERROR_DUP_TSN;
}
@@ -6226,10 +6230,14 @@ static int sctp_eat_data(const struct sctp_association *asoc,
/* Note: Some chunks may get overcounted (if we drop) or overcounted
* if we renege and the chunk arrives again.
*/
- if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED)
+ if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED) {
SCTP_INC_STATS(net, SCTP_MIB_INUNORDERCHUNKS);
- else {
+ if (chunk->asoc)
+ chunk->asoc->iuodchunks++;
+ } else {
SCTP_INC_STATS(net, SCTP_MIB_INORDERCHUNKS);
+ if (chunk->asoc)
+ chunk->asoc->iodchunks++;
ordered = 1;
}
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 59d16ea..ca6d0a1 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -610,6 +610,7 @@ static int sctp_send_asconf_add_ip(struct sock *sk,
2*asoc->pathmtu, 4380));
trans->ssthresh = asoc->peer.i.a_rwnd;
trans->rto = asoc->rto_initial;
+ SCTP_MAX_RTO(asoc, trans);
trans->rtt = trans->srtt = trans->rttvar = 0;
sctp_transport_route(trans, NULL,
sctp_sk(asoc->base.sk));
@@ -5632,6 +5633,69 @@ static int sctp_getsockopt_paddr_thresholds(struct sock *sk,
return 0;
}
+/*
+ * SCTP_GET_ASSOC_STATS
+ *
+ * This option retrieves local per endpoint statistics. It is modeled
+ * after OpenSolaris' implementation
+ */
+static int sctp_getsockopt_assoc_stats(struct sock *sk, int len,
+ char __user *optval,
+ int __user *optlen)
+{
+ struct sctp_assoc_stats sas;
+ struct sctp_association *asoc = NULL;
+
+ if (len < sizeof(struct sctp_assoc_stats))
+ return -EINVAL;
+
+ len = sizeof(struct sctp_assoc_stats);
+ if (copy_from_user(&sas, optval, len))
+ return -EFAULT;
+
+ asoc = sctp_id2assoc(sk, sas.sas_assoc_id);
+ if (!asoc)
+ return -EINVAL;
+
+ sas.sas_rtxchunks = asoc->rtxchunks;
+ sas.sas_gapcnt = asoc->gapcnt;
+ sas.sas_outseqtsns = asoc->outseqtsns;
+ sas.sas_osacks = asoc->osacks;
+ sas.sas_isacks = asoc->isacks;
+ sas.sas_octrlchunks = asoc->octrlchunks;
+ sas.sas_ictrlchunks = asoc->ictrlchunks;
+ sas.sas_oodchunks = asoc->oodchunks;
+ sas.sas_iodchunks = asoc->iodchunks;
+ sas.sas_ouodchunks = asoc->ouodchunks;
+ sas.sas_iuodchunks = asoc->iuodchunks;
+ sas.sas_idupchunks = asoc->idupchunks;
+ sas.sas_opackets = asoc->opackets;
+ sas.sas_ipackets = asoc->ipackets;
+ sas.sas_rtxpackets = asoc->rtxpackets;
+
+ if (asoc->max_obs_rto == 0) /* unchanged during obervation period */
+ sas.sas_maxrto = asoc->max_prev_obs_rto;
+ else /* record new period maximum */
+ sas.sas_maxrto = asoc->max_obs_rto;
+
+ /* Record the value sent to the user this period */
+ asoc->max_prev_obs_rto = sas.sas_maxrto;
+
+ /* Mark beginning of a new observation period */
+ asoc->max_obs_rto = 0;
+
+ if (put_user(len, optlen))
+ return -EFAULT;
+
+ SCTP_DEBUG_PRINTK("sctp_getsockopt_assoc_stat(%d): %d\n",
+ len, sas.sas_assoc_id);
+
+ if (copy_to_user(optval, &sas, len))
+ return -EFAULT;
+
+ return 0;
+}
+
SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen)
{
@@ -5773,6 +5837,9 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
case SCTP_PEER_ADDR_THLDS:
retval = sctp_getsockopt_paddr_thresholds(sk, optval, len, optlen);
break;
+ case SCTP_GET_ASSOC_STATS:
+ retval = sctp_getsockopt_assoc_stats(sk, len, optval, optlen);
+ break;
default:
retval = -ENOPROTOOPT;
break;
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index 953c21e..dd20f6f 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -350,6 +350,7 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)
/* 6.3.1 C3) After the computation, update RTO <- SRTT + 4 * RTTVAR. */
tp->rto = tp->srtt + (tp->rttvar << 2);
+ SCTP_MAX_RTO(tp->asoc, tp);
/* 6.3.1 C6) Whenever RTO is computed, if it is less than RTO.Min
* seconds then it is rounded up to RTO.Min seconds.
@@ -620,6 +621,7 @@ void sctp_transport_reset(struct sctp_transport *t)
t->burst_limited = 0;
t->ssthresh = asoc->peer.i.a_rwnd;
t->rto = asoc->rto_initial;
+ SCTP_MAX_RTO(asoc, t);
t->rtt = 0;
t->srtt = 0;
t->rttvar = 0;
--
1.7.12.1
^ permalink raw reply related
* [RFC PATCH net-next v2] ipv6: remove rt6i_peer_genid from rt6_info and its handler
From: roy.qing.li @ 2012-10-26 13:52 UTC (permalink / raw)
To: netdev
From: Li RongQing <roy.qing.li@gmail.com>
6431cbc25f(Create a mechanism for upward inetpeer propagation into routes)
introduces these codes, but this mechanism is never enabled since
rt6i_peer_genid always is zero whether it is not assigned or assigned by
rt6_peer_genid(). After 5943634fc5 (ipv4: Maintain redirect and PMTU info
in struct rtable again), the ipv4 related codes of this mechanism has been
removed, I think we maybe able to remove them now.
Signed-off-by: Li RongQing <roy.qing.li@gmail.com>
---
v2: sorry, remove probably rt6_bind_peer in ip6_dst_check
include/net/ip6_fib.h | 1 -
net/ipv6/route.c | 18 ++----------------
2 files changed, 2 insertions(+), 17 deletions(-)
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index 20210d7..26210cf 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -117,7 +117,6 @@ struct rt6_info {
struct rt6key rt6i_src;
struct rt6key rt6i_prefsrc;
u32 rt6i_metric;
- u32 rt6i_peer_genid;
struct inet6_dev *rt6i_idev;
unsigned long _rt6i_peer;
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index c42650c..0db1828 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -321,13 +321,6 @@ static void ip6_dst_destroy(struct dst_entry *dst)
}
}
-static atomic_t __rt6_peer_genid = ATOMIC_INIT(0);
-
-static u32 rt6_peer_genid(void)
-{
- return atomic_read(&__rt6_peer_genid);
-}
-
void rt6_bind_peer(struct rt6_info *rt, int create)
{
struct inet_peer_base *base;
@@ -341,8 +334,6 @@ void rt6_bind_peer(struct rt6_info *rt, int create)
if (peer) {
if (!rt6_set_peer(rt, peer))
inet_putpeer(peer);
- else
- rt->rt6i_peer_genid = rt6_peer_genid();
}
}
@@ -1099,14 +1090,9 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie)
if (rt->rt6i_genid != rt_genid(dev_net(rt->dst.dev)))
return NULL;
- if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) {
- if (rt->rt6i_peer_genid != rt6_peer_genid()) {
- if (!rt6_has_peer(rt))
- rt6_bind_peer(rt, 0);
- rt->rt6i_peer_genid = rt6_peer_genid();
- }
+ if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie))
return dst;
- }
+
return NULL;
}
--
1.7.4.1
^ permalink raw reply related
* [PATCH 1/1] smsc95xx: add wol support for more frame types
From: Steve Glendinning @ 2012-10-26 13:43 UTC (permalink / raw)
To: netdev; +Cc: Steve Glendinning
In-Reply-To: <1351259036-5375-1-git-send-email-steve.glendinning@shawell.net>
This patch adds support for wol wakeup on unicast, broadcast,
multicast and arp frames.
The wakeup filter code isn't pretty, but it works.
Signed-off-by: Steve Glendinning <steve.glendinning@shawell.net>
---
drivers/net/usb/Kconfig | 2 +
drivers/net/usb/smsc95xx.c | 127 +++++++++++++++++++++++++++++++++++++++++---
drivers/net/usb/smsc95xx.h | 5 ++
3 files changed, 128 insertions(+), 6 deletions(-)
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index 2ab8043..e62882c 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -256,6 +256,8 @@ config USB_NET_SMSC75XX
config USB_NET_SMSC95XX
tristate "SMSC LAN95XX based USB 2.0 10/100 ethernet devices"
depends on USB_USBNET
+ select BITREVERSE
+ select CRC16
select CRC32
help
This option adds support for SMSC LAN95XX based USB 2.0
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index 1730f75..46cd784 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -26,6 +26,8 @@
#include <linux/ethtool.h>
#include <linux/mii.h>
#include <linux/usb.h>
+#include <linux/bitrev.h>
+#include <linux/crc16.h>
#include <linux/crc32.h>
#include <linux/usb/usbnet.h>
#include <linux/slab.h>
@@ -46,7 +48,8 @@
#define SMSC95XX_INTERNAL_PHY_ID (1)
#define SMSC95XX_TX_OVERHEAD (8)
#define SMSC95XX_TX_OVERHEAD_CSUM (12)
-#define SUPPORTED_WAKE (WAKE_MAGIC)
+#define SUPPORTED_WAKE (WAKE_UCAST | WAKE_BCAST | \
+ WAKE_MCAST | WAKE_ARP | WAKE_MAGIC)
#define check_warn(ret, fmt, args...) \
({ if (ret < 0) netdev_warn(dev->net, fmt, ##args); })
@@ -63,6 +66,7 @@ struct smsc95xx_priv {
u32 hash_lo;
u32 wolopts;
spinlock_t mac_cr_lock;
+ int wuff_filter_count;
};
static bool turbo_mode = true;
@@ -956,6 +960,7 @@ static const struct net_device_ops smsc95xx_netdev_ops = {
static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
{
struct smsc95xx_priv *pdata = NULL;
+ u32 val;
int ret;
printk(KERN_INFO SMSC_CHIPNAME " v" SMSC_DRIVER_VERSION "\n");
@@ -986,6 +991,15 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
/* Init all registers */
ret = smsc95xx_reset(dev);
+ /* detect device revision as different features may be available */
+ ret = smsc95xx_read_reg(dev, ID_REV, &val);
+ check_warn_return(ret, "Failed to read ID_REV: %d\n", ret);
+ val >>= 16;
+ if ((val == ID_REV_CHIP_ID_9500A_) || (val == ID_REV_CHIP_ID_9512_))
+ pdata->wuff_filter_count = LAN9500A_WUFF_NUM;
+ else
+ pdata->wuff_filter_count = LAN9500_WUFF_NUM;
+
dev->net->netdev_ops = &smsc95xx_netdev_ops;
dev->net->ethtool_ops = &smsc95xx_ethtool_ops;
dev->net->flags |= IFF_MULTICAST;
@@ -1005,6 +1019,11 @@ static void smsc95xx_unbind(struct usbnet *dev, struct usb_interface *intf)
}
}
+static u16 smsc_crc(const u8 *buffer, size_t len, int filter)
+{
+ return bitrev16(crc16(0xFFFF, buffer, len)) << ((filter % 2) * 16);
+}
+
static int smsc95xx_suspend(struct usb_interface *intf, pm_message_t message)
{
struct usbnet *dev = usb_get_intfdata(intf);
@@ -1049,6 +1068,94 @@ static int smsc95xx_suspend(struct usb_interface *intf, pm_message_t message)
return 0;
}
+ if (pdata->wolopts & (WAKE_BCAST | WAKE_MCAST | WAKE_ARP | WAKE_UCAST)) {
+ u32 *filter_mask = kzalloc(32, GFP_KERNEL);
+ u32 *command = kzalloc(2, GFP_KERNEL);
+ u32 *offset = kzalloc(2, GFP_KERNEL);
+ u32 *crc = kzalloc(4, GFP_KERNEL);
+ int i, filter = 0;
+
+ if (pdata->wolopts & WAKE_BCAST) {
+ const u8 bcast[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+ netdev_info(dev->net, "enabling broadcast detection");
+ filter_mask[filter * 4] = 0x003F;
+ filter_mask[filter * 4 + 1] = 0x00;
+ filter_mask[filter * 4 + 2] = 0x00;
+ filter_mask[filter * 4 + 3] = 0x00;
+ command[filter/4] |= 0x05UL << ((filter % 4) * 8);
+ offset[filter/4] |= 0x00 << ((filter % 4) * 8);
+ crc[filter/2] |= smsc_crc(bcast, 6, filter);
+ filter++;
+ }
+
+ if (pdata->wolopts & WAKE_MCAST) {
+ const u8 mcast[] = {0x01, 0x00, 0x5E};
+ netdev_info(dev->net, "enabling multicast detection");
+ filter_mask[filter * 4] = 0x0007;
+ filter_mask[filter * 4 + 1] = 0x00;
+ filter_mask[filter * 4 + 2] = 0x00;
+ filter_mask[filter * 4 + 3] = 0x00;
+ command[filter/4] |= 0x09UL << ((filter % 4) * 8);
+ offset[filter/4] |= 0x00 << ((filter % 4) * 8);
+ crc[filter/2] |= smsc_crc(mcast, 3, filter);
+ filter++;
+ }
+
+ if (pdata->wolopts & WAKE_ARP) {
+ const u8 arp[] = {0x08, 0x06};
+ netdev_info(dev->net, "enabling ARP detection");
+ filter_mask[filter * 4] = 0x0003;
+ filter_mask[filter * 4 + 1] = 0x00;
+ filter_mask[filter * 4 + 2] = 0x00;
+ filter_mask[filter * 4 + 3] = 0x00;
+ command[filter/4] |= 0x05UL << ((filter % 4) * 8);
+ offset[filter/4] |= 0x0C << ((filter % 4) * 8);
+ crc[filter/2] |= smsc_crc(arp, 2, filter);
+ filter++;
+ }
+
+ if (pdata->wolopts & WAKE_UCAST) {
+ netdev_info(dev->net, "enabling unicast detection");
+ filter_mask[filter * 4] = 0x003F;
+ filter_mask[filter * 4 + 1] = 0x00;
+ filter_mask[filter * 4 + 2] = 0x00;
+ filter_mask[filter * 4 + 3] = 0x00;
+ command[filter/4] |= 0x01UL << ((filter % 4) * 8);
+ offset[filter/4] |= 0x00 << ((filter % 4) * 8);
+ crc[filter/2] |= smsc_crc(dev->net->dev_addr, ETH_ALEN, filter);
+ filter++;
+ }
+
+ for (i = 0; i < (pdata->wuff_filter_count * 4); i++) {
+ ret = smsc95xx_write_reg(dev, WUFF, filter_mask[i]);
+ check_warn_return(ret, "Error writing WUFF");
+ }
+
+ for (i = 0; i < (pdata->wuff_filter_count / 4); i++) {
+ ret = smsc95xx_write_reg(dev, WUFF, command[i]);
+ check_warn_return(ret, "Error writing WUFF");
+ }
+
+ for (i = 0; i < (pdata->wuff_filter_count / 4); i++) {
+ ret = smsc95xx_write_reg(dev, WUFF, offset[i]);
+ check_warn_return(ret, "Error writing WUFF");
+ }
+
+ for (i = 0; i < (pdata->wuff_filter_count / 2); i++) {
+ ret = smsc95xx_write_reg(dev, WUFF, crc[i]);
+ check_warn_return(ret, "Error writing WUFF");
+ }
+
+ /* clear any pending pattern match packet status */
+ ret = smsc95xx_read_reg(dev, WUCSR, &val);
+ check_warn_return(ret, "Error reading WUCSR");
+
+ val |= WUCSR_WUFR_;
+
+ ret = smsc95xx_write_reg(dev, WUCSR, val);
+ check_warn_return(ret, "Error writing WUCSR");
+ }
+
if (pdata->wolopts & WAKE_MAGIC) {
/* clear any pending magic packet status */
ret = smsc95xx_read_reg(dev, WUCSR, &val);
@@ -1060,10 +1167,18 @@ static int smsc95xx_suspend(struct usb_interface *intf, pm_message_t message)
check_warn_return(ret, "Error writing WUCSR");
}
- /* enable/disable magic packup wake */
+ /* enable/disable wakeup sources */
ret = smsc95xx_read_reg(dev, WUCSR, &val);
check_warn_return(ret, "Error reading WUCSR");
+ if (pdata->wolopts & (WAKE_BCAST | WAKE_MCAST | WAKE_ARP | WAKE_UCAST)) {
+ netdev_info(dev->net, "enabling pattern match wakeup");
+ val |= WUCSR_WAKE_EN_;
+ } else {
+ netdev_info(dev->net, "disabling pattern match wakeup");
+ val &= ~WUCSR_WAKE_EN_;
+ }
+
if (pdata->wolopts & WAKE_MAGIC) {
netdev_info(dev->net, "enabling magic packet wakeup");
val |= WUCSR_MPEN_;
@@ -1084,7 +1199,7 @@ static int smsc95xx_suspend(struct usb_interface *intf, pm_message_t message)
ret = smsc95xx_write_reg(dev, PM_CTRL, val);
check_warn_return(ret, "Error writing PM_CTRL");
- /* enable receiver */
+ /* enable receiver to enable frame reception */
smsc95xx_start_rx_path(dev);
/* some wol options are enabled, so enter SUSPEND0 */
@@ -1123,14 +1238,14 @@ static int smsc95xx_resume(struct usb_interface *intf)
BUG_ON(!dev);
- if (pdata->wolopts & WAKE_MAGIC) {
+ if (pdata->wolopts) {
smsc95xx_clear_feature(dev, USB_DEVICE_REMOTE_WAKEUP);
- /* Disable magic packup wake */
+ /* clear wake-up sources */
ret = smsc95xx_read_reg(dev, WUCSR, &val);
check_warn_return(ret, "Error reading WUCSR");
- val &= ~WUCSR_MPEN_;
+ val &= ~(WUCSR_WAKE_EN_ | WUCSR_MPEN_);
ret = smsc95xx_write_reg(dev, WUCSR, val);
check_warn_return(ret, "Error writing WUCSR");
diff --git a/drivers/net/usb/smsc95xx.h b/drivers/net/usb/smsc95xx.h
index 2ff9815..1f86269 100644
--- a/drivers/net/usb/smsc95xx.h
+++ b/drivers/net/usb/smsc95xx.h
@@ -53,6 +53,8 @@
#define ID_REV_CHIP_ID_MASK_ (0xFFFF0000)
#define ID_REV_CHIP_REV_MASK_ (0x0000FFFF)
#define ID_REV_CHIP_ID_9500_ (0x9500)
+#define ID_REV_CHIP_ID_9500A_ (0x9E00)
+#define ID_REV_CHIP_ID_9512_ (0xEC00)
#define INT_STS (0x08)
#define INT_STS_TX_STOP_ (0x00020000)
@@ -203,8 +205,11 @@
#define VLAN2 (0x124)
#define WUFF (0x128)
+#define LAN9500_WUFF_NUM (4)
+#define LAN9500A_WUFF_NUM (8)
#define WUCSR (0x12C)
+#define WUCSR_WFF_PTR_RST_ (0x80000000)
#define WUCSR_GUE_ (0x00000200)
#define WUCSR_WUFR_ (0x00000040)
#define WUCSR_MPR_ (0x00000020)
--
1.7.9.5
^ permalink raw reply related
* [PATCH 0/1] smsc95xx: wol enhancements
From: Steve Glendinning @ 2012-10-26 13:43 UTC (permalink / raw)
To: netdev; +Cc: Steve Glendinning
This patch adds support for more WOL frame types to smsc95xx.
Please review and consider for inclusion into net-next.
Steve Glendinning (1):
smsc95xx: add wol support for more frame types
drivers/net/usb/Kconfig | 2 +
drivers/net/usb/smsc95xx.c | 127 +++++++++++++++++++++++++++++++++++++++++---
drivers/net/usb/smsc95xx.h | 5 ++
3 files changed, 128 insertions(+), 6 deletions(-)
--
1.7.9.5
^ permalink raw reply
* [PATCH v2] sctp: Clean up type-punning in sctp_cmd_t union
From: Neil Horman @ 2012-10-26 13:41 UTC (permalink / raw)
To: netdev; +Cc: Neil Horman, Vlad Yasevich, David S. Miller, linux-sctp
In-Reply-To: <1351198075-20385-1-git-send-email-nhorman@tuxdriver.com>
Lots of points in the sctp_cmd_interpreter function treat the sctp_cmd_t arg as
a void pointer, even though they are written as various other types. Theres no
need for this as doing so just leads to possible type-punning issues that could
cause crashes, and if we remain type-consistent we can actually just remove the
void * member of the union entirely.
Change Notes:
v2)
* Dropped chunk that modified SCTP_NULL to create a marker pattern
should anyone try to use a SCTP_NULL() assigned sctp_arg_t, Assigning
to .zero provides the same effect and should be faster, per Vlad Y.
Signed-off-by: Neil Horman <nhorman@tuxdriver.com
CC: Vlad Yasevich <vyasevich@gmail.com>
CC: "David S. Miller" <davem@davemloft.net>
CC: linux-sctp@vger.kernel.org
---
include/net/sctp/command.h | 4 +---
include/net/sctp/ulpqueue.h | 2 +-
net/sctp/sm_sideeffect.c | 45 ++++++++++++++++++++++-----------------------
net/sctp/ulpqueue.c | 3 +--
4 files changed, 25 insertions(+), 29 deletions(-)
diff --git a/include/net/sctp/command.h b/include/net/sctp/command.h
index 712b3be..8d52cd7 100644
--- a/include/net/sctp/command.h
+++ b/include/net/sctp/command.h
@@ -131,7 +131,6 @@ typedef union {
sctp_state_t state;
sctp_event_timeout_t to;
unsigned long zero;
- void *ptr;
struct sctp_chunk *chunk;
struct sctp_association *asoc;
struct sctp_transport *transport;
@@ -156,7 +155,7 @@ typedef union {
*/
static inline sctp_arg_t SCTP_NULL(void)
{
- sctp_arg_t retval; retval.ptr = NULL; return retval;
+ sctp_arg_t retval = { .zero = 0UL}; return retval;
}
static inline sctp_arg_t SCTP_NOFORCE(void)
{
@@ -181,7 +180,6 @@ SCTP_ARG_CONSTRUCTOR(ERROR, int, error)
SCTP_ARG_CONSTRUCTOR(PERR, __be16, err) /* protocol error */
SCTP_ARG_CONSTRUCTOR(STATE, sctp_state_t, state)
SCTP_ARG_CONSTRUCTOR(TO, sctp_event_timeout_t, to)
-SCTP_ARG_CONSTRUCTOR(PTR, void *, ptr)
SCTP_ARG_CONSTRUCTOR(CHUNK, struct sctp_chunk *, chunk)
SCTP_ARG_CONSTRUCTOR(ASOC, struct sctp_association *, asoc)
SCTP_ARG_CONSTRUCTOR(TRANSPORT, struct sctp_transport *, transport)
diff --git a/include/net/sctp/ulpqueue.h b/include/net/sctp/ulpqueue.h
index 2e5ee0d..ff1b8ba7 100644
--- a/include/net/sctp/ulpqueue.h
+++ b/include/net/sctp/ulpqueue.h
@@ -72,7 +72,7 @@ int sctp_ulpq_tail_event(struct sctp_ulpq *, struct sctp_ulpevent *ev);
void sctp_ulpq_renege(struct sctp_ulpq *, struct sctp_chunk *, gfp_t);
/* Perform partial delivery. */
-void sctp_ulpq_partial_delivery(struct sctp_ulpq *, struct sctp_chunk *, gfp_t);
+void sctp_ulpq_partial_delivery(struct sctp_ulpq *, gfp_t);
/* Abort the partial delivery. */
void sctp_ulpq_abort_pd(struct sctp_ulpq *, gfp_t);
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 6773d78..6eecf7e 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -1268,14 +1268,14 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
sctp_outq_uncork(&asoc->outqueue);
local_cork = 0;
}
- asoc = cmd->obj.ptr;
+ asoc = cmd->obj.asoc;
/* Register with the endpoint. */
sctp_endpoint_add_asoc(ep, asoc);
sctp_hash_established(asoc);
break;
case SCTP_CMD_UPDATE_ASSOC:
- sctp_assoc_update(asoc, cmd->obj.ptr);
+ sctp_assoc_update(asoc, cmd->obj.asoc);
break;
case SCTP_CMD_PURGE_OUTQUEUE:
@@ -1315,7 +1315,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
break;
case SCTP_CMD_PROCESS_FWDTSN:
- sctp_cmd_process_fwdtsn(&asoc->ulpq, cmd->obj.ptr);
+ sctp_cmd_process_fwdtsn(&asoc->ulpq, cmd->obj.chunk);
break;
case SCTP_CMD_GEN_SACK:
@@ -1331,7 +1331,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
case SCTP_CMD_PROCESS_SACK:
/* Process an inbound SACK. */
error = sctp_cmd_process_sack(commands, asoc,
- cmd->obj.ptr);
+ cmd->obj.chunk);
break;
case SCTP_CMD_GEN_INIT_ACK:
@@ -1352,15 +1352,15 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
* layer which will bail.
*/
error = sctp_cmd_process_init(commands, asoc, chunk,
- cmd->obj.ptr, gfp);
+ cmd->obj.init, gfp);
break;
case SCTP_CMD_GEN_COOKIE_ECHO:
/* Generate a COOKIE ECHO chunk. */
new_obj = sctp_make_cookie_echo(asoc, chunk);
if (!new_obj) {
- if (cmd->obj.ptr)
- sctp_chunk_free(cmd->obj.ptr);
+ if (cmd->obj.chunk)
+ sctp_chunk_free(cmd->obj.chunk);
goto nomem;
}
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
@@ -1369,9 +1369,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
/* If there is an ERROR chunk to be sent along with
* the COOKIE_ECHO, send it, too.
*/
- if (cmd->obj.ptr)
+ if (cmd->obj.chunk)
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
- SCTP_CHUNK(cmd->obj.ptr));
+ SCTP_CHUNK(cmd->obj.chunk));
if (new_obj->transport) {
new_obj->transport->init_sent_count++;
@@ -1417,18 +1417,18 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
case SCTP_CMD_CHUNK_ULP:
/* Send a chunk to the sockets layer. */
SCTP_DEBUG_PRINTK("sm_sideff: %s %p, %s %p.\n",
- "chunk_up:", cmd->obj.ptr,
+ "chunk_up:", cmd->obj.chunk,
"ulpq:", &asoc->ulpq);
- sctp_ulpq_tail_data(&asoc->ulpq, cmd->obj.ptr,
+ sctp_ulpq_tail_data(&asoc->ulpq, cmd->obj.chunk,
GFP_ATOMIC);
break;
case SCTP_CMD_EVENT_ULP:
/* Send a notification to the sockets layer. */
SCTP_DEBUG_PRINTK("sm_sideff: %s %p, %s %p.\n",
- "event_up:",cmd->obj.ptr,
+ "event_up:",cmd->obj.ulpevent,
"ulpq:",&asoc->ulpq);
- sctp_ulpq_tail_event(&asoc->ulpq, cmd->obj.ptr);
+ sctp_ulpq_tail_event(&asoc->ulpq, cmd->obj.ulpevent);
break;
case SCTP_CMD_REPLY:
@@ -1438,12 +1438,12 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
local_cork = 1;
}
/* Send a chunk to our peer. */
- error = sctp_outq_tail(&asoc->outqueue, cmd->obj.ptr);
+ error = sctp_outq_tail(&asoc->outqueue, cmd->obj.chunk);
break;
case SCTP_CMD_SEND_PKT:
/* Send a full packet to our peer. */
- packet = cmd->obj.ptr;
+ packet = cmd->obj.packet;
sctp_packet_transmit(packet);
sctp_ootb_pkt_free(packet);
break;
@@ -1480,7 +1480,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
break;
case SCTP_CMD_SETUP_T2:
- sctp_cmd_setup_t2(commands, asoc, cmd->obj.ptr);
+ sctp_cmd_setup_t2(commands, asoc, cmd->obj.chunk);
break;
case SCTP_CMD_TIMER_START_ONCE:
@@ -1514,7 +1514,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
break;
case SCTP_CMD_INIT_CHOOSE_TRANSPORT:
- chunk = cmd->obj.ptr;
+ chunk = cmd->obj.chunk;
t = sctp_assoc_choose_alter_transport(asoc,
asoc->init_last_sent_to);
asoc->init_last_sent_to = t;
@@ -1665,17 +1665,16 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
break;
case SCTP_CMD_PART_DELIVER:
- sctp_ulpq_partial_delivery(&asoc->ulpq, cmd->obj.ptr,
- GFP_ATOMIC);
+ sctp_ulpq_partial_delivery(&asoc->ulpq, GFP_ATOMIC);
break;
case SCTP_CMD_RENEGE:
- sctp_ulpq_renege(&asoc->ulpq, cmd->obj.ptr,
+ sctp_ulpq_renege(&asoc->ulpq, cmd->obj.chunk,
GFP_ATOMIC);
break;
case SCTP_CMD_SETUP_T4:
- sctp_cmd_setup_t4(commands, asoc, cmd->obj.ptr);
+ sctp_cmd_setup_t4(commands, asoc, cmd->obj.chunk);
break;
case SCTP_CMD_PROCESS_OPERR:
@@ -1734,8 +1733,8 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
break;
default:
- pr_warn("Impossible command: %u, %p\n",
- cmd->verb, cmd->obj.ptr);
+ pr_warn("Impossible command: %u\n",
+ cmd->verb);
break;
}
diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c
index 360d869..ada1746 100644
--- a/net/sctp/ulpqueue.c
+++ b/net/sctp/ulpqueue.c
@@ -997,7 +997,6 @@ static __u16 sctp_ulpq_renege_frags(struct sctp_ulpq *ulpq, __u16 needed)
/* Partial deliver the first message as there is pressure on rwnd. */
void sctp_ulpq_partial_delivery(struct sctp_ulpq *ulpq,
- struct sctp_chunk *chunk,
gfp_t gfp)
{
struct sctp_ulpevent *event;
@@ -1060,7 +1059,7 @@ void sctp_ulpq_renege(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk,
sctp_tsnmap_mark(&asoc->peer.tsn_map, tsn, chunk->transport);
sctp_ulpq_tail_data(ulpq, chunk, gfp);
- sctp_ulpq_partial_delivery(ulpq, chunk, gfp);
+ sctp_ulpq_partial_delivery(ulpq, gfp);
}
sk_mem_reclaim(asoc->base.sk);
--
1.7.11.7
^ permalink raw reply related
* Re: [PATCH] sctp: Clean up type-punning in sctp_cmd_t union
From: Neil Horman @ 2012-10-26 13:28 UTC (permalink / raw)
To: David Laight; +Cc: netdev, Vlad Yasevich, David S. Miller, linux-sctp
In-Reply-To: <AE90C24D6B3A694183C094C60CF0A2F6026B706F@saturn3.aculab.com>
On Fri, Oct 26, 2012 at 10:00:13AM +0100, David Laight wrote:
> > Subject: [PATCH] sctp: Clean up type-punning in sctp_cmd_t union
> ...
> > +#define SCTP_NULL_BYTE 0xAA
> > static inline sctp_arg_t SCTP_NULL(void)
> > {
> > - sctp_arg_t retval; retval.ptr = NULL; return retval;
> > + sctp_arg_t retval;
> > + memset(&retval, SCTP_NULL_BYTE, sizeof(sctp_arg_t));
> > + return retval;
> > }
>
> You really don't want to be taking the address of a local
> variable that would normally be held in a register.
> It stops the compiler doing a lot of optimisations.
> In this case the structure is also being returned by value,
> not nice except that all(?) modern ABI do pass small structures
> in registers.
>
Thank you dave, I hadn't considered the implications of missed optimizations
when storing to a register here.
> An assignment of some member of the union to NULL would
> seem most appropriate.
> OTOH the code that uses this must be someones 'bright idea (tm)'
> that probably wasn't such a good idea after all.
>
nobody uses it currently, Its just that some state machine side effects don't
require an argument, but you still have to pass one in, so I was trying to
enhance this to make it obvious in a backtrace should someone inadvertently use
it in the future. I'm going to revert it though, a big fat zero is probably
just as clear.
Neil
> David
>
>
>
>
^ permalink raw reply
* Re: [PATCH] sctp: Clean up type-punning in sctp_cmd_t union
From: Neil Horman @ 2012-10-26 13:24 UTC (permalink / raw)
To: Vlad Yasevich; +Cc: netdev, David S. Miller, linux-sctp
In-Reply-To: <508A0800.10404@gmail.com>
On Thu, Oct 25, 2012 at 11:48:16PM -0400, Vlad Yasevich wrote:
> On 10/25/2012 07:58 PM, Neil Horman wrote:
> >On Thu, Oct 25, 2012 at 05:42:15PM -0400, Vlad Yasevich wrote:
> >>On 10/25/2012 04:47 PM, Neil Horman wrote:
> >>>Lots of points in the sctp_cmd_interpreter function treat the sctp_cmd_t arg as
> >>>a void pointer, even though they are written as various other types. Theres no
> >>>need for this as doing so just leads to possible type-punning issues that could
> >>>cause crashes, and if we remain type-consistent we can actually just remove the
> >>>void * member of the union entirely.
> >>>
> >>>Signed-off-by: Neil Horman <nhorman@tuxdriver.com
> >>>CC: Vlad Yasevich <vyasevich@gmail.com>
> >>>CC: "David S. Miller" <davem@davemloft.net>
> >>>CC: linux-sctp@vger.kernel.org
> >>>---
> >>> include/net/sctp/command.h | 7 ++++---
> >>> include/net/sctp/ulpqueue.h | 2 +-
> >>> net/sctp/sm_sideeffect.c | 45 ++++++++++++++++++++++-----------------------
> >>> net/sctp/ulpqueue.c | 3 +--
> >>> 4 files changed, 28 insertions(+), 29 deletions(-)
> >>>
> >>>diff --git a/include/net/sctp/command.h b/include/net/sctp/command.h
> >>>index 712b3be..7f1b0f3 100644
> >>>--- a/include/net/sctp/command.h
> >>>+++ b/include/net/sctp/command.h
> >>>@@ -131,7 +131,6 @@ typedef union {
> >>> sctp_state_t state;
> >>> sctp_event_timeout_t to;
> >>> unsigned long zero;
> >>>- void *ptr;
> >>> struct sctp_chunk *chunk;
> >>> struct sctp_association *asoc;
> >>> struct sctp_transport *transport;
> >>>@@ -154,9 +153,12 @@ typedef union {
> >>> * which takes an __s32 and returns a sctp_arg_t containing the
> >>> * __s32. So, after foo = SCTP_I32(arg), foo.i32 == arg.
> >>> */
> >>>+#define SCTP_NULL_BYTE 0xAA
> >>> static inline sctp_arg_t SCTP_NULL(void)
> >>> {
> >>>- sctp_arg_t retval; retval.ptr = NULL; return retval;
> >>>+ sctp_arg_t retval;
> >>>+ memset(&retval, SCTP_NULL_BYTE, sizeof(sctp_arg_t));
> >>>+ return retval;
> >>
> >>What's this for? Can't we just use retval.zero?
> >>
> >>-vlad
> >>
> >My intent was to highlight any users of sctp_arg_t when SCTP_NULL was passed.
> >My thinking was that the 0xAA byte patern would be a good indicator. Although,
> >admittedly I didn't see the zero argument there. Looking at it though, the zero
> >member of the union is effectively unused. Strictly speaking its used for
> >initalization of sctp_arg_t, but its done somewhat poorly, since theres no
> >guarantee that an unsigned long will be the largest member of that union. Doing
> >the memset guarantees the whole instance is set to a predefined value.
> >
> >I could go either way with this, would you rather we just have SCTP_NULL return
> >retval = { .zero = 0}; or would you rather remove the zero initialization from
> >SCTP_[NO]FORCE, and SCTP_ARG_CONSTRUCTOR and do the memset. I think the memset
> >reduces to a single 64 bit assignment as long as the union doesn't exceed that
> >size anyway, and it ensures that you initalize the whole union's storage if it
> >does in the future. And if we remove the initialization step (I don't see that
> >its needed in the three macros above anyway), then we can remove the zero member
> >as well.
> >
>
> You need the initialization step, otherwise things might fail (they
> did on IA64 a while back). That's why the zero member was added.
> You can go with memset if you want, but I was primarily wondering
> why the 0xAA pattern was there.
>
The AA I did was just meant as a pattern marker, so that, should someone use an
instance of sctp_arg_t that was passed in as SCTP_NULL(), it would be visually
obvious in the stack trace, but I suppose its not really needed given that NULL
is equally clear. And since Dave pointed out the lack of optimization
opportunity when using a store to an address rather than a register, I think I
should probably just revert it and use zero as you initially suggested.
The need for the initalization in SCTP_[NO]FORCE and SCTP_ARG_CONSTRUCTOR
concerns me though. All its doing is setting part of the storage to zero, and
then overwriting it again with whatever type spcific member you're assigning
from the corresponding SCTP_* macro. That kind of sounds to me like ia64 might
have fallen to some amount of type-punning problem. do you have a link to
discussion about that problem?
Regards
Neil
> -vlad
> >Let me know what you want to do here, and I can respin this.
> >Best
> >Neil
> >
>
>
^ permalink raw reply
* [RFC PATCH net-next] ipv6: remove rt6i_peer_genid from rt6_info and its handler
From: roy.qing.li @ 2012-10-26 13:01 UTC (permalink / raw)
To: netdev
From: Li RongQing <roy.qing.li@gmail.com>
6431cbc25f(Create a mechanism for upward inetpeer propagation into routes)
introduces these codes, but this mechanism is never enabled since
rt6i_peer_genid always is zero whether it is not assigned or assigned by
rt6_peer_genid(). After 5943634fc5 (ipv4: Maintain redirect and PMTU info
in struct rtable again), the ipv4 related codes of this mechanism have been
removed, I think we maybe able to remove them now.
Signed-off-by: Li RongQing <roy.qing.li@gmail.com>
---
include/net/ip6_fib.h | 1 -
net/ipv6/route.c | 16 ++--------------
2 files changed, 2 insertions(+), 15 deletions(-)
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index 20210d7..26210cf 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -117,7 +117,6 @@ struct rt6_info {
struct rt6key rt6i_src;
struct rt6key rt6i_prefsrc;
u32 rt6i_metric;
- u32 rt6i_peer_genid;
struct inet6_dev *rt6i_idev;
unsigned long _rt6i_peer;
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index c42650c..6ceee24 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -321,13 +321,6 @@ static void ip6_dst_destroy(struct dst_entry *dst)
}
}
-static atomic_t __rt6_peer_genid = ATOMIC_INIT(0);
-
-static u32 rt6_peer_genid(void)
-{
- return atomic_read(&__rt6_peer_genid);
-}
-
void rt6_bind_peer(struct rt6_info *rt, int create)
{
struct inet_peer_base *base;
@@ -341,8 +334,6 @@ void rt6_bind_peer(struct rt6_info *rt, int create)
if (peer) {
if (!rt6_set_peer(rt, peer))
inet_putpeer(peer);
- else
- rt->rt6i_peer_genid = rt6_peer_genid();
}
}
@@ -1100,11 +1091,8 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie)
return NULL;
if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) {
- if (rt->rt6i_peer_genid != rt6_peer_genid()) {
- if (!rt6_has_peer(rt))
- rt6_bind_peer(rt, 0);
- rt->rt6i_peer_genid = rt6_peer_genid();
- }
+ if (!rt6_has_peer(rt))
+ rt6_bind_peer(rt, 0);
return dst;
}
return NULL;
--
1.7.4.1
^ permalink raw reply related
* RE: [net-next 10/14] ixgbevf: make sure probe fails on MSI-X enable error
From: Kicinski, Jakub @ 2012-10-26 12:43 UTC (permalink / raw)
To: Kirsher, Jeffrey T, davem@davemloft.net
Cc: netdev@vger.kernel.org, gospo@redhat.com, sassmann@redhat.com
In-Reply-To: <1351252702-16532-11-git-send-email-jeffrey.t.kirsher@intel.com>
> From: Jakub Kicinski <jakub.kicinski@intel.com>
>
> This driver cannot work without MSI-X interrupts so there is no mechanism to
> fall back to.
>
> Signed-off-by: Jakub Kicinski <jakub.kicinski@intel.com>
> Acked-by: Greg Rose <gregory.v.rose@intel.com>
> Tested-by: Sibai Li <sibai.li@intel.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> ---
> drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 24 +++++++++++------------
> 1 file changed, 11 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
> b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
> index b5979ba..7ceccff 100644
> --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
> +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
[...]
> @@ -1858,7 +1856,7 @@ static int ixgbevf_set_interrupt_capability(struct
> ixgbevf_adapter *adapter)
> for (vector = 0; vector < v_budget; vector++)
> adapter->msix_entries[vector].entry = vector;
>
> - ixgbevf_acquire_msix_vectors(adapter, v_budget);
> + err = ixgbevf_acquire_msix_vectors(adapter, v_budget);
>
> err = netif_set_real_num_tx_queues(netdev, adapter->num_tx_queues);
> if (err)
This is clearly wrong. My change was overtaken by:
commit 91e2b89b04d3f568dc4ec99f242a4a742061e399
Author: Greg Rose <gregory.v.rose@intel.com>
Date: Wed Oct 3 00:57:23 2012 +0000
ixgbevf: Set the netdev number of Tx queues
Please drop this patch, I'll resend a fixed version to Greg.
-- Kuba
---------------------------------------------------------------------
Intel Technology Poland sp. z o.o.
z siedziba w Gdansku
ul. Slowackiego 173
80-298 Gdansk
Sad Rejonowy Gdansk Polnoc w Gdansku,
VII Wydzial Gospodarczy Krajowego Rejestru Sadowego,
numer KRS 101882
NIP 957-07-52-316
Kapital zakladowy 200.000 zl
This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.
^ permalink raw reply
* Re: [net-next 07/14] ixgbe: eliminate Smatch warnings in ixgbe_debugfs.c
From: Dan Carpenter @ 2012-10-26 12:41 UTC (permalink / raw)
To: Jeff Kirsher; +Cc: davem, joshua.a.hay@intel.com, netdev, gospo, sassmann
In-Reply-To: <1351252702-16532-8-git-send-email-jeffrey.t.kirsher@intel.com>
On Fri, Oct 26, 2012 at 04:58:15AM -0700, Jeff Kirsher wrote:
> From: "joshua.a.hay@intel.com" <joshua.a.hay@intel.com>
>
> This patch replaces calls to copy_to_user, copy_from_user, and the associated
> logic, with calls to simple_read_from_buffer and simple_write_to_buffer
> respectively. This was done to eliminate warnings generated by the Smatch
> static analysis tool.
There were some bugs, it wasn't just about silencing warnings.
> + buf = kasprintf(GFP_KERNEL, "%s: %s\n",
> + adapter->netdev->name,
> + ixgbe_dbg_reg_ops_buf);
> + if (!buf)
> + return -ENOMEM;
> +
> + if (count < strlen(buf))
> return -ENOSPC;
You need a kfree(buf) here.
> - ixgbe_dbg_reg_ops_buf[count] = '\0';
> + len = simple_write_to_buffer(ixgbe_dbg_reg_ops_buf,
> + sizeof(ixgbe_dbg_reg_ops_buf),
This should be "sizeof(ixgbe_dbg_reg_ops_buf) - 1" to leave space
for the NUL terminator.
> + ppos,
> + buffer,
> + count);
> + ixgbe_dbg_reg_ops_buf[len] = '\0';
simple_write_to_buffer() returns negative error codes so this could
corrupt memory.
> + buf = kasprintf(GFP_KERNEL, "%s: %s\n",
> + adapter->netdev->name,
> + ixgbe_dbg_netdev_ops_buf);
> + if (!buf)
> + return -ENOMEM;
>
> - *ppos = len;
> + if (count < strlen(buf))
> + return -ENOSPC;
Missing kfree().
> - ixgbe_dbg_netdev_ops_buf[count] = '\0';
> + len = simple_write_to_buffer(ixgbe_dbg_netdev_ops_buf,
> + sizeof(ixgbe_dbg_netdev_ops_buf),
> + ppos,
> + buffer,
> + count);
> + ixgbe_dbg_netdev_ops_buf[len] = '\0';
Same issues as before.
regards,
dan carpenter
^ permalink raw reply
* [net-next 14/14] igb: Fix sparse warning in igb_ptp_rx_pktstamp
From: Jeff Kirsher @ 2012-10-26 11:58 UTC (permalink / raw)
To: davem; +Cc: Alexander Duyck, netdev, gospo, sassmann, Jeff Kirsher
In-Reply-To: <1351252702-16532-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Alexander Duyck <alexander.h.duyck@intel.com>
This change fixes a sparse warning triggered by us casting the timestamp in
the packet as a u64 instead of as a __le64. This change corrects that in
order to resolve the sparse warning.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/igb/igb_ptp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c
index a7db4ce..aa10f69 100644
--- a/drivers/net/ethernet/intel/igb/igb_ptp.c
+++ b/drivers/net/ethernet/intel/igb/igb_ptp.c
@@ -455,7 +455,7 @@ void igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector,
unsigned char *va,
struct sk_buff *skb)
{
- u64 *regval = (u64 *)va;
+ __le64 *regval = (__le64 *)va;
/*
* The timestamp is recorded in little endian format.
--
1.7.11.7
^ permalink raw reply related
* [net-next 13/14] igb: Update firmware version info for ethtool output.
From: Jeff Kirsher @ 2012-10-26 11:58 UTC (permalink / raw)
To: davem; +Cc: Carolyn Wyborny, netdev, gospo, sassmann, Jeff Kirsher
In-Reply-To: <1351252702-16532-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Carolyn Wyborny <carolyn.wyborny@intel.com>
There are multiple places in our device nvm where the version is stored.
This update fixes some output errors with some types of images and
refactors the way the version data is gathered and stored for ethtool output.
Signed-off-by: Carolyn Wyborny <carolyn.wyborny@intel.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/igb/e1000_defines.h | 14 +++++
drivers/net/ethernet/intel/igb/e1000_nvm.c | 70 ++++++++++++++++++++++++
drivers/net/ethernet/intel/igb/e1000_nvm.h | 16 ++++++
drivers/net/ethernet/intel/igb/igb_main.c | 76 +++++++++-----------------
4 files changed, 126 insertions(+), 50 deletions(-)
diff --git a/drivers/net/ethernet/intel/igb/e1000_defines.h b/drivers/net/ethernet/intel/igb/e1000_defines.h
index de4b41e..e647cff 100644
--- a/drivers/net/ethernet/intel/igb/e1000_defines.h
+++ b/drivers/net/ethernet/intel/igb/e1000_defines.h
@@ -636,6 +636,7 @@
/* NVM Word Offsets */
#define NVM_COMPAT 0x0003
#define NVM_ID_LED_SETTINGS 0x0004 /* SERDES output amplitude */
+#define NVM_VERSION 0x0005
#define NVM_INIT_CONTROL2_REG 0x000F
#define NVM_INIT_CONTROL3_PORT_B 0x0014
#define NVM_INIT_CONTROL3_PORT_A 0x0024
@@ -653,6 +654,19 @@
#define NVM_LED_1_CFG 0x001C
#define NVM_LED_0_2_CFG 0x001F
+/* NVM version defines */
+#define NVM_ETRACK_WORD 0x0042
+#define NVM_COMB_VER_OFF 0x0083
+#define NVM_COMB_VER_PTR 0x003d
+#define NVM_MAJOR_MASK 0xF000
+#define NVM_MINOR_MASK 0x0FF0
+#define NVM_BUILD_MASK 0x000F
+#define NVM_COMB_VER_MASK 0x00FF
+#define NVM_MAJOR_SHIFT 12
+#define NVM_MINOR_SHIFT 4
+#define NVM_COMB_VER_SHFT 8
+#define NVM_VER_INVALID 0xFFFF
+#define NVM_ETRACK_SHIFT 16
#define E1000_NVM_CFG_DONE_PORT_0 0x040000 /* MNG config cycle done */
#define E1000_NVM_CFG_DONE_PORT_1 0x080000 /* ...for second port */
diff --git a/drivers/net/ethernet/intel/igb/e1000_nvm.c b/drivers/net/ethernet/intel/igb/e1000_nvm.c
index aa5fcdf..54ff539 100644
--- a/drivers/net/ethernet/intel/igb/e1000_nvm.c
+++ b/drivers/net/ethernet/intel/igb/e1000_nvm.c
@@ -710,3 +710,73 @@ s32 igb_update_nvm_checksum(struct e1000_hw *hw)
out:
return ret_val;
}
+
+/**
+ * igb_get_fw_version - Get firmware version information
+ * @hw: pointer to the HW structure
+ * @fw_vers: pointer to output structure
+ *
+ * unsupported MAC types will return all 0 version structure
+ **/
+void igb_get_fw_version(struct e1000_hw *hw, struct e1000_fw_version *fw_vers)
+{
+ u16 eeprom_verh, eeprom_verl, comb_verh, comb_verl, comb_offset;
+ u16 fw_version;
+
+ memset(fw_vers, 0, sizeof(struct e1000_fw_version));
+
+ switch (hw->mac.type) {
+ case e1000_i211:
+ return;
+ case e1000_82575:
+ case e1000_82576:
+ case e1000_82580:
+ case e1000_i350:
+ case e1000_i210:
+ break;
+ default:
+ return;
+ }
+ /* basic eeprom version numbers */
+ hw->nvm.ops.read(hw, NVM_VERSION, 1, &fw_version);
+ fw_vers->eep_major = (fw_version & NVM_MAJOR_MASK) >> NVM_MAJOR_SHIFT;
+ fw_vers->eep_minor = (fw_version & NVM_MINOR_MASK);
+
+ /* etrack id */
+ hw->nvm.ops.read(hw, NVM_ETRACK_WORD, 1, &eeprom_verl);
+ hw->nvm.ops.read(hw, (NVM_ETRACK_WORD + 1), 1, &eeprom_verh);
+ fw_vers->etrack_id = (eeprom_verh << NVM_ETRACK_SHIFT) | eeprom_verl;
+
+ switch (hw->mac.type) {
+ case e1000_i210:
+ case e1000_i350:
+ /* find combo image version */
+ hw->nvm.ops.read(hw, NVM_COMB_VER_PTR, 1, &comb_offset);
+ if ((comb_offset != 0x0) && (comb_offset != NVM_VER_INVALID)) {
+
+ hw->nvm.ops.read(hw, (NVM_COMB_VER_OFF + comb_offset
+ + 1), 1, &comb_verh);
+ hw->nvm.ops.read(hw, (NVM_COMB_VER_OFF + comb_offset),
+ 1, &comb_verl);
+
+ /* get Option Rom version if it exists and is valid */
+ if ((comb_verh && comb_verl) &&
+ ((comb_verh != NVM_VER_INVALID) &&
+ (comb_verl != NVM_VER_INVALID))) {
+
+ fw_vers->or_valid = true;
+ fw_vers->or_major =
+ comb_verl >> NVM_COMB_VER_SHFT;
+ fw_vers->or_build =
+ ((comb_verl << NVM_COMB_VER_SHFT)
+ | (comb_verh >> NVM_COMB_VER_SHFT));
+ fw_vers->or_patch =
+ comb_verh & NVM_COMB_VER_MASK;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return;
+}
diff --git a/drivers/net/ethernet/intel/igb/e1000_nvm.h b/drivers/net/ethernet/intel/igb/e1000_nvm.h
index 825b022..7012d45 100644
--- a/drivers/net/ethernet/intel/igb/e1000_nvm.h
+++ b/drivers/net/ethernet/intel/igb/e1000_nvm.h
@@ -40,4 +40,20 @@ s32 igb_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
s32 igb_validate_nvm_checksum(struct e1000_hw *hw);
s32 igb_update_nvm_checksum(struct e1000_hw *hw);
+struct e1000_fw_version {
+ u32 etrack_id;
+ u16 eep_major;
+ u16 eep_minor;
+
+ u8 invm_major;
+ u8 invm_minor;
+ u8 invm_img_type;
+
+ bool or_valid;
+ u16 or_major;
+ u16 or_build;
+ u16 or_patch;
+};
+void igb_get_fw_version(struct e1000_hw *hw, struct e1000_fw_version *fw_vers);
+
#endif
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index b07d679..df1e790 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -1785,58 +1785,34 @@ static const struct net_device_ops igb_netdev_ops = {
void igb_set_fw_version(struct igb_adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
- u16 eeprom_verh, eeprom_verl, comb_verh, comb_verl, comb_offset;
- u16 major, build, patch, fw_version;
- u32 etrack_id;
-
- hw->nvm.ops.read(hw, 5, 1, &fw_version);
- if (adapter->hw.mac.type != e1000_i211) {
- hw->nvm.ops.read(hw, NVM_ETRACK_WORD, 1, &eeprom_verh);
- hw->nvm.ops.read(hw, (NVM_ETRACK_WORD + 1), 1, &eeprom_verl);
- etrack_id = (eeprom_verh << IGB_ETRACK_SHIFT) | eeprom_verl;
-
- /* combo image version needs to be found */
- hw->nvm.ops.read(hw, NVM_COMB_VER_PTR, 1, &comb_offset);
- if ((comb_offset != 0x0) &&
- (comb_offset != IGB_NVM_VER_INVALID)) {
- hw->nvm.ops.read(hw, (NVM_COMB_VER_OFF + comb_offset
- + 1), 1, &comb_verh);
- hw->nvm.ops.read(hw, (NVM_COMB_VER_OFF + comb_offset),
- 1, &comb_verl);
-
- /* Only display Option Rom if it exists and is valid */
- if ((comb_verh && comb_verl) &&
- ((comb_verh != IGB_NVM_VER_INVALID) &&
- (comb_verl != IGB_NVM_VER_INVALID))) {
- major = comb_verl >> IGB_COMB_VER_SHFT;
- build = (comb_verl << IGB_COMB_VER_SHFT) |
- (comb_verh >> IGB_COMB_VER_SHFT);
- patch = comb_verh & IGB_COMB_VER_MASK;
- snprintf(adapter->fw_version,
- sizeof(adapter->fw_version),
- "%d.%d%d, 0x%08x, %d.%d.%d",
- (fw_version & IGB_MAJOR_MASK) >>
- IGB_MAJOR_SHIFT,
- (fw_version & IGB_MINOR_MASK) >>
- IGB_MINOR_SHIFT,
- (fw_version & IGB_BUILD_MASK),
- etrack_id, major, build, patch);
- goto out;
- }
- }
- snprintf(adapter->fw_version, sizeof(adapter->fw_version),
- "%d.%d%d, 0x%08x",
- (fw_version & IGB_MAJOR_MASK) >> IGB_MAJOR_SHIFT,
- (fw_version & IGB_MINOR_MASK) >> IGB_MINOR_SHIFT,
- (fw_version & IGB_BUILD_MASK), etrack_id);
- } else {
+ struct e1000_fw_version fw;
+
+ igb_get_fw_version(hw, &fw);
+
+ switch (hw->mac.type) {
+ case e1000_i211:
snprintf(adapter->fw_version, sizeof(adapter->fw_version),
- "%d.%d%d",
- (fw_version & IGB_MAJOR_MASK) >> IGB_MAJOR_SHIFT,
- (fw_version & IGB_MINOR_MASK) >> IGB_MINOR_SHIFT,
- (fw_version & IGB_BUILD_MASK));
+ "%2d.%2d-%d",
+ fw.invm_major, fw.invm_minor, fw.invm_img_type);
+ break;
+
+ default:
+ /* if option is rom valid, display its version too */
+ if (fw.or_valid) {
+ snprintf(adapter->fw_version,
+ sizeof(adapter->fw_version),
+ "%d.%d, 0x%08x, %d.%d.%d",
+ fw.eep_major, fw.eep_minor, fw.etrack_id,
+ fw.or_major, fw.or_build, fw.or_patch);
+ /* no option rom */
+ } else {
+ snprintf(adapter->fw_version,
+ sizeof(adapter->fw_version),
+ "%d.%d, 0x%08x",
+ fw.eep_major, fw.eep_minor, fw.etrack_id);
+ }
+ break;
}
-out:
return;
}
--
1.7.11.7
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox