static int ack_tx(struct net_device *dev, int acked)
{
  struct arcnet_local *lp = netdev_priv(dev);
  struct sk_buff *ackskb;
  struct archdr *ackpkt;
  int length=sizeof(struct arc_cap);

  BUGMSG(D_DURING, "capmode: ack_tx: protocol: %x: result: %d\n",
	 lp->outgoing.skb->protocol, acked);

  BUGLVL(D_SKB) arcnet_dump_skb(dev, lp->outgoing.skb, "ack_tx");

  /* Now alloc a skb to send back up through the layers: */
  ackskb = alloc_skb(length + ARC_HDR_SIZE , GFP_ATOMIC);
  if (ackskb == NULL) {
	  BUGMSG(D_NORMAL, "Memory squeeze, can't acknowledge.\n");
	  goto free_outskb;
  }

  skb_put(ackskb, length + ARC_HDR_SIZE );
  ackskb->dev = dev;

  skb_reset_mac_header(ackskb);
  ackpkt = (struct archdr *)skb_mac_header(ackskb);
  /* skb_pull(ackskb, ARC_HDR_SIZE); */


  skb_copy_from_linear_data(lp->outgoing.skb, ackpkt,
		ARC_HDR_SIZE + sizeof(struct arc_cap));
  ackpkt->soft.cap.proto=0; /* using protocol 0 for acknowledge */
  ackpkt->soft.cap.mes.ack=acked;

  BUGMSG(D_PROTO, "Ackknowledge for cap packet %x.\n",
	 *((int*)&ackpkt->soft.cap.cookie[0]));

  ackskb->protocol = __constant_htons(ETH_P_ARCNET);

  BUGLVL(D_SKB) arcnet_dump_skb(dev, ackskb, "ack_tx_recv");
  netif_rx(ackskb);

 free_outskb:
  dev_kfree_skb_irq(lp->outgoing.skb);
  lp->outgoing.proto = NULL; /* We are always finished when in this protocol */

  return 0;
}
示例#2
0
/* packet receiver */
static void rx(struct net_device *dev, int bufnum,
	       struct archdr *pkthdr, int length)
{
	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
	struct sk_buff *skb;
	struct archdr *pkt = pkthdr;
	char *pktbuf, *pkthdrbuf;
	int ofs;

	BUGMSG(D_DURING, "it's a raw(cap) packet (length=%d)\n", length);

	if (length >= MinTU)
		ofs = 512 - length;
	else
		ofs = 256 - length;

	skb = alloc_skb(length + ARC_HDR_SIZE + sizeof(int), GFP_ATOMIC);
	if (skb == NULL) {
		BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n");
		lp->stats.rx_dropped++;
		return;
	}
	skb_put(skb, length + ARC_HDR_SIZE + sizeof(int));
	skb->dev = dev;

	pkt = (struct archdr *) skb->data;

	skb->mac.raw = skb->data;
	skb_pull(skb, ARC_HDR_SIZE);

	/* up to sizeof(pkt->soft) has already been copied from the card */
	/* squeeze in an int for the cap encapsulation */

	/* use these variables to be sure we count in bytes, not in
	   sizeof(struct archdr) */
	pktbuf=(char*)pkt;
	pkthdrbuf=(char*)pkthdr;
	memcpy(pktbuf, pkthdrbuf, ARC_HDR_SIZE+sizeof(pkt->soft.cap.proto));
	memcpy(pktbuf+ARC_HDR_SIZE+sizeof(pkt->soft.cap.proto)+sizeof(int),
	       pkthdrbuf+ARC_HDR_SIZE+sizeof(pkt->soft.cap.proto),
	       sizeof(struct archdr)-ARC_HDR_SIZE-sizeof(pkt->soft.cap.proto));

	if (length > sizeof(pkt->soft))
		lp->hw.copy_from_card(dev, bufnum, ofs + sizeof(pkt->soft),
				      pkt->soft.raw + sizeof(pkt->soft)
				      + sizeof(int),
				      length - sizeof(pkt->soft));

	BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");

	skb->protocol = __constant_htons(ETH_P_ARCNET);
;
	netif_rx(skb);
	dev->last_rx = jiffies;
}
示例#3
0
static void rx(struct net_device *dev, int bufnum,
	       struct archdr *pkthdr, int length)
{
	struct arcnet_local *lp = netdev_priv(dev);
	struct sk_buff *skb;
	struct archdr *pkt = pkthdr;
	char *pktbuf, *pkthdrbuf;
	int ofs;

	BUGMSG(D_DURING, "it's a raw(cap) packet (length=%d)\n", length);

	if (length >= MinTU)
		ofs = 512 - length;
	else
		ofs = 256 - length;

	skb = alloc_skb(length + ARC_HDR_SIZE + sizeof(int), GFP_ATOMIC);
	if (skb == NULL) {
		BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n");
		dev->stats.rx_dropped++;
		return;
	}
	skb_put(skb, length + ARC_HDR_SIZE + sizeof(int));
	skb->dev = dev;
	skb_reset_mac_header(skb);
	pkt = (struct archdr *)skb_mac_header(skb);
	skb_pull(skb, ARC_HDR_SIZE);

	/*                                                               */
	/*                                             */

	/*                                                         
                          */
	pktbuf=(char*)pkt;
	pkthdrbuf=(char*)pkthdr;
	memcpy(pktbuf, pkthdrbuf, ARC_HDR_SIZE+sizeof(pkt->soft.cap.proto));
	memcpy(pktbuf+ARC_HDR_SIZE+sizeof(pkt->soft.cap.proto)+sizeof(int),
	       pkthdrbuf+ARC_HDR_SIZE+sizeof(pkt->soft.cap.proto),
	       sizeof(struct archdr)-ARC_HDR_SIZE-sizeof(pkt->soft.cap.proto));

	if (length > sizeof(pkt->soft))
		lp->hw.copy_from_card(dev, bufnum, ofs + sizeof(pkt->soft),
				      pkt->soft.raw + sizeof(pkt->soft)
				      + sizeof(int),
				      length - sizeof(pkt->soft));

	BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");

	skb->protocol = cpu_to_be16(ETH_P_ARCNET);
	netif_rx(skb);
}
示例#4
0
文件: arc-rawmode.c 项目: 274914765/C
/* packet receiver */
static void rx(struct net_device *dev, int bufnum,
           struct archdr *pkthdr, int length)
{
    struct arcnet_local *lp = dev->priv;
    struct sk_buff *skb;
    struct archdr *pkt = pkthdr;
    int ofs;

    BUGMSG(D_DURING, "it's a raw packet (length=%d)\n", length);

    if (length > MTU)
        ofs = 512 - length;
    else
        ofs = 256 - length;

    skb = alloc_skb(length + ARC_HDR_SIZE, GFP_ATOMIC);
    if (skb == NULL) {
        BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n");
        lp->stats.rx_dropped++;
        return;
    }
    skb_put(skb, length + ARC_HDR_SIZE);
    skb->dev = dev;

    pkt = (struct archdr *) skb->data;

    skb_reset_mac_header(skb);
    skb_pull(skb, ARC_HDR_SIZE);

    /* up to sizeof(pkt->soft) has already been copied from the card */
    memcpy(pkt, pkthdr, sizeof(struct archdr));
    if (length > sizeof(pkt->soft))
        lp->hw.copy_from_card(dev, bufnum, ofs + sizeof(pkt->soft),
                      pkt->soft.raw + sizeof(pkt->soft),
                      length - sizeof(pkt->soft));

    BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");

    skb->protocol = __constant_htons(ETH_P_ARCNET);
;
    netif_rx(skb);
    dev->last_rx = jiffies;
}
示例#5
0
/* packet receiver */
static void rx(struct net_device *dev, int bufnum,
	       struct archdr *pkthdr, int length)
{
	struct arcnet_local *lp = netdev_priv(dev);
	struct sk_buff *skb;
	struct archdr *pkt = pkthdr;
	int ofs;

	arc_printk(D_DURING, dev, "it's a raw packet (length=%d)\n", length);

	if (length >= MinTU)
		ofs = 512 - length;
	else
		ofs = 256 - length;

	skb = alloc_skb(length + ARC_HDR_SIZE, GFP_ATOMIC);
	if (!skb) {
		dev->stats.rx_dropped++;
		return;
	}
	skb_put(skb, length + ARC_HDR_SIZE);
	skb->dev = dev;

	pkt = (struct archdr *)skb->data;

	/* up to sizeof(pkt->soft) has already been copied from the card */
	memcpy(pkt, pkthdr, sizeof(struct archdr));
	if (length > sizeof(pkt->soft))
		lp->hw.copy_from_card(dev, bufnum, ofs + sizeof(pkt->soft),
				      pkt->soft.raw + sizeof(pkt->soft),
				      length - sizeof(pkt->soft));

	if (BUGLVL(D_SKB))
		arcnet_dump_skb(dev, skb, "rx");

	skb->protocol = type_trans(skb, dev);
	netif_rx(skb);
}
/* packet receiver */
static void rx(struct net_device *dev, int bufnum,
	       struct archdr *pkthdr, int length)
{
	struct arcnet_local *lp = netdev_priv(dev);
	struct sk_buff *skb;
	struct archdr *pkt = pkthdr;
	struct arc_rfc1201 *soft = &pkthdr->soft.rfc1201;
	int saddr = pkt->hard.source, ofs;
	struct Incoming *in = &lp->rfc1201.incoming[saddr];

	BUGMSG(D_DURING, "it's an RFC1201 packet (length=%d)\n", length);

	if (length >= MinTU)
		ofs = 512 - length;
	else
		ofs = 256 - length;

	if (soft->split_flag == 0xFF) {		/* Exception Packet */
		if (length >= 4 + RFC1201_HDR_SIZE)
			BUGMSG(D_DURING, "compensating for exception packet\n");
		else {
			BUGMSG(D_EXTRA, "short RFC1201 exception packet from %02Xh",
			       saddr);
			return;
		}

		/* skip over 4-byte junkola */
		length -= 4;
		ofs += 4;
		lp->hw.copy_from_card(dev, bufnum, 512 - length,
				      soft, sizeof(pkt->soft));
	}
	if (!soft->split_flag) {	/* not split */
		BUGMSG(D_RX, "incoming is not split (splitflag=%d)\n",
		       soft->split_flag);

		if (in->skb) {	/* already assembling one! */
			BUGMSG(D_EXTRA, "aborting assembly (seq=%d) for unsplit packet (splitflag=%d, seq=%d)\n",
			 in->sequence, soft->split_flag, soft->sequence);
			lp->rfc1201.aborted_seq = soft->sequence;
			dev_kfree_skb_irq(in->skb);
			lp->stats.rx_errors++;
			lp->stats.rx_missed_errors++;
			in->skb = NULL;
		}
		in->sequence = soft->sequence;

		skb = alloc_skb(length + ARC_HDR_SIZE, GFP_ATOMIC);
		if (skb == NULL) {
			BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n");
			lp->stats.rx_dropped++;
			return;
		}
		skb_put(skb, length + ARC_HDR_SIZE);
		skb->dev = dev;

		pkt = (struct archdr *) skb->data;
		soft = &pkt->soft.rfc1201;

		/* up to sizeof(pkt->soft) has already been copied from the card */
		memcpy(pkt, pkthdr, sizeof(struct archdr));
		if (length > sizeof(pkt->soft))
			lp->hw.copy_from_card(dev, bufnum, ofs + sizeof(pkt->soft),
				       pkt->soft.raw + sizeof(pkt->soft),
					      length - sizeof(pkt->soft));

		/*
		 * ARP packets have problems when sent from some DOS systems: the
		 * source address is always 0!  So we take the hardware source addr
		 * (which is impossible to fumble) and insert it ourselves.
		 */
		if (soft->proto == ARC_P_ARP) {
			struct arphdr *arp = (struct arphdr *) soft->payload;

			/* make sure addresses are the right length */
			if (arp->ar_hln == 1 && arp->ar_pln == 4) {
				uint8_t *cptr = (uint8_t *) arp + sizeof(struct arphdr);

				if (!*cptr) {	/* is saddr = 00? */
					BUGMSG(D_EXTRA,
					       "ARP source address was 00h, set to %02Xh.\n",
					       saddr);
					lp->stats.rx_crc_errors++;
					*cptr = saddr;
				} else {
					BUGMSG(D_DURING, "ARP source address (%Xh) is fine.\n",
					       *cptr);
				}
			} else {
				BUGMSG(D_NORMAL, "funny-shaped ARP packet. (%Xh, %Xh)\n",
				       arp->ar_hln, arp->ar_pln);
				lp->stats.rx_errors++;
				lp->stats.rx_crc_errors++;
			}
		}
		BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");

		skb->protocol = type_trans(skb, dev);
		netif_rx(skb);
	} else {		/* split packet */
		/*
		 * NOTE: MSDOS ARP packet correction should only need to apply to
		 * unsplit packets, since ARP packets are so short.
		 *
		 * My interpretation of the RFC1201 document is that if a packet is
		 * received out of order, the entire assembly process should be
		 * aborted.
		 *
		 * The RFC also mentions "it is possible for successfully received
		 * packets to be retransmitted." As of 0.40 all previously received
		 * packets are allowed, not just the most recent one.
		 *
		 * We allow multiple assembly processes, one for each ARCnet card
		 * possible on the network.  Seems rather like a waste of memory,
		 * but there's no other way to be reliable.
		 */

		BUGMSG(D_RX, "packet is split (splitflag=%d, seq=%d)\n",
		       soft->split_flag, in->sequence);

		if (in->skb && in->sequence != soft->sequence) {
			BUGMSG(D_EXTRA, "wrong seq number (saddr=%d, expected=%d, seq=%d, splitflag=%d)\n",
			       saddr, in->sequence, soft->sequence,
			       soft->split_flag);
			dev_kfree_skb_irq(in->skb);
			in->skb = NULL;
			lp->stats.rx_errors++;
			lp->stats.rx_missed_errors++;
			in->lastpacket = in->numpackets = 0;
		}
		if (soft->split_flag & 1) {	/* first packet in split */
			BUGMSG(D_RX, "brand new splitpacket (splitflag=%d)\n",
			       soft->split_flag);
			if (in->skb) {	/* already assembling one! */
				BUGMSG(D_EXTRA, "aborting previous (seq=%d) assembly "
				       "(splitflag=%d, seq=%d)\n",
				       in->sequence, soft->split_flag,
				       soft->sequence);
				lp->stats.rx_errors++;
				lp->stats.rx_missed_errors++;
				dev_kfree_skb_irq(in->skb);
			}
			in->sequence = soft->sequence;
			in->numpackets = ((unsigned) soft->split_flag >> 1) + 2;
			in->lastpacket = 1;

			if (in->numpackets > 16) {
				BUGMSG(D_EXTRA, "incoming packet more than 16 segments; dropping. (splitflag=%d)\n",
				       soft->split_flag);
				lp->rfc1201.aborted_seq = soft->sequence;
				lp->stats.rx_errors++;
				lp->stats.rx_length_errors++;
				return;
			}
			in->skb = skb = alloc_skb(508 * in->numpackets + ARC_HDR_SIZE,
						  GFP_ATOMIC);
			if (skb == NULL) {
				BUGMSG(D_NORMAL, "(split) memory squeeze, dropping packet.\n");
				lp->rfc1201.aborted_seq = soft->sequence;
				lp->stats.rx_dropped++;
				return;
			}
			skb->dev = dev;
			pkt = (struct archdr *) skb->data;
			soft = &pkt->soft.rfc1201;

			memcpy(pkt, pkthdr, ARC_HDR_SIZE + RFC1201_HDR_SIZE);
			skb_put(skb, ARC_HDR_SIZE + RFC1201_HDR_SIZE);

			soft->split_flag = 0;	/* end result won't be split */
		} else {	/* not first packet */