示例#1
0
static irqreturn_t __s3c4510b_tx_int(int irq, void *dev_id, struct pt_regs *regs)
{
	struct net_device *dev = (struct net_device *) dev_id;
	struct eth_priv *priv = (struct eth_priv *) dev->priv;
	volatile TX_FrameDesc *pTxFD;
	volatile TX_FrameDesc *cTxFD;

	spin_lock(&priv->lock);

	pTxFD = priv->m_oldTX_FD;
	cTxFD = (TX_FrameDesc *)inl(REG_BDMATXPTR);

	while ( pTxFD != cTxFD) {

		if ( likely(pTxFD->m_status.bf.complete)) {
			priv->stats.tx_packets++;
		}
		if( pTxFD->m_status.bf.exColl) {
			_EPRINTK("TX collision detected");
			priv->stats.tx_errors++;
			priv->stats.collisions++;
		}
		if( pTxFD->m_status.bf.underRun) {
			_EPRINTK("TX Underrun detected");
			priv->stats.tx_errors++;
			priv->stats.tx_fifo_errors++;
		}
		if( pTxFD->m_status.bf.noCarrier) {
			_EPRINTK("TX no carrier detected");
			priv->stats.tx_errors++;
			priv->stats.tx_carrier_errors++;
		}
		if(  pTxFD->m_status.bf.lateColl) {
			_EPRINTK("TX late collision detected");
			priv->stats.tx_errors++;
			priv->stats.tx_window_errors++;
		}
		if(  pTxFD->m_status.bf.parityErr) {
			_EPRINTK("TX parity error detected");
			priv->stats.tx_errors++;
			priv->stats.tx_aborted_errors++;
		}

		dev_kfree_skb_irq( pTxFD->skb);
		pTxFD = pTxFD->m_nextFD;
	}

	priv->m_oldTX_FD = pTxFD;

	LED_CLR(3);

	spin_unlock(&priv->lock);

	return IRQ_HANDLED;

}
示例#2
0
uint8_t wibo_run(void)
{
	uint8_t isLeave=0;
	uint8_t isStay=0;
	unsigned long timeout = WIBO_TIMEOUT;
	
	while(!isLeave) {
#if !defined(NO_LEDS)
		LED_CLR(PROGLED);
#endif
		if (!(isStay))
		{
			while(!(wibo_available()) && (timeout--))  _delay_ms(1);	// minimum frame time @ 250kbps ~ 2ms.
		
			if (!(wibo_available()))	// no packets received, bye bye!
			{
				isLeave=1;
				return isLeave;
			}			
		}
		else
		{
			while(!(wibo_available()));	// wait for next packet
		}

		trx_reg_write(RG_IRQ_STATUS, TRX_IRQ_RX_END); /* clear the flag */

		trx_frame_read(rxbuf.data, sizeof(rxbuf.data) / sizeof(rxbuf.data[0]),
				&tmp); /* dont use LQI, write into tmp variable */

#if !defined(NO_LEDS)
		LED_SET(PROGLED);
		/* light as long as actions are running */
#endif

		switch (rxbuf.hdr.cmd)
		{

		case P2P_PING_REQ:
			isStay=1;
			if (0 == deaf)
			{
				pingrep.hdr.dst = rxbuf.hdr.src;
				pingrep.hdr.seq++;
				pingrep.crc = datacrc;

				trx_reg_write(RG_TRX_STATE, CMD_TX_ARET_ON);

				/* no need to make block atomic since no IRQs are used */
				TRX_SLPTR_HIGH()
				;
				TRX_SLPTR_LOW()
				;
				trx_frame_write(sizeof(p2p_ping_cnf_t) + sizeof(BOARD_NAME) + 2,
						(uint8_t*) &pingrep);
				/*******************************************************/

#if defined(_DEBUG_SERIAL_)
				printf("Pinged by 0x%04X"EOL, rxbuf.hdr.src);
#endif

#if defined(TRX_IF_RFA1)
				while (!(trx_reg_read(RG_IRQ_STATUS) & TRX_IRQ_TX_END))
					;
				trx_reg_write(RG_IRQ_STATUS, TRX_IRQ_TX_END); /* clear the flag */
#else
				while (!(trx_reg_read(RG_IRQ_STATUS) & TRX_IRQ_TRX_END))
				;
#endif /* defined(TRX_IF_RFA1) */
				trx_reg_write(RG_TRX_STATE, CMD_RX_AACK_ON);
			} /* (0 == deaf) */
			break;

		case P2P_WIBO_TARGET:
			isStay=1;
			target = rxbuf.wibo_target.targmem;
#if defined(_DEBUG_SERIAL_)
			printf("Set Target to %c"EOL, target);
#endif
			break;

		case P2P_WIBO_RESET:
			isStay=1;
#if defined(_DEBUG_SERIAL_)
			printf("Reset"EOL);
#endif

			addr = SPM_PAGESIZE; /* misuse as counter */
			ptr = pagebuf;
			do
			{
				*ptr++ = 0xFF;
			} while (--addr);

			addr = 0;
			datacrc = 0;
			pagebufidx = 0;
			deaf = 0;
			break;

		case P2P_WIBO_ADDR:
			isStay=1;
#if defined(_DEBUG_SERIAL_)
			printf("Set address: 0x%08lX"EOL, rxbuf.wibo_addr.address);
#endif
			addr = rxbuf.wibo_addr.address;
			pagebufidx = 0;
			break;

		case P2P_WIBO_DATA:
			isStay=1;
#if defined(_DEBUG_SERIAL_)
			printf("Data[%d]", rxbuf.wibo_data.dsize);
			uint8_t len = rxbuf.wibo_data.dsize;
			if (len > 10) len = 10;
			for(uint8_t j=0;j<len;j++)
			{
				printf(" %02X", rxbuf.wibo_data.data[j]);
			}
			if (len != rxbuf.wibo_data.dsize)
				printf("...");
			printf(EOL);
#endif
			tmp = rxbuf.wibo_data.dsize;
			ptr = rxbuf.wibo_data.data;
			do
			{
				datacrc = _crc_ccitt_update(datacrc, *ptr);
				pagebuf[pagebufidx++] = *ptr;
				if (pagebufidx >= PAGEBUFSIZE)
				{
					/* LED off to save current and avoid flash corruption
					 *  because of possible voltage drops
					 */
#if !defined(NO_LEDS)
					LED_CLR(PROGLED);
#endif

					if (target == 'F') /* Flash memory */
					{
						boot_program_page(addr, pagebuf);
					}
					else if (target == 'E')
					{
						/* not implemented */
					}
					else
					{
						/* unknown target, dry run */
					}

					/* also for dry run! */
					addr += SPM_PAGESIZE;
					pagebufidx = 0;
				}
				ptr++;
			} while (--tmp);
			break;
#if defined(WIBO_FLAVOUR_BOOTLUP)
		case P2P_WIBO_BOOTLUP:
			isStay=1;
			bootlup();
		break;
#endif

		case P2P_WIBO_FINISH:
			isStay=1;
#if defined(_DEBUG_SERIAL_)
			printf("Finish"EOL);
#endif
			if (target == 'F') /* Flash memory */
			{
				boot_program_page(addr, pagebuf);
			}
			else if (target == 'E')
			{
				/* not implemented */
			}
			else
			{
				/* unknown target, dry run */
			}

			/* also for dry run! */
			addr += SPM_PAGESIZE;
			pagebufidx = 0;

			break;

		case P2P_WIBO_EXIT:
#if defined(_DEBUG_SERIAL_)
			printf("Exit"EOL);
#endif
#if !defined(NO_LEDS)
			LED_CLR(PROGLED);
#endif
			isLeave=1;
			break;

		case P2P_WIBO_DEAF:
			isStay=1;
			deaf = 1;
			break;
		default:
			/* unknown or unhandled command */
			if (!(isStay)) {
				if (!(timeout--)) {
					isLeave = 1;
				}
			}
			break;
		}; /* switch (rxbuf.hdr.cmd) */
	}

	return isLeave;
}
示例#3
0
static irqreturn_t __s3c4510b_rx_int(int irq, void *dev_id, struct pt_regs *regs)
{
	struct sk_buff          *skb;
	struct net_device       *dev = (struct net_device *) dev_id;
	struct eth_priv        *priv = (struct eth_priv *) dev->priv;
	volatile RX_FrameDesc *pRxFD;
	volatile RX_FrameDesc *cRxFD;

	spin_lock(&priv->lock);

	LED_SET(4);

	pRxFD = priv->m_curRX_FD;
	cRxFD = (RX_FrameDesc *)inl(REG_BDMARXPTR);

	/* clear received frame bit */
	outl( ETH_S_BRxRDF, REG_BDMASTAT);

	do {
		if ( likely( pRxFD->m_status.bf.good)) {
			skb = pRxFD->skb;

			__skb_prepare( dev, pRxFD);

			/* reserve two words used by protocol layers */
			skb_reserve(skb, 2);
			skb_put(skb, pRxFD->m_status.bf.len);
			skb->protocol = eth_type_trans(skb, dev);
			priv->stats.rx_packets++;
			priv->stats.rx_bytes += pRxFD->m_status.bf.len;
			netif_rx(skb);
		}
		else {
			priv->stats.rx_errors++;
			if( pRxFD->m_status.bf.overFlow)
				priv->stats.rx_fifo_errors++;
			if( pRxFD->m_status.bf.overMax)
				priv->stats.rx_length_errors++;
			if( pRxFD->m_status.bf.crcErr)
				priv->stats.rx_crc_errors++;
			if( pRxFD->m_status.bf.longErr)
				priv->stats.rx_length_errors++;
			if( pRxFD->m_status.bf.alignErr)
				priv->stats.rx_frame_errors++;
			/**
			 ** No good category for these errors
			if( pRxFD->m_status.bf.parityErr)
			**/			

		}

		/* set owner back to CPU */
		pRxFD->m_frameDataPtr.bf.owner = 1;
		/* clear status */
		pRxFD->m_status.ui = 0x0;
		/* advance to next descriptor */
		pRxFD = pRxFD->m_nextFD;

	} while ( pRxFD != cRxFD);

	priv->m_curRX_FD = pRxFD;

	LED_CLR(4);

	spin_unlock(&priv->lock);

	return IRQ_HANDLED;

}