Exemplo n.º 1
0
/**
 * Poll for completed packets
 *
 * @v netdev		Network device
 */
static void snpnet_poll_tx ( struct net_device *netdev ) {
    struct snp_nic *snp = netdev->priv;
    struct io_buffer *iobuf;
    UINT32 irq;
    VOID *txbuf;
    EFI_STATUS efirc;
    int rc;

    /* Get status */
    if ( ( efirc = snp->snp->GetStatus ( snp->snp, &irq, &txbuf ) ) != 0 ) {
        rc = -EEFI ( efirc );
        DBGC ( snp, "SNP %s could not get status: %s\n",
               netdev->name, strerror ( rc ) );
        netdev_rx_err ( netdev, NULL, rc );
        return;
    }

    /* Do nothing unless we have a completion */
    if ( ! txbuf )
        return;

    /* Sanity check */
    if ( ! snp->txbuf ) {
        DBGC ( snp, "SNP %s reported spurious TX completion\n",
               netdev->name );
        netdev_tx_err ( netdev, NULL, -EPIPE );
        return;
    }

    /* Complete transmission */
    iobuf = snp->txbuf;
    snp->txbuf = NULL;
    netdev_tx_complete ( netdev, iobuf );
}
Exemplo n.º 2
0
/**
 * Poll for completed and received packets
 *
 * @v netdev		Network device
 */
static void intelx_poll ( struct net_device *netdev ) {
	struct intel_nic *intel = netdev->priv;
	uint32_t eicr;

	/* Check for and acknowledge interrupts */
	eicr = readl ( intel->regs + INTELX_EICR );
	if ( ! eicr )
		return;

	/* Poll for TX completions, if applicable */
	if ( eicr & INTELX_EIRQ_TX0 )
		intel_poll_tx ( netdev );

	/* Poll for RX completions, if applicable */
	if ( eicr & ( INTELX_EIRQ_RX0 | INTELX_EIRQ_RXO ) )
		intel_poll_rx ( netdev );

	/* Report receive overruns */
	if ( eicr & INTELX_EIRQ_RXO )
		netdev_rx_err ( netdev, NULL, -ENOBUFS );

	/* Check link state, if applicable */
	if ( eicr & INTELX_EIRQ_LSC )
		intelx_check_link ( netdev );

	/* Refill RX ring */
	intel_refill_rx ( intel );
}
Exemplo n.º 3
0
/**
 * Poll for completed and received packets
 *
 * @v netdev		Network device
 */
static void intelxvf_poll ( struct net_device *netdev ) {
	struct intel_nic *intel = netdev->priv;
	uint32_t eicr;
	int rc;

	/* Check for and acknowledge interrupts */
	eicr = readl ( intel->regs + INTELXVF_EICR );
	if ( ! eicr )
		return;

	/* Poll for TX completions, if applicable */
	if ( eicr & INTELXVF_EIRQ_TX0 )
		intel_poll_tx ( netdev );

	/* Poll for RX completions, if applicable */
	if ( eicr & INTELXVF_EIRQ_RX0 )
		intel_poll_rx ( netdev );

	/* Poll for mailbox messages, if applicable */
	if ( eicr & INTELXVF_EIRQ_MBOX ) {

		/* Poll mailbox */
		if ( ( rc = intelvf_mbox_poll ( intel ) ) != 0 ) {
			DBGC ( intel, "INTEL %p mailbox poll failed!\n",
			       intel );
			netdev_rx_err ( netdev, NULL, rc );
		}

		/* Update link state */
		intelxvf_check_link ( netdev );
	}

	/* Refill RX ring */
	intel_refill_rx ( intel );
}
Exemplo n.º 4
0
/**
 * Complete bulk IN transfer
 *
 * @v ep		USB endpoint
 * @v iobuf		I/O buffer
 * @v rc		Completion status code
 */
static void smsc95xx_in_complete ( struct usb_endpoint *ep,
				   struct io_buffer *iobuf, int rc ) {
	struct smsc95xx_device *smsc95xx =
		container_of ( ep, struct smsc95xx_device, usbnet.in );
	struct net_device *netdev = smsc95xx->netdev;
	struct smsc95xx_rx_header *header;

	/* Profile completions */
	profile_start ( &smsc95xx_in_profiler );

	/* Ignore packets cancelled when the endpoint closes */
	if ( ! ep->open ) {
		free_iob ( iobuf );
		return;
	}

	/* Record USB errors against the network device */
	if ( rc != 0 ) {
		DBGC ( smsc95xx, "SMSC95XX %p bulk IN failed: %s\n",
		       smsc95xx, strerror ( rc ) );
		goto err;
	}

	/* Sanity check */
	if ( iob_len ( iobuf ) < ( sizeof ( *header ) + 4 /* CRC */ ) ) {
		DBGC ( smsc95xx, "SMSC95XX %p underlength bulk IN\n",
		       smsc95xx );
		DBGC_HDA ( smsc95xx, 0, iobuf->data, iob_len ( iobuf ) );
		rc = -EINVAL;
		goto err;
	}

	/* Strip header and CRC */
	header = iobuf->data;
	iob_pull ( iobuf, sizeof ( *header ) );
	iob_unput ( iobuf, 4 /* CRC */ );

	/* Check for errors */
	if ( header->command & cpu_to_le32 ( SMSC95XX_RX_RUNT |
					     SMSC95XX_RX_LATE |
					     SMSC95XX_RX_CRC ) ) {
		DBGC ( smsc95xx, "SMSC95XX %p receive error (%08x):\n",
		       smsc95xx, le32_to_cpu ( header->command ) );
		DBGC_HDA ( smsc95xx, 0, iobuf->data, iob_len ( iobuf ) );
		rc = -EIO;
		goto err;
	}

	/* Hand off to network stack */
	netdev_rx ( netdev, iob_disown ( iobuf ) );

	profile_stop ( &smsc95xx_in_profiler );
	return;

 err:
	/* Hand off to network stack */
	netdev_rx_err ( netdev, iob_disown ( iobuf ), rc );
}
Exemplo n.º 5
0
/**
 * Poll for completed and received packets
 *
 * @v netdev		Network device
 */
static void smsc95xx_poll ( struct net_device *netdev ) {
	struct smsc95xx_device *smsc95xx = netdev->priv;
	uint32_t int_sts;
	int rc;

	/* Poll USB bus */
	usb_poll ( smsc95xx->bus );

	/* Refill endpoints */
	if ( ( rc = usbnet_refill ( &smsc95xx->usbnet ) ) != 0 )
		netdev_rx_err ( netdev, NULL, rc );

	/* Do nothing more unless there are interrupts to handle */
	int_sts = smsc95xx->int_sts;
	if ( ! int_sts )
		return;

	/* Check link status if applicable */
	if ( int_sts & SMSC95XX_INT_STS_PHY_INT ) {
		smsc95xx_check_link ( smsc95xx );
		int_sts &= ~SMSC95XX_INT_STS_PHY_INT;
	}

	/* Record RX FIFO overflow if applicable */
	if ( int_sts & SMSC95XX_INT_STS_RXDF_INT ) {
		DBGC2 ( smsc95xx, "SMSC95XX %p RX FIFO overflowed\n",
			smsc95xx );
		netdev_rx_err ( netdev, NULL, -ENOBUFS );
		int_sts &= ~SMSC95XX_INT_STS_RXDF_INT;
	}

	/* Check for unexpected interrupts */
	if ( int_sts ) {
		DBGC ( smsc95xx, "SMSC95XX %p unexpected interrupt %#08x\n",
		       smsc95xx, int_sts );
		netdev_rx_err ( netdev, NULL, -ENOTTY );
	}

	/* Clear interrupts */
	if ( ( rc = smsc95xx_writel ( smsc95xx, SMSC95XX_INT_STS,
				      smsc95xx->int_sts ) ) != 0 )
		netdev_rx_err ( netdev, NULL, rc );
	smsc95xx->int_sts = 0;
}
Exemplo n.º 6
0
/**
 * e1000_process_rx_packets - process received packets
 *
 * @v netdev	network interface device structure
 **/
static void e1000e_process_rx_packets ( struct net_device *netdev )
{
	struct e1000_adapter *adapter = netdev_priv ( netdev );
	uint32_t i;
	uint32_t rx_status;
	uint32_t rx_len;
	uint32_t rx_err;
	struct e1000_rx_desc *rx_curr_desc;

	/* Process received packets
	 */
	while ( 1 ) {

		i = adapter->rx_curr;

		rx_curr_desc = ( void * )  ( adapter->rx_base ) +
				  ( i * sizeof ( *adapter->rx_base ) );
		rx_status = rx_curr_desc->status;

		DBG2 ( "Before DD Check RX_status: %#08x\n", rx_status );

		if ( ! ( rx_status & E1000_RXD_STAT_DD ) )
			break;

		if ( adapter->rx_iobuf[i] == NULL )
			break;

		DBG ( "E1000_RCTL = %#08x\n", E1000_READ_REG ( &adapter->hw, E1000_RCTL ) );

		rx_len = rx_curr_desc->length;

		DBG ( "Received packet, rx_curr: %d  rx_status: %#08x  rx_len: %d\n",
		      i, rx_status, rx_len );

		rx_err = rx_curr_desc->errors;

		iob_put ( adapter->rx_iobuf[i], rx_len );

		if ( rx_err & E1000_RXD_ERR_FRAME_ERR_MASK ) {

			netdev_rx_err ( netdev, adapter->rx_iobuf[i], -EINVAL );
			DBG ( "e1000_poll: Corrupted packet received!"
			      " rx_err: %#08x\n", rx_err );
		} else	{
			/* Add this packet to the receive queue. */
			netdev_rx ( netdev, adapter->rx_iobuf[i] );
		}
		adapter->rx_iobuf[i] = NULL;

		memset ( rx_curr_desc, 0, sizeof ( *rx_curr_desc ) );

		adapter->rx_curr = ( adapter->rx_curr + 1 ) % NUM_RX_DESC;
	}
}
Exemplo n.º 7
0
/**
 * Poll for completed and received packets
 *
 * @v netdev		Network device
 */
static void dm96xx_poll ( struct net_device *netdev ) {
	struct dm96xx_device *dm96xx = netdev->priv;
	int rc;

	/* Poll USB bus */
	usb_poll ( dm96xx->bus );

	/* Refill endpoints */
	if ( ( rc = usbnet_refill ( &dm96xx->usbnet ) ) != 0 )
		netdev_rx_err ( netdev, NULL, rc );
}
Exemplo n.º 8
0
/**
 * Complete interrupt transfer
 *
 * @v ep		USB endpoint
 * @v iobuf		I/O buffer
 * @v rc		Completion status code
 */
static void smsc95xx_intr_complete ( struct usb_endpoint *ep,
				     struct io_buffer *iobuf, int rc ) {
	struct smsc95xx_device *smsc95xx =
		container_of ( ep, struct smsc95xx_device, usbnet.intr );
	struct net_device *netdev = smsc95xx->netdev;
	struct smsc95xx_interrupt *intr;

	/* Profile completions */
	profile_start ( &smsc95xx_intr_profiler );

	/* Ignore packets cancelled when the endpoint closes */
	if ( ! ep->open )
		goto done;

	/* Record USB errors against the network device */
	if ( rc != 0 ) {
		DBGC ( smsc95xx, "SMSC95XX %p interrupt failed: %s\n",
		       smsc95xx, strerror ( rc ) );
		DBGC_HDA ( smsc95xx, 0, iobuf->data, iob_len ( iobuf ) );
		netdev_rx_err ( netdev, NULL, rc );
		goto done;
	}

	/* Extract interrupt data */
	if ( iob_len ( iobuf ) != sizeof ( *intr ) ) {
		DBGC ( smsc95xx, "SMSC95XX %p malformed interrupt\n",
		       smsc95xx );
		DBGC_HDA ( smsc95xx, 0, iobuf->data, iob_len ( iobuf ) );
		netdev_rx_err ( netdev, NULL, rc );
		goto done;
	}
	intr = iobuf->data;

	/* Record interrupt status */
	smsc95xx->int_sts = le32_to_cpu ( intr->int_sts );
	profile_stop ( &smsc95xx_intr_profiler );

 done:
	/* Free I/O buffer */
	free_iob ( iobuf );
}
Exemplo n.º 9
0
static void b44_process_rx_packets(struct b44_private *bp)
{
	struct io_buffer *iob;	/* received data */
	struct rx_header *rh;
	u32 pending, i;
	u16 len;

	pending = pending_rx_index(bp);

	for (i = bp->rx_cur; i != pending; i = ring_next(i)) {
		iob = bp->rx_iobuf[i];
		if (iob == NULL)
			break;

		rh = iob->data;
		len = le16_to_cpu(rh->len);

		/*
		 * Guard against incompletely written RX descriptors.
		 * Without this, things can get really slow!
		 */
		if (len == 0)
			break;

		/* Discard CRC that is generated by the card */
		len -= 4;

		/* Check for invalid packets and errors */
		if (len > RX_PKT_BUF_SZ - RX_PKT_OFFSET ||
		    (rh->flags & cpu_to_le16(RX_FLAG_ERRORS))) {
			DBG("rx error len=%d flags=%04x\n", len,
			                 cpu_to_le16(rh->flags));
			rh->len = 0;
			rh->flags = 0;
			netdev_rx_err(bp->netdev, iob, -EINVAL);
			continue;
		}

		/* Clear RX descriptor */
		rh->len = 0;
		rh->flags = 0;
		bp->rx_iobuf[i] = NULL;

		/* Hand off the IO buffer to the network stack */
		iob_reserve(iob, RX_PKT_OFFSET);
		iob_put(iob, len);
		netdev_rx(bp->netdev, iob);
	}
	bp->rx_cur = i;
	b44_rx_refill(bp, pending_rx_index(bp));
}
Exemplo n.º 10
0
/**
 * Complete bulk IN transfer
 *
 * @v ep		USB endpoint
 * @v iobuf		I/O buffer
 * @v rc		Completion status code
 */
static void dm96xx_in_complete ( struct usb_endpoint *ep,
				 struct io_buffer *iobuf, int rc ) {
	struct dm96xx_device *dm96xx = container_of ( ep, struct dm96xx_device,
						      usbnet.in );
	struct net_device *netdev = dm96xx->netdev;
	struct dm96xx_rx_header *header;

	/* Ignore packets cancelled when the endpoint closes */
	if ( ! ep->open ) {
		free_iob ( iobuf );
		return;
	}

	/* Record USB errors against the network device */
	if ( rc != 0 ) {
		DBGC ( dm96xx, "DM96XX %p bulk IN failed: %s\n",
		       dm96xx, strerror ( rc ) );
		goto err;
	}

	/* Sanity check */
	if ( iob_len ( iobuf ) < ( sizeof ( *header ) + 4 /* CRC */ ) ) {
		DBGC ( dm96xx, "DM96XX %p underlength bulk IN\n", dm96xx );
		DBGC_HDA ( dm96xx, 0, iobuf->data, iob_len ( iobuf ) );
		rc = -EINVAL;
		goto err;
	}

	/* Strip header and CRC */
	header = iobuf->data;
	iob_pull ( iobuf, sizeof ( *header ) );
	iob_unput ( iobuf, 4 /* CRC */ );

	/* Check status */
	if ( header->rsr & ~DM96XX_RSR_MF ) {
		DBGC ( dm96xx, "DM96XX %p receive error %02x:\n",
		       dm96xx, header->rsr );
		DBGC_HDA ( dm96xx, 0, iobuf->data, iob_len ( iobuf ) );
		rc = -EIO;
		goto err;
	}

	/* Hand off to network stack */
	netdev_rx ( netdev, iob_disown ( iobuf ) );
	return;

 err:
	/* Hand off to network stack */
	netdev_rx_err ( netdev, iob_disown ( iobuf ), rc );
}
Exemplo n.º 11
0
Arquivo: nii.c Projeto: baloo/ipxe
/**
 * Poll for received packets
 *
 * @v netdev		Network device
 */
static void nii_poll_rx ( struct net_device *netdev ) {
	struct nii_nic *nii = netdev->priv;
	PXE_CPB_RECEIVE cpb;
	PXE_DB_RECEIVE db;
	unsigned int quota;
	int stat;
	int rc;

	/* Retrieve up to NII_RX_QUOTA packets */
	for ( quota = NII_RX_QUOTA ; quota ; quota-- ) {

		/* Allocate buffer, if required */
		if ( ! nii->rxbuf ) {
			nii->rxbuf = alloc_iob ( nii->mtu );
			if ( ! nii->rxbuf ) {
				/* Leave for next poll */
				break;
			}
		}

		/* Construct parameter block */
		memset ( &cpb, 0, sizeof ( cpb ) );
		cpb.BufferAddr = virt_to_bus ( nii->rxbuf->data );
		cpb.BufferLen = iob_tailroom ( nii->rxbuf );

		/* Issue command */
		if ( ( stat = nii_issue_cpb_db ( nii, PXE_OPCODE_RECEIVE,
						 &cpb, sizeof ( cpb ),
						 &db, sizeof ( db ) ) ) < 0 ) {

			/* PXE_STATCODE_NO_DATA is just the usual "no packet"
			 * status indicator; ignore it.
			 */
			if ( stat == -PXE_STATCODE_NO_DATA )
				break;

			/* Anything else is an error */
			rc = -EIO_STAT ( stat );
			DBGC ( nii, "NII %s could not receive: %s\n",
			       nii->dev.name, strerror ( rc ) );
			netdev_rx_err ( netdev, NULL, rc );
			break;
		}

		/* Hand off to network stack */
		iob_put ( nii->rxbuf, db.FrameLen );
		netdev_rx ( netdev, nii->rxbuf );
		nii->rxbuf = NULL;
	}
}
Exemplo n.º 12
0
/**
 * Complete interrupt transfer
 *
 * @v ep		USB endpoint
 * @v iobuf		I/O buffer
 * @v rc		Completion status code
 */
static void dm96xx_intr_complete ( struct usb_endpoint *ep,
				   struct io_buffer *iobuf, int rc ) {
	struct dm96xx_device *dm96xx = container_of ( ep, struct dm96xx_device,
						      usbnet.intr );
	struct net_device *netdev = dm96xx->netdev;
	struct dm96xx_interrupt *intr;
	size_t len = iob_len ( iobuf );

	/* Ignore packets cancelled when the endpoint closes */
	if ( ! ep->open )
		goto done;

	/* Record USB errors against the network device */
	if ( rc != 0 ) {
		DBGC ( dm96xx, "DM96XX %p interrupt failed: %s\n",
		       dm96xx, strerror ( rc ) );
		DBGC_HDA ( dm96xx, 0, iobuf->data, iob_len ( iobuf ) );
		netdev_rx_err ( netdev, NULL, rc );
		goto done;
	}

	/* Extract message header */
	if ( len < sizeof ( *intr ) ) {
		DBGC ( dm96xx, "DM96XX %p underlength interrupt:\n", dm96xx );
		DBGC_HDA ( dm96xx, 0, iobuf->data, iob_len ( iobuf ) );
		netdev_rx_err ( netdev, NULL, -EINVAL );
		goto done;
	}
	intr = iobuf->data;

	/* Update link status */
	dm96xx_link_nsr ( dm96xx, intr->nsr );

 done:
	/* Free I/O buffer */
	free_iob ( iobuf );
}
Exemplo n.º 13
0
/**
 * Refill receive descriptor ring
 *
 * @v netdev		Network device
 */
static void myson_refill_rx ( struct net_device *netdev ) {
	struct myson_nic *myson = netdev->priv;
	struct myson_descriptor *rx;
	struct io_buffer *iobuf;
	unsigned int rx_idx;
	physaddr_t address;

	while ( ( myson->rx.prod - myson->rx.cons ) < MYSON_NUM_RX_DESC ) {

		/* Allocate I/O buffer */
		iobuf = alloc_iob ( MYSON_RX_MAX_LEN );
		if ( ! iobuf ) {
			/* Wait for next refill */
			return;
		}

		/* Check address is usable by card */
		address = virt_to_bus ( iobuf->data );
		if ( ! myson_address_ok ( address ) ) {
			DBGC ( myson, "MYSON %p cannot support 64-bit RX "
			       "buffer address\n", myson );
			netdev_rx_err ( netdev, iobuf, -ENOTSUP );
			return;
		}

		/* Get next receive descriptor */
		rx_idx = ( myson->rx.prod++ % MYSON_NUM_RX_DESC );
		rx = &myson->rx.desc[rx_idx];

		/* Populate receive descriptor */
		rx->address = cpu_to_le32 ( address );
		rx->control =
			cpu_to_le32 ( MYSON_RX_CTRL_RBS ( MYSON_RX_MAX_LEN ) );
		wmb();
		rx->status = cpu_to_le32 ( MYSON_RX_STAT_OWN );
		wmb();

		/* Record I/O buffer */
		assert ( myson->rx_iobuf[rx_idx] == NULL );
		myson->rx_iobuf[rx_idx] = iobuf;

		/* Notify card that there are descriptors available */
		writel ( 0, myson->regs + MYSON_RXPDR );

		DBGC2 ( myson, "MYSON %p RX %d is [%llx,%llx)\n", myson,
			rx_idx, ( ( unsigned long long ) address ),
			( ( unsigned long long ) address + MYSON_RX_MAX_LEN ) );
	}
}
Exemplo n.º 14
0
Arquivo: rhine.c Projeto: 42wim/ipxe
/**
 * Poll for completed and received packets
 *
 * @v netdev		Network device
 */
static void rhine_poll ( struct net_device *netdev ) {
	struct rhine_nic *rhn = netdev->priv;
	uint8_t isr0;
	uint8_t isr1;

	/* Read and acknowledge interrupts */
	isr0 = readb ( rhn->regs + RHINE_ISR0 );
	isr1 = readb ( rhn->regs + RHINE_ISR1 );
	if ( isr0 )
		writeb ( isr0, rhn->regs + RHINE_ISR0 );
	if ( isr1 )
		writeb ( isr1, rhn->regs + RHINE_ISR1 );

	/* Report unexpected errors */
	if ( ( isr0 & ( RHINE_ISR0_MIBOVFL | RHINE_ISR0_PCIERR |
			RHINE_ISR0_RXRINGERR | RHINE_ISR0_TXRINGERR ) ) ||
	     ( isr1 & ( RHINE_ISR1_GPI | RHINE_ISR1_TXABORT |
			RHINE_ISR1_RXFIFOOVFL | RHINE_ISR1_RXFIFOUNFL |
			RHINE_ISR1_TXFIFOUNFL ) ) ) {
		DBGC ( rhn, "RHINE %p unexpected ISR0 %02x ISR1 %02x\n",
		       rhn, isr0, isr1 );
		/* Report as a TX error */
		netdev_tx_err ( netdev, NULL, -EIO );
	}

	/* Poll for TX completions, if applicable */
	if ( isr0 & ( RHINE_ISR0_TXDONE | RHINE_ISR0_TXERR ) )
		rhine_poll_tx ( netdev );

	/* Poll for RX completions, if applicable */
	if ( isr0 & ( RHINE_ISR0_RXDONE | RHINE_ISR0_RXERR ) )
		rhine_poll_rx ( netdev );

	/* Handle RX buffer exhaustion */
	if ( isr1 & RHINE_ISR1_RXNOBUF ) {
		rhine_poll_rx ( netdev );
		netdev_rx_err ( netdev, NULL, -ENOBUFS );
	}

	/* Check link state, if applicable */
	if ( isr1 & RHINE_ISR1_PORTSTATE )
		rhine_check_link ( netdev );

	/* Refill RX ring */
	rhine_refill_rx ( rhn );
}
Exemplo n.º 15
0
/**
 * Poll for received packets
 *
 * @v netdev		Network device
 */
static void snpnet_poll_rx ( struct net_device *netdev ) {
    struct snp_nic *snp = netdev->priv;
    UINTN len;
    unsigned int quota;
    EFI_STATUS efirc;
    int rc;

    /* Retrieve up to SNP_RX_QUOTA packets */
    for ( quota = SNP_RX_QUOTA ; quota ; quota-- ) {

        /* Allocate buffer, if required */
        if ( ! snp->rxbuf ) {
            snp->rxbuf = alloc_iob ( snp->mtu );
            if ( ! snp->rxbuf ) {
                /* Leave for next poll */
                break;
            }
        }

        /* Receive packet */
        len = iob_tailroom ( snp->rxbuf );
        if ( ( efirc = snp->snp->Receive ( snp->snp, NULL, &len,
                                           snp->rxbuf->data, NULL,
                                           NULL, NULL ) ) != 0 ) {

            /* EFI_NOT_READY is just the usual "no packet"
             * status indication; ignore it.
             */
            if ( efirc == EFI_NOT_READY )
                break;

            /* Anything else is an error */
            rc = -EEFI ( efirc );
            DBGC ( snp, "SNP %s could not receive: %s\n",
                   netdev->name, strerror ( rc ) );
            netdev_rx_err ( netdev, NULL, rc );
            break;
        }

        /* Hand off to network stack */
        iob_put ( snp->rxbuf, len );
        netdev_rx ( netdev, snp->rxbuf );
        snp->rxbuf = NULL;
    }
}
Exemplo n.º 16
0
/**
 * Refill receive descriptor ring
 *
 * @v netdev		Network device
 */
static void netfront_refill_rx ( struct net_device *netdev ) {
	struct netfront_nic *netfront = netdev->priv;
	struct xen_device *xendev = netfront->xendev;
	struct io_buffer *iobuf;
	struct netif_rx_request *request;
	int notify;
	int rc;

	/* Do nothing if ring is already full */
	if ( netfront_ring_is_full ( &netfront->rx ) )
		return;

	/* Refill ring */
	do {

		/* Allocate I/O buffer */
		iobuf = alloc_iob ( PAGE_SIZE );
		if ( ! iobuf ) {
			/* Wait for next refill */
			break;
		}

		/* Add to descriptor ring */
		request = RING_GET_REQUEST ( &netfront->rx_fring,
					     netfront->rx_fring.req_prod_pvt );
		if ( ( rc = netfront_push ( netfront, &netfront->rx,
					    iobuf, &request->id,
					    &request->gref ) ) != 0 ) {
			netdev_rx_err ( netdev, iobuf, rc );
			break;
		}
		DBGC2 ( netfront, "NETFRONT %s RX id %d ref %d is %#08lx+%zx\n",
			xendev->key, request->id, request->gref,
			virt_to_phys ( iobuf->data ), iob_tailroom ( iobuf ) );

		/* Move to next descriptor */
		netfront->rx_fring.req_prod_pvt++;

	} while ( ! netfront_ring_is_full ( &netfront->rx ) );

	/* Push new descriptors and notify backend if applicable */
	RING_PUSH_REQUESTS_AND_CHECK_NOTIFY ( &netfront->rx_fring, notify );
	if ( notify )
		netfront_send_event ( netfront );
}
Exemplo n.º 17
0
Arquivo: rhine.c Projeto: 42wim/ipxe
/**
 * Poll for received packets
 *
 * @v netdev		Network device
 */
static void rhine_poll_rx ( struct net_device *netdev ) {
	struct rhine_nic *rhn = netdev->priv;
	struct rhine_descriptor *desc;
	struct io_buffer *iobuf;
	unsigned int rx_idx;
	uint32_t des0;
	size_t len;

	/* Check for received packets */
	while ( rhn->rx.cons != rhn->rx.prod ) {

		/* Get next receive descriptor */
		rx_idx = ( rhn->rx.cons % RHINE_RXDESC_NUM );
		desc = &rhn->rx.desc[rx_idx];

		/* Stop if descriptor is still in use */
		if ( desc->des0 & cpu_to_le32 ( RHINE_DES0_OWN ) )
			return;

		/* Populate I/O buffer */
		iobuf = rhn->rx_iobuf[rx_idx];
		rhn->rx_iobuf[rx_idx] = NULL;
		des0 = le32_to_cpu ( desc->des0 );
		len = ( RHINE_DES0_GETSIZE ( des0 ) - 4 /* strip CRC */ );
		iob_put ( iobuf, len );

		/* Hand off to network stack */
		if ( des0 & RHINE_RDES0_RXOK ) {
			DBGC2 ( rhn, "RHINE %p RX %d complete (length %zd)\n",
				rhn, rx_idx, len );
			netdev_rx ( netdev, iobuf );
		} else {
			DBGC ( rhn, "RHINE %p RX %d error (length %zd, DES0 "
			       "%08x)\n", rhn, rx_idx, len, des0 );
			netdev_rx_err ( netdev, iobuf, -EIO );
		}
		rhn->rx.cons++;
	}
}
Exemplo n.º 18
0
/**
 * Poll for received packets
 *
 * @v netdev		Network device
 */
static void myson_poll_rx ( struct net_device *netdev ) {
	struct myson_nic *myson = netdev->priv;
	struct myson_descriptor *rx;
	struct io_buffer *iobuf;
	unsigned int rx_idx;
	size_t len;

	/* Check for received packets */
	while ( myson->rx.cons != myson->rx.prod ) {

		/* Get next receive descriptor */
		rx_idx = ( myson->rx.cons % MYSON_NUM_RX_DESC );
		rx = &myson->rx.desc[rx_idx];

		/* Stop if descriptor is still in use */
		if ( rx->status & MYSON_RX_STAT_OWN )
			return;

		/* Populate I/O buffer */
		iobuf = myson->rx_iobuf[rx_idx];
		myson->rx_iobuf[rx_idx] = NULL;
		len = MYSON_RX_STAT_FLNG ( le32_to_cpu ( rx->status ) );
		iob_put ( iobuf, len - 4 /* strip CRC */ );

		/* Hand off to network stack */
		if ( rx->status & cpu_to_le32 ( MYSON_RX_STAT_ES ) ) {
			DBGC ( myson, "MYSON %p RX %d error (length %zd, "
			       "status %08x)\n", myson, rx_idx, len,
			       le32_to_cpu ( rx->status ) );
			netdev_rx_err ( netdev, iobuf, -EIO );
		} else {
			DBGC2 ( myson, "MYSON %p RX %d complete (length "
				"%zd)\n", myson, rx_idx, len );
			netdev_rx ( netdev, iobuf );
		}
		myson->rx.cons++;
	}
}
Exemplo n.º 19
0
/**
 * Poll for received packets
 *
 * @v netdev		Network device
 */
static void netfront_poll_rx ( struct net_device *netdev ) {
	struct netfront_nic *netfront = netdev->priv;
	struct xen_device *xendev = netfront->xendev;
	struct netif_rx_response *response;
	struct io_buffer *iobuf;
	int status;
	size_t len;
	int rc;

	/* Consume any unconsumed responses */
	while ( RING_HAS_UNCONSUMED_RESPONSES ( &netfront->rx_fring ) ) {

		/* Get next response */
		response = RING_GET_RESPONSE ( &netfront->rx_fring,
					       netfront->rx_fring.rsp_cons++ );

		/* Retrieve from descriptor ring */
		iobuf = netfront_pull ( netfront, &netfront->rx, response->id );
		status = response->status;
		if ( status >= 0 ) {
			len = status;
			iob_reserve ( iobuf, response->offset );
			iob_put ( iobuf, len );
			DBGC2 ( netfront, "NETFRONT %s RX id %d complete "
				"%#08lx+%zx\n", xendev->key, response->id,
				virt_to_phys ( iobuf->data ), len );
			netdev_rx ( netdev, iobuf );
		} else {
			rc = -EIO_NETIF_RSP ( status );
			DBGC2 ( netfront, "NETFRONT %s RX id %d error %d: %s\n",
				xendev->key, response->id, status,
				strerror ( rc ) );
			netdev_rx_err ( netdev, iobuf, rc );
		}
	}
}
Exemplo n.º 20
0
/** 
 * e1000_poll - Poll for received packets
 *
 * @v netdev	Network device
 */
static void
e1000_poll ( struct net_device *netdev )
{
	struct e1000_adapter *adapter = netdev_priv( netdev );
	struct e1000_hw *hw = &adapter->hw;

	uint32_t icr;
	uint32_t tx_status;
	uint32_t rx_status;
	uint32_t rx_len;
	uint32_t rx_err;
	struct e1000_tx_desc *tx_curr_desc;
	struct e1000_rx_desc *rx_curr_desc;
	uint32_t i;

	DBGP ( "e1000_poll\n" );

	/* Acknowledge interrupts */
	icr = E1000_READ_REG ( hw, ICR );
	if ( ! icr )
		return;
		
        DBG ( "e1000_poll: intr_status = %#08x\n", icr );

	/* Check status of transmitted packets
	 */
	while ( ( i = adapter->tx_head ) != adapter->tx_tail ) {
			
		tx_curr_desc = ( void * )  ( adapter->tx_base ) + 
					   ( i * sizeof ( *adapter->tx_base ) ); 
					    		
		tx_status = tx_curr_desc->upper.data;

		/* if the packet at tx_head is not owned by hardware it is for us */
		if ( ! ( tx_status & E1000_TXD_STAT_DD ) )
			break;
		
		DBG ( "Sent packet. tx_head: %d tx_tail: %d tx_status: %#08x\n",
	    	      adapter->tx_head, adapter->tx_tail, tx_status );

		if ( tx_status & ( E1000_TXD_STAT_EC | E1000_TXD_STAT_LC | 
				   E1000_TXD_STAT_TU ) ) {
			netdev_tx_complete_err ( netdev, adapter->tx_iobuf[i], -EINVAL );
			DBG ( "Error transmitting packet, tx_status: %#08x\n",
			      tx_status );
		} else {
			netdev_tx_complete ( netdev, adapter->tx_iobuf[i] );
			DBG ( "Success transmitting packet, tx_status: %#08x\n",
			      tx_status );
		}

		/* Decrement count of used descriptors, clear this descriptor 
		 */
		adapter->tx_fill_ctr--;
		memset ( tx_curr_desc, 0, sizeof ( *tx_curr_desc ) );
		
		adapter->tx_head = ( adapter->tx_head + 1 ) % NUM_TX_DESC;		
	}
	
	/* Process received packets 
	 */
	while ( 1 ) {
	
		i = adapter->rx_curr;
		
		rx_curr_desc = ( void * )  ( adapter->rx_base ) + 
			          ( i * sizeof ( *adapter->rx_base ) ); 
		rx_status = rx_curr_desc->status;
		
		DBG2 ( "Before DD Check RX_status: %#08x\n", rx_status );
	
		if ( ! ( rx_status & E1000_RXD_STAT_DD ) )
			break;

		if ( adapter->rx_iobuf[i] == NULL )
			break;

		DBG ( "RCTL = %#08x\n", E1000_READ_REG ( &adapter->hw, RCTL ) );
	
		rx_len = rx_curr_desc->length;

                DBG ( "Received packet, rx_curr: %d  rx_status: %#08x  rx_len: %d\n",
                      i, rx_status, rx_len );

                rx_err = rx_curr_desc->errors;

		iob_put ( adapter->rx_iobuf[i], rx_len );

		if ( rx_err & E1000_RXD_ERR_FRAME_ERR_MASK ) {
		
			netdev_rx_err ( netdev, adapter->rx_iobuf[i], -EINVAL );
			DBG ( "e1000_poll: Corrupted packet received!"
			      " rx_err: %#08x\n", rx_err );
		} else 	{
			/* Add this packet to the receive queue. */
			netdev_rx ( netdev, adapter->rx_iobuf[i] );
		}
		adapter->rx_iobuf[i] = NULL;

		memset ( rx_curr_desc, 0, sizeof ( *rx_curr_desc ) );

		adapter->rx_curr = ( adapter->rx_curr + 1 ) % NUM_RX_DESC;
	}
	e1000_refill_rx_ring(adapter);
}