Example #1
0
/***
 *  rt_loopback_xmit - begin packet transmission
 *  @skb: packet to be sent
 *  @dev: network device to which packet is sent
 *
 */
static int rt_loopback_xmit(struct rtskb *skb, struct rtnet_device *rtdev)
{
    /* make sure that critical field are re-intialised */
    skb->chain_end = skb;

    /* parse the Ethernet header as usual */
    skb->protocol = rt_eth_type_trans(skb, rtdev);

#ifdef DEBUG_LOOPBACK_DRIVER
    {
        int i, cuantos;
        rt_printk("\n\nPACKET:");
        rt_printk("\nskb->protocol = %d", skb->protocol);
        rt_printk("\nskb->pkt_type = %d", skb->pkt_type);
        rt_printk("\nskb->csum = %d", skb->csum);
        rt_printk("\nskb->len = %d", skb->len);

        rt_printk("\n\nETHERNET HEADER:");
        rt_printk("\nMAC dest: "); for(i=0;i<6;i++){ rt_printk("0x%02X ", skb->buf_start[i+2]); }
        rt_printk("\nMAC orig: "); for(i=0;i<6;i++){ rt_printk("0x%02X ", skb->buf_start[i+8]); }
        rt_printk("\nPROTOCOL: "); for(i=0;i<2;i++){ rt_printk("0x%02X ", skb->buf_start[i+14]); }

        rt_printk("\n\nIP HEADER:");
        rt_printk("\nVERSIZE : "); for(i=0;i<1;i++){ rt_printk("0x%02X ", skb->buf_start[i+16]); }
        rt_printk("\nPRIORITY: "); for(i=0;i<1;i++){ rt_printk("0x%02X ", skb->buf_start[i+17]); }
        rt_printk("\nLENGTH  : "); for(i=0;i<2;i++){ rt_printk("0x%02X ", skb->buf_start[i+18]); }
        rt_printk("\nIDENT   : "); for(i=0;i<2;i++){ rt_printk("0x%02X ", skb->buf_start[i+20]); }
        rt_printk("\nFRAGMENT: "); for(i=0;i<2;i++){ rt_printk("0x%02X ", skb->buf_start[i+22]); }
        rt_printk("\nTTL     : "); for(i=0;i<1;i++){ rt_printk("0x%02X ", skb->buf_start[i+24]); }
        rt_printk("\nPROTOCOL: "); for(i=0;i<1;i++){ rt_printk("0x%02X ", skb->buf_start[i+25]); }
        rt_printk("\nCHECKSUM: "); for(i=0;i<2;i++){ rt_printk("0x%02X ", skb->buf_start[i+26]); }
        rt_printk("\nIP ORIGE: "); for(i=0;i<4;i++){ rt_printk("0x%02X ", skb->buf_start[i+28]); }
        rt_printk("\nIP DESTI: "); for(i=0;i<4;i++){ rt_printk("0x%02X ", skb->buf_start[i+32]); }

        cuantos = (int)(*(unsigned short *)(skb->buf_start+18)) - 20;
        rt_printk("\n\nDATA (%d):", cuantos);
        rt_printk("\n:"); for(i=0;i<cuantos;i++){ rt_printk("0x%02X ", skb->buf_start[i+36]); }
    }
#endif

    rtnetif_rx(skb);
    rt_mark_stack_mgr(rtdev);

    return 0;
}
Example #2
0
static int
fec_enet_interrupt(rtdm_irq_t *irq_handle)
{
	struct rtnet_device *ndev =
		rtdm_irq_get_arg(irq_handle, struct rtnet_device); /* RTnet */
	struct fec_enet_private *fep = rtnetdev_priv(ndev);
	uint int_events;
	irqreturn_t ret = RTDM_IRQ_NONE;
	/* RTnet */
	nanosecs_abs_t time_stamp = rtdm_clock_read();
	int packets = 0;

	do {
		int_events = readl(fep->hwp + FEC_IEVENT);
		writel(int_events, fep->hwp + FEC_IEVENT);

		if (int_events & FEC_ENET_RXF) {
			ret = RTDM_IRQ_HANDLED;
			fec_enet_rx(ndev, &packets, &time_stamp);
		}

		/* Transmit OK, or non-fatal error. Update the buffer
		 * descriptors. FEC handles all errors, we just discover
		 * them as part of the transmit process.
		 */
		if (int_events & FEC_ENET_TXF) {
			ret = RTDM_IRQ_HANDLED;
			fec_enet_tx(ndev);
		}

		if (int_events & FEC_ENET_MII) {
			ret = RTDM_IRQ_HANDLED;
			rtdm_nrtsig_pend(&fep->mdio_done_sig);
		}
	} while (int_events);

	if (packets > 0)
		rt_mark_stack_mgr(ndev);

	return ret;
}
int rt2x00_interrupt(rtdm_irq_t *irq_handle) {

    nanosecs_t time_stamp = rtdm_clock_read();

    struct rtnet_device   * rtnet_dev = rtdm_irq_get_arg(irq_handle, struct rtnet_device);
    struct _rt2x00_device * device    = rtwlan_priv(rtnet_dev);
    struct _rt2x00_pci	  * rt2x00pci = rt2x00_priv(device);
    struct rtwlan_device  * rtwlan    = rtnetdev_priv(rtnet_dev);
    unsigned int old_packet_cnt       = rtwlan->stats.rx_packets;
    u32			reg           = 0x00000000;
    rtdm_lockctx_t context;

    rtdm_lock_get_irqsave(&rtwlan->lock, context);

    rt2x00_register_read(rt2x00pci, CSR7, &reg);
    rt2x00_register_write(rt2x00pci, CSR7, reg);

    if(!reg)
        return RTDM_IRQ_NONE;

    if(rt2x00_get_field32(reg, CSR7_TBCN_EXPIRE))		/* Beacon timer expired interrupt. */
        DEBUG("Beacon timer expired.\n");
    if(rt2x00_get_field32(reg, CSR7_RXDONE))		/* Rx ring done interrupt. */
        rt2x00_interrupt_rxdone(&rt2x00pci->rx, &time_stamp);
    if(rt2x00_get_field32(reg, CSR7_TXDONE_ATIMRING))	/* Atim ring transmit done interrupt. */
        DEBUG("AtimTxDone.\n");
    if(rt2x00_get_field32(reg, CSR7_TXDONE_PRIORING))	/* Priority ring transmit done interrupt. */
        DEBUG("PrioTxDone.\n");
    if(rt2x00_get_field32(reg, CSR7_TXDONE_TXRING))	/* Tx ring transmit done interrupt. */
        rt2x00_interrupt_txdone(&rt2x00pci->tx);

    if (old_packet_cnt != rtwlan->stats.rx_packets)
        rt_mark_stack_mgr(rtnet_dev);

    rtdm_lock_put_irqrestore(&rtwlan->lock, context);

    return RTDM_IRQ_HANDLED;
}
Example #4
0
/* The interrupt handler.
 * This is called from the CPM handler, not the MPC core interrupt.
 */
static int scc_enet_interrupt(rtdm_irq_t *irq_handle)
{
	struct rtnet_device *rtdev = rtdm_irq_get_arg(irq_handle, struct rtnet_device);
	int packets = 0;
	struct	scc_enet_private *cep;
	volatile cbd_t	*bdp;
	ushort	int_events;
	int	must_restart;
	nanosecs_abs_t time_stamp = rtdm_clock_read();


	cep = (struct scc_enet_private *)rtdev->priv;

	/* Get the interrupt events that caused us to be here.
	*/
	int_events = cep->sccp->scc_scce;
	cep->sccp->scc_scce = int_events;
	must_restart = 0;

	/* Handle receive event in its own function.
	*/
	if (int_events & SCCE_ENET_RXF) {
		scc_enet_rx(rtdev, &packets, &time_stamp);
	}

	/* Check for a transmit error.  The manual is a little unclear
	 * about this, so the debug code until I get it figured out.  It
	 * appears that if TXE is set, then TXB is not set.  However,
	 * if carrier sense is lost during frame transmission, the TXE
	 * bit is set, "and continues the buffer transmission normally."
	 * I don't know if "normally" implies TXB is set when the buffer
	 * descriptor is closed.....trial and error :-).
	 */

	/* Transmit OK, or non-fatal error.  Update the buffer descriptors.
	*/
	if (int_events & (SCCE_ENET_TXE | SCCE_ENET_TXB)) {
	    rtdm_lock_get(&cep->lock);
	    bdp = cep->dirty_tx;
	    while ((bdp->cbd_sc&BD_ENET_TX_READY)==0) {
		RT_DEBUG(__FUNCTION__": Tx ok\n");
		if ((bdp==cep->cur_tx) && (cep->tx_full == 0))
		    break;

		if (bdp->cbd_sc & BD_ENET_TX_HB)	/* No heartbeat */
			cep->stats.tx_heartbeat_errors++;
		if (bdp->cbd_sc & BD_ENET_TX_LC)	/* Late collision */
			cep->stats.tx_window_errors++;
		if (bdp->cbd_sc & BD_ENET_TX_RL)	/* Retrans limit */
			cep->stats.tx_aborted_errors++;
		if (bdp->cbd_sc & BD_ENET_TX_UN)	/* Underrun */
			cep->stats.tx_fifo_errors++;
		if (bdp->cbd_sc & BD_ENET_TX_CSL)	/* Carrier lost */
			cep->stats.tx_carrier_errors++;


		/* No heartbeat or Lost carrier are not really bad errors.
		 * The others require a restart transmit command.
		 */
		if (bdp->cbd_sc &
		    (BD_ENET_TX_LC | BD_ENET_TX_RL | BD_ENET_TX_UN)) {
			must_restart = 1;
			cep->stats.tx_errors++;
		}

		cep->stats.tx_packets++;

		/* Deferred means some collisions occurred during transmit,
		 * but we eventually sent the packet OK.
		 */
		if (bdp->cbd_sc & BD_ENET_TX_DEF)
			cep->stats.collisions++;

		/* Free the sk buffer associated with this last transmit.
		*/
		dev_kfree_rtskb(cep->tx_skbuff[cep->skb_dirty]);
		cep->skb_dirty = (cep->skb_dirty + 1) & TX_RING_MOD_MASK;

		/* Update pointer to next buffer descriptor to be transmitted.
		*/
		if (bdp->cbd_sc & BD_ENET_TX_WRAP)
			bdp = cep->tx_bd_base;
		else
			bdp++;

		/* I don't know if we can be held off from processing these
		 * interrupts for more than one frame time.  I really hope
		 * not.  In such a case, we would now want to check the
		 * currently available BD (cur_tx) and determine if any
		 * buffers between the dirty_tx and cur_tx have also been
		 * sent.  We would want to process anything in between that
		 * does not have BD_ENET_TX_READY set.
		 */

		/* Since we have freed up a buffer, the ring is no longer
		 * full.
		 */
		if (cep->tx_full) {
			cep->tx_full = 0;
			if (rtnetif_queue_stopped(rtdev))
				rtnetif_wake_queue(rtdev);
		}

		cep->dirty_tx = (cbd_t *)bdp;
	    }

	    if (must_restart) {
		volatile cpm8xx_t *cp;

		/* Some transmit errors cause the transmitter to shut
		 * down.  We now issue a restart transmit.  Since the
		 * errors close the BD and update the pointers, the restart
		 * _should_ pick up without having to reset any of our
		 * pointers either.
		 */
		cp = cpmp;
		cp->cp_cpcr =
		    mk_cr_cmd(CPM_CR_ENET, CPM_CR_RESTART_TX) | CPM_CR_FLG;
		while (cp->cp_cpcr & CPM_CR_FLG);
	    }
	    rtdm_lock_put(&cep->lock);
	}

	/* Check for receive busy, i.e. packets coming but no place to
	 * put them.  This "can't happen" because the receive interrupt
	 * is tossing previous frames.
	 */
	if (int_events & SCCE_ENET_BSY) {
		cep->stats.rx_dropped++;
		rtdm_printk("CPM ENET: BSY can't happen.\n");
	}

	if (packets > 0)
		rt_mark_stack_mgr(rtdev);
	return RTDM_IRQ_HANDLED;
}
Example #5
0
/***
 * rt_loopback_xmit - begin packet transmission
 * @skb: packet to be sent
 * @dev: network device to which packet is sent
 *
 */
static int rt_loopback_xmit(struct rtskb *skb, struct rtnet_device *rtdev)
{
	int err=0;
	struct rtskb *new_skb;

	if ( (new_skb=dev_alloc_rtskb(skb->len + 2))==NULL ) 
	{
		rt_printk("RTnet %s: couldn't allocate a rtskb of size %d.\n", rtdev->name, skb->len);
		err = -ENOMEM;
		goto rt_loopback_xmit_end;
	}
	else 
	{
		new_skb->rx = rt_get_time();
		new_skb->rtdev = rtdev;
		rtskb_reserve(new_skb,2);
		memcpy(new_skb->buf_start, skb->buf_start, SKB_DATA_ALIGN(ETH_FRAME_LEN));
		rtskb_put(new_skb, skb->len);
		new_skb->protocol = rt_eth_type_trans(new_skb, rtdev);

#ifdef DEBUG_LOOPBACK_DRIVER
		{
			int i, cuantos;
			rt_printk("\n\nPACKET:");
			rt_printk("\nskb->protocol = %d", 		skb->protocol);
			rt_printk("\nskb->pkt_type = %d", 		skb->pkt_type);
			rt_printk("\nskb->users = %d", 			skb->users);
			rt_printk("\nskb->cloned = %d", 		skb->cloned);
			rt_printk("\nskb->csum = %d",	 		skb->csum);
			rt_printk("\nskb->len = %d", 			skb->len);
			
			rt_printk("\nnew_skb->protocol = %d", 	new_skb->protocol);
			rt_printk("\nnew_skb->pkt_type = %d", 	new_skb->pkt_type);
			rt_printk("\nnew_skb->users = %d", 		new_skb->users);
			rt_printk("\nnew_skb->cloned = %d", 	new_skb->cloned);
			rt_printk("\nnew_skb->csum = %d",	 	new_skb->csum);
			rt_printk("\nnew_skb->len = %d", 		new_skb->len);
			
			rt_printk("\n\nETHERNET HEADER:");
			rt_printk("\nMAC dest: "); for(i=0;i<6;i++){ rt_printk("0x%02X ", new_skb->buf_start[i+2]); }
			rt_printk("\nMAC orig: "); for(i=0;i<6;i++){ rt_printk("0x%02X ", new_skb->buf_start[i+8]); }
			rt_printk("\nPROTOCOL: "); for(i=0;i<2;i++){ rt_printk("0x%02X ", new_skb->buf_start[i+14]); }
		
			rt_printk("\n\nIP HEADER:");
			rt_printk("\nVERSIZE : "); for(i=0;i<1;i++){ rt_printk("0x%02X ", new_skb->buf_start[i+16]); }
			rt_printk("\nPRIORITY: "); for(i=0;i<1;i++){ rt_printk("0x%02X ", new_skb->buf_start[i+17]); }
			rt_printk("\nLENGTH  : "); for(i=0;i<2;i++){ rt_printk("0x%02X ", new_skb->buf_start[i+18]); }
			rt_printk("\nIDENT   : "); for(i=0;i<2;i++){ rt_printk("0x%02X ", new_skb->buf_start[i+20]); }
			rt_printk("\nFRAGMENT: "); for(i=0;i<2;i++){ rt_printk("0x%02X ", new_skb->buf_start[i+22]); }
			rt_printk("\nTTL     : "); for(i=0;i<1;i++){ rt_printk("0x%02X ", new_skb->buf_start[i+24]); }
			rt_printk("\nPROTOCOL: "); for(i=0;i<1;i++){ rt_printk("0x%02X ", new_skb->buf_start[i+25]); }
			rt_printk("\nCHECKSUM: "); for(i=0;i<2;i++){ rt_printk("0x%02X ", new_skb->buf_start[i+26]); }
			rt_printk("\nIP ORIGE: "); for(i=0;i<4;i++){ rt_printk("0x%02X ", new_skb->buf_start[i+28]); }
			rt_printk("\nIP DESTI: "); for(i=0;i<4;i++){ rt_printk("0x%02X ", new_skb->buf_start[i+32]); }
		
			cuantos = (int)(*(unsigned short *)(new_skb->buf_start+18)) - 20;
			rt_printk("\n\nDATA (%d):", cuantos);  
			rt_printk("\n:");  		   for(i=0;i<cuantos;i++){ rt_printk("0x%02X ", new_skb->buf_start[i+36]); }		
		}
#endif

		rtnetif_rx(new_skb);
		rt_mark_stack_mgr(rtdev);
	}
	
rt_loopback_xmit_end:
	kfree_rtskb(skb);
	return err;
}