static INLINE int mailbox_rx_irq_handler(unsigned int ch) // return: < 0 - descriptor not available, 0 - received one packet { unsigned int ndev = ch; struct sk_buff *skb; struct sk_buff *new_skb; volatile struct rx_descriptor *desc; struct rx_descriptor reg_desc; int netif_rx_ret; desc = &g_ptm_priv_data.itf[ndev].rx_desc[g_ptm_priv_data.itf[ndev].rx_desc_pos]; if ( desc->own || !desc->c ) // if PP32 hold descriptor or descriptor not completed return -EAGAIN; if ( ++g_ptm_priv_data.itf[ndev].rx_desc_pos == dma_rx_descriptor_length ) g_ptm_priv_data.itf[ndev].rx_desc_pos = 0; reg_desc = *desc; skb = get_skb_rx_pointer(reg_desc.dataptr); if ( !reg_desc.err ) { new_skb = alloc_skb_rx(); if ( new_skb != NULL ) { skb_reserve(skb, reg_desc.byteoff); skb_put(skb, reg_desc.datalen); dump_skb(skb, DUMP_SKB_LEN, (char *)__func__, ndev, ndev, 0); // parse protocol header skb->dev = g_net_dev[ndev]; skb->protocol = eth_type_trans(skb, skb->dev); g_net_dev[ndev]->last_rx = jiffies; netif_rx_ret = netif_receive_skb(skb); if ( netif_rx_ret != NET_RX_DROP ) { g_ptm_priv_data.itf[ndev].stats.rx_packets++; g_ptm_priv_data.itf[ndev].stats.rx_bytes += reg_desc.datalen; } reg_desc.dataptr = ((unsigned int)new_skb->data >> 2) & 0x0FFFFFFF; reg_desc.byteoff = RX_HEAD_MAC_ADDR_ALIGNMENT; }
void zc_handle(unsigned char *user, const struct pcap_pkthdr *h, const unsigned char *bytes) { struct ether_header *eth; struct iphdr *iph; struct tcphdr *th; const unsigned char *p = bytes; __u16 sport, dport; eth = (struct ether_header*)p; g_count ++; dump_skb("test", bytes, h->caplen); printf("\npacket:%d, snaplen:%d\n", g_count, h->caplen); #if 1 if (eth->ether_type == ntohs(ETHERTYPE_IP)){ iph = (struct iphdr *)(eth + 1); sport = ((__u16 *)(((void *)iph) + (iph->ihl<<2)))[0]; dport = ((__u16 *)(((void *)iph) + (iph->ihl<<2)))[1]; printf("packet length: %d %u.%u.%u.%u -> %u.%u.%u.%u, protocal: l3 %x, l4 %u\n", h->len, NIPQUAD(iph->saddr), NIPQUAD(iph->daddr), ntohs(eth->ether_type), iph->protocol); printf("==================================================================\n"); if(iph->protocol == IPPROTO_TCP) { //printf(" port %u -> %u", ntohs(sport), ntohs(dport)); th = (struct tcphdr *)(((void *)iph) + (iph->ihl<<2)); //printf("seq: %u, ack: %u, ", ntohl(th->seq), ntohl(th->ack_seq)); } if(iph->protocol == IPPROTO_UDP) { //printf(" port %u -> %u", ntohs(sport), ntohs(dport)); } } //printf("\n"); #endif return; }
static int ptm_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) { int ndev; unsigned int f_full; int desc_base; register struct tx_descriptor reg_desc = {0}; for ( ndev = 0; ndev < ARRAY_SIZE(g_net_dev) && g_net_dev[ndev] != dev; ndev++ ); ASSERT(ndev >= 0 && ndev < ARRAY_SIZE(g_net_dev), "ndev = %d (wrong value)", ndev); if ( !g_showtime ) { err("not in showtime"); goto PTM_HARD_START_XMIT_FAIL; } /* allocate descriptor */ desc_base = get_tx_desc(ndev, &f_full); if ( f_full ) { dev->trans_start = jiffies; netif_stop_queue(dev); IFX_REG_W32_MASK(0, 1 << (ndev + 16), MBOX_IGU1_ISRC); IFX_REG_W32_MASK(0, 1 << (ndev + 16), MBOX_IGU1_IER); } if ( desc_base < 0 ) goto PTM_HARD_START_XMIT_FAIL; if ( g_ptm_priv_data.itf[ndev].tx_skb[desc_base] != NULL ) dev_kfree_skb_any(g_ptm_priv_data.itf[ndev].tx_skb[desc_base]); g_ptm_priv_data.itf[ndev].tx_skb[desc_base] = skb; reg_desc.dataptr = (unsigned int)skb->data >> 2; reg_desc.datalen = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len; reg_desc.byteoff = (unsigned int)skb->data & (DATA_BUFFER_ALIGNMENT - 1); reg_desc.own = 1; reg_desc.c = 1; reg_desc.sop = reg_desc.eop = 1; /* write discriptor to memory and write back cache */ g_ptm_priv_data.itf[ndev].tx_desc[desc_base] = reg_desc; dma_cache_wback((unsigned long)skb->data, skb->len); wmb(); dump_skb(skb, DUMP_SKB_LEN, (char *)__func__, ndev, ndev, 1); if ( (ifx_ptm_dbg_enable & DBG_ENABLE_MASK_MAC_SWAP) ) { skb_swap(skb); } g_ptm_priv_data.itf[ndev].stats.tx_packets++; g_ptm_priv_data.itf[ndev].stats.tx_bytes += reg_desc.datalen; dev->trans_start = jiffies; mailbox_signal(ndev, 1); adsl_led_flash(); return NETDEV_TX_OK; PTM_HARD_START_XMIT_FAIL: dev_kfree_skb_any(skb); g_ptm_priv_data.itf[ndev].stats.tx_dropped++; return NETDEV_TX_OK; }