/*** * 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; }
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, ®); 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; }
/* 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; }
/*** * 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; }