Annotation of qemu/roms/SLOF/drivers/e1k/e1k.c, revision 1.1.1.1

1.1       root        1: /******************************************************************************
                      2:  * Copyright (c) 2007, 2011 IBM Corporation
                      3:  * All rights reserved.
                      4:  * This program and the accompanying materials
                      5:  * are made available under the terms of the BSD License
                      6:  * which accompanies this distribution, and is available at
                      7:  * http://www.opensource.org/licenses/bsd-license.php
                      8:  *
                      9:  * Contributors:
                     10:  *     IBM Corporation - initial implementation
                     11:  *****************************************************************************/
                     12: /*
                     13:  * e1000 Gigabit Ethernet Driver for SLOF
                     14:  *
                     15:  * Reference:
                     16:  *   PCI/PCI-X Family of Gigabit Ethernet Controllers
                     17:  *   Software Developer's Manual Rev. 3.3, Intel, December 2006
                     18:  */
                     19: 
                     20: #include <stdint.h>
                     21: #include <string.h>
                     22: #include <byteorder.h>
                     23: #include "e1k.h"
                     24: 
                     25: 
                     26: /*
                     27:  * local defines
                     28:  ******************************************************************************
                     29:  */
                     30: #define E1K_NUM_RX_DESC        128     // do not change
                     31: #define E1K_NUM_TX_DESC        128     // do not change
                     32: #define E1K_BUF_SIZE   2096    // do not change
                     33: 
                     34: #define NUM_MAC_ADDR   16      // number of mac address register pairs
                     35: #define EEPROM_MAC_OFFS        0       // position of mac address in eeprom
                     36: 
                     37: /*
                     38:  * local types
                     39:  ******************************************************************************
                     40:  */
                     41: typedef struct {
                     42:        uint32_t m_dev_u32;
                     43:        uint64_t m_devmsk_u64;
                     44:        char *m_name;
                     45: }      e1k_dev_t;
                     46: 
                     47: /*
                     48:  * e1k common data structures
                     49:  */
                     50: 
                     51: /*
                     52:  * transmit buffer descriptor
                     53:  */
                     54: typedef struct {
                     55:        uint64_t m_buffer_u64;
                     56:        uint16_t m_len_u16;
                     57:        uint8_t m_cso_u08;
                     58:        uint8_t m_cmd_u08;
                     59:        uint8_t m_sta_u08;
                     60:        uint8_t m_css_u08;
                     61:        uint16_t m_spe_u16;
                     62: }      __attribute__ ((packed)) e1k_tx_desc_st;
                     63: 
                     64: 
                     65: /*
                     66:  * receive buffer descriptor
                     67:  */
                     68: typedef struct {
                     69:        uint64_t m_buffer_u64;
                     70:        uint16_t m_len_u16;
                     71:        uint16_t m_csm_u16;
                     72:        uint8_t m_sta_u08;
                     73:        uint8_t m_err_u08;
                     74:        uint16_t m_spe_u16;
                     75: }      __attribute__ ((packed)) e1k_rx_desc_st;
                     76: 
                     77: /*
                     78:  * e1k device structure
                     79:  */
                     80: typedef struct {
                     81:        /*
                     82:         * device identification mask
                     83:         */
                     84:        uint64_t        m_device_u64;
                     85: 
                     86:        /*
                     87:         * memory mapped base address of NIC
                     88:         */
                     89:        uint64_t        m_baseaddr_u64;
                     90: 
                     91:        /*
                     92:         * transmit & receive rings
                     93:         * must be 16 byte aligned
                     94:         */
                     95:        e1k_tx_desc_st  m_tx_ring_pst[E1K_NUM_TX_DESC];
                     96:        e1k_rx_desc_st  m_rx_ring_pst[E1K_NUM_RX_DESC];
                     97: 
                     98:        /*
                     99:         * transmit & receive buffers
                    100:         * must be 16 byte aligned
                    101:         */
                    102:        uint8_t         m_tx_buffer_pu08[E1K_NUM_TX_DESC][E1K_BUF_SIZE];
                    103:        uint8_t         m_rx_buffer_pu08[E1K_NUM_RX_DESC][E1K_BUF_SIZE];
                    104: 
                    105:        /*
                    106:         * next receive descriptor index
                    107:         */
                    108:        uint32_t        m_rx_next_u32;
                    109: 
                    110:        /*
                    111:         * command register storage
                    112:         */
                    113:        uint16_t        m_com_r_u16;
                    114: 
                    115:        /*
                    116:         * padding to make the size of the structure a multiple of 16 byte
                    117:         */
                    118:        uint16_t        m_pad16_u16;
                    119:        uint64_t        m_pad64_u32;
                    120: 
                    121:        /*
                    122:         * PCI related data
                    123:         */
                    124:        uint64_t        pcicfg_puid;
                    125:        uint8_t         pcicfg_bus;
                    126:        uint8_t         pcicfg_devfn;
                    127: }      __attribute__ ((packed)) e1k_st;
                    128: 
                    129: /*
                    130:  * local constants
                    131:  ******************************************************************************
                    132:  */
                    133: #define E1K_82540      ((uint64_t) 0x1)
                    134: #define E1K_82541      ((uint64_t) 0x2)
                    135: #define E1K_82544      ((uint64_t) 0x4)
                    136: #define E1K_82545      ((uint64_t) 0x8)
                    137: #define E1K_82546      ((uint64_t) 0x10)
                    138: #define E1K_82547      ((uint64_t) 0x20)
                    139: 
                    140: #define IS_82541       ((m_e1k.m_device_u64 & E1K_82541) != 0)
                    141: #define IS_82546       ((m_e1k.m_device_u64 & E1K_82546) != 0)
                    142: #define IS_82547       ((m_e1k.m_device_u64 & E1K_82547) != 0)
                    143: 
                    144: static const e1k_dev_t e1k_dev[] = {
                    145:        { 0x1019, E1K_82547, "82547EI/GI Copper" },
                    146:        { 0x101A, E1K_82547, "82547EI Mobile" },
                    147:        { 0x1010, E1K_82546, "52546EB Copper, Dual Port" },
                    148:        { 0x1012, E1K_82546, "82546EB Fiber, Dual Port" },
                    149: /*     { 0x101D, E1K_82546, "82546EB Copper, Quad Port" }, */
                    150:        { 0x1079, E1K_82546, "82546GB Copper, Dual Port" },
                    151:        { 0x107A, E1K_82546, "82546GB Fiber, Dual Port" },
                    152:        { 0x107B, E1K_82546, "82546GB SerDes, Dual Port" },
                    153:        { 0x100F, E1K_82545, "82545EM Copper" },
                    154:        { 0x1011, E1K_82545, "82545EM Fiber" },
                    155:        { 0x1026, E1K_82545, "82545GM Copper" },
                    156:        { 0x1027, E1K_82545, "82545GM Fiber" },
                    157:        { 0x1028, E1K_82545, "82545GM SerDes" },
                    158:        { 0x1107, E1K_82544, "82544EI Copper" },
                    159:        { 0x1112, E1K_82544, "82544GC Copper" },
                    160:        { 0x1013, E1K_82541, "82541EI Copper" },
                    161:        { 0x1018, E1K_82541, "82541EI Mobile" },
                    162:        { 0x1076, E1K_82541, "82541GI Copper" },
                    163:        { 0x1077, E1K_82541, "82541GI Mobile" },
                    164:        { 0x1078, E1K_82541, "82541ER Copper" },
                    165:        { 0x107C, E1K_82541, "82541PI" },
                    166:        { 0x1015, E1K_82540, "82540EM Mobile" },
                    167:        { 0x1016, E1K_82540, "82540EP Mobile" },
                    168:        { 0x1017, E1K_82540, "82540EP Desktop" },
                    169:        { 0x100E, E1K_82540, "82540EM Desktop" },
                    170:        { 0     , 0 }
                    171: };
                    172: 
                    173: /*
                    174:  * local variables
                    175:  ******************************************************************************
                    176:  */
                    177: static e1k_st  m_e1k __attribute__ ((aligned(16)));
                    178: static long dma_offset;
                    179: 
                    180: /*
                    181:  * global functions
                    182:  ******************************************************************************
                    183:  */
                    184: int
                    185: check_driver(pci_config_t *pci_conf);
                    186: 
                    187: 
                    188: /*
                    189:  * snk module interface
                    190:  ******************************************************************************
                    191:  */
                    192: static int e1k_init(void);
                    193: static int e1k_term(void);
                    194: static int e1k_xmit(char *f_buffer_pc, int f_len_i);
                    195: static int e1k_receive(char *f_buffer_pc, int f_len_i);
                    196: static int e1k_ioctl(int request, void* data);
                    197: 
                    198: snk_module_t snk_module_interface = {
                    199:        .version = 1,
                    200:        .type    = MOD_TYPE_NETWORK,
                    201:        .running = 0,
                    202:        .init    = e1k_init,
                    203:        .term    = e1k_term,
                    204:        .write   = e1k_xmit,
                    205:        .read    = e1k_receive,
                    206:        .ioctl   = e1k_ioctl
                    207: };
                    208: 
                    209: 
                    210: /**
                    211:  * Translate virtual to "physical" address, ie. an address
                    212:  * which can be used for DMA transfers.
                    213:  */
                    214: static uint64_t
                    215: virt2dma(void *addr)
                    216: {
                    217:        return (uint64_t)addr + dma_offset;
                    218: }
                    219: 
                    220: static void *
                    221: dma2virt(uint64_t addr)
                    222: {
                    223:        return (void *)(addr - dma_offset);
                    224: }
                    225: 
                    226: 
                    227: /*
                    228:  * local inline functions for e1k register access
                    229:  ******************************************************************************
                    230:  */
                    231: static uint32_t
                    232: e1k_rd32(uint16_t f_offs_u16)
                    233: {      // caution: shall only be used after initialization!
                    234:        return bswap_32(rd32(m_e1k.m_baseaddr_u64 + (uint64_t) f_offs_u16));
                    235: }
                    236: 
                    237: /* not used so far
                    238: static uint16_t
                    239: e1k_rd16(uint16_t f_offs_u16)
                    240: {      // caution: shall only be used after initialization!
                    241:        return bswap_16(rd16(m_e1k.m_baseaddr_u64 + (uint64_t) f_offs_u16));
                    242: }*/
                    243: 
                    244: /* not used so far
                    245: static uint8_t
                    246: e1k_rd08(uint16_t f_offs_u16)
                    247: {      // caution: shall only be used after initialization!
                    248:        return rd08(m_e1k.m_baseaddr_u64 + (uint64_t) f_offs_u16);
                    249: }*/
                    250: 
                    251: static void
                    252: e1k_wr32(uint16_t f_offs_u16, uint32_t f_val_u32)
                    253: {      // caution: shall only be used after initialization!
                    254:        wr32(m_e1k.m_baseaddr_u64 + (uint64_t) f_offs_u16, bswap_32(f_val_u32));
                    255: }
                    256: 
                    257: /* not used so far
                    258: static void
                    259: e1k_wr16(uint16_t f_offs_u16, uint16_t f_val_u16)
                    260: {      // caution: shall only be used after initialization!
                    261:        wr16(m_e1k.m_baseaddr_u64 + (uint64_t) f_offs_u16, bswap_16(f_val_u16));
                    262: }*/
                    263: 
                    264: /* not used so far
                    265: static void
                    266: e1k_wr08(uint16_t f_offs_u16, uint8_t f_val_u08)
                    267: {      // caution: shall only be used after initialization!
                    268:        wr08(m_e1k.m_baseaddr_u64 + (uint64_t) f_offs_u16, f_val_u08);
                    269: }*/
                    270: 
                    271: static void
                    272: e1k_setb32(uint16_t f_offs_u16, uint32_t f_mask_u32)
                    273: {
                    274:        uint32_t v;
                    275: 
                    276:        v  = e1k_rd32(f_offs_u16);
                    277:        v |= f_mask_u32;
                    278:        e1k_wr32(f_offs_u16, v);
                    279: }
                    280: 
                    281: /* not used so far
                    282: static void
                    283: e1k_setb16(uint16_t f_offs_u16, uint16_t f_mask_u16)
                    284: {
                    285:        uint16_t v;
                    286:        v  = e1k_rd16(f_offs_u16);
                    287:        v |= f_mask_u16;
                    288:        e1k_wr16(f_offs_u16, v);
                    289: }*/
                    290: 
                    291: /* not used so far
                    292: static void
                    293: e1k_setb08(uint16_t f_offs_u16, uint8_t f_mask_u08)
                    294: {
                    295:        uint8_t v;
                    296:        v  = e1k_rd08(f_offs_u16);
                    297:        v |= f_mask_u08;
                    298:        e1k_wr08(f_offs_u16, v);
                    299: }*/
                    300: 
                    301: static void
                    302: e1k_clrb32(uint16_t f_offs_u16, uint32_t f_mask_u32)
                    303: {
                    304:        uint32_t v;
                    305: 
                    306:        v  = e1k_rd32(f_offs_u16);
                    307:        v &= ~f_mask_u32;
                    308:        e1k_wr32(f_offs_u16, v);
                    309: }
                    310: 
                    311: /* not used so far
                    312: static void
                    313: e1k_clrb16(uint16_t f_offs_u16, uint16_t f_mask_u16)
                    314: {
                    315:        uint16_t v;
                    316: 
                    317:        v  = e1k_rd16(f_offs_u16);
                    318:        v &= ~f_mask_u16;
                    319:        e1k_wr16(f_offs_u16, v);
                    320: }*/
                    321: 
                    322: /* not used so far
                    323: static void
                    324: e1k_clrb08(uint16_t f_offs_u16, uint8_t f_mask_u08)
                    325: {
                    326:        uint8_t v;
                    327:        v  = e1k_rd08(f_offs_u16);
                    328:        v &= ~f_mask_u08;
                    329:        e1k_wr08(f_offs_u16, v);
                    330: }*/
                    331: 
                    332: static int32_t
                    333: e1k_eep_rd16(uint8_t f_offs_u08, uint16_t *f_data_pu16)
                    334: {
                    335:        uint32_t i;
                    336:        uint32_t v;
                    337:        int32_t done_shft;
                    338:        int32_t addr_shft;
                    339: 
                    340:        if(IS_82541 || IS_82547) {
                    341:                addr_shft = 2;
                    342:                done_shft = 1;
                    343:        } else {
                    344:                addr_shft = 8;
                    345:                done_shft = 4;
                    346:        }
                    347: 
                    348:        /*
                    349:         * initiate eeprom read
                    350:         */
                    351:        e1k_wr32(EERD, ((uint32_t) f_offs_u08 << addr_shft) |   // address
                    352:                  BIT32(0));                                    // start read
                    353: 
                    354:        /*
                    355:         * wait for read done bit to be set
                    356:         */
                    357:        i = 1000;
                    358:        v = e1k_rd32(EERD);
                    359:        while ((--i) &&
                    360:               ((v & BIT32(done_shft)) == 0)) {
                    361:                ms_delay(1);
                    362:                v = e1k_rd32(EERD);
                    363:        }
                    364: 
                    365:        /*
                    366:         * return on error
                    367:         */
                    368:        if ((v & BIT32(done_shft)) == 0) {
                    369:                return -1;
                    370:        }
                    371:        
                    372:        /*
                    373:         * return data
                    374:         */
                    375:        *f_data_pu16 = (uint16_t) ((v >> 16) & 0xffff);
                    376: 
                    377:        return 0;
                    378: }
                    379: 
                    380: /*
                    381:  * ring initialization
                    382:  */
                    383: static void
                    384: e1k_init_receiver(void)
                    385: {
                    386:        uint32_t i;
                    387:        uint64_t addr;
                    388: 
                    389:        /*
                    390:         * disable receiver for initialization
                    391:         */
                    392:        e1k_wr32(RCTL, 0);
                    393: 
                    394:        /*
                    395:         * clear receive desciptors and setup buffer pointers
                    396:         */
                    397:        for (i = 0; i < E1K_NUM_RX_DESC; i++) {
                    398:                memset((uint8_t *) &m_e1k.m_rx_ring_pst[i], 0,
                    399:                        sizeof(e1k_rx_desc_st));
                    400:                mb();
                    401: 
                    402:                m_e1k.m_rx_ring_pst[i].m_buffer_u64 =
                    403:                        bswap_64(virt2dma(&m_e1k.m_rx_buffer_pu08[i][0]));
                    404:        }
                    405: 
                    406:        /*
                    407:         * initialize previously received index
                    408:         */
                    409:        m_e1k.m_rx_next_u32 = 0;
                    410: 
                    411:        /*
                    412:         * setup the base address and the length of the rx descriptor ring
                    413:         */
                    414:        addr = virt2dma(&m_e1k.m_rx_ring_pst[0]);
                    415:        e1k_wr32(RDBAH, (uint32_t) ((uint64_t) addr >> 32));
                    416:        e1k_wr32(RDBAL, (uint32_t) ((uint64_t) addr & 0xffffffff));
                    417:        e1k_wr32(RDLEN, E1K_NUM_RX_DESC * sizeof(e1k_rx_desc_st));
                    418: 
                    419:        /*
                    420:         * setup the rx head and tail descriptor indices
                    421:         */
                    422:        e1k_wr32(RDH, 0);
                    423:        e1k_wr32(RDT, E1K_NUM_RX_DESC - 1);
                    424: 
                    425:        /*
                    426:         * setup the receive delay timer register
                    427:         */
                    428:        e1k_wr32(RDTR, 0);
                    429: 
                    430:        /*
                    431:         * setup the receive control register
                    432:         */
                    433:        e1k_wr32(RCTL,  BIT32( 1) |     // enable receiver
                    434:                        BIT32( 4) |     // enable multicast reception
                    435:                        BIT32(15));     // broadcast accept mode
                    436:                                        // packet size 2048
                    437:                                        // no buffer extension
                    438: }
                    439: 
                    440: static void
                    441: e1k_init_transmitter(void)
                    442: {
                    443:        uint32_t i;
                    444:        uint64_t addr;
                    445: 
                    446:        /*
                    447:         * clear transmit desciptors and setup buffer pointers
                    448:         */
                    449:        for (i = 0; i < E1K_NUM_TX_DESC; i++) {
                    450:                memset((uint8_t *) &m_e1k.m_tx_ring_pst[i], 0,
                    451:                        sizeof(e1k_tx_desc_st));
                    452:                mb();
                    453: 
                    454:                m_e1k.m_tx_ring_pst[i].m_buffer_u64 =
                    455:                        bswap_64(virt2dma(&m_e1k.m_tx_buffer_pu08[i][0]));
                    456:        }
                    457: 
                    458:        /*
                    459:         * setup the base address and the length of the tx descriptor ring
                    460:         */
                    461:        addr = virt2dma(&m_e1k.m_tx_ring_pst[0]);
                    462:        e1k_wr32(TDBAH, (uint32_t) ((uint64_t) addr >> 32));
                    463:        e1k_wr32(TDBAL, (uint32_t) ((uint64_t) addr & 0xffffffff));
                    464:        e1k_wr32(TDLEN, E1K_NUM_TX_DESC * sizeof(e1k_tx_desc_st));
                    465: 
                    466:        /*
                    467:         * setup the rx head and tail descriptor indices
                    468:         */
                    469:        e1k_wr32(TDH, 0);
                    470:        e1k_wr32(TDT, 0);
                    471: 
                    472:        /*
                    473:         * initialize the transmit control register
                    474:         */
                    475:        e1k_wr32(TCTL, BIT32(1) |                       // enable transmitter
                    476:                        BIT32(3) |                      // pad short packets
                    477:                        ((uint32_t) 0x0f <<  4) |       // collision threshhold
                    478:                        ((uint32_t) 0x40 << 12));       // collision distance
                    479: }
                    480: 
                    481: static int32_t
                    482: e1k_mac_init(uint8_t *f_mac_pu08)
                    483: {
                    484:        uint32_t l_ah_u32;
                    485:        uint32_t l_al_u32;
                    486:        uint32_t i;
                    487:        uint32_t v;
                    488: 
                    489:        /*
                    490:         * Use MAC address from device tree if possible
                    491:         */
                    492:        for (i = 0, v = 0; i < 6; i++) {
                    493:                v += (uint32_t) f_mac_pu08[i];
                    494:        }
                    495: 
                    496:        if (v != 0) {
                    497:                /*
                    498:                 * use passed mac address for transmission to nic
                    499:                 */
                    500:                l_al_u32  = ((uint32_t) f_mac_pu08[3] << 24);
                    501:                l_al_u32 |= ((uint32_t) f_mac_pu08[2] << 16);
                    502:                l_al_u32 |= ((uint32_t) f_mac_pu08[1] <<  8);
                    503:                l_al_u32 |= ((uint32_t) f_mac_pu08[0] <<  0);
                    504:                l_ah_u32  = ((uint32_t) f_mac_pu08[5] <<  8);
                    505:                l_ah_u32 |= ((uint32_t) f_mac_pu08[4] <<  0);
                    506:        } else {
                    507:                /*
                    508:                 * read mac address from eeprom
                    509:                 */
                    510:                uint16_t w[3];  // 3 16 bit words from eeprom
                    511: 
                    512:                for (i = 0; i < 3; i++) {
                    513:                        if (e1k_eep_rd16(EEPROM_MAC_OFFS + i, &w[i]) != 0) {
                    514:                                printk("Failed to read MAC address from EEPROM!\n");
                    515:                                return -1;
                    516:                        }
                    517:                }
                    518: 
                    519:                /*
                    520:                 * invert the least significant bit for 82546 dual port
                    521:                 * if the second device is in use (remember word is byteswapped)
                    522:                 */
                    523:                if ((IS_82546) &&
                    524:                    ((e1k_rd32(STATUS) & BIT32(2)) != 0)) {
                    525:                        w[2] ^= (uint16_t) 0x100;
                    526:                }
                    527: 
                    528:                /*
                    529:                 * store mac address for transmission to nic
                    530:                 */
                    531:                l_ah_u32  = ((uint32_t) w[2] <<  0);
                    532:                l_al_u32  = ((uint32_t) w[1] << 16);
                    533:                l_al_u32 |= ((uint32_t) w[0] <<  0);
                    534: 
                    535:                /*
                    536:                 * return mac address
                    537:                 * mac address in eeprom is stored byteswapped
                    538:                 */
                    539:                f_mac_pu08[1] = (uint8_t) ((w[0] >> 8) & 0xff);
                    540:                f_mac_pu08[0] = (uint8_t) ((w[0] >> 0) & 0xff);
                    541:                f_mac_pu08[3] = (uint8_t) ((w[1] >> 8) & 0xff);
                    542:                f_mac_pu08[2] = (uint8_t) ((w[1] >> 0) & 0xff);
                    543:                f_mac_pu08[5] = (uint8_t) ((w[2] >> 8) & 0xff);
                    544:                f_mac_pu08[4] = (uint8_t) ((w[2] >> 0) & 0xff);
                    545:        }
                    546: 
                    547:        /*
                    548:         * insert mac address in receive address register
                    549:         * and set AV bit
                    550:         */
                    551:        e1k_wr32(RAL0, l_al_u32);
                    552:        e1k_wr32(RAH0, l_ah_u32 | BIT32(31));
                    553: 
                    554:        /*
                    555:         * clear remaining receive address registers
                    556:         */
                    557:        for (i = 1; i < NUM_MAC_ADDR; i++) {
                    558:                e1k_wr32(RAL0 + i * sizeof(uint64_t), 0);
                    559:                e1k_wr32(RAH0 + i * sizeof(uint64_t), 0);
                    560:        }
                    561: 
                    562:        return 0;
                    563: }
                    564: 
                    565: 
                    566: /*
                    567:  * interface
                    568:  ******************************************************************************
                    569:  */
                    570:   
                    571: /*
                    572:  * e1k_receive
                    573:  */
                    574: static int
                    575: e1k_receive(char *f_buffer_pc, int f_len_i)
                    576: {
                    577:        uint32_t        l_rdh_u32 = e1k_rd32(RDH);      // this includes needed dummy read
                    578:        e1k_rx_desc_st  *rx;
                    579:        int             l_ret_i;
                    580: 
                    581:        #ifdef E1K_DEBUG
                    582:        #ifdef E1K_SHOW_RCV_DATA
                    583:        int             i;
                    584:        #endif
                    585:        #endif
                    586: 
                    587:        /*
                    588:         * check whether new packets have arrived
                    589:         */
                    590:        if (m_e1k.m_rx_next_u32 == l_rdh_u32) {
                    591:                return 0;
                    592:        }
                    593: 
                    594:        /*
                    595:         * get a pointer to the next rx descriptor for ease of use
                    596:         */
                    597:        rx = &m_e1k.m_rx_ring_pst[m_e1k.m_rx_next_u32];
                    598: 
                    599:        /*
                    600:         * check whether the descriptor done bit is set
                    601:         */
                    602:        if ((rx->m_sta_u08 & 0x1) == 0) {
                    603:                return 0;
                    604:        }
                    605: 
                    606:        /*
                    607:         * get the length of the packet, throw away checksum
                    608:         */
                    609:        l_ret_i = (int) bswap_16(rx->m_len_u16) - (int) 4;
                    610: 
                    611:        /*
                    612:         * copy the data
                    613:         */
                    614:        memcpy((uint8_t *) f_buffer_pc, dma2virt(bswap_64(rx->m_buffer_u64)),
                    615:                (size_t) l_ret_i);
                    616: 
                    617:        #ifdef E1K_DEBUG
                    618:        #if defined(E1K_SHOW_RCV) || defined(E1K_SHOW_RCV_DATA)
                    619:        printk("e1k: %d bytes received\n", l_ret_i);
                    620:        #endif
                    621: 
                    622:        #ifdef E1K_SHOW_RCV_DATA
                    623:        for (i = 0; i < l_ret_i; i++) {
                    624: 
                    625:                if ((i & 0x1f) == 0) {
                    626:                        printk("\n       ");
                    627:                }
                    628: 
                    629:                printk("%02X ", f_buffer_pc[i]);
                    630:        }
                    631: 
                    632:        printk("\n\n");
                    633:        #endif
                    634:        #endif
                    635: 
                    636:        /*
                    637:         * clear descriptor for reusage, but leave buffer pointer untouched
                    638:         */
                    639:        memset((uint8_t *) &rx->m_len_u16, 0,
                    640:                sizeof(e1k_rx_desc_st) - sizeof(uint64_t));
                    641:        mb();
                    642: 
                    643:        /*
                    644:         * write new tail pointer
                    645:         */
                    646:        e1k_wr32(RDT, m_e1k.m_rx_next_u32);
                    647: 
                    648:        /*
                    649:         * update next receive index
                    650:         */
                    651:        m_e1k.m_rx_next_u32 = (m_e1k.m_rx_next_u32 + 1) & (E1K_NUM_RX_DESC - 1);
                    652: 
                    653:        return l_ret_i;
                    654: }
                    655: 
                    656: static int
                    657: e1k_xmit(char *f_buffer_pc, int f_len_i)
                    658: {
                    659:        uint32_t        l_tdh_u32 = e1k_rd32(TDH);
                    660:        uint32_t        l_tdt_u32 = e1k_rd32(TDT);
                    661:        uint32_t        l_pre_u32 = (l_tdh_u32 + (E1K_NUM_TX_DESC - 1)) &
                    662:                                    (E1K_NUM_TX_DESC - 1);
                    663:        e1k_tx_desc_st  *tx;
                    664:        #if defined(E1K_DEBUG) && defined(E1K_SHOW_XMIT_DATA)
                    665:        int             i;
                    666:        #endif
                    667: 
                    668:        /*
                    669:         * check for available buffers
                    670:         */
                    671:        if (l_pre_u32 == l_tdt_u32) {
                    672:                return 0;
                    673:        }
                    674: 
                    675:        /*
                    676:         * get a pointer to the next tx descriptor for ease of use
                    677:         */
                    678:        tx = &m_e1k.m_tx_ring_pst[l_tdt_u32];
                    679: 
                    680:        /*
                    681:         * copy the data
                    682:         */
                    683:        memcpy(dma2virt(bswap_64(tx->m_buffer_u64)), (uint8_t *) f_buffer_pc,
                    684:                (size_t) f_len_i);
                    685: 
                    686:        /*
                    687:         * insert length & command flags
                    688:         */
                    689:        tx->m_len_u16 = bswap_16((uint16_t) f_len_i);
                    690:        tx->m_cmd_u08 = (BIT08(0) |             // EOP
                    691:                          BIT08(1));            // IFCS
                    692:        tx->m_sta_u08 = 0;
                    693:        mb();
                    694: 
                    695:        /*
                    696:         * update tail index
                    697:         */
                    698:        l_tdt_u32 = (l_tdt_u32 + 1) & (E1K_NUM_TX_DESC - 1);
                    699:        e1k_wr32(TDT, l_tdt_u32);
                    700: 
                    701:        #ifdef E1K_DEBUG
                    702:        #if defined(E1K_SHOW_XMIT) || defined(E1K_SHOW_XMIT_DATA)
                    703:        printk("e1k: %d bytes transmitted\n", bswap_16(tx->m_len_u16));
                    704:        #endif
                    705: 
                    706:        #ifdef E1K_SHOW_XMIT_DATA
                    707:        for (i = 0; i < bswap_16(tx->m_len_u16); i++) {
                    708: 
                    709:                if ((i & 0x1f) == 0) {
                    710:                        printk("\n       ");
                    711:                }
                    712: 
                    713:                f_buffer_pc = dma2virt(bswap_64(tx->m_buffer_u64));
                    714:                printk("%02X ", f_buffer_pc[i]);
                    715:        }
                    716: 
                    717:        printk("\n\n");
                    718:        #endif
                    719:        #endif
                    720: 
                    721:        return f_len_i;
                    722: }
                    723: 
                    724: int
                    725: check_driver(pci_config_t *pci_conf)
                    726: {
                    727:        uint64_t i;
                    728: 
                    729:        /*
                    730:         * checks whether the driver is handling this device
                    731:         * by verifying vendor & device id
                    732:         * vendor id 0x8086 == Intel
                    733:         */
                    734:        if (pci_conf->vendor_id != 0x8086) {
                    735:                #ifdef E1K_DEBUG
                    736:                printk("e1k: netdevice with vendor id %04X not supported\n",
                    737:                        pci_conf->vendor_id);
                    738:                #endif
                    739:                return -1;
                    740:        }
                    741: 
                    742:        for (i = 0; e1k_dev[i].m_dev_u32 != 0; i++) {
                    743:                if (e1k_dev[i].m_dev_u32 == (uint32_t) pci_conf->device_id) {
                    744:                        break;
                    745:                }
                    746:        }
                    747: 
                    748:        if (e1k_dev[i].m_dev_u32 == 0) {
                    749:                #ifdef E1K_DEBUG
                    750:                printk("e1k: netdevice with device id %04X not supported\n",
                    751:                        pci_conf->device_id);
                    752:                #endif
                    753:                return -1;
                    754:        }
                    755: 
                    756:        /*
                    757:         * initialize static variables
                    758:         */
                    759:        m_e1k.m_device_u64   = e1k_dev[i].m_devmsk_u64;
                    760:        m_e1k.m_baseaddr_u64 = 0;
                    761:        m_e1k.pcicfg_puid    = pci_conf->puid;
                    762:        m_e1k.pcicfg_bus     = pci_conf->bus;
                    763:        m_e1k.pcicfg_devfn   = pci_conf->devfn;
                    764: 
                    765:        // success
                    766:        #ifdef E1K_DEBUG
                    767:        printk("e1k: found device %s\n", e1k_dev[i].m_name);
                    768:        #endif
                    769: 
                    770:        return 0;
                    771: }
                    772: 
                    773: static int
                    774: e1k_init(void)
                    775: {
                    776:        uint32_t i;
                    777:        uint32_t v;
                    778:        char *mac_addr = snk_module_interface.mac_addr;
                    779: 
                    780:        if (snk_module_interface.running != 0) {
                    781:                return 0;
                    782:        }
                    783: 
                    784:        #ifdef E1K_DEBUG
                    785:        printk("\ne1k: initializing\n");
                    786:        #endif
                    787: 
                    788:        dma_offset = snk_kernel_interface->dma_map_in(&m_e1k, sizeof(m_e1k), 0);
                    789:        #ifdef E1K_DEBUG
                    790:        printk("e1k: dma offset: %lx - %lx = %lx\n", dma_offset, (long)&m_e1k,
                    791:                dma_offset - (long)&m_e1k);
                    792:        #endif
                    793:        dma_offset = dma_offset - (long)&m_e1k;
                    794: 
                    795:        /*
                    796:         * setup register & memory base addresses of NIC
                    797:         */
                    798:        m_e1k.m_baseaddr_u64 = (uint64_t) ((uint32_t) ~0xf & (uint32_t)
                    799:                snk_kernel_interface->pci_config_read(m_e1k.pcicfg_puid,
                    800:                                                        4,
                    801:                                                        m_e1k.pcicfg_bus,
                    802:                                                        m_e1k.pcicfg_devfn,
                    803:                                                        PCI_BAR1_R));
                    804:        #ifdef E1K_DEBUG
                    805:        printk("e1k: base address register = 0x%lx\n", m_e1k.m_baseaddr_u64);
                    806:        #endif
                    807: 
                    808:        snk_kernel_interface->translate_addr(((void *) &m_e1k.m_baseaddr_u64));
                    809: 
                    810: #ifdef E1K_DEBUG
                    811:        printk("e1k: PCI-Puid  = 0x%llX\n", m_e1k.pcicfg_puid);
                    812:        printk("e1k: PCI-Bus   = 0x%X\n", m_e1k.pcicfg_bus);
                    813:        printk("e1k: PCI-DevFn = 0x%X\n", m_e1k.pcicfg_devfn);
                    814:        printk("e1k: device's register base address = 0x%lx\n",
                    815:                m_e1k.m_baseaddr_u64);
                    816: #endif
                    817: 
                    818:        /*
                    819:         * e1k hardware initialization
                    820:         */
                    821: 
                    822:        /*
                    823:         * save pci command register
                    824:         */
                    825:        m_e1k.m_com_r_u16 = (uint16_t)
                    826:                snk_kernel_interface->pci_config_read(m_e1k.pcicfg_puid,
                    827:                                                        2,
                    828:                                                        m_e1k.pcicfg_bus,
                    829:                                                        m_e1k.pcicfg_devfn,
                    830:                                                        PCI_COM_R);
                    831: 
                    832: /*
                    833:  * bus mastering does not need to be enabled, it is already set
                    834:        // enable bus master & memory space in command reg
                    835:        i = (BIT32(10) | BIT32(2) | BIT32(1));
                    836:        snk_kernel_interface->pci_config_write(m_e1k.pcicfg_puid,
                    837:                                                2,
                    838:                                                m_e1k.pcicfg_bus,
                    839:                                                m_e1k.pcicfg_devfn,
                    840:                                                PCI_COM_R,
                    841:                                                (int) i);
                    842: */
                    843: 
                    844:        /*
                    845:         * at first disable all interrupts
                    846:         */
                    847:        e1k_wr32(IMC, (uint32_t) ~0);
                    848: 
                    849:        /*
                    850:         * check for link up
                    851:         */
                    852:        #ifdef E1K_DEBUG
                    853:        printk("e1k: checking link status..\n");
                    854:        #endif
                    855: 
                    856:        i = 50;
                    857:        v = e1k_rd32(STATUS);
                    858:        while ((--i) &&
                    859:               ((v & BIT32(1)) == 0)) {
                    860:                ms_delay(100);
                    861:                v = e1k_rd32(STATUS);
                    862:        }
                    863: 
                    864:        if ((v & BIT32(1)) == 0) {
                    865:                #ifdef E1K_DEBUG
                    866:                printk("e1k: link is down.\n");
                    867:                printk("       terminating.\n");
                    868:                #endif
                    869: 
                    870:                return -1;
                    871:        }
                    872: 
                    873:        #ifdef E1K_DEBUG
                    874:        printk("e1k: link is up\n");
                    875: 
                    876:        switch ((v >> 6) & 0x3) {
                    877:                case 0: {
                    878:                        printk("       10 Mb/s\n");
                    879:                }       break;
                    880:                case 1: {
                    881:                        printk("       100 Mb/s\n");
                    882:                }       break;
                    883:                case 2:
                    884:                case 3: {
                    885:                        printk("       1000 Mb/s\n");
                    886:                }       break;
                    887:        }
                    888: 
                    889:        if ((v & BIT32(0)) == 0) {
                    890:                printk("       half-duplex\n");
                    891:        } else {
                    892:                printk("       full-duplex\n");
                    893:        }
                    894:        #endif
                    895: 
                    896:        /*
                    897:         * initialize mac address
                    898:         */
                    899:        #ifdef E1K_DEBUG
                    900:        printk("e1k: initializing mac address.. ");
                    901:        #endif
                    902:        if (e1k_mac_init((uint8_t *)mac_addr) != 0) {
                    903:                #ifdef E1K_DEBUG
                    904:                printk("failed.\n");
                    905:                printk("       terminating.\n");
                    906:                #endif
                    907: 
                    908:                return -1;
                    909:        }
                    910: 
                    911:        #ifdef E1K_DEBUG
                    912:        printk("done.\n");
                    913:        printk("       mac address = %02X:%02X:%02X:%02X:%02X:%02X\n",
                    914:                mac_addr[0], mac_addr[1], mac_addr[2],
                    915:                mac_addr[3], mac_addr[4], mac_addr[5]);
                    916:        #endif
                    917: 
                    918:        /*
                    919:         * initialize transmitter
                    920:         */
                    921:        #ifdef E1K_DEBUG
                    922:        printk("e1k: initializing transmitter.. ");
                    923:        #endif
                    924:        e1k_init_transmitter();
                    925:        #ifdef E1K_DEBUG
                    926:        printk("done.\n");
                    927:        #endif
                    928: 
                    929:        /*
                    930:         * initialize receiver
                    931:         */
                    932:        #ifdef E1K_DEBUG
                    933:        printk("e1k: initializing receiver.. ");
                    934:        #endif
                    935:        e1k_init_receiver();
                    936:        #ifdef E1K_DEBUG
                    937:        printk("done.\n");
                    938:        printk("e1k: initialization complete\n");
                    939:        #endif
                    940: 
                    941:        snk_module_interface.running = 1;
                    942: 
                    943:        return 0;
                    944: }
                    945: 
                    946: static int
                    947: e1k_reset(void)
                    948: {
                    949:        /*
                    950:         * reset the PHY
                    951:         */
                    952:        e1k_setb32(CTRL, BIT32(31));
                    953:        ms_delay(10);
                    954: 
                    955:        /*
                    956:         * reset the MAC
                    957:         */
                    958:        e1k_setb32(CTRL, BIT32(26));
                    959:        ms_delay(10);
                    960: 
                    961:        return 0;
                    962: }
                    963: 
                    964: static int 
                    965: e1k_term(void)
                    966: {
                    967:        if (snk_module_interface.running == 0) {
                    968:                return 0;
                    969:        }
                    970: 
                    971:        #ifdef E1K_DEBUG
                    972:        printk("e1k: shutdown.. ");
                    973:        #endif
                    974: 
                    975:        /*
                    976:         * disable receiver & transmitter
                    977:         */
                    978:        e1k_wr32(RCTL, 0);
                    979:        e1k_wr32(TCTL, 0);
                    980:        ms_delay(10);
                    981: 
                    982:        /*
                    983:         * reset the ring indices
                    984:         */
                    985:        e1k_wr32(RDH, 0);
                    986:        e1k_wr32(RDT, 0);
                    987:        e1k_wr32(TDH, 0);
                    988:        e1k_wr32(TDT, 0);
                    989: 
                    990:        /*
                    991:         * disable receive address
                    992:         */
                    993:        e1k_clrb32(RAH0, BIT32(31));
                    994: 
                    995:        /*
                    996:         * reset the mac/phy
                    997:         */
                    998:        e1k_reset();
                    999: 
                   1000:        /*
                   1001:         * reset pci command register
                   1002:         */
                   1003:        snk_kernel_interface->pci_config_write(m_e1k.pcicfg_puid,
                   1004:                                                2,
                   1005:                                                m_e1k.pcicfg_bus,
                   1006:                                                m_e1k.pcicfg_devfn,
                   1007:                                                PCI_COM_R,
                   1008:                                                (int) m_e1k.m_com_r_u16);
                   1009: 
                   1010:        /*
                   1011:         * Disable DMA translation
                   1012:         */
                   1013:        snk_kernel_interface->dma_map_out(&m_e1k, virt2dma(&m_e1k),
                   1014:                                          sizeof(m_e1k));
                   1015: 
                   1016:        #ifdef E1K_DEBUG
                   1017:        printk("done.\n");
                   1018:        #endif
                   1019: 
                   1020:        snk_module_interface.running = 0;
                   1021:        return 0;
                   1022: }
                   1023: 
                   1024: static int
                   1025: e1k_ioctl(int request, void* data)
                   1026: {
                   1027:        return 0;
                   1028: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.