mirror of
https://github.com/adulau/aha.git
synced 2024-12-28 03:36:19 +00:00
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts: drivers/net/can/Kconfig
This commit is contained in:
commit
a2bfbc072e
32 changed files with 363 additions and 465 deletions
|
@ -4304,6 +4304,7 @@ 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: 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/
|
||||||
|
@ -4391,7 +4392,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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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--;
|
||||||
|
|
|
@ -35,63 +35,9 @@ 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.
|
||||||
|
|
||||||
|
@ -127,6 +73,10 @@ config CAN_MPC52XX
|
||||||
This driver can also be built as a module. If so, the module
|
This driver can also be built as a module. If so, the module
|
||||||
will be called mpc5xxx_can.
|
will be called mpc5xxx_can.
|
||||||
|
|
||||||
|
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
|
||||||
|
|
|
@ -677,6 +677,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);
|
||||||
|
@ -705,6 +710,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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
47
drivers/net/can/sja1000/Kconfig
Normal file
47
drivers/net/can/sja1000/Kconfig
Normal 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
|
10
drivers/net/can/usb/Kconfig
Normal file
10
drivers/net/can/usb/Kconfig
Normal 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
|
|
@ -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
|
||||||
|
|
|
@ -2136,9 +2136,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);
|
||||||
|
|
||||||
|
|
|
@ -5820,10 +5820,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",
|
||||||
|
|
|
@ -5988,6 +5988,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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -103,25 +103,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;
|
||||||
|
@ -8673,6 +8654,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) {
|
||||||
|
@ -9972,7 +9971,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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -2206,7 +2206,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);
|
||||||
|
@ -2395,6 +2395,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:
|
||||||
|
@ -2402,6 +2406,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:
|
||||||
|
@ -2411,9 +2419,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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -999,14 +999,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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -494,8 +494,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);
|
||||||
|
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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(¶m, 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. */
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue