Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (42 commits)
  cxgb3: fix premature page unmap
  ibm_newemac: Fix EMACx_TRTR[TRT] bit shifts
  vlan: Fix register_vlan_dev() error path
  gro: Fix illegal merging of trailer trash
  sungem: Fix Serdes detection.
  net: fix mdio section mismatch warning
  ppp: fix BUG on non-linear SKB (multilink receive)
  ixgbe: Fixing EEH handler to handle more than one error
  net: Fix the rollback test in dev_change_name()
  Revert "isdn: isdn_ppp: Use SKB list facilities instead of home-grown implementation."
  TI Davinci EMAC : Fix Console Hang when bringing the interface down
  smsc911x: Fix Console Hang when bringing the interface down.
  mISDN: fix error return in HFCmulti_init()
  forcedeth: mac address fix
  r6040: fix version printing
  Bluetooth: Fix regression with L2CAP configuration in Basic Mode
  Bluetooth: Select Basic Mode as default for SOCK_SEQPACKET
  Bluetooth: Set general bonding security for ACL by default
  r8169: Fix receive buffer length when MTU is between 1515 and 1536
  can: add the missing netlink get_xstats_size callback
  ...
This commit is contained in:
Linus Torvalds 2009-11-18 14:54:45 -08:00
commit 486bfe5c7c
49 changed files with 430 additions and 488 deletions

View File

@ -4332,6 +4332,8 @@ F: drivers/video/aty/aty128fb.c
RALINK RT2X00 WIRELESS LAN DRIVER RALINK RT2X00 WIRELESS LAN DRIVER
P: rt2x00 project P: rt2x00 project
M: Ivo van Doorn <IvDoorn@gmail.com>
M: Gertjan van Wingerde <gwingerde@gmail.com>
L: linux-wireless@vger.kernel.org L: linux-wireless@vger.kernel.org
L: users@rt2x00.serialmonkey.com (moderated for non-subscribers) L: users@rt2x00.serialmonkey.com (moderated for non-subscribers)
W: http://rt2x00.serialmonkey.com/ W: http://rt2x00.serialmonkey.com/
@ -4419,7 +4421,7 @@ RFKILL
M: Johannes Berg <johannes@sipsolutions.net> M: Johannes Berg <johannes@sipsolutions.net>
L: linux-wireless@vger.kernel.org L: linux-wireless@vger.kernel.org
S: Maintained S: Maintained
F Documentation/rfkill.txt F: Documentation/rfkill.txt
F: net/rfkill/ F: net/rfkill/
RISCOM8 DRIVER RISCOM8 DRIVER

View File

@ -5481,7 +5481,7 @@ HFCmulti_init(void)
if (err) { if (err) {
printk(KERN_ERR "error registering embedded driver: " printk(KERN_ERR "error registering embedded driver: "
"%x\n", err); "%x\n", err);
return -err; return err;
} }
HFC_cnt++; HFC_cnt++;
printk(KERN_INFO "%d devices registered\n", HFC_cnt); printk(KERN_INFO "%d devices registered\n", HFC_cnt);

View File

@ -1535,10 +1535,8 @@ static int isdn_ppp_mp_bundle_array_init(void)
int sz = ISDN_MAX_CHANNELS*sizeof(ippp_bundle); int sz = ISDN_MAX_CHANNELS*sizeof(ippp_bundle);
if( (isdn_ppp_bundle_arr = kzalloc(sz, GFP_KERNEL)) == NULL ) if( (isdn_ppp_bundle_arr = kzalloc(sz, GFP_KERNEL)) == NULL )
return -ENOMEM; return -ENOMEM;
for (i = 0; i < ISDN_MAX_CHANNELS; i++) { for( i = 0; i < ISDN_MAX_CHANNELS; i++ )
spin_lock_init(&isdn_ppp_bundle_arr[i].lock); spin_lock_init(&isdn_ppp_bundle_arr[i].lock);
skb_queue_head_init(&isdn_ppp_bundle_arr[i].frags);
}
return 0; return 0;
} }
@ -1571,7 +1569,7 @@ static int isdn_ppp_mp_init( isdn_net_local * lp, ippp_bundle * add_to )
if ((lp->netdev->pb = isdn_ppp_mp_bundle_alloc()) == NULL) if ((lp->netdev->pb = isdn_ppp_mp_bundle_alloc()) == NULL)
return -ENOMEM; return -ENOMEM;
lp->next = lp->last = lp; /* nobody else in a queue */ lp->next = lp->last = lp; /* nobody else in a queue */
skb_queue_head_init(&lp->netdev->pb->frags); lp->netdev->pb->frags = NULL;
lp->netdev->pb->frames = 0; lp->netdev->pb->frames = 0;
lp->netdev->pb->seq = UINT_MAX; lp->netdev->pb->seq = UINT_MAX;
} }
@ -1583,29 +1581,28 @@ static int isdn_ppp_mp_init( isdn_net_local * lp, ippp_bundle * add_to )
static u32 isdn_ppp_mp_get_seq( int short_seq, static u32 isdn_ppp_mp_get_seq( int short_seq,
struct sk_buff * skb, u32 last_seq ); struct sk_buff * skb, u32 last_seq );
static void isdn_ppp_mp_discard(ippp_bundle *mp, struct sk_buff *from, static struct sk_buff * isdn_ppp_mp_discard( ippp_bundle * mp,
struct sk_buff *to); struct sk_buff * from, struct sk_buff * to );
static void isdn_ppp_mp_reassembly(isdn_net_dev *net_dev, isdn_net_local *lp, static void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp,
struct sk_buff *from, struct sk_buff *to, struct sk_buff * from, struct sk_buff * to );
u32 lastseq); static void isdn_ppp_mp_free_skb( ippp_bundle * mp, struct sk_buff * skb );
static void isdn_ppp_mp_free_skb(ippp_bundle *mp, struct sk_buff *skb);
static void isdn_ppp_mp_print_recv_pkt( int slot, struct sk_buff * skb ); static void isdn_ppp_mp_print_recv_pkt( int slot, struct sk_buff * skb );
static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
struct sk_buff *skb) struct sk_buff *skb)
{ {
struct sk_buff *newfrag, *frag, *start, *nextf;
u32 newseq, minseq, thisseq;
isdn_mppp_stats *stats;
struct ippp_struct *is; struct ippp_struct *is;
isdn_net_local * lpq;
ippp_bundle * mp;
isdn_mppp_stats * stats;
struct sk_buff * newfrag, * frag, * start, *nextf;
u32 newseq, minseq, thisseq;
unsigned long flags; unsigned long flags;
isdn_net_local *lpq;
ippp_bundle *mp;
int slot; int slot;
spin_lock_irqsave(&net_dev->pb->lock, flags); spin_lock_irqsave(&net_dev->pb->lock, flags);
mp = net_dev->pb; mp = net_dev->pb;
stats = &mp->stats; stats = &mp->stats;
slot = lp->ppp_slot; slot = lp->ppp_slot;
if (slot < 0 || slot >= ISDN_MAX_CHANNELS) { if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
printk(KERN_ERR "%s: lp->ppp_slot(%d)\n", printk(KERN_ERR "%s: lp->ppp_slot(%d)\n",
@ -1616,19 +1613,20 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
return; return;
} }
is = ippp_table[slot]; is = ippp_table[slot];
if (++mp->frames > stats->max_queue_len) if( ++mp->frames > stats->max_queue_len )
stats->max_queue_len = mp->frames; stats->max_queue_len = mp->frames;
if (is->debug & 0x8) if (is->debug & 0x8)
isdn_ppp_mp_print_recv_pkt(lp->ppp_slot, skb); isdn_ppp_mp_print_recv_pkt(lp->ppp_slot, skb);
newseq = isdn_ppp_mp_get_seq(is->mpppcfg & SC_IN_SHORT_SEQ, newseq = isdn_ppp_mp_get_seq(is->mpppcfg & SC_IN_SHORT_SEQ,
skb, is->last_link_seqno); skb, is->last_link_seqno);
/* if this packet seq # is less than last already processed one, /* if this packet seq # is less than last already processed one,
* toss it right away, but check for sequence start case first * toss it right away, but check for sequence start case first
*/ */
if (mp->seq > MP_LONGSEQ_MAX && (newseq & MP_LONGSEQ_MAXBIT)) { if( mp->seq > MP_LONGSEQ_MAX && (newseq & MP_LONGSEQ_MAXBIT) ) {
mp->seq = newseq; /* the first packet: required for mp->seq = newseq; /* the first packet: required for
* rfc1990 non-compliant clients -- * rfc1990 non-compliant clients --
* prevents constant packet toss */ * prevents constant packet toss */
@ -1638,7 +1636,7 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
spin_unlock_irqrestore(&mp->lock, flags); spin_unlock_irqrestore(&mp->lock, flags);
return; return;
} }
/* find the minimum received sequence number over all links */ /* find the minimum received sequence number over all links */
is->last_link_seqno = minseq = newseq; is->last_link_seqno = minseq = newseq;
for (lpq = net_dev->queue;;) { for (lpq = net_dev->queue;;) {
@ -1659,31 +1657,22 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
* packets */ * packets */
newfrag = skb; newfrag = skb;
/* Insert new fragment into the proper sequence slot. */ /* if this new fragment is before the first one, then enqueue it now. */
skb_queue_walk(&mp->frags, frag) { if ((frag = mp->frags) == NULL || MP_LT(newseq, MP_SEQ(frag))) {
if (MP_SEQ(frag) == newseq) { newfrag->next = frag;
isdn_ppp_mp_free_skb(mp, newfrag); mp->frags = frag = newfrag;
newfrag = NULL; newfrag = NULL;
break; }
}
if (MP_LT(newseq, MP_SEQ(frag))) {
__skb_queue_before(&mp->frags, frag, newfrag);
newfrag = NULL;
break;
}
}
if (newfrag)
__skb_queue_tail(&mp->frags, newfrag);
frag = skb_peek(&mp->frags); start = MP_FLAGS(frag) & MP_BEGIN_FRAG &&
start = ((MP_FLAGS(frag) & MP_BEGIN_FRAG) && MP_SEQ(frag) == mp->seq ? frag : NULL;
(MP_SEQ(frag) == mp->seq)) ? frag : NULL;
if (!start)
goto check_overflow;
/* main fragment traversing loop /*
* main fragment traversing loop
* *
* try to accomplish several tasks: * try to accomplish several tasks:
* - insert new fragment into the proper sequence slot (once that's done
* newfrag will be set to NULL)
* - reassemble any complete fragment sequence (non-null 'start' * - reassemble any complete fragment sequence (non-null 'start'
* indicates there is a continguous sequence present) * indicates there is a continguous sequence present)
* - discard any incomplete sequences that are below minseq -- due * - discard any incomplete sequences that are below minseq -- due
@ -1692,46 +1681,71 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
* come to complete such sequence and it should be discarded * come to complete such sequence and it should be discarded
* *
* loop completes when we accomplished the following tasks: * loop completes when we accomplished the following tasks:
* - new fragment is inserted in the proper sequence ('newfrag' is
* set to NULL)
* - we hit a gap in the sequence, so no reassembly/processing is * - we hit a gap in the sequence, so no reassembly/processing is
* possible ('start' would be set to NULL) * possible ('start' would be set to NULL)
* *
* algorithm for this code is derived from code in the book * algorithm for this code is derived from code in the book
* 'PPP Design And Debugging' by James Carlson (Addison-Wesley) * 'PPP Design And Debugging' by James Carlson (Addison-Wesley)
*/ */
skb_queue_walk_safe(&mp->frags, frag, nextf) { while (start != NULL || newfrag != NULL) {
thisseq = MP_SEQ(frag);
/* check for misplaced start */ thisseq = MP_SEQ(frag);
if (start != frag && (MP_FLAGS(frag) & MP_BEGIN_FRAG)) { nextf = frag->next;
printk(KERN_WARNING"isdn_mppp(seq %d): new "
"BEGIN flag with no prior END", thisseq); /* drop any duplicate fragments */
stats->seqerrs++; if (newfrag != NULL && thisseq == newseq) {
stats->frame_drops++; isdn_ppp_mp_free_skb(mp, newfrag);
isdn_ppp_mp_discard(mp, start, frag); newfrag = NULL;
start = frag; }
} else if (MP_LE(thisseq, minseq)) {
if (MP_FLAGS(frag) & MP_BEGIN_FRAG) /* insert new fragment before next element if possible. */
if (newfrag != NULL && (nextf == NULL ||
MP_LT(newseq, MP_SEQ(nextf)))) {
newfrag->next = nextf;
frag->next = nextf = newfrag;
newfrag = NULL;
}
if (start != NULL) {
/* check for misplaced start */
if (start != frag && (MP_FLAGS(frag) & MP_BEGIN_FRAG)) {
printk(KERN_WARNING"isdn_mppp(seq %d): new "
"BEGIN flag with no prior END", thisseq);
stats->seqerrs++;
stats->frame_drops++;
start = isdn_ppp_mp_discard(mp, start,frag);
nextf = frag->next;
}
} else if (MP_LE(thisseq, minseq)) {
if (MP_FLAGS(frag) & MP_BEGIN_FRAG)
start = frag; start = frag;
else { else {
if (MP_FLAGS(frag) & MP_END_FRAG) if (MP_FLAGS(frag) & MP_END_FRAG)
stats->frame_drops++; stats->frame_drops++;
__skb_unlink(skb, &mp->frags); if( mp->frags == frag )
mp->frags = nextf;
isdn_ppp_mp_free_skb(mp, frag); isdn_ppp_mp_free_skb(mp, frag);
frag = nextf;
continue; continue;
} }
} }
/* if we have end fragment, then we have full reassembly /* if start is non-null and we have end fragment, then
* sequence -- reassemble and process packet now * we have full reassembly sequence -- reassemble
* and process packet now
*/ */
if (MP_FLAGS(frag) & MP_END_FRAG) { if (start != NULL && (MP_FLAGS(frag) & MP_END_FRAG)) {
minseq = mp->seq = (thisseq+1) & MP_LONGSEQ_MASK; minseq = mp->seq = (thisseq+1) & MP_LONGSEQ_MASK;
/* Reassemble the packet then dispatch it */ /* Reassemble the packet then dispatch it */
isdn_ppp_mp_reassembly(net_dev, lp, start, frag, thisseq); isdn_ppp_mp_reassembly(net_dev, lp, start, nextf);
start = NULL;
frag = NULL;
start = NULL; mp->frags = nextf;
frag = NULL; }
}
/* check if need to update start pointer: if we just /* check if need to update start pointer: if we just
* reassembled the packet and sequence is contiguous * reassembled the packet and sequence is contiguous
@ -1742,25 +1756,26 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
* below low watermark and set start to the next frag or * below low watermark and set start to the next frag or
* clear start ptr. * clear start ptr.
*/ */
if (nextf != (struct sk_buff *)&mp->frags && if (nextf != NULL &&
((thisseq+1) & MP_LONGSEQ_MASK) == MP_SEQ(nextf)) { ((thisseq+1) & MP_LONGSEQ_MASK) == MP_SEQ(nextf)) {
/* if we just reassembled and the next one is here, /* if we just reassembled and the next one is here,
* then start another reassembly. * then start another reassembly. */
*/
if (frag == NULL) { if (frag == NULL) {
if (MP_FLAGS(nextf) & MP_BEGIN_FRAG) if (MP_FLAGS(nextf) & MP_BEGIN_FRAG)
start = nextf; start = nextf;
else { else
printk(KERN_WARNING"isdn_mppp(seq %d):" {
" END flag with no following " printk(KERN_WARNING"isdn_mppp(seq %d):"
"BEGIN", thisseq); " END flag with no following "
"BEGIN", thisseq);
stats->seqerrs++; stats->seqerrs++;
} }
} }
} else {
if (nextf != (struct sk_buff *)&mp->frags && } else {
frag != NULL && if ( nextf != NULL && frag != NULL &&
MP_LT(thisseq, minseq)) { MP_LT(thisseq, minseq)) {
/* we've got a break in the sequence /* we've got a break in the sequence
* and we not at the end yet * and we not at the end yet
* and we did not just reassembled * and we did not just reassembled
@ -1769,39 +1784,41 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
* discard all the frames below low watermark * discard all the frames below low watermark
* and start over */ * and start over */
stats->frame_drops++; stats->frame_drops++;
isdn_ppp_mp_discard(mp, start, nextf); mp->frags = isdn_ppp_mp_discard(mp,start,nextf);
} }
/* break in the sequence, no reassembly */ /* break in the sequence, no reassembly */
start = NULL; start = NULL;
} }
if (!start)
break; frag = nextf;
} } /* while -- main loop */
check_overflow: if (mp->frags == NULL)
mp->frags = frag;
/* rather straighforward way to deal with (not very) possible /* rather straighforward way to deal with (not very) possible
* queue overflow * queue overflow */
*/
if (mp->frames > MP_MAX_QUEUE_LEN) { if (mp->frames > MP_MAX_QUEUE_LEN) {
stats->overflows++; stats->overflows++;
skb_queue_walk_safe(&mp->frags, frag, nextf) { while (mp->frames > MP_MAX_QUEUE_LEN) {
if (mp->frames <= MP_MAX_QUEUE_LEN) frag = mp->frags->next;
break; isdn_ppp_mp_free_skb(mp, mp->frags);
__skb_unlink(frag, &mp->frags); mp->frags = frag;
isdn_ppp_mp_free_skb(mp, frag);
} }
} }
spin_unlock_irqrestore(&mp->lock, flags); spin_unlock_irqrestore(&mp->lock, flags);
} }
static void isdn_ppp_mp_cleanup(isdn_net_local *lp) static void isdn_ppp_mp_cleanup( isdn_net_local * lp )
{ {
struct sk_buff *skb, *tmp; struct sk_buff * frag = lp->netdev->pb->frags;
struct sk_buff * nextfrag;
skb_queue_walk_safe(&lp->netdev->pb->frags, skb, tmp) { while( frag ) {
__skb_unlink(skb, &lp->netdev->pb->frags); nextfrag = frag->next;
isdn_ppp_mp_free_skb(lp->netdev->pb, skb); isdn_ppp_mp_free_skb(lp->netdev->pb, frag);
frag = nextfrag;
} }
lp->netdev->pb->frags = NULL;
} }
static u32 isdn_ppp_mp_get_seq( int short_seq, static u32 isdn_ppp_mp_get_seq( int short_seq,
@ -1838,115 +1855,72 @@ static u32 isdn_ppp_mp_get_seq( int short_seq,
return seq; return seq;
} }
static void isdn_ppp_mp_discard(ippp_bundle *mp, struct sk_buff *from, struct sk_buff * isdn_ppp_mp_discard( ippp_bundle * mp,
struct sk_buff *to) struct sk_buff * from, struct sk_buff * to )
{ {
if (from) { if( from )
struct sk_buff *skb, *tmp; while (from != to) {
int freeing = 0; struct sk_buff * next = from->next;
isdn_ppp_mp_free_skb(mp, from);
skb_queue_walk_safe(&mp->frags, skb, tmp) { from = next;
if (skb == to)
break;
if (skb == from)
freeing = 1;
if (!freeing)
continue;
__skb_unlink(skb, &mp->frags);
isdn_ppp_mp_free_skb(mp, skb);
} }
} return from;
} }
static unsigned int calc_tot_len(struct sk_buff_head *queue, void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp,
struct sk_buff *from, struct sk_buff *to) struct sk_buff * from, struct sk_buff * to )
{ {
unsigned int tot_len = 0; ippp_bundle * mp = net_dev->pb;
struct sk_buff *skb;
int found_start = 0;
skb_queue_walk(queue, skb) {
if (skb == from)
found_start = 1;
if (!found_start)
continue;
tot_len += skb->len - MP_HEADER_LEN;
if (skb == to)
break;
}
return tot_len;
}
/* Reassemble packet using fragments in the reassembly queue from
* 'from' until 'to', inclusive.
*/
static void isdn_ppp_mp_reassembly(isdn_net_dev *net_dev, isdn_net_local *lp,
struct sk_buff *from, struct sk_buff *to,
u32 lastseq)
{
ippp_bundle *mp = net_dev->pb;
unsigned int tot_len;
struct sk_buff *skb;
int proto; int proto;
struct sk_buff * skb;
unsigned int tot_len;
if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS) { if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS) {
printk(KERN_ERR "%s: lp->ppp_slot(%d) out of range\n", printk(KERN_ERR "%s: lp->ppp_slot(%d) out of range\n",
__func__, lp->ppp_slot); __func__, lp->ppp_slot);
return; return;
} }
if( MP_FLAGS(from) == (MP_BEGIN_FRAG | MP_END_FRAG) ) {
tot_len = calc_tot_len(&mp->frags, from, to); if( ippp_table[lp->ppp_slot]->debug & 0x40 )
if (MP_FLAGS(from) == (MP_BEGIN_FRAG | MP_END_FRAG)) {
if (ippp_table[lp->ppp_slot]->debug & 0x40)
printk(KERN_DEBUG "isdn_mppp: reassembly: frame %d, " printk(KERN_DEBUG "isdn_mppp: reassembly: frame %d, "
"len %d\n", MP_SEQ(from), from->len); "len %d\n", MP_SEQ(from), from->len );
skb = from; skb = from;
skb_pull(skb, MP_HEADER_LEN); skb_pull(skb, MP_HEADER_LEN);
__skb_unlink(skb, &mp->frags);
mp->frames--; mp->frames--;
} else { } else {
struct sk_buff *walk, *tmp; struct sk_buff * frag;
int found_start = 0; int n;
if (ippp_table[lp->ppp_slot]->debug & 0x40) for(tot_len=n=0, frag=from; frag != to; frag=frag->next, n++)
tot_len += frag->len - MP_HEADER_LEN;
if( ippp_table[lp->ppp_slot]->debug & 0x40 )
printk(KERN_DEBUG"isdn_mppp: reassembling frames %d " printk(KERN_DEBUG"isdn_mppp: reassembling frames %d "
"to %d, len %d\n", MP_SEQ(from), lastseq, "to %d, len %d\n", MP_SEQ(from),
tot_len); (MP_SEQ(from)+n-1) & MP_LONGSEQ_MASK, tot_len );
if( (skb = dev_alloc_skb(tot_len)) == NULL ) {
skb = dev_alloc_skb(tot_len);
if (!skb)
printk(KERN_ERR "isdn_mppp: cannot allocate sk buff " printk(KERN_ERR "isdn_mppp: cannot allocate sk buff "
"of size %d\n", tot_len); "of size %d\n", tot_len);
isdn_ppp_mp_discard(mp, from, to);
return;
}
found_start = 0; while( from != to ) {
skb_queue_walk_safe(&mp->frags, walk, tmp) { unsigned int len = from->len - MP_HEADER_LEN;
if (walk == from)
found_start = 1;
if (!found_start)
continue;
if (skb) { skb_copy_from_linear_data_offset(from, MP_HEADER_LEN,
unsigned int len = walk->len - MP_HEADER_LEN; skb_put(skb,len),
skb_copy_from_linear_data_offset(walk, MP_HEADER_LEN, len);
skb_put(skb, len), frag = from->next;
len); isdn_ppp_mp_free_skb(mp, from);
} from = frag;
__skb_unlink(walk, &mp->frags);
isdn_ppp_mp_free_skb(mp, walk);
if (walk == to)
break;
} }
} }
if (!skb)
return;
proto = isdn_ppp_strip_proto(skb); proto = isdn_ppp_strip_proto(skb);
isdn_ppp_push_higher(net_dev, lp, skb, proto); isdn_ppp_push_higher(net_dev, lp, skb, proto);
} }
static void isdn_ppp_mp_free_skb(ippp_bundle *mp, struct sk_buff *skb) static void isdn_ppp_mp_free_skb(ippp_bundle * mp, struct sk_buff * skb)
{ {
dev_kfree_skb(skb); dev_kfree_skb(skb);
mp->frames--; mp->frames--;

View File

@ -35,66 +35,16 @@ config CAN_CALC_BITTIMING
arguments "tq", "prop_seg", "phase_seg1", "phase_seg2" and "sjw". arguments "tq", "prop_seg", "phase_seg1", "phase_seg2" and "sjw".
If unsure, say Y. If unsure, say Y.
config CAN_SJA1000
depends on CAN_DEV && HAS_IOMEM
tristate "Philips SJA1000"
---help---
Driver for the SJA1000 CAN controllers from Philips or NXP
config CAN_SJA1000_ISA
depends on CAN_SJA1000 && ISA
tristate "ISA Bus based legacy SJA1000 driver"
---help---
This driver adds legacy support for SJA1000 chips connected to
the ISA bus using I/O port, memory mapped or indirect access.
config CAN_SJA1000_PLATFORM
depends on CAN_SJA1000
tristate "Generic Platform Bus based SJA1000 driver"
---help---
This driver adds support for the SJA1000 chips connected to
the "platform bus" (Linux abstraction for directly to the
processor attached devices). Which can be found on various
boards from Phytec (http://www.phytec.de) like the PCM027,
PCM038.
config CAN_SJA1000_OF_PLATFORM
depends on CAN_SJA1000 && PPC_OF
tristate "Generic OF Platform Bus based SJA1000 driver"
---help---
This driver adds support for the SJA1000 chips connected to
the OpenFirmware "platform bus" found on embedded systems with
OpenFirmware bindings, e.g. if you have a PowerPC based system
you may want to enable this option.
config CAN_EMS_PCI
tristate "EMS CPC-PCI, CPC-PCIe and CPC-104P Card"
depends on PCI && CAN_SJA1000
---help---
This driver is for the one, two or four channel CPC-PCI,
CPC-PCIe and CPC-104P cards from EMS Dr. Thomas Wuensche
(http://www.ems-wuensche.de).
config CAN_EMS_USB
tristate "EMS CPC-USB/ARM7 CAN/USB interface"
depends on USB && CAN_DEV
---help---
This driver is for the one channel CPC-USB/ARM7 CAN/USB interface
from from EMS Dr. Thomas Wuensche (http://www.ems-wuensche.de).
config CAN_KVASER_PCI
tristate "Kvaser PCIcanx and Kvaser PCIcan PCI Cards"
depends on PCI && CAN_SJA1000
---help---
This driver is for the the PCIcanx and PCIcan cards (1, 2 or
4 channel) from Kvaser (http://www.kvaser.com).
config CAN_AT91 config CAN_AT91
tristate "Atmel AT91 onchip CAN controller" tristate "Atmel AT91 onchip CAN controller"
depends on CAN && CAN_DEV && ARCH_AT91SAM9263 depends on CAN_DEV && ARCH_AT91SAM9263
---help--- ---help---
This is a driver for the SoC CAN controller in Atmel's AT91SAM9263. This is a driver for the SoC CAN controller in Atmel's AT91SAM9263.
source "drivers/net/can/sja1000/Kconfig"
source "drivers/net/can/usb/Kconfig"
config CAN_DEBUG_DEVICES config CAN_DEBUG_DEVICES
bool "CAN devices debugging messages" bool "CAN devices debugging messages"
depends on CAN depends on CAN

View File

@ -629,6 +629,11 @@ nla_put_failure:
return -EMSGSIZE; return -EMSGSIZE;
} }
static size_t can_get_xstats_size(const struct net_device *dev)
{
return sizeof(struct can_device_stats);
}
static int can_fill_xstats(struct sk_buff *skb, const struct net_device *dev) static int can_fill_xstats(struct sk_buff *skb, const struct net_device *dev)
{ {
struct can_priv *priv = netdev_priv(dev); struct can_priv *priv = netdev_priv(dev);
@ -657,6 +662,7 @@ static struct rtnl_link_ops can_link_ops __read_mostly = {
.changelink = can_changelink, .changelink = can_changelink,
.get_size = can_get_size, .get_size = can_get_size,
.fill_info = can_fill_info, .fill_info = can_fill_info,
.get_xstats_size = can_get_xstats_size,
.fill_xstats = can_fill_xstats, .fill_xstats = can_fill_xstats,
}; };

View File

@ -0,0 +1,47 @@
menuconfig CAN_SJA1000
tristate "Philips/NXP SJA1000 devices"
depends on CAN_DEV && HAS_IOMEM
if CAN_SJA1000
config CAN_SJA1000_ISA
tristate "ISA Bus based legacy SJA1000 driver"
depends on ISA
---help---
This driver adds legacy support for SJA1000 chips connected to
the ISA bus using I/O port, memory mapped or indirect access.
config CAN_SJA1000_PLATFORM
tristate "Generic Platform Bus based SJA1000 driver"
---help---
This driver adds support for the SJA1000 chips connected to
the "platform bus" (Linux abstraction for directly to the
processor attached devices). Which can be found on various
boards from Phytec (http://www.phytec.de) like the PCM027,
PCM038.
config CAN_SJA1000_OF_PLATFORM
tristate "Generic OF Platform Bus based SJA1000 driver"
depends on PPC_OF
---help---
This driver adds support for the SJA1000 chips connected to
the OpenFirmware "platform bus" found on embedded systems with
OpenFirmware bindings, e.g. if you have a PowerPC based system
you may want to enable this option.
config CAN_EMS_PCI
tristate "EMS CPC-PCI, CPC-PCIe and CPC-104P Card"
depends on PCI
---help---
This driver is for the one, two or four channel CPC-PCI,
CPC-PCIe and CPC-104P cards from EMS Dr. Thomas Wuensche
(http://www.ems-wuensche.de).
config CAN_KVASER_PCI
tristate "Kvaser PCIcanx and Kvaser PCIcan PCI Cards"
depends on PCI
---help---
This driver is for the the PCIcanx and PCIcan cards (1, 2 or
4 channel) from Kvaser (http://www.kvaser.com).
endif

View File

@ -0,0 +1,10 @@
menu "CAN USB interfaces"
depends on USB && CAN_DEV
config CAN_EMS_USB
tristate "EMS CPC-USB/ARM7 CAN/USB interface"
---help---
This driver is for the one channel CPC-USB/ARM7 CAN/USB interface
from from EMS Dr. Thomas Wuensche (http://www.ems-wuensche.de).
endmenu

View File

@ -3,3 +3,5 @@
# #
obj-$(CONFIG_CAN_EMS_USB) += ems_usb.o obj-$(CONFIG_CAN_EMS_USB) += ems_usb.o
ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG

View File

@ -879,7 +879,7 @@ recycle:
pci_dma_sync_single_for_cpu(adap->pdev, dma_addr, len, pci_dma_sync_single_for_cpu(adap->pdev, dma_addr, len,
PCI_DMA_FROMDEVICE); PCI_DMA_FROMDEVICE);
(*sd->pg_chunk.p_cnt)--; (*sd->pg_chunk.p_cnt)--;
if (!*sd->pg_chunk.p_cnt) if (!*sd->pg_chunk.p_cnt && sd->pg_chunk.page != fl->pg_chunk.page)
pci_unmap_page(adap->pdev, pci_unmap_page(adap->pdev,
sd->pg_chunk.mapping, sd->pg_chunk.mapping,
fl->alloc_size, fl->alloc_size,
@ -2088,7 +2088,7 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
PCI_DMA_FROMDEVICE); PCI_DMA_FROMDEVICE);
(*sd->pg_chunk.p_cnt)--; (*sd->pg_chunk.p_cnt)--;
if (!*sd->pg_chunk.p_cnt) if (!*sd->pg_chunk.p_cnt && sd->pg_chunk.page != fl->pg_chunk.page)
pci_unmap_page(adap->pdev, pci_unmap_page(adap->pdev,
sd->pg_chunk.mapping, sd->pg_chunk.mapping,
fl->alloc_size, fl->alloc_size,

View File

@ -2140,9 +2140,6 @@ static int emac_poll(struct napi_struct *napi, int budget)
u32 status = 0; u32 status = 0;
u32 num_pkts = 0; u32 num_pkts = 0;
if (!netif_running(ndev))
return 0;
/* Check interrupt vectors and call packet processing */ /* Check interrupt vectors and call packet processing */
status = emac_read(EMAC_MACINVECTOR); status = emac_read(EMAC_MACINVECTOR);

View File

@ -5821,10 +5821,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
dev->dev_addr); dev->dev_addr);
dev_printk(KERN_ERR, &pci_dev->dev, dev_printk(KERN_ERR, &pci_dev->dev,
"Please complain to your hardware vendor. Switching to a random MAC.\n"); "Please complain to your hardware vendor. Switching to a random MAC.\n");
dev->dev_addr[0] = 0x00; random_ether_addr(dev->dev_addr);
dev->dev_addr[1] = 0x00;
dev->dev_addr[2] = 0x6c;
get_random_bytes(&dev->dev_addr[3], 3);
} }
dprintk(KERN_DEBUG "%s: MAC Address %pM\n", dprintk(KERN_DEBUG "%s: MAC Address %pM\n",

View File

@ -263,8 +263,8 @@ struct emac_regs {
/* EMACx_TRTR */ /* EMACx_TRTR */
#define EMAC_TRTR_SHIFT_EMAC4 27 #define EMAC_TRTR_SHIFT_EMAC4 24
#define EMAC_TRTR_SHIFT 24 #define EMAC_TRTR_SHIFT 27
/* EMAC specific TX descriptor control fields (write access) */ /* EMAC specific TX descriptor control fields (write access) */
#define EMAC_TX_CTRL_GFCS 0x0200 #define EMAC_TX_CTRL_GFCS 0x0200

View File

@ -5994,6 +5994,7 @@ static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev)
} else { } else {
pci_set_master(pdev); pci_set_master(pdev);
pci_restore_state(pdev); pci_restore_state(pdev);
pci_save_state(pdev);
pci_wake_from_d3(pdev, false); pci_wake_from_d3(pdev, false);

View File

@ -139,7 +139,7 @@ out:
return NULL; return NULL;
} }
static void __devinit mdio_gpio_bus_deinit(struct device *dev) static void mdio_gpio_bus_deinit(struct device *dev)
{ {
struct mii_bus *bus = dev_get_drvdata(dev); struct mii_bus *bus = dev_get_drvdata(dev);
struct mdio_gpio_info *bitbang = bus->priv; struct mdio_gpio_info *bitbang = bus->priv;

View File

@ -1944,8 +1944,15 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
} }
/* Pull completed packets off the queue and receive them. */ /* Pull completed packets off the queue and receive them. */
while ((skb = ppp_mp_reconstruct(ppp))) while ((skb = ppp_mp_reconstruct(ppp))) {
ppp_receive_nonmp_frame(ppp, skb); if (pskb_may_pull(skb, 2))
ppp_receive_nonmp_frame(ppp, skb);
else {
++ppp->dev->stats.rx_length_errors;
kfree_skb(skb);
ppp_receive_error(ppp);
}
}
return; return;

View File

@ -1085,7 +1085,7 @@ static int __devinit r6040_init_one(struct pci_dev *pdev,
int bar = 0; int bar = 0;
u16 *adrp; u16 *adrp;
printk(KERN_INFO "%s\n", version); printk("%s\n", version);
err = pci_enable_device(pdev); err = pci_enable_device(pdev);
if (err) if (err)

View File

@ -3243,9 +3243,9 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev)
static void rtl8169_set_rxbufsize(struct rtl8169_private *tp, static void rtl8169_set_rxbufsize(struct rtl8169_private *tp,
struct net_device *dev) struct net_device *dev)
{ {
unsigned int mtu = dev->mtu; unsigned int max_frame = dev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN;
tp->rx_buf_sz = (mtu > RX_BUF_SIZE) ? mtu + ETH_HLEN + 8 : RX_BUF_SIZE; tp->rx_buf_sz = (max_frame > RX_BUF_SIZE) ? max_frame : RX_BUF_SIZE;
} }
static int rtl8169_open(struct net_device *dev) static int rtl8169_open(struct net_device *dev)

View File

@ -3494,6 +3494,7 @@ static void s2io_reset(struct s2io_nic *sp)
/* Restore the PCI state saved during initialization. */ /* Restore the PCI state saved during initialization. */
pci_restore_state(sp->pdev); pci_restore_state(sp->pdev);
pci_save_state(sp->pdev);
pci_read_config_word(sp->pdev, 0x2, &val16); pci_read_config_word(sp->pdev, 0x2, &val16);
if (check_pci_device_id(val16) != (u16)PCI_ANY_ID) if (check_pci_device_id(val16) != (u16)PCI_ANY_ID)
break; break;

View File

@ -986,7 +986,7 @@ static int smsc911x_poll(struct napi_struct *napi, int budget)
struct net_device *dev = pdata->dev; struct net_device *dev = pdata->dev;
int npackets = 0; int npackets = 0;
while (likely(netif_running(dev)) && (npackets < budget)) { while (npackets < budget) {
unsigned int pktlength; unsigned int pktlength;
unsigned int pktwords; unsigned int pktwords;
struct sk_buff *skb; struct sk_buff *skb;

View File

@ -2063,7 +2063,15 @@ static int gem_check_invariants(struct gem *gp)
mif_cfg &= ~MIF_CFG_PSELECT; mif_cfg &= ~MIF_CFG_PSELECT;
writel(mif_cfg, gp->regs + MIF_CFG); writel(mif_cfg, gp->regs + MIF_CFG);
} else { } else {
gp->phy_type = phy_serialink; #ifdef CONFIG_SPARC
const char *p;
p = of_get_property(gp->of_node, "shared-pins", NULL);
if (p && !strcmp(p, "serdes"))
gp->phy_type = phy_serdes;
else
#endif
gp->phy_type = phy_serialink;
} }
if (gp->phy_type == phy_mii_mdio1 || if (gp->phy_type == phy_mii_mdio1 ||
gp->phy_type == phy_mii_mdio0) { gp->phy_type == phy_mii_mdio0) {

View File

@ -1125,7 +1125,6 @@ ath5k_mode_setup(struct ath5k_softc *sc)
/* configure operational mode */ /* configure operational mode */
ath5k_hw_set_opmode(ah); ath5k_hw_set_opmode(ah);
ath5k_hw_set_mcast_filter(ah, 0, 0);
ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt);
} }

View File

@ -63,12 +63,16 @@ static const struct pci_device_id ath5k_led_devices[] = {
{ ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0422), ATH_LED(1, 1) }, { ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0422), ATH_LED(1, 1) },
/* E-machines E510 (tuliom@gmail.com) */ /* E-machines E510 (tuliom@gmail.com) */
{ ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0428), ATH_LED(3, 0) }, { ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0428), ATH_LED(3, 0) },
/* BenQ Joybook R55v (nowymarluk@wp.pl) */
{ ATH_SDEVICE(PCI_VENDOR_ID_QMI, 0x0100), ATH_LED(1, 0) },
/* Acer Extensa 5620z (nekoreeve@gmail.com) */ /* Acer Extensa 5620z (nekoreeve@gmail.com) */
{ ATH_SDEVICE(PCI_VENDOR_ID_QMI, 0x0105), ATH_LED(3, 0) }, { ATH_SDEVICE(PCI_VENDOR_ID_QMI, 0x0105), ATH_LED(3, 0) },
/* Fukato Datacask Jupiter 1014a (mrb74@gmx.at) */ /* Fukato Datacask Jupiter 1014a (mrb74@gmx.at) */
{ ATH_SDEVICE(PCI_VENDOR_ID_AZWAVE, 0x1026), ATH_LED(3, 0) }, { ATH_SDEVICE(PCI_VENDOR_ID_AZWAVE, 0x1026), ATH_LED(3, 0) },
/* IBM ThinkPad AR5BXB6 (legovini@spiro.fisica.unipd.it) */ /* IBM ThinkPad AR5BXB6 (legovini@spiro.fisica.unipd.it) */
{ ATH_SDEVICE(PCI_VENDOR_ID_IBM, 0x058a), ATH_LED(1, 0) }, { ATH_SDEVICE(PCI_VENDOR_ID_IBM, 0x058a), ATH_LED(1, 0) },
/* HP Compaq CQ60-206US (ddreggors@jumptv.com) */
{ ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137a), ATH_LED(3, 1) },
/* HP Compaq C700 (nitrousnrg@gmail.com) */ /* HP Compaq C700 (nitrousnrg@gmail.com) */
{ ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137b), ATH_LED(3, 1) }, { ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137b), ATH_LED(3, 1) },
/* IBM-specific AR5212 (all others) */ /* IBM-specific AR5212 (all others) */

View File

@ -4521,9 +4521,8 @@ static int b43_op_beacon_set_tim(struct ieee80211_hw *hw,
{ {
struct b43_wl *wl = hw_to_b43_wl(hw); struct b43_wl *wl = hw_to_b43_wl(hw);
mutex_lock(&wl->mutex); /* FIXME: add locking */
b43_update_templates(wl); b43_update_templates(wl);
mutex_unlock(&wl->mutex);
return 0; return 0;
} }

View File

@ -6029,7 +6029,7 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
struct ipw2100_priv *priv; struct ipw2100_priv *priv;
struct net_device *dev; struct net_device *dev;
dev = alloc_ieee80211(sizeof(struct ipw2100_priv), 0); dev = alloc_ieee80211(sizeof(struct ipw2100_priv));
if (!dev) if (!dev)
return NULL; return NULL;
priv = libipw_priv(dev); priv = libipw_priv(dev);
@ -6342,7 +6342,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
sysfs_remove_group(&pci_dev->dev.kobj, sysfs_remove_group(&pci_dev->dev.kobj,
&ipw2100_attribute_group); &ipw2100_attribute_group);
free_ieee80211(dev, 0); free_ieee80211(dev);
pci_set_drvdata(pci_dev, NULL); pci_set_drvdata(pci_dev, NULL);
} }
@ -6400,7 +6400,7 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
if (dev->base_addr) if (dev->base_addr)
iounmap((void __iomem *)dev->base_addr); iounmap((void __iomem *)dev->base_addr);
free_ieee80211(dev, 0); free_ieee80211(dev);
} }
pci_release_regions(pci_dev); pci_release_regions(pci_dev);

View File

@ -104,25 +104,6 @@ static int antenna = CFG_SYS_ANTENNA_BOTH;
static int rtap_iface = 0; /* def: 0 -- do not create rtap interface */ static int rtap_iface = 0; /* def: 0 -- do not create rtap interface */
#endif #endif
static struct ieee80211_rate ipw2200_rates[] = {
{ .bitrate = 10 },
{ .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
{ .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
{ .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
{ .bitrate = 60 },
{ .bitrate = 90 },
{ .bitrate = 120 },
{ .bitrate = 180 },
{ .bitrate = 240 },
{ .bitrate = 360 },
{ .bitrate = 480 },
{ .bitrate = 540 }
};
#define ipw2200_a_rates (ipw2200_rates + 4)
#define ipw2200_num_a_rates 8
#define ipw2200_bg_rates (ipw2200_rates + 0)
#define ipw2200_num_bg_rates 12
#ifdef CONFIG_IPW2200_QOS #ifdef CONFIG_IPW2200_QOS
static int qos_enable = 0; static int qos_enable = 0;
@ -8674,6 +8655,24 @@ static int ipw_sw_reset(struct ipw_priv *priv, int option)
* *
*/ */
static int ipw_wx_get_name(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
struct ipw_priv *priv = libipw_priv(dev);
mutex_lock(&priv->mutex);
if (priv->status & STATUS_RF_KILL_MASK)
strcpy(wrqu->name, "radio off");
else if (!(priv->status & STATUS_ASSOCIATED))
strcpy(wrqu->name, "unassociated");
else
snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11%c",
ipw_modes[priv->assoc_request.ieee_mode]);
IPW_DEBUG_WX("Name: %s\n", wrqu->name);
mutex_unlock(&priv->mutex);
return 0;
}
static int ipw_set_channel(struct ipw_priv *priv, u8 channel) static int ipw_set_channel(struct ipw_priv *priv, u8 channel)
{ {
if (channel == 0) { if (channel == 0) {
@ -9973,7 +9972,7 @@ static int ipw_wx_sw_reset(struct net_device *dev,
/* Rebase the WE IOCTLs to zero for the handler array */ /* Rebase the WE IOCTLs to zero for the handler array */
#define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT] #define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT]
static iw_handler ipw_wx_handlers[] = { static iw_handler ipw_wx_handlers[] = {
IW_IOCTL(SIOCGIWNAME) = (iw_handler) cfg80211_wext_giwname, IW_IOCTL(SIOCGIWNAME) = ipw_wx_get_name,
IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq, IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq,
IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq, IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq,
IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode, IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode,
@ -11417,100 +11416,16 @@ static void ipw_bg_down(struct work_struct *work)
/* Called by register_netdev() */ /* Called by register_netdev() */
static int ipw_net_init(struct net_device *dev) static int ipw_net_init(struct net_device *dev)
{ {
int i, rc = 0;
struct ipw_priv *priv = libipw_priv(dev); struct ipw_priv *priv = libipw_priv(dev);
const struct libipw_geo *geo = libipw_get_geo(priv->ieee);
struct wireless_dev *wdev = &priv->ieee->wdev;
mutex_lock(&priv->mutex); mutex_lock(&priv->mutex);
if (ipw_up(priv)) { if (ipw_up(priv)) {
rc = -EIO; mutex_unlock(&priv->mutex);
goto out; return -EIO;
} }
memcpy(wdev->wiphy->perm_addr, priv->mac_addr, ETH_ALEN);
/* fill-out priv->ieee->bg_band */
if (geo->bg_channels) {
struct ieee80211_supported_band *bg_band = &priv->ieee->bg_band;
bg_band->band = IEEE80211_BAND_2GHZ;
bg_band->n_channels = geo->bg_channels;
bg_band->channels =
kzalloc(geo->bg_channels *
sizeof(struct ieee80211_channel), GFP_KERNEL);
/* translate geo->bg to bg_band.channels */
for (i = 0; i < geo->bg_channels; i++) {
bg_band->channels[i].band = IEEE80211_BAND_2GHZ;
bg_band->channels[i].center_freq = geo->bg[i].freq;
bg_band->channels[i].hw_value = geo->bg[i].channel;
bg_band->channels[i].max_power = geo->bg[i].max_power;
if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY)
bg_band->channels[i].flags |=
IEEE80211_CHAN_PASSIVE_SCAN;
if (geo->bg[i].flags & LIBIPW_CH_NO_IBSS)
bg_band->channels[i].flags |=
IEEE80211_CHAN_NO_IBSS;
if (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT)
bg_band->channels[i].flags |=
IEEE80211_CHAN_RADAR;
/* No equivalent for LIBIPW_CH_80211H_RULES,
LIBIPW_CH_UNIFORM_SPREADING, or
LIBIPW_CH_B_ONLY... */
}
/* point at bitrate info */
bg_band->bitrates = ipw2200_bg_rates;
bg_band->n_bitrates = ipw2200_num_bg_rates;
wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = bg_band;
}
/* fill-out priv->ieee->a_band */
if (geo->a_channels) {
struct ieee80211_supported_band *a_band = &priv->ieee->a_band;
a_band->band = IEEE80211_BAND_5GHZ;
a_band->n_channels = geo->a_channels;
a_band->channels =
kzalloc(geo->a_channels *
sizeof(struct ieee80211_channel), GFP_KERNEL);
/* translate geo->bg to a_band.channels */
for (i = 0; i < geo->a_channels; i++) {
a_band->channels[i].band = IEEE80211_BAND_2GHZ;
a_band->channels[i].center_freq = geo->a[i].freq;
a_band->channels[i].hw_value = geo->a[i].channel;
a_band->channels[i].max_power = geo->a[i].max_power;
if (geo->a[i].flags & LIBIPW_CH_PASSIVE_ONLY)
a_band->channels[i].flags |=
IEEE80211_CHAN_PASSIVE_SCAN;
if (geo->a[i].flags & LIBIPW_CH_NO_IBSS)
a_band->channels[i].flags |=
IEEE80211_CHAN_NO_IBSS;
if (geo->a[i].flags & LIBIPW_CH_RADAR_DETECT)
a_band->channels[i].flags |=
IEEE80211_CHAN_RADAR;
/* No equivalent for LIBIPW_CH_80211H_RULES,
LIBIPW_CH_UNIFORM_SPREADING, or
LIBIPW_CH_B_ONLY... */
}
/* point at bitrate info */
a_band->bitrates = ipw2200_a_rates;
a_band->n_bitrates = ipw2200_num_a_rates;
wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = a_band;
}
set_wiphy_dev(wdev->wiphy, &priv->pci_dev->dev);
/* With that information in place, we can now register the wiphy... */
if (wiphy_register(wdev->wiphy)) {
rc = -EIO;
goto out;
}
out:
mutex_unlock(&priv->mutex); mutex_unlock(&priv->mutex);
return rc; return 0;
} }
/* PCI driver stuff */ /* PCI driver stuff */
@ -11641,7 +11556,7 @@ static int ipw_prom_alloc(struct ipw_priv *priv)
if (priv->prom_net_dev) if (priv->prom_net_dev)
return -EPERM; return -EPERM;
priv->prom_net_dev = alloc_ieee80211(sizeof(struct ipw_prom_priv), 1); priv->prom_net_dev = alloc_ieee80211(sizeof(struct ipw_prom_priv));
if (priv->prom_net_dev == NULL) if (priv->prom_net_dev == NULL)
return -ENOMEM; return -ENOMEM;
@ -11660,7 +11575,7 @@ static int ipw_prom_alloc(struct ipw_priv *priv)
rc = register_netdev(priv->prom_net_dev); rc = register_netdev(priv->prom_net_dev);
if (rc) { if (rc) {
free_ieee80211(priv->prom_net_dev, 1); free_ieee80211(priv->prom_net_dev);
priv->prom_net_dev = NULL; priv->prom_net_dev = NULL;
return rc; return rc;
} }
@ -11674,7 +11589,7 @@ static void ipw_prom_free(struct ipw_priv *priv)
return; return;
unregister_netdev(priv->prom_net_dev); unregister_netdev(priv->prom_net_dev);
free_ieee80211(priv->prom_net_dev, 1); free_ieee80211(priv->prom_net_dev);
priv->prom_net_dev = NULL; priv->prom_net_dev = NULL;
} }
@ -11702,7 +11617,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
struct ipw_priv *priv; struct ipw_priv *priv;
int i; int i;
net_dev = alloc_ieee80211(sizeof(struct ipw_priv), 0); net_dev = alloc_ieee80211(sizeof(struct ipw_priv));
if (net_dev == NULL) { if (net_dev == NULL) {
err = -ENOMEM; err = -ENOMEM;
goto out; goto out;
@ -11850,7 +11765,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
pci_disable_device(pdev); pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL); pci_set_drvdata(pdev, NULL);
out_free_ieee80211: out_free_ieee80211:
free_ieee80211(priv->net_dev, 0); free_ieee80211(priv->net_dev);
out: out:
return err; return err;
} }
@ -11917,7 +11832,7 @@ static void __devexit ipw_pci_remove(struct pci_dev *pdev)
pci_release_regions(pdev); pci_release_regions(pdev);
pci_disable_device(pdev); pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL); pci_set_drvdata(pdev, NULL);
free_ieee80211(priv->net_dev, 0); free_ieee80211(priv->net_dev);
free_firmware(); free_firmware();
} }

View File

@ -31,7 +31,6 @@
#include <linux/ieee80211.h> #include <linux/ieee80211.h>
#include <net/lib80211.h> #include <net/lib80211.h>
#include <net/cfg80211.h>
#define LIBIPW_VERSION "git-1.1.13" #define LIBIPW_VERSION "git-1.1.13"
@ -784,15 +783,12 @@ struct libipw_geo {
struct libipw_device { struct libipw_device {
struct net_device *dev; struct net_device *dev;
struct wireless_dev wdev;
struct libipw_security sec; struct libipw_security sec;
/* Bookkeeping structures */ /* Bookkeeping structures */
struct libipw_stats ieee_stats; struct libipw_stats ieee_stats;
struct libipw_geo geo; struct libipw_geo geo;
struct ieee80211_supported_band bg_band;
struct ieee80211_supported_band a_band;
/* Probe / Beacon management */ /* Probe / Beacon management */
struct list_head network_free_list; struct list_head network_free_list;
@ -1018,8 +1014,8 @@ static inline int libipw_is_cck_rate(u8 rate)
} }
/* ieee80211.c */ /* ieee80211.c */
extern void free_ieee80211(struct net_device *dev, int monitor); extern void free_ieee80211(struct net_device *dev);
extern struct net_device *alloc_ieee80211(int sizeof_priv, int monitor); extern struct net_device *alloc_ieee80211(int sizeof_priv);
extern int libipw_change_mtu(struct net_device *dev, int new_mtu); extern int libipw_change_mtu(struct net_device *dev, int new_mtu);
extern void libipw_networks_age(struct libipw_device *ieee, extern void libipw_networks_age(struct libipw_device *ieee,

View File

@ -62,9 +62,6 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION);
MODULE_AUTHOR(DRV_COPYRIGHT); MODULE_AUTHOR(DRV_COPYRIGHT);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
struct cfg80211_ops libipw_config_ops = { };
void *libipw_wiphy_privid = &libipw_wiphy_privid;
static int libipw_networks_allocate(struct libipw_device *ieee) static int libipw_networks_allocate(struct libipw_device *ieee)
{ {
if (ieee->networks) if (ieee->networks)
@ -143,7 +140,7 @@ int libipw_change_mtu(struct net_device *dev, int new_mtu)
} }
EXPORT_SYMBOL(libipw_change_mtu); EXPORT_SYMBOL(libipw_change_mtu);
struct net_device *alloc_ieee80211(int sizeof_priv, int monitor) struct net_device *alloc_ieee80211(int sizeof_priv)
{ {
struct libipw_device *ieee; struct libipw_device *ieee;
struct net_device *dev; struct net_device *dev;
@ -160,31 +157,10 @@ struct net_device *alloc_ieee80211(int sizeof_priv, int monitor)
ieee->dev = dev; ieee->dev = dev;
if (!monitor) {
ieee->wdev.wiphy = wiphy_new(&libipw_config_ops, 0);
if (!ieee->wdev.wiphy) {
LIBIPW_ERROR("Unable to allocate wiphy.\n");
goto failed_free_netdev;
}
ieee->dev->ieee80211_ptr = &ieee->wdev;
ieee->wdev.iftype = NL80211_IFTYPE_STATION;
/* Fill-out wiphy structure bits we know... Not enough info
here to call set_wiphy_dev or set MAC address or channel info
-- have to do that in ->ndo_init... */
ieee->wdev.wiphy->privid = libipw_wiphy_privid;
ieee->wdev.wiphy->max_scan_ssids = 1;
ieee->wdev.wiphy->max_scan_ie_len = 0;
ieee->wdev.wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
| BIT(NL80211_IFTYPE_ADHOC);
}
err = libipw_networks_allocate(ieee); err = libipw_networks_allocate(ieee);
if (err) { if (err) {
LIBIPW_ERROR("Unable to allocate beacon storage: %d\n", err); LIBIPW_ERROR("Unable to allocate beacon storage: %d\n", err);
goto failed_free_wiphy; goto failed_free_netdev;
} }
libipw_networks_initialize(ieee); libipw_networks_initialize(ieee);
@ -217,31 +193,19 @@ struct net_device *alloc_ieee80211(int sizeof_priv, int monitor)
return dev; return dev;
failed_free_wiphy:
if (!monitor)
wiphy_free(ieee->wdev.wiphy);
failed_free_netdev: failed_free_netdev:
free_netdev(dev); free_netdev(dev);
failed: failed:
return NULL; return NULL;
} }
void free_ieee80211(struct net_device *dev, int monitor) void free_ieee80211(struct net_device *dev)
{ {
struct libipw_device *ieee = netdev_priv(dev); struct libipw_device *ieee = netdev_priv(dev);
lib80211_crypt_info_free(&ieee->crypt_info); lib80211_crypt_info_free(&ieee->crypt_info);
libipw_networks_free(ieee); libipw_networks_free(ieee);
/* free cfg80211 resources */
if (!monitor) {
wiphy_unregister(ieee->wdev.wiphy);
kfree(ieee->a_band.channels);
kfree(ieee->bg_band.channels);
wiphy_free(ieee->wdev.wiphy);
}
free_netdev(dev); free_netdev(dev);
} }

View File

@ -161,5 +161,6 @@ struct iwl_cfg iwl1000_bgn_cfg = {
.max_ll_items = OTP_MAX_LL_ITEMS_1000, .max_ll_items = OTP_MAX_LL_ITEMS_1000,
.shadow_ram_support = false, .shadow_ram_support = false,
.ht_greenfield_support = true, .ht_greenfield_support = true,
.use_rts_for_ht = true, /* use rts/cts protection */
}; };

View File

@ -175,6 +175,7 @@ struct iwl_cfg iwl6000h_2agn_cfg = {
.max_ll_items = OTP_MAX_LL_ITEMS_6x00, .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
.shadow_ram_support = true, .shadow_ram_support = true,
.ht_greenfield_support = true, .ht_greenfield_support = true,
.use_rts_for_ht = true, /* use rts/cts protection */
}; };
/* /*
@ -198,6 +199,7 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
.max_ll_items = OTP_MAX_LL_ITEMS_6x00, .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
.shadow_ram_support = true, .shadow_ram_support = true,
.ht_greenfield_support = true, .ht_greenfield_support = true,
.use_rts_for_ht = true, /* use rts/cts protection */
}; };
struct iwl_cfg iwl6050_2agn_cfg = { struct iwl_cfg iwl6050_2agn_cfg = {
@ -218,6 +220,7 @@ struct iwl_cfg iwl6050_2agn_cfg = {
.max_ll_items = OTP_MAX_LL_ITEMS_6x00, .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
.shadow_ram_support = true, .shadow_ram_support = true,
.ht_greenfield_support = true, .ht_greenfield_support = true,
.use_rts_for_ht = true, /* use rts/cts protection */
}; };
struct iwl_cfg iwl6000_3agn_cfg = { struct iwl_cfg iwl6000_3agn_cfg = {
@ -238,6 +241,7 @@ struct iwl_cfg iwl6000_3agn_cfg = {
.max_ll_items = OTP_MAX_LL_ITEMS_6x00, .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
.shadow_ram_support = true, .shadow_ram_support = true,
.ht_greenfield_support = true, .ht_greenfield_support = true,
.use_rts_for_ht = true, /* use rts/cts protection */
}; };
struct iwl_cfg iwl6050_3agn_cfg = { struct iwl_cfg iwl6050_3agn_cfg = {
@ -258,6 +262,7 @@ struct iwl_cfg iwl6050_3agn_cfg = {
.max_ll_items = OTP_MAX_LL_ITEMS_6x00, .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
.shadow_ram_support = true, .shadow_ram_support = true,
.ht_greenfield_support = true, .ht_greenfield_support = true,
.use_rts_for_ht = true, /* use rts/cts protection */
}; };
MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));

View File

@ -418,6 +418,15 @@ static void rs_tl_turn_on_agg(struct iwl_priv *priv, u8 tid,
else if (tid == IWL_AGG_ALL_TID) else if (tid == IWL_AGG_ALL_TID)
for (tid = 0; tid < TID_MAX_LOAD_COUNT; tid++) for (tid = 0; tid < TID_MAX_LOAD_COUNT; tid++)
rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta); rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta);
if (priv->cfg->use_rts_for_ht) {
/*
* switch to RTS/CTS if it is the prefer protection method
* for HT traffic
*/
IWL_DEBUG_HT(priv, "use RTS/CTS protection for HT\n");
priv->staging_rxon.flags &= ~RXON_FLG_SELF_CTS_EN;
iwlcore_commit_rxon(priv);
}
} }
static inline int get_num_of_ant_from_rate(u32 rate_n_flags) static inline int get_num_of_ant_from_rate(u32 rate_n_flags)

View File

@ -116,9 +116,6 @@ int iwl_commit_rxon(struct iwl_priv *priv)
/* always get timestamp with Rx frame */ /* always get timestamp with Rx frame */
priv->staging_rxon.flags |= RXON_FLG_TSF2HOST_MSK; priv->staging_rxon.flags |= RXON_FLG_TSF2HOST_MSK;
/* allow CTS-to-self if possible. this is relevant only for
* 5000, but will not damage 4965 */
priv->staging_rxon.flags |= RXON_FLG_SELF_CTS_EN;
ret = iwl_check_rxon_cmd(priv); ret = iwl_check_rxon_cmd(priv);
if (ret) { if (ret) {
@ -218,6 +215,13 @@ int iwl_commit_rxon(struct iwl_priv *priv)
"Could not send WEP static key.\n"); "Could not send WEP static key.\n");
} }
/*
* allow CTS-to-self if possible for new association.
* this is relevant only for 5000 series and up,
* but will not damage 4965
*/
priv->staging_rxon.flags |= RXON_FLG_SELF_CTS_EN;
/* Apply the new configuration /* Apply the new configuration
* RXON assoc doesn't clear the station table in uCode, * RXON assoc doesn't clear the station table in uCode,
*/ */

View File

@ -213,6 +213,7 @@ struct iwl_mod_params {
* @pa_type: used by 6000 series only to identify the type of Power Amplifier * @pa_type: used by 6000 series only to identify the type of Power Amplifier
* @max_ll_items: max number of OTP blocks * @max_ll_items: max number of OTP blocks
* @shadow_ram_support: shadow support for OTP memory * @shadow_ram_support: shadow support for OTP memory
* @use_rts_for_ht: use rts/cts protection for HT traffic
* *
* We enable the driver to be backward compatible wrt API version. The * We enable the driver to be backward compatible wrt API version. The
* driver specifies which APIs it supports (with @ucode_api_max being the * driver specifies which APIs it supports (with @ucode_api_max being the
@ -255,6 +256,7 @@ struct iwl_cfg {
const bool shadow_ram_support; const bool shadow_ram_support;
const bool ht_greenfield_support; const bool ht_greenfield_support;
const bool broken_powersave; const bool broken_powersave;
bool use_rts_for_ht;
}; };
/*************************** /***************************

View File

@ -169,16 +169,19 @@ static int lbs_ethtool_set_wol(struct net_device *dev,
struct lbs_private *priv = dev->ml_priv; struct lbs_private *priv = dev->ml_priv;
uint32_t criteria = 0; uint32_t criteria = 0;
if (priv->wol_criteria == 0xffffffff && wol->wolopts)
return -EOPNOTSUPP;
if (wol->wolopts & ~(WAKE_UCAST|WAKE_MCAST|WAKE_BCAST|WAKE_PHY)) if (wol->wolopts & ~(WAKE_UCAST|WAKE_MCAST|WAKE_BCAST|WAKE_PHY))
return -EOPNOTSUPP; return -EOPNOTSUPP;
if (wol->wolopts & WAKE_UCAST) criteria |= EHS_WAKE_ON_UNICAST_DATA; if (wol->wolopts & WAKE_UCAST)
if (wol->wolopts & WAKE_MCAST) criteria |= EHS_WAKE_ON_MULTICAST_DATA; criteria |= EHS_WAKE_ON_UNICAST_DATA;
if (wol->wolopts & WAKE_BCAST) criteria |= EHS_WAKE_ON_BROADCAST_DATA; if (wol->wolopts & WAKE_MCAST)
if (wol->wolopts & WAKE_PHY) criteria |= EHS_WAKE_ON_MAC_EVENT; criteria |= EHS_WAKE_ON_MULTICAST_DATA;
if (wol->wolopts & WAKE_BCAST)
criteria |= EHS_WAKE_ON_BROADCAST_DATA;
if (wol->wolopts & WAKE_PHY)
criteria |= EHS_WAKE_ON_MAC_EVENT;
if (wol->wolopts == 0)
criteria |= EHS_REMOVE_WAKEUP;
return lbs_host_sleep_cfg(priv, criteria, (struct wol_config *)NULL); return lbs_host_sleep_cfg(priv, criteria, (struct wol_config *)NULL);
} }

View File

@ -426,12 +426,16 @@ static const char p54u_romboot_3887[] = "~~~~";
static int p54u_firmware_reset_3887(struct ieee80211_hw *dev) static int p54u_firmware_reset_3887(struct ieee80211_hw *dev)
{ {
struct p54u_priv *priv = dev->priv; struct p54u_priv *priv = dev->priv;
u8 buf[4]; u8 *buf;
int ret; int ret;
memcpy(&buf, p54u_romboot_3887, sizeof(buf)); buf = kmalloc(4, GFP_KERNEL);
if (!buf)
return -ENOMEM;
memcpy(buf, p54u_romboot_3887, 4);
ret = p54u_bulk_msg(priv, P54U_PIPE_DATA, ret = p54u_bulk_msg(priv, P54U_PIPE_DATA,
buf, sizeof(buf)); buf, 4);
kfree(buf);
if (ret) if (ret)
dev_err(&priv->udev->dev, "(p54usb) unable to jump to " dev_err(&priv->udev->dev, "(p54usb) unable to jump to "
"boot ROM (%d)!\n", ret); "boot ROM (%d)!\n", ret);

View File

@ -18,6 +18,7 @@
#include <net/mac80211.h> #include <net/mac80211.h>
#include "rtl8187.h" #include "rtl8187.h"
#include "rtl8187_rfkill.h"
static bool rtl8187_is_radio_enabled(struct rtl8187_priv *priv) static bool rtl8187_is_radio_enabled(struct rtl8187_priv *priv)
{ {

View File

@ -162,6 +162,8 @@ static u8 chipid_to_nrcores(u16 chipid)
static u32 scan_read32(struct ssb_bus *bus, u8 current_coreidx, static u32 scan_read32(struct ssb_bus *bus, u8 current_coreidx,
u16 offset) u16 offset)
{ {
u32 lo, hi;
switch (bus->bustype) { switch (bus->bustype) {
case SSB_BUSTYPE_SSB: case SSB_BUSTYPE_SSB:
offset += current_coreidx * SSB_CORE_SIZE; offset += current_coreidx * SSB_CORE_SIZE;
@ -174,7 +176,9 @@ static u32 scan_read32(struct ssb_bus *bus, u8 current_coreidx,
offset -= 0x800; offset -= 0x800;
} else } else
ssb_pcmcia_switch_segment(bus, 0); ssb_pcmcia_switch_segment(bus, 0);
break; lo = readw(bus->mmio + offset);
hi = readw(bus->mmio + offset + 2);
return lo | (hi << 16);
case SSB_BUSTYPE_SDIO: case SSB_BUSTYPE_SDIO:
offset += current_coreidx * SSB_CORE_SIZE; offset += current_coreidx * SSB_CORE_SIZE;
return ssb_sdio_scan_read32(bus, offset); return ssb_sdio_scan_read32(bus, offset);

View File

@ -157,7 +157,7 @@ typedef struct {
typedef struct { typedef struct {
int mp_mrru; /* unused */ int mp_mrru; /* unused */
struct sk_buff_head frags; /* fragments sl list */ struct sk_buff * frags; /* fragments sl list -- use skb->next */
long frames; /* number of frames in the frame list */ long frames; /* number of frames in the frame list */
unsigned int seq; /* last processed packet seq #: any packets unsigned int seq; /* last processed packet seq #: any packets
* with smaller seq # will be dropped * with smaller seq # will be dropped

View File

@ -1980,7 +1980,7 @@ void sctp_assoc_set_primary(struct sctp_association *,
void sctp_assoc_del_nonprimary_peers(struct sctp_association *, void sctp_assoc_del_nonprimary_peers(struct sctp_association *,
struct sctp_transport *); struct sctp_transport *);
int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *, int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *,
gfp_t); sctp_scope_t, gfp_t);
int sctp_assoc_set_bind_addr_from_cookie(struct sctp_association *, int sctp_assoc_set_bind_addr_from_cookie(struct sctp_association *,
struct sctp_cookie*, struct sctp_cookie*,
gfp_t gfp); gfp_t gfp);

View File

@ -281,8 +281,11 @@ out_uninit_applicant:
if (ngrp) if (ngrp)
vlan_gvrp_uninit_applicant(real_dev); vlan_gvrp_uninit_applicant(real_dev);
out_free_group: out_free_group:
if (ngrp) if (ngrp) {
vlan_group_free(ngrp); hlist_del_rcu(&ngrp->hlist);
/* Free the group, after all cpu's are done. */
call_rcu(&ngrp->rcu, vlan_rcu_free);
}
return err; return err;
} }

View File

@ -211,6 +211,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
conn->type = type; conn->type = type;
conn->mode = HCI_CM_ACTIVE; conn->mode = HCI_CM_ACTIVE;
conn->state = BT_OPEN; conn->state = BT_OPEN;
conn->auth_type = HCI_AT_GENERAL_BONDING;
conn->power_save = 1; conn->power_save = 1;
conn->disc_timeout = HCI_DISCONN_TIMEOUT; conn->disc_timeout = HCI_DISCONN_TIMEOUT;

View File

@ -2205,7 +2205,7 @@ static int l2cap_build_conf_req(struct sock *sk, void *data)
{ {
struct l2cap_pinfo *pi = l2cap_pi(sk); struct l2cap_pinfo *pi = l2cap_pi(sk);
struct l2cap_conf_req *req = data; struct l2cap_conf_req *req = data;
struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_ERTM }; struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
void *ptr = req->data; void *ptr = req->data;
BT_DBG("sk %p", sk); BT_DBG("sk %p", sk);
@ -2394,6 +2394,10 @@ done:
rfc.monitor_timeout = L2CAP_DEFAULT_MONITOR_TO; rfc.monitor_timeout = L2CAP_DEFAULT_MONITOR_TO;
pi->conf_state |= L2CAP_CONF_MODE_DONE; pi->conf_state |= L2CAP_CONF_MODE_DONE;
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
sizeof(rfc), (unsigned long) &rfc);
break; break;
case L2CAP_MODE_STREAMING: case L2CAP_MODE_STREAMING:
@ -2401,6 +2405,10 @@ done:
pi->max_pdu_size = rfc.max_pdu_size; pi->max_pdu_size = rfc.max_pdu_size;
pi->conf_state |= L2CAP_CONF_MODE_DONE; pi->conf_state |= L2CAP_CONF_MODE_DONE;
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
sizeof(rfc), (unsigned long) &rfc);
break; break;
default: default:
@ -2410,9 +2418,6 @@ done:
rfc.mode = pi->mode; rfc.mode = pi->mode;
} }
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
sizeof(rfc), (unsigned long) &rfc);
if (result == L2CAP_CONF_SUCCESS) if (result == L2CAP_CONF_SUCCESS)
pi->conf_state |= L2CAP_CONF_OUTPUT_DONE; pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
} }

View File

@ -942,14 +942,15 @@ rollback:
ret = notifier_to_errno(ret); ret = notifier_to_errno(ret);
if (ret) { if (ret) {
if (err) { /* err >= 0 after dev_alloc_name() or stores the first errno */
printk(KERN_ERR if (err >= 0) {
"%s: name change rollback failed: %d.\n",
dev->name, ret);
} else {
err = ret; err = ret;
memcpy(dev->name, oldname, IFNAMSIZ); memcpy(dev->name, oldname, IFNAMSIZ);
goto rollback; goto rollback;
} else {
printk(KERN_ERR
"%s: name change rollback failed: %d.\n",
dev->name, ret);
} }
} }

View File

@ -2701,7 +2701,8 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb)
NAPI_GRO_CB(skb)->free = 1; NAPI_GRO_CB(skb)->free = 1;
goto done; goto done;
} } else if (skb_gro_len(p) != pinfo->gso_size)
return -E2BIG;
headroom = skb_headroom(p); headroom = skb_headroom(p);
nskb = netdev_alloc_skb(p->dev, headroom + skb_gro_offset(p)); nskb = netdev_alloc_skb(p->dev, headroom + skb_gro_offset(p));

View File

@ -483,8 +483,10 @@ static int vif_add(struct net *net, struct vifctl *vifc, int mrtsock)
return -EINVAL; return -EINVAL;
} }
if ((in_dev = __in_dev_get_rtnl(dev)) == NULL) if ((in_dev = __in_dev_get_rtnl(dev)) == NULL) {
dev_put(dev);
return -EADDRNOTAVAIL; return -EADDRNOTAVAIL;
}
IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)++; IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)++;
ip_rt_multicast_event(in_dev); ip_rt_multicast_event(in_dev);

View File

@ -1183,7 +1183,9 @@ void tcp_cleanup_rbuf(struct sock *sk, int copied)
#if TCP_DEBUG #if TCP_DEBUG
struct sk_buff *skb = skb_peek(&sk->sk_receive_queue); struct sk_buff *skb = skb_peek(&sk->sk_receive_queue);
WARN_ON(skb && !before(tp->copied_seq, TCP_SKB_CB(skb)->end_seq)); WARN(skb && !before(tp->copied_seq, TCP_SKB_CB(skb)->end_seq),
KERN_INFO "cleanup rbuf bug: copied %X seq %X rcvnxt %X\n",
tp->copied_seq, TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt);
#endif #endif
if (inet_csk_ack_scheduled(sk)) { if (inet_csk_ack_scheduled(sk)) {
@ -1430,11 +1432,13 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
/* Now that we have two receive queues this /* Now that we have two receive queues this
* shouldn't happen. * shouldn't happen.
*/ */
if (before(*seq, TCP_SKB_CB(skb)->seq)) { if (WARN(before(*seq, TCP_SKB_CB(skb)->seq),
printk(KERN_INFO "recvmsg bug: copied %X " KERN_INFO "recvmsg bug: copied %X "
"seq %X\n", *seq, TCP_SKB_CB(skb)->seq); "seq %X rcvnxt %X fl %X\n", *seq,
TCP_SKB_CB(skb)->seq, tp->rcv_nxt,
flags))
break; break;
}
offset = *seq - TCP_SKB_CB(skb)->seq; offset = *seq - TCP_SKB_CB(skb)->seq;
if (tcp_hdr(skb)->syn) if (tcp_hdr(skb)->syn)
offset--; offset--;
@ -1443,8 +1447,9 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
if (tcp_hdr(skb)->fin) if (tcp_hdr(skb)->fin)
goto found_fin_ok; goto found_fin_ok;
WARN(!(flags & MSG_PEEK), KERN_INFO "recvmsg bug 2: " WARN(!(flags & MSG_PEEK), KERN_INFO "recvmsg bug 2: "
"copied %X seq %X\n", *seq, "copied %X seq %X rcvnxt %X fl %X\n",
TCP_SKB_CB(skb)->seq); *seq, TCP_SKB_CB(skb)->seq,
tp->rcv_nxt, flags);
} }
/* Well, if we have backlog, try to process it now yet. */ /* Well, if we have backlog, try to process it now yet. */

View File

@ -1485,15 +1485,13 @@ void sctp_assoc_rwnd_decrease(struct sctp_association *asoc, unsigned len)
* local endpoint and the remote peer. * local endpoint and the remote peer.
*/ */
int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *asoc, int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *asoc,
gfp_t gfp) sctp_scope_t scope, gfp_t gfp)
{ {
sctp_scope_t scope;
int flags; int flags;
/* Use scoping rules to determine the subset of addresses from /* Use scoping rules to determine the subset of addresses from
* the endpoint. * the endpoint.
*/ */
scope = sctp_scope(&asoc->peer.active_path->ipaddr);
flags = (PF_INET6 == asoc->base.sk->sk_family) ? SCTP_ADDR6_ALLOWED : 0; flags = (PF_INET6 == asoc->base.sk->sk_family) ? SCTP_ADDR6_ALLOWED : 0;
if (asoc->peer.ipv4_address) if (asoc->peer.ipv4_address)
flags |= SCTP_ADDR4_PEERSUPP; flags |= SCTP_ADDR4_PEERSUPP;

View File

@ -384,6 +384,11 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
if (!new_asoc) if (!new_asoc)
goto nomem; goto nomem;
if (sctp_assoc_set_bind_addr_from_ep(new_asoc,
sctp_scope(sctp_source(chunk)),
GFP_ATOMIC) < 0)
goto nomem_init;
/* The call, sctp_process_init(), can fail on memory allocation. */ /* The call, sctp_process_init(), can fail on memory allocation. */
if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type, if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type,
sctp_source(chunk), sctp_source(chunk),
@ -401,9 +406,6 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
len = ntohs(err_chunk->chunk_hdr->length) - len = ntohs(err_chunk->chunk_hdr->length) -
sizeof(sctp_chunkhdr_t); sizeof(sctp_chunkhdr_t);
if (sctp_assoc_set_bind_addr_from_ep(new_asoc, GFP_ATOMIC) < 0)
goto nomem_init;
repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len); repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len);
if (!repl) if (!repl)
goto nomem_init; goto nomem_init;
@ -1452,6 +1454,10 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
if (!new_asoc) if (!new_asoc)
goto nomem; goto nomem;
if (sctp_assoc_set_bind_addr_from_ep(new_asoc,
sctp_scope(sctp_source(chunk)), GFP_ATOMIC) < 0)
goto nomem;
/* In the outbound INIT ACK the endpoint MUST copy its current /* In the outbound INIT ACK the endpoint MUST copy its current
* Verification Tag and Peers Verification tag into a reserved * Verification Tag and Peers Verification tag into a reserved
* place (local tie-tag and per tie-tag) within the state cookie. * place (local tie-tag and per tie-tag) within the state cookie.
@ -1488,9 +1494,6 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
sizeof(sctp_chunkhdr_t); sizeof(sctp_chunkhdr_t);
} }
if (sctp_assoc_set_bind_addr_from_ep(new_asoc, GFP_ATOMIC) < 0)
goto nomem;
repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len); repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len);
if (!repl) if (!repl)
goto nomem; goto nomem;

View File

@ -1080,6 +1080,13 @@ static int __sctp_connect(struct sock* sk,
err = -ENOMEM; err = -ENOMEM;
goto out_free; goto out_free;
} }
err = sctp_assoc_set_bind_addr_from_ep(asoc, scope,
GFP_KERNEL);
if (err < 0) {
goto out_free;
}
} }
/* Prime the peer's transport structures. */ /* Prime the peer's transport structures. */
@ -1095,11 +1102,6 @@ static int __sctp_connect(struct sock* sk,
walk_size += af->sockaddr_len; walk_size += af->sockaddr_len;
} }
err = sctp_assoc_set_bind_addr_from_ep(asoc, GFP_KERNEL);
if (err < 0) {
goto out_free;
}
/* In case the user of sctp_connectx() wants an association /* In case the user of sctp_connectx() wants an association
* id back, assign one now. * id back, assign one now.
*/ */
@ -1274,22 +1276,30 @@ SCTP_STATIC int sctp_setsockopt_connectx(struct sock* sk,
} }
/* /*
* New (hopefully final) interface for the API. The option buffer is used * New (hopefully final) interface for the API.
* both for the returned association id and the addresses. * We use the sctp_getaddrs_old structure so that use-space library
* can avoid any unnecessary allocations. The only defferent part
* is that we store the actual length of the address buffer into the
* addrs_num structure member. That way we can re-use the existing
* code.
*/ */
SCTP_STATIC int sctp_getsockopt_connectx3(struct sock* sk, int len, SCTP_STATIC int sctp_getsockopt_connectx3(struct sock* sk, int len,
char __user *optval, char __user *optval,
int __user *optlen) int __user *optlen)
{ {
struct sctp_getaddrs_old param;
sctp_assoc_t assoc_id = 0; sctp_assoc_t assoc_id = 0;
int err = 0; int err = 0;
if (len < sizeof(assoc_id)) if (len < sizeof(param))
return -EINVAL; return -EINVAL;
if (copy_from_user(&param, optval, sizeof(param)))
return -EFAULT;
err = __sctp_setsockopt_connectx(sk, err = __sctp_setsockopt_connectx(sk,
(struct sockaddr __user *)(optval + sizeof(assoc_id)), (struct sockaddr __user *)param.addrs,
len - sizeof(assoc_id), &assoc_id); param.addr_num, &assoc_id);
if (err == 0 || err == -EINPROGRESS) { if (err == 0 || err == -EINPROGRESS) {
if (copy_to_user(optval, &assoc_id, sizeof(assoc_id))) if (copy_to_user(optval, &assoc_id, sizeof(assoc_id)))
@ -1689,6 +1699,11 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
goto out_unlock; goto out_unlock;
} }
asoc = new_asoc; asoc = new_asoc;
err = sctp_assoc_set_bind_addr_from_ep(asoc, scope, GFP_KERNEL);
if (err < 0) {
err = -ENOMEM;
goto out_free;
}
/* If the SCTP_INIT ancillary data is specified, set all /* If the SCTP_INIT ancillary data is specified, set all
* the association init values accordingly. * the association init values accordingly.
@ -1718,11 +1733,6 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
err = -ENOMEM; err = -ENOMEM;
goto out_free; goto out_free;
} }
err = sctp_assoc_set_bind_addr_from_ep(asoc, GFP_KERNEL);
if (err < 0) {
err = -ENOMEM;
goto out_free;
}
} }
/* ASSERT: we have a valid association at this point. */ /* ASSERT: we have a valid association at this point. */

View File

@ -308,7 +308,8 @@ void sctp_transport_route(struct sctp_transport *transport,
/* Initialize sk->sk_rcv_saddr, if the transport is the /* Initialize sk->sk_rcv_saddr, if the transport is the
* association's active path for getsockname(). * association's active path for getsockname().
*/ */
if (asoc && (transport == asoc->peer.active_path)) if (asoc && (!asoc->peer.primary_path ||
(transport == asoc->peer.active_path)))
opt->pf->af->to_sk_saddr(&transport->saddr, opt->pf->af->to_sk_saddr(&transport->saddr,
asoc->base.sk); asoc->base.sk);
} else } else