Example #1
0
static void rtl8169_setup_descriptors(rtl8169 *r)
{
	int i;

	/* set up the rx/tx descriptors */
	for (i=0; i < NUM_RX_DESCRIPTORS; i++) {
		addr_t physaddr;

		physaddr = vtophys(RXBUF(r, i));
		SHOW_FLOW(2, "setup_descriptors: rx buffer at %p, addr 0x%x\n", RXBUF(r, i), physaddr);

		r->rxdesc[i].rx_buffer_low = physaddr;
		r->rxdesc[i].rx_buffer_high = physaddr >> 32;
		r->rxdesc[i].frame_len = BUFSIZE_PER_FRAME;
		r->rxdesc[i].flags = RTL_DESC_OWN | ((i == (NUM_RX_DESCRIPTORS - 1)) ? RTL_DESC_EOR : 0);
	}
	for (i=0; i < NUM_TX_DESCRIPTORS; i++) {
		addr_t physaddr;

		physaddr = vtophys(TXBUF(r, i));
		SHOW_FLOW(2, "setup_descriptors: tx buffer at %p, addr 0x%x\n", TXBUF(r, i), physaddr);

		r->txdesc[i].tx_buffer_low = physaddr;
		r->txdesc[i].tx_buffer_high = physaddr >> 32;
		r->txdesc[i].frame_len = 0; // will need to be filled in when transmitting
		r->txdesc[i].flags = (i == (NUM_TX_DESCRIPTORS - 1)) ? RTL_DESC_EOR : 0;
	}

	/* set up our index pointers */
	r->rx_idx_free = 0;
	r->rx_idx_full = 0;
	r->tx_idx_free = 0;
	r->tx_idx_full = 0;

	/* point the nic at the descriptors */
	RTL_WRITE_32(r, REG_TNPDS_LOW, r->txdesc_phys);
	RTL_WRITE_32(r, REG_TNPDS_HIGH, r->txdesc_phys >> 32);
	RTL_WRITE_32(r, REG_RDSAR_LOW, r->rxdesc_phys);
	RTL_WRITE_32(r, REG_RDSAR_HIGH, r->rxdesc_phys >> 32);
}
void rtl8169_xmit(rtl8169 *r, const char *ptr, ssize_t len)
{
    //int i;

#if debug_level_flow >= 3
    dprintf("rtl8169_xmit dumping packet:");
    hexdump(ptr, len, 0, 0);
#endif

restart:
    hal_sem_acquire(&r->tx_sem);
    hal_mutex_lock(&r->lock);

    int_disable_interrupts();
    acquire_spinlock(&r->reg_spinlock);

    /* look at the descriptor pointed to by tx_idx_free */
    if (r->txdesc[r->tx_idx_free].flags & RTL_DESC_OWN) {
        /* card owns this one, wait and try again later */
        release_spinlock(&r->reg_spinlock);
        int_restore_interrupts();
        mutex_unlock(&r->lock);
        //		sem_release(r->tx_sem, 1);
        goto restart;
    }

    /* queue it up */
    memcpy(TXBUF(r, r->tx_idx_free), ptr, len);
    if (len < 64)
        len = 64;

    r->txdesc[r->tx_idx_free].frame_len = len;
    r->txdesc[r->tx_idx_free].flags = (r->txdesc[r->tx_idx_free].flags & RTL_DESC_EOR) | RTL_DESC_FS | RTL_DESC_LS | RTL_DESC_OWN;
    inc_tx_idx_free(r);
    RTL_WRITE_8(r, REG_TPPOLL, (1<<6)); // something is on the normal queue

    release_spinlock(&r->reg_spinlock);
    int_restore_interrupts();

    mutex_unlock(&r->lock);
}