Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a2bfbc07 authored by David S. Miller's avatar David S. Miller
Browse files

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

Conflicts:
	drivers/net/can/Kconfig
parents 5c427ff9 82b3cc1a
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -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
+1 −1
Original line number Original line Diff line number Diff line
@@ -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);
+163 −189
Original line number Original line Diff line number Diff line
@@ -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,24 +1581,23 @@ 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;
	unsigned long flags;
	isdn_net_local * lpq;
	isdn_net_local * lpq;
	ippp_bundle * mp;
	ippp_bundle * mp;
	isdn_mppp_stats * stats;
	struct sk_buff * newfrag, * frag, * start, *nextf;
	u32 newseq, minseq, thisseq;
	unsigned long flags;
	int slot;
	int slot;


	spin_lock_irqsave(&net_dev->pb->lock, flags);
	spin_lock_irqsave(&net_dev->pb->lock, flags);
@@ -1625,6 +1622,7 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
	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 
	 */
	 */
@@ -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,45 +1681,70 @@ 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);
    		thisseq = MP_SEQ(frag);
    		nextf = frag->next;

    		/* drop any duplicate fragments */
    		if (newfrag != NULL && thisseq == newseq) {
      			isdn_ppp_mp_free_skb(mp, newfrag);
      			newfrag = NULL;
    		}


    		/* 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 */
	    		/* check for misplaced start */
      			if (start != frag && (MP_FLAGS(frag) & MP_BEGIN_FRAG)) {
      			if (start != frag && (MP_FLAGS(frag) & MP_BEGIN_FRAG)) {
				printk(KERN_WARNING"isdn_mppp(seq %d): new "
				printk(KERN_WARNING"isdn_mppp(seq %d): new "
				      "BEGIN flag with no prior END", thisseq);
				      "BEGIN flag with no prior END", thisseq);
				stats->seqerrs++;
				stats->seqerrs++;
				stats->frame_drops++;
				stats->frame_drops++;
			isdn_ppp_mp_discard(mp, start, frag);
				start = isdn_ppp_mp_discard(mp, start,frag);
			start = frag;
				nextf = frag->next;
      			}
    		} else if (MP_LE(thisseq, minseq)) {		
    		} else if (MP_LE(thisseq, minseq)) {		
      			if (MP_FLAGS(frag) & MP_BEGIN_FRAG)
      			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;
      			start = NULL;
      			frag = NULL;
      			frag = NULL;

      			mp->frags = nextf;
    		}
    		}


		/* check if need to update start pointer: if we just
		/* check if need to update start pointer: if we just
@@ -1742,24 +1756,25 @@ 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):"
	  				printk(KERN_WARNING"isdn_mppp(seq %d):"
						" END flag with no following "
						" END flag with no following "
						"BEGIN", thisseq);
						"BEGIN", thisseq);
					stats->seqerrs++;
					stats->seqerrs++;
				}
				}
			}
			}

    		} else {
    		} else {
			if (nextf != (struct sk_buff *)&mp->frags &&
			if ( nextf != NULL && frag != 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
@@ -1769,26 +1784,26 @@ 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;
	}
	  			
	  			
check_overflow:
    		frag = nextf;
  	}	/* while -- main loop */
	
  	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);
@@ -1796,12 +1811,14 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,


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,110 +1855,67 @@ 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)
{
	if (from) {
		struct sk_buff *skb, *tmp;
		int freeing = 0;

		skb_queue_walk_safe(&mp->frags, skb, tmp) {
			if (skb == to)
				break;
			if (skb == from)
				freeing = 1;
			if (!freeing)
				continue;
			__skb_unlink(skb, &mp->frags);
			isdn_ppp_mp_free_skb(mp, skb);
		}
	}
}

static unsigned int calc_tot_len(struct sk_buff_head *queue,
			struct sk_buff * from, struct sk_buff * to )
			struct sk_buff * from, struct sk_buff * to )
{
{
	unsigned int tot_len = 0;
	if( from )
	struct sk_buff *skb;
		while (from != to) {
	int found_start = 0;
	  		struct sk_buff * next = from->next;

			isdn_ppp_mp_free_skb(mp, from);
	skb_queue_walk(queue, skb) {
	  		from = next;
		if (skb == from)
			found_start = 1;
		if (!found_start)
			continue;
		tot_len += skb->len - MP_HEADER_LEN;
		if (skb == to)
			break;
		}
		}
	return tot_len;
	return from;
}
}


/* Reassemble packet using fragments in the reassembly queue from
void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp,
 * 'from' until 'to', inclusive.
				struct sk_buff * from, struct sk_buff * to )
 */
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;
	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;
	}
	}

	tot_len = calc_tot_len(&mp->frags, from, to);

	if( MP_FLAGS(from) == (MP_BEGIN_FRAG | MP_END_FRAG) ) {
	if( MP_FLAGS(from) == (MP_BEGIN_FRAG | MP_END_FRAG) ) {
		if( ippp_table[lp->ppp_slot]->debug & 0x40 )
		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;

		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 )
		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_copy_from_linear_data_offset(walk, MP_HEADER_LEN,
							 skb_put(skb,len),
							 skb_put(skb,len),
							 len);
							 len);
			}
			frag = from->next;
			__skb_unlink(walk, &mp->frags);
			isdn_ppp_mp_free_skb(mp, from);
			isdn_ppp_mp_free_skb(mp, walk);
			from = frag; 

			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);
}
}
+5 −55
Original line number Original line Diff line number Diff line
@@ -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
+6 −0
Original line number Original line Diff line number Diff line
@@ -677,6 +677,11 @@ static int can_fill_info(struct sk_buff *skb, const struct net_device *dev)
	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,
};
};


Loading