Ignore:
File:
1 edited

Legend:

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

    r9f0fb84 r6d8455d  
    6767#define E1000_RECEIVE_ADDRESS  16
    6868
     69/** Maximum sending packet size */
     70#define E1000_MAX_SEND_FRAME_SIZE  2048
    6971/** Maximum receiving packet size */
    7072#define E1000_MAX_RECEIVE_PACKET_SIZE  2048
     
    125127        void *tx_ring_virt;
    126128       
    127         /** Packets in tx ring  */
    128         packet_t **tx_ring_packets;
     129        /** Ring of TX frames, physical address */
     130        void **tx_frame_phys;
     131        /** Ring of TX frames, virtual address */
     132        void **tx_frame_virt;
    129133       
    130134        /** Physical rx ring address */
     
    223227static int e1000_on_activating(nic_t *);
    224228static int e1000_on_stopping(nic_t *);
    225 static void e1000_write_packet(nic_t *, packet_t *);
     229static void e1000_send_frame(nic_t *, void *, size_t);
    226230
    227231/** Commands to deal with interrupt
     
    11261130            (e1000->tx_ring_virt + offset * sizeof(e1000_tx_descriptor_t));
    11271131       
    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        
    11341132        tx_descriptor->phys_addr = 0;
    11351133        tx_descriptor->length = 0;
     
    15221520static int e1000_initialize_tx_structure(e1000_t *e1000)
    15231521{
     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;
    15251530       
    15261531        int rc = dmamem_map_anonymous(
     
    15291534            &e1000->tx_ring_virt);
    15301535        if (rc != EOK)
    1531                 return rc;
     1536                goto error;
    15321537       
    15331538        bzero(e1000->tx_ring_virt,
    15341539            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        }
    15351556       
    15361557        E1000_REG_WRITE(e1000, E1000_TDBAH,
     
    15391560            (uint32_t) PTR_TO_U64(e1000->tx_ring_phys));
    15401561       
    1541         e1000->tx_ring_packets =
    1542             malloc(E1000_TX_PACKETS_COUNT * sizeof(packet_t *));
    1543         // FIXME: Check return value
    1544        
    15451562        e1000_initialize_tx_registers(e1000);
    15461563       
    15471564        fibril_mutex_unlock(&e1000->tx_lock);
    15481565        return EOK;
     1566       
     1567error:
     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;
    15491594}
    15501595
     
    15561601static void e1000_uninitialize_tx_structure(e1000_t *e1000)
    15571602{
    1558         free(e1000->tx_ring_packets);
     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        }
    15591620        dmamem_unmap_anonymous(e1000->tx_ring_virt);
    15601621}
     
    17711832       
    17721833        nic_set_specific(nic, e1000);
    1773         nic_set_write_packet_handler(nic, e1000_write_packet);
     1834        nic_set_send_frame_handler(nic, e1000_send_frame);
    17741835        nic_set_state_change_handlers(nic, e1000_on_activating,
    17751836            e1000_on_down, e1000_on_stopping);
     
    21902251}
    21912252
    2192 /** Send packet
     2253/** Send frame
    21932254 *
    21942255 * @param nic    NIC driver data structure
    2195  * @param packet Packet to send
     2256 * @param data   Frame data
     2257 * @param size   Frame size in bytes
    21962258 *
    21972259 * @return EOK if succeed
     
    21992261 *
    22002262 */
    2201 static void e1000_write_packet(nic_t *nic, packet_t *packet)
     2263static void e1000_send_frame(nic_t *nic, void *data, size_t size)
    22022264{
    22032265        assert(nic);
     
    22172279       
    22182280        /* Descriptor done */
    2219         if (tx_descriptor_addr->status & TXDESCRIPTOR_STATUS_DD) {
     2281        if (tx_descriptor_addr->status & TXDESCRIPTOR_STATUS_DD)
    22202282                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         }
    22282283       
    22292284        if (!descriptor_available) {
     
    22332288        }
    22342289       
    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;
     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;
    22492294       
    22502295        /*
Note: See TracChangeset for help on using the changeset viewer.