Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/nic/e1k/e1k.c

    r6d8455d r9f0fb84  
    6767#define E1000_RECEIVE_ADDRESS  16
    6868
    69 /** Maximum sending packet size */
    70 #define E1000_MAX_SEND_FRAME_SIZE  2048
    7169/** Maximum receiving packet size */
    7270#define E1000_MAX_RECEIVE_PACKET_SIZE  2048
     
    127125        void *tx_ring_virt;
    128126       
    129         /** Ring of TX frames, physical address */
    130         void **tx_frame_phys;
    131         /** Ring of TX frames, virtual address */
    132         void **tx_frame_virt;
     127        /** Packets in tx ring  */
     128        packet_t **tx_ring_packets;
    133129       
    134130        /** Physical rx ring address */
     
    227223static int e1000_on_activating(nic_t *);
    228224static int e1000_on_stopping(nic_t *);
    229 static void e1000_send_frame(nic_t *, void *, size_t);
     225static void e1000_write_packet(nic_t *, packet_t *);
    230226
    231227/** Commands to deal with interrupt
     
    11301126            (e1000->tx_ring_virt + offset * sizeof(e1000_tx_descriptor_t));
    11311127       
     1128        if (tx_descriptor->length) {
     1129                packet_t *old_packet = *(e1000->tx_ring_packets + offset);
     1130                if (old_packet)
     1131                        nic_release_packet(nic, old_packet);
     1132        }
     1133       
    11321134        tx_descriptor->phys_addr = 0;
    11331135        tx_descriptor->length = 0;
     
    15201522static int e1000_initialize_tx_structure(e1000_t *e1000)
    15211523{
    1522         size_t i;
    1523        
    15241524        fibril_mutex_lock(&e1000->tx_lock);
    1525        
    1526         e1000->tx_ring_phys = NULL;
    1527         e1000->tx_ring_virt = NULL;
    1528         e1000->tx_frame_phys = NULL;
    1529         e1000->tx_frame_virt = NULL;
    15301525       
    15311526        int rc = dmamem_map_anonymous(
     
    15341529            &e1000->tx_ring_virt);
    15351530        if (rc != EOK)
    1536                 goto error;
     1531                return rc;
    15371532       
    15381533        bzero(e1000->tx_ring_virt,
    15391534            E1000_TX_PACKETS_COUNT * sizeof(e1000_tx_descriptor_t));
    1540        
    1541         e1000->tx_frame_phys = calloc(E1000_TX_PACKETS_COUNT, sizeof(void *));
    1542         e1000->tx_frame_virt = calloc(E1000_TX_PACKETS_COUNT, sizeof(void *));
    1543 
    1544         if (e1000->tx_frame_phys == NULL || e1000->tx_frame_virt == NULL) {
    1545                 rc = ENOMEM;
    1546                 goto error;
    1547         }
    1548        
    1549         for (i = 0; i < E1000_TX_PACKETS_COUNT; i++) {
    1550                 rc = dmamem_map_anonymous(
    1551                     E1000_MAX_SEND_FRAME_SIZE, AS_AREA_READ | AS_AREA_WRITE,
    1552                     0, &e1000->tx_frame_phys[i], &e1000->tx_frame_virt[i]);
    1553                 if (rc != EOK)
    1554                         goto error;
    1555         }
    15561535       
    15571536        E1000_REG_WRITE(e1000, E1000_TDBAH,
     
    15601539            (uint32_t) PTR_TO_U64(e1000->tx_ring_phys));
    15611540       
     1541        e1000->tx_ring_packets =
     1542            malloc(E1000_TX_PACKETS_COUNT * sizeof(packet_t *));
     1543        // FIXME: Check return value
     1544       
    15621545        e1000_initialize_tx_registers(e1000);
    15631546       
    15641547        fibril_mutex_unlock(&e1000->tx_lock);
    15651548        return EOK;
    1566        
    1567 error:
    1568         if (e1000->tx_ring_virt != NULL) {
    1569                 dmamem_unmap_anonymous(e1000->tx_ring_virt);
    1570                 e1000->tx_ring_virt = NULL;
    1571         }
    1572        
    1573         if (e1000->tx_frame_phys != NULL && e1000->tx_frame_virt != NULL) {
    1574                 for (i = 0; i < E1000_TX_PACKETS_COUNT; i++) {
    1575                         if (e1000->tx_frame_virt[i] != NULL) {
    1576                                 dmamem_unmap_anonymous(e1000->tx_frame_virt[i]);
    1577                                 e1000->tx_frame_virt[i] = NULL;
    1578                                 e1000->tx_frame_phys[i] = NULL;
    1579                         }
    1580                 }
    1581         }
    1582        
    1583         if (e1000->tx_frame_phys != NULL) {
    1584                 free(e1000->tx_frame_phys);
    1585                 e1000->tx_frame_phys = NULL;
    1586         }
    1587        
    1588         if (e1000->tx_frame_virt != NULL) {
    1589                 free(e1000->tx_frame_virt);
    1590                 e1000->tx_frame_phys = NULL;
    1591         }
    1592        
    1593         return rc;
    15941549}
    15951550
     
    16011556static void e1000_uninitialize_tx_structure(e1000_t *e1000)
    16021557{
    1603         size_t i;
    1604        
    1605         for (i = 0; i < E1000_TX_PACKETS_COUNT; i++) {
    1606                 dmamem_unmap_anonymous(e1000->tx_frame_virt[i]);
    1607                 e1000->tx_frame_virt[i] = NULL;
    1608                 e1000->tx_frame_phys[i] = NULL;
    1609         }
    1610        
    1611         if (e1000->tx_frame_phys != NULL) {
    1612                 free(e1000->tx_frame_phys);
    1613                 e1000->tx_frame_phys = NULL;
    1614         }
    1615        
    1616         if (e1000->tx_frame_virt != NULL) {
    1617                 free(e1000->tx_frame_virt);
    1618                 e1000->tx_frame_phys = NULL;
    1619         }
     1558        free(e1000->tx_ring_packets);
    16201559        dmamem_unmap_anonymous(e1000->tx_ring_virt);
    16211560}
     
    18321771       
    18331772        nic_set_specific(nic, e1000);
    1834         nic_set_send_frame_handler(nic, e1000_send_frame);
     1773        nic_set_write_packet_handler(nic, e1000_write_packet);
    18351774        nic_set_state_change_handlers(nic, e1000_on_activating,
    18361775            e1000_on_down, e1000_on_stopping);
     
    22512190}
    22522191
    2253 /** Send frame
     2192/** Send packet
    22542193 *
    22552194 * @param nic    NIC driver data structure
    2256  * @param data   Frame data
    2257  * @param size   Frame size in bytes
     2195 * @param packet Packet to send
    22582196 *
    22592197 * @return EOK if succeed
     
    22612199 *
    22622200 */
    2263 static void e1000_send_frame(nic_t *nic, void *data, size_t size)
     2201static void e1000_write_packet(nic_t *nic, packet_t *packet)
    22642202{
    22652203        assert(nic);
     
    22792217       
    22802218        /* Descriptor done */
    2281         if (tx_descriptor_addr->status & TXDESCRIPTOR_STATUS_DD)
     2219        if (tx_descriptor_addr->status & TXDESCRIPTOR_STATUS_DD) {
    22822220                descriptor_available = true;
     2221                packet_t *old_packet = *(e1000->tx_ring_packets + tdt);
     2222                if (old_packet) {
     2223                        size_t old_packet_size = packet_get_data_length(old_packet);
     2224                        nic_dma_unlock_packet(old_packet, old_packet_size);
     2225                        nic_release_packet(nic, old_packet);
     2226                }
     2227        }
    22832228       
    22842229        if (!descriptor_available) {
     
    22882233        }
    22892234       
    2290         memcpy(e1000->tx_frame_virt[tdt], data, size);
    2291        
    2292         tx_descriptor_addr->phys_addr = PTR_TO_U64(e1000->tx_frame_phys[tdt]);
    2293         tx_descriptor_addr->length = size;
     2235        size_t packet_size = packet_get_data_length(packet);
     2236       
     2237        void *phys;
     2238        int rc = nic_dma_lock_packet(packet, packet_size, &phys);
     2239        if (rc != EOK) {
     2240                fibril_mutex_unlock(&e1000->tx_lock);
     2241                return;
     2242        }
     2243       
     2244        *(e1000->tx_ring_packets + tdt) = packet;
     2245       
     2246        tx_descriptor_addr->phys_addr =
     2247            PTR_TO_U64(phys + packet->data_start);
     2248        tx_descriptor_addr->length = packet_size;
    22942249       
    22952250        /*
Note: See TracChangeset for help on using the changeset viewer.