Commit d9993be6 authored by David S. Miller's avatar David S. Miller

Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6

parents c4266263 aa3e2199
...@@ -1004,7 +1004,6 @@ typhoon_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) ...@@ -1004,7 +1004,6 @@ typhoon_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
} }
strcpy(info->driver, KBUILD_MODNAME); strcpy(info->driver, KBUILD_MODNAME);
strcpy(info->version, UTS_RELEASE);
strcpy(info->bus_info, pci_name(pci_dev)); strcpy(info->bus_info, pci_name(pci_dev));
} }
......
/* /*
* MOSCHIP MCS7830 based USB 2.0 Ethernet Devices * MOSCHIP MCS7830 based (7730/7830/7832) USB 2.0 Ethernet Devices
* *
* based on usbnet.c, asix.c and the vendor provided mcs7830 driver * based on usbnet.c, asix.c and the vendor provided mcs7830 driver
* *
...@@ -11,6 +11,9 @@ ...@@ -11,6 +11,9 @@
* *
* Definitions gathered from MOSCHIP, Data Sheet_7830DA.pdf (thanks!). * Definitions gathered from MOSCHIP, Data Sheet_7830DA.pdf (thanks!).
* *
* 2010-12-19: add 7832 USB PID ("functionality same as MCS7830"),
* per active notification by manufacturer
*
* TODO: * TODO:
* - support HIF_REG_CONFIG_SLEEPMODE/HIF_REG_CONFIG_TXENABLE (via autopm?) * - support HIF_REG_CONFIG_SLEEPMODE/HIF_REG_CONFIG_TXENABLE (via autopm?)
* - implement ethtool_ops get_pauseparam/set_pauseparam * - implement ethtool_ops get_pauseparam/set_pauseparam
...@@ -60,6 +63,7 @@ ...@@ -60,6 +63,7 @@
#define MCS7830_MAX_MCAST 64 #define MCS7830_MAX_MCAST 64
#define MCS7830_VENDOR_ID 0x9710 #define MCS7830_VENDOR_ID 0x9710
#define MCS7832_PRODUCT_ID 0x7832
#define MCS7830_PRODUCT_ID 0x7830 #define MCS7830_PRODUCT_ID 0x7830
#define MCS7730_PRODUCT_ID 0x7730 #define MCS7730_PRODUCT_ID 0x7730
...@@ -626,7 +630,7 @@ static int mcs7830_rx_fixup(struct usbnet *dev, struct sk_buff *skb) ...@@ -626,7 +630,7 @@ static int mcs7830_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
} }
static const struct driver_info moschip_info = { static const struct driver_info moschip_info = {
.description = "MOSCHIP 7830/7730 usb-NET adapter", .description = "MOSCHIP 7830/7832/7730 usb-NET adapter",
.bind = mcs7830_bind, .bind = mcs7830_bind,
.rx_fixup = mcs7830_rx_fixup, .rx_fixup = mcs7830_rx_fixup,
.flags = FLAG_ETHER, .flags = FLAG_ETHER,
...@@ -644,6 +648,10 @@ static const struct driver_info sitecom_info = { ...@@ -644,6 +648,10 @@ static const struct driver_info sitecom_info = {
}; };
static const struct usb_device_id products[] = { static const struct usb_device_id products[] = {
{
USB_DEVICE(MCS7830_VENDOR_ID, MCS7832_PRODUCT_ID),
.driver_info = (unsigned long) &moschip_info,
},
{ {
USB_DEVICE(MCS7830_VENDOR_ID, MCS7830_PRODUCT_ID), USB_DEVICE(MCS7830_VENDOR_ID, MCS7830_PRODUCT_ID),
.driver_info = (unsigned long) &moschip_info, .driver_info = (unsigned long) &moschip_info,
......
...@@ -175,5 +175,15 @@ static inline int ipv6_unicast_destination(struct sk_buff *skb) ...@@ -175,5 +175,15 @@ static inline int ipv6_unicast_destination(struct sk_buff *skb)
return rt->rt6i_flags & RTF_LOCAL; return rt->rt6i_flags & RTF_LOCAL;
} }
int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *));
static inline int ip6_skb_dst_mtu(struct sk_buff *skb)
{
struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL;
return (np && np->pmtudisc == IPV6_PMTUDISC_PROBE) ?
skb_dst(skb)->dev->mtu : dst_mtu(skb_dst(skb));
}
#endif #endif
#endif #endif
...@@ -611,11 +611,7 @@ static inline struct sk_buff *skb_act_clone(struct sk_buff *skb, gfp_t gfp_mask, ...@@ -611,11 +611,7 @@ static inline struct sk_buff *skb_act_clone(struct sk_buff *skb, gfp_t gfp_mask,
{ {
struct sk_buff *n; struct sk_buff *n;
if ((action == TC_ACT_STOLEN || action == TC_ACT_QUEUED) && n = skb_clone(skb, gfp_mask);
!skb_shared(skb))
n = skb_get(skb);
else
n = skb_clone(skb, gfp_mask);
if (n) { if (n) {
n->tc_verd = SET_TC_VERD(n->tc_verd, 0); n->tc_verd = SET_TC_VERD(n->tc_verd, 0);
......
...@@ -56,7 +56,7 @@ ...@@ -56,7 +56,7 @@
#include <net/checksum.h> #include <net/checksum.h>
#include <linux/mroute6.h> #include <linux/mroute6.h>
static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)); int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *));
int __ip6_local_out(struct sk_buff *skb) int __ip6_local_out(struct sk_buff *skb)
{ {
...@@ -145,14 +145,6 @@ static int ip6_finish_output2(struct sk_buff *skb) ...@@ -145,14 +145,6 @@ static int ip6_finish_output2(struct sk_buff *skb)
return -EINVAL; return -EINVAL;
} }
static inline int ip6_skb_dst_mtu(struct sk_buff *skb)
{
struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL;
return (np && np->pmtudisc == IPV6_PMTUDISC_PROBE) ?
skb_dst(skb)->dev->mtu : dst_mtu(skb_dst(skb));
}
static int ip6_finish_output(struct sk_buff *skb) static int ip6_finish_output(struct sk_buff *skb)
{ {
if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) || if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) ||
...@@ -601,7 +593,7 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) ...@@ -601,7 +593,7 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
return offset; return offset;
} }
static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
{ {
struct sk_buff *frag; struct sk_buff *frag;
struct rt6_info *rt = (struct rt6_info*)skb_dst(skb); struct rt6_info *rt = (struct rt6_info*)skb_dst(skb);
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/netfilter_ipv6.h> #include <linux/netfilter_ipv6.h>
#include <net/dst.h> #include <net/dst.h>
#include <net/ipv6.h> #include <net/ipv6.h>
#include <net/ip6_route.h>
#include <net/xfrm.h> #include <net/xfrm.h>
int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb, int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb,
...@@ -88,8 +89,21 @@ static int xfrm6_output_finish(struct sk_buff *skb) ...@@ -88,8 +89,21 @@ static int xfrm6_output_finish(struct sk_buff *skb)
return xfrm_output(skb); return xfrm_output(skb);
} }
static int __xfrm6_output(struct sk_buff *skb)
{
struct dst_entry *dst = skb_dst(skb);
struct xfrm_state *x = dst->xfrm;
if ((x && x->props.mode == XFRM_MODE_TUNNEL) &&
((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) ||
dst_allfrag(skb_dst(skb)))) {
return ip6_fragment(skb, xfrm6_output_finish);
}
return xfrm6_output_finish(skb);
}
int xfrm6_output(struct sk_buff *skb) int xfrm6_output(struct sk_buff *skb)
{ {
return NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING, skb, NULL, return NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING, skb, NULL,
skb_dst(skb)->dev, xfrm6_output_finish); skb_dst(skb)->dev, __xfrm6_output);
} }
...@@ -270,7 +270,6 @@ static unsigned int sfq_drop(struct Qdisc *sch) ...@@ -270,7 +270,6 @@ static unsigned int sfq_drop(struct Qdisc *sch)
/* It is difficult to believe, but ALL THE SLOTS HAVE LENGTH 1. */ /* It is difficult to believe, but ALL THE SLOTS HAVE LENGTH 1. */
d = q->next[q->tail]; d = q->next[q->tail];
q->next[q->tail] = q->next[d]; q->next[q->tail] = q->next[d];
q->allot[q->next[d]] += q->quantum;
skb = q->qs[d].prev; skb = q->qs[d].prev;
len = qdisc_pkt_len(skb); len = qdisc_pkt_len(skb);
__skb_unlink(skb, &q->qs[d]); __skb_unlink(skb, &q->qs[d]);
...@@ -321,14 +320,13 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch) ...@@ -321,14 +320,13 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
sfq_inc(q, x); sfq_inc(q, x);
if (q->qs[x].qlen == 1) { /* The flow is new */ if (q->qs[x].qlen == 1) { /* The flow is new */
if (q->tail == SFQ_DEPTH) { /* It is the first flow */ if (q->tail == SFQ_DEPTH) { /* It is the first flow */
q->tail = x;
q->next[x] = x; q->next[x] = x;
q->allot[x] = q->quantum;
} else { } else {
q->next[x] = q->next[q->tail]; q->next[x] = q->next[q->tail];
q->next[q->tail] = x; q->next[q->tail] = x;
q->tail = x;
} }
q->tail = x;
q->allot[x] = q->quantum;
} }
if (++sch->q.qlen <= q->limit) { if (++sch->q.qlen <= q->limit) {
sch->bstats.bytes += qdisc_pkt_len(skb); sch->bstats.bytes += qdisc_pkt_len(skb);
...@@ -359,13 +357,13 @@ sfq_dequeue(struct Qdisc *sch) ...@@ -359,13 +357,13 @@ sfq_dequeue(struct Qdisc *sch)
{ {
struct sfq_sched_data *q = qdisc_priv(sch); struct sfq_sched_data *q = qdisc_priv(sch);
struct sk_buff *skb; struct sk_buff *skb;
sfq_index a, old_a; sfq_index a, next_a;
/* No active slots */ /* No active slots */
if (q->tail == SFQ_DEPTH) if (q->tail == SFQ_DEPTH)
return NULL; return NULL;
a = old_a = q->next[q->tail]; a = q->next[q->tail];
/* Grab packet */ /* Grab packet */
skb = __skb_dequeue(&q->qs[a]); skb = __skb_dequeue(&q->qs[a]);
...@@ -376,17 +374,15 @@ sfq_dequeue(struct Qdisc *sch) ...@@ -376,17 +374,15 @@ sfq_dequeue(struct Qdisc *sch)
/* Is the slot empty? */ /* Is the slot empty? */
if (q->qs[a].qlen == 0) { if (q->qs[a].qlen == 0) {
q->ht[q->hash[a]] = SFQ_DEPTH; q->ht[q->hash[a]] = SFQ_DEPTH;
a = q->next[a]; next_a = q->next[a];
if (a == old_a) { if (a == next_a) {
q->tail = SFQ_DEPTH; q->tail = SFQ_DEPTH;
return skb; return skb;
} }
q->next[q->tail] = a; q->next[q->tail] = next_a;
q->allot[a] += q->quantum;
} else if ((q->allot[a] -= qdisc_pkt_len(skb)) <= 0) { } else if ((q->allot[a] -= qdisc_pkt_len(skb)) <= 0) {
q->tail = a;
a = q->next[a];
q->allot[a] += q->quantum; q->allot[a] += q->quantum;
q->tail = a;
} }
return skb; return skb;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment