Annotation of qemu/roms/SLOF/board-qemu/veth/veth.c, revision 1.1.1.1

1.1       root        1: /******************************************************************************
                      2:  * Copyright (c) 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: #include "types.h"
                     14: #include "netdriver_int.h"
                     15: #include "libhvcall.h"
                     16: 
                     17: static snk_kernel_t     *snk_kernel_interface;
                     18: static snk_module_t    *snk_module_interface;
                     19: static unsigned int    g_reg;
                     20: 
                     21: #define printk(fmt...)  do { snk_kernel_interface->print(fmt); } while(0)
                     22: #define malloc(args...) snk_kernel_interface->k_malloc(args)
                     23: #define malloc_aligned(args...) snk_kernel_interface->k_malloc_aligned(args)
                     24: #define free(args...)  do { snk_kernel_interface->k_free(args); } while(0)
                     25: 
                     26: #define dprintk(fmt...)
                     27: //#define dprintk(fmt...)      printk(fmt)
                     28: 
                     29: /* *** WARNING: We pass our addresses as-is as DMA addresses,
                     30:  *     we -do- rely on the forth code to have enabled TCE bypass
                     31:  *     on our device !
                     32:  */
                     33: #define vaddr_to_dma(vaddr)    ((u64)vaddr)
                     34: 
                     35: struct ibmveth_buf_desc_fields {
                     36:        u32 flags_len;
                     37: #define IBMVETH_BUF_VALID      0x80000000
                     38: #define IBMVETH_BUF_TOGGLE     0x40000000
                     39: #define IBMVETH_BUF_NO_CSUM    0x02000000
                     40: #define IBMVETH_BUF_CSUM_GOOD  0x01000000
                     41: #define IBMVETH_BUF_LEN_MASK   0x00FFFFFF
                     42:        u32 address;
                     43: };
                     44: 
                     45: union ibmveth_buf_desc {
                     46:        u64 desc;
                     47:        struct ibmveth_buf_desc_fields fields;
                     48: };
                     49: 
                     50: struct ibmveth_rx_q_entry {
                     51:        u32 flags_off;
                     52: #define IBMVETH_RXQ_TOGGLE             0x80000000
                     53: #define IBMVETH_RXQ_TOGGLE_SHIFT       31
                     54: #define IBMVETH_RXQ_VALID              0x40000000
                     55: #define IBMVETH_RXQ_NO_CSUM            0x02000000
                     56: #define IBMVETH_RXQ_CSUM_GOOD          0x01000000
                     57: #define IBMVETH_RXQ_OFF_MASK           0x0000FFFF
                     58: 
                     59:        u32 length;
                     60:        u64 correlator;
                     61: };
                     62: 
                     63: static void *buffer_list; 
                     64: static void *filter_list; 
                     65: static u64 *rx_bufs;
                     66: static u64 *rx_bufs_aligned;
                     67: static u32 cur_rx_toggle;
                     68: static u32 cur_rx_index;
                     69: 
                     70: #define RX_QUEUE_SIZE  16
                     71: #define RX_BUF_SIZE    2048
                     72: #define RX_BUF_MULT    (RX_BUF_SIZE >> 3)
                     73: 
                     74: static struct ibmveth_rx_q_entry *rx_queue;
                     75: 
                     76: static char * memcpy( char *dest, const char *src, size_t n )
                     77: {
                     78:         char *ret = dest;
                     79:         while( n-- ) {
                     80:                 *dest++ = *src++;
                     81:         }
                     82: 
                     83:         return( ret );
                     84: }
                     85: 
                     86: static inline u64 *veth_get_rx_buf(unsigned int i)
                     87: {
                     88:        return &rx_bufs_aligned[i * RX_BUF_MULT];
                     89: }
                     90: 
                     91: static int veth_init(void)
                     92: {
                     93:        char *mac_addr = snk_module_interface->mac_addr;
                     94:        union ibmveth_buf_desc rxq_desc;
                     95:        unsigned long rx_queue_len = sizeof(struct ibmveth_rx_q_entry) *
                     96:                RX_QUEUE_SIZE;
                     97:        unsigned int i;
                     98:        long rc;
                     99: 
                    100:        dprintk("veth_init(%02x:%02x:%02x:%02x:%02x:%02x)\n",
                    101:                mac_addr[0], mac_addr[1], mac_addr[2],
                    102:                mac_addr[3], mac_addr[4], mac_addr[5]);
                    103: 
                    104:        if (snk_module_interface->running != 0)
                    105:                return 0;
                    106: 
                    107:        cur_rx_toggle = IBMVETH_RXQ_TOGGLE;
                    108:        cur_rx_index = 0;
                    109:        buffer_list = malloc_aligned(8192, 4096);
                    110:        filter_list = buffer_list + 4096;
                    111:        rx_queue = malloc_aligned(rx_queue_len, 16);
                    112:        rx_bufs = malloc(2048 * RX_QUEUE_SIZE + 4);
                    113:        if (!buffer_list || !filter_list || !rx_queue || !rx_bufs) {
                    114:                printk("veth: Failed to allocate memory !\n");
                    115:                goto fail;
                    116:        }
                    117:        rx_bufs_aligned = (u64 *)(((u64)rx_bufs | 3) + 1);
                    118:        rxq_desc.fields.address = vaddr_to_dma(rx_queue);
                    119:        rxq_desc.fields.flags_len = IBMVETH_BUF_VALID | rx_queue_len;
                    120: 
                    121:        rc = h_register_logical_lan(g_reg,
                    122:                                    vaddr_to_dma(buffer_list),
                    123:                                    rxq_desc.desc,
                    124:                                    vaddr_to_dma(filter_list),
                    125:                                    (*(u64 *)mac_addr) >> 16);
                    126:        if (rc != H_SUCCESS) {
                    127:                printk("veth: Error %ld registering interface !\n", rc);
                    128:                goto fail;
                    129:        }
                    130:        for (i = 0; i < RX_QUEUE_SIZE; i++) {
                    131:                u64 *buf = veth_get_rx_buf(i);
                    132:                union ibmveth_buf_desc desc;
                    133:                *buf = (u64)buf;
                    134:                desc.fields.address = vaddr_to_dma(buf);
                    135:                desc.fields.flags_len = IBMVETH_BUF_VALID | RX_BUF_SIZE;
                    136:                h_add_logical_lan_buffer(g_reg, desc.desc);
                    137:        }
                    138: 
                    139:        snk_module_interface->running = 1;
                    140: 
                    141:        return 0;
                    142:  fail:
                    143:        if (filter_list)
                    144:                free(filter_list);
                    145:        if (buffer_list)
                    146:                free(buffer_list);
                    147:        if (rx_queue)
                    148:                free(rx_queue);
                    149:        if (rx_bufs)
                    150:                free(rx_bufs);
                    151:        return -1;
                    152: }
                    153: 
                    154: static int veth_term(void)
                    155: {
                    156:        dprintk("veth_term()\n");
                    157: 
                    158:        if (snk_module_interface->running == 0)
                    159:                return 0;
                    160: 
                    161:        h_free_logical_lan(g_reg);
                    162: 
                    163:        if (filter_list)
                    164:                free(filter_list);
                    165:        if (buffer_list)
                    166:                free(buffer_list);
                    167:        if (rx_queue)
                    168:                free(rx_queue);
                    169:        if (rx_bufs)
                    170:                free(rx_bufs);
                    171: 
                    172:        snk_module_interface->running = 0;
                    173: 
                    174:        return 0;
                    175: }
                    176: 
                    177: static int veth_xmit(char *f_buffer_pc, int f_len_i)
                    178: {
                    179:        union ibmveth_buf_desc tx_desc;
                    180:        long rc;
                    181: 
                    182:        dprintk("veth_xmit(packet at %p, %d bytes)\n", f_buffer_pc, f_len_i);
                    183: 
                    184:        tx_desc.fields.address = vaddr_to_dma(f_buffer_pc);
                    185:        tx_desc.fields.flags_len = IBMVETH_BUF_VALID | f_len_i;
                    186: 
                    187:        rc = hv_send_logical_lan(g_reg, tx_desc.desc, 0, 0, 0, 0, 0);
                    188:        if (rc != H_SUCCESS) {
                    189:                printk("veth: Error %ld sending packet !\n", rc);
                    190:                return -1;
                    191:        }
                    192: 
                    193:        return f_len_i;
                    194: }
                    195: 
                    196: static int veth_receive(char *f_buffer_pc, int f_len_i)
                    197: {
                    198:        int packet = 0;
                    199: 
                    200:        dprintk("veth_receive()\n");
                    201: 
                    202:        while(!packet) {
                    203:                struct ibmveth_rx_q_entry *desc = &rx_queue[cur_rx_index];
                    204:                union ibmveth_buf_desc bdesc;
                    205:                void *buf;
                    206: 
                    207:                if ((desc->flags_off & IBMVETH_RXQ_TOGGLE) != cur_rx_toggle)
                    208:                        break;
                    209: 
                    210:                if (!(desc->flags_off & IBMVETH_RXQ_VALID))
                    211:                        goto recycle;
                    212:                if (desc->length > f_len_i) {
                    213:                        printk("veth: Dropping too big packet [%d bytes]\n",
                    214:                               desc->length);
                    215:                        goto recycle;
                    216:                }
                    217: 
                    218:                buf = (void *)desc->correlator;
                    219:                packet = desc->length;
                    220:                memcpy(f_buffer_pc,
                    221:                       buf + (desc->flags_off & IBMVETH_RXQ_OFF_MASK), packet);
                    222:        recycle:
                    223:                bdesc.fields.address = vaddr_to_dma(buf);
                    224:                bdesc.fields.flags_len = IBMVETH_BUF_VALID | RX_BUF_SIZE;
                    225:                h_add_logical_lan_buffer(g_reg, bdesc.desc);
                    226: 
                    227:                cur_rx_index = (cur_rx_index + 1) % RX_QUEUE_SIZE;
                    228:                if (cur_rx_index == 0)
                    229:                        cur_rx_toggle ^= IBMVETH_RXQ_TOGGLE;
                    230:        }
                    231: 
                    232:        return packet;
                    233: }
                    234: 
                    235: static int veth_ioctl(int request, void* data)
                    236: {
                    237:        dprintk("veth_ioctl()\n");
                    238: 
                    239:        return 0;
                    240: }
                    241: 
                    242: static snk_module_t veth_interface = {
                    243:        .version = 1,
                    244:        .type    = MOD_TYPE_NETWORK,
                    245:        .running = 0,
                    246:        .init    = veth_init,
                    247:        .term    = veth_term,
                    248:        .write   = veth_xmit,
                    249:        .read    = veth_receive,
                    250:        .ioctl   = veth_ioctl
                    251: };
                    252: 
                    253: 
                    254: static int check_driver(vio_config_t *conf)
                    255: {
                    256:        
                    257:         if (snk_kernel_interface->strcmp(conf->compat, "IBM,l-lan")) {
                    258:                printk( "veth: netdevice not supported\n" );
                    259:                return -1;
                    260:        }
                    261:        g_reg = conf->reg;
                    262:        
                    263:        return 0;
                    264: }
                    265: 
                    266: snk_module_t* veth_module_init(snk_kernel_t *snk_kernel_int, vio_config_t *conf)
                    267: {
                    268:        snk_kernel_interface = snk_kernel_int;
                    269:        snk_module_interface = &veth_interface;
                    270: 
                    271:        if (snk_kernel_int->version != snk_module_interface->version)
                    272:                return 0;
                    273: 
                    274:        /* Check if this is the right driver */
                    275:        if (check_driver(conf) < 0)
                    276:                return 0;
                    277: 
                    278:        snk_module_interface->link_addr = module_init;
                    279:        return snk_module_interface;
                    280: }

unix.superglobalmegacorp.com

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