/** * Poll for completed packets * * @v netdev Network device */ static void myson_poll_tx ( struct net_device *netdev ) { struct myson_nic *myson = netdev->priv; struct myson_descriptor *tx; unsigned int tx_idx; /* Check for completed packets */ while ( myson->tx.cons != myson->tx.prod ) { /* Get next transmit descriptor */ tx_idx = ( myson->tx.cons % MYSON_NUM_TX_DESC ); tx = &myson->tx.desc[tx_idx]; /* Stop if descriptor is still in use */ if ( tx->status & cpu_to_le32 ( MYSON_TX_STAT_OWN ) ) return; /* Complete TX descriptor */ if ( tx->status & cpu_to_le32 ( MYSON_TX_STAT_ABORT | MYSON_TX_STAT_CSL ) ) { DBGC ( myson, "MYSON %p TX %d completion error " "(%08x)\n", myson, tx_idx, le32_to_cpu ( tx->status ) ); netdev_tx_complete_next_err ( netdev, -EIO ); } else { DBGC2 ( myson, "MYSON %p TX %d complete\n", myson, tx_idx ); netdev_tx_complete_next ( netdev ); } myson->tx.cons++; } }
/** * Poll for completed packets * * @v netdev Network device */ static void rhine_poll_tx ( struct net_device *netdev ) { struct rhine_nic *rhn = netdev->priv; struct rhine_descriptor *desc; unsigned int tx_idx; uint32_t des0; /* Check for completed packets */ while ( rhn->tx.cons != rhn->tx.prod ) { /* Get next transmit descriptor */ tx_idx = ( rhn->tx.cons % RHINE_TXDESC_NUM ); desc = &rhn->tx.desc[tx_idx]; /* Stop if descriptor is still in use */ if ( desc->des0 & cpu_to_le32 ( RHINE_DES0_OWN ) ) return; /* Complete TX descriptor */ des0 = le32_to_cpu ( desc->des0 ); if ( des0 & RHINE_TDES0_TERR ) { DBGC ( rhn, "RHINE %p TX %d error (DES0 %08x)\n", rhn, tx_idx, des0 ); netdev_tx_complete_next_err ( netdev, -EIO ); } else { DBGC2 ( rhn, "RHINE %p TX %d complete\n", rhn, tx_idx ); netdev_tx_complete_next ( netdev ); } rhn->tx.cons++; } }