[9] | 1 | /*
|
---|
| 2 | ** File: netbuff.c Jun. 10, 2000
|
---|
| 3 | **
|
---|
| 4 | ** Author: Giovanni Falzoni <gfalzoni@inwind.it>
|
---|
| 5 | **
|
---|
| 6 | ** This file contains specific implementation of buffering
|
---|
| 7 | ** for network packets.
|
---|
| 8 | **
|
---|
| 9 | ** $Id: netbuff.c,v 1.3 2005/08/05 19:08:43 beng Exp $
|
---|
| 10 | */
|
---|
| 11 |
|
---|
| 12 | #include "drivers.h"
|
---|
| 13 | #include <net/gen/ether.h>
|
---|
| 14 | #include <net/gen/eth_io.h>
|
---|
| 15 | #include "dp.h"
|
---|
| 16 |
|
---|
| 17 | #if (HAVE_BUFFERS == 1)
|
---|
| 18 |
|
---|
| 19 | static m_hdr_t *allocptr = NULL;
|
---|
| 20 | static char tx_rx_buff[8192];
|
---|
| 21 |
|
---|
| 22 | /*
|
---|
| 23 | ** Name: void *alloc_buff(dpeth_t *dep, int size)
|
---|
| 24 | ** Function: Allocates a buffer from the common pool.
|
---|
| 25 | */
|
---|
| 26 | PUBLIC void *alloc_buff(dpeth_t *dep, int size)
|
---|
| 27 | {
|
---|
| 28 | m_hdr_t *ptr, *wrk = allocptr;
|
---|
| 29 | int units = ((size + sizeof(m_hdr_t) - 1) / sizeof(m_hdr_t)) + 1;
|
---|
| 30 |
|
---|
| 31 | lock();
|
---|
| 32 | for (ptr = wrk->next;; wrk = ptr, ptr = ptr->next) {
|
---|
| 33 | if (ptr->size >= units) {
|
---|
| 34 | /* Memory is available, carve requested size from pool */
|
---|
| 35 | if (ptr->size == units) {
|
---|
| 36 | wrk->next = ptr->next;
|
---|
| 37 | } else {
|
---|
| 38 | /* Get memory from top address */
|
---|
| 39 | ptr->size -= units;
|
---|
| 40 | ptr += ptr->size;
|
---|
| 41 | ptr->size = units;
|
---|
| 42 | }
|
---|
| 43 | allocptr = wrk;
|
---|
| 44 | unlock();
|
---|
| 45 | return ptr + 1;
|
---|
| 46 | }
|
---|
| 47 | if (ptr == allocptr) break;
|
---|
| 48 | }
|
---|
| 49 | unlock();
|
---|
| 50 | return NULL; /* No memory available */
|
---|
| 51 | }
|
---|
| 52 |
|
---|
| 53 | /*
|
---|
| 54 | ** Name: void free_buff(dpeth_t *dep, void *blk)
|
---|
| 55 | ** Function: Returns a buffer to the common pool.
|
---|
| 56 | */
|
---|
| 57 | PUBLIC void free_buff(dpeth_t *dep, void *blk)
|
---|
| 58 | {
|
---|
| 59 | m_hdr_t *wrk, *ptr = (m_hdr_t *) blk - 1;
|
---|
| 60 |
|
---|
| 61 | lock(); /* Scan linked list for the correct place */
|
---|
| 62 | for (wrk = allocptr; !(ptr > wrk && ptr < wrk->next); wrk = wrk->next)
|
---|
| 63 | if (wrk >= wrk->next && (ptr > wrk || ptr < wrk->next)) break;
|
---|
| 64 |
|
---|
| 65 | /* Check if adjacent block is free and join blocks */
|
---|
| 66 | if (ptr + ptr->size == wrk->next) {
|
---|
| 67 | ptr->size += wrk->next->size;
|
---|
| 68 | ptr->next = wrk->next->next;
|
---|
| 69 | } else
|
---|
| 70 | ptr->next = wrk->next;
|
---|
| 71 | if (wrk + wrk->size == ptr) {
|
---|
| 72 | wrk->size += ptr->size;
|
---|
| 73 | wrk->next = ptr->next;
|
---|
| 74 | } else
|
---|
| 75 | wrk->next = ptr;
|
---|
| 76 | allocptr = wrk; /* Point allocptr to block just released */
|
---|
| 77 | unlock();
|
---|
| 78 | return;
|
---|
| 79 | }
|
---|
| 80 |
|
---|
| 81 | /*
|
---|
| 82 | ** Name: void init_buff(dpeth_t *dep, buff_t **tx_buff)
|
---|
| 83 | ** Function: Initalizes driver data structures.
|
---|
| 84 | */
|
---|
| 85 | PUBLIC void init_buff(dpeth_t *dep, buff_t **tx_buff)
|
---|
| 86 | {
|
---|
| 87 |
|
---|
| 88 | /* Initializes buffer pool */
|
---|
| 89 | if (allocptr == NULL) {
|
---|
| 90 | m_hdr_t *rx = (m_hdr_t *) tx_rx_buff;
|
---|
| 91 | rx->next = allocptr = rx;
|
---|
| 92 | rx->size = 0;
|
---|
| 93 | rx += 1;
|
---|
| 94 | rx->next = NULL;
|
---|
| 95 | rx->size = (sizeof(tx_rx_buff) / sizeof(m_hdr_t)) - 1;
|
---|
| 96 | free_buff(dep, rx + 1);
|
---|
| 97 | dep->de_recvq_tail = dep->de_recvq_head = NULL;
|
---|
| 98 | if (tx_buff != NULL) {
|
---|
| 99 | *tx_buff = alloc_buff(dep, ETH_MAX_PACK_SIZE + sizeof(buff_t));
|
---|
| 100 | (*tx_buff)->size = 0;
|
---|
| 101 | }
|
---|
| 102 | }
|
---|
| 103 | return; /* Done */
|
---|
| 104 | }
|
---|
| 105 |
|
---|
| 106 | /*
|
---|
| 107 | ** Name: void mem2user(dpeth_t *dep, buff_t *rxbuff);
|
---|
| 108 | ** Function: Copies a packet from local buffer to user area.
|
---|
| 109 | */
|
---|
| 110 | PUBLIC void mem2user(dpeth_t *dep, buff_t *rxbuff)
|
---|
| 111 | {
|
---|
| 112 | phys_bytes phys_user;
|
---|
| 113 | int bytes, ix = 0;
|
---|
| 114 | iovec_dat_t *iovp = &dep->de_read_iovec;
|
---|
| 115 | int pktsize = rxbuff->size;
|
---|
| 116 | char *buffer = rxbuff->buffer;
|
---|
| 117 |
|
---|
| 118 | do { /* Reads chuncks of packet into user buffers */
|
---|
| 119 |
|
---|
| 120 | bytes = iovp->iod_iovec[ix].iov_size; /* Size of buffer */
|
---|
| 121 | if (bytes > pktsize) bytes = pktsize;
|
---|
| 122 |
|
---|
| 123 | /* Reads from Rx buffer to user area */
|
---|
| 124 | sys_datacopy(SELF, (vir_bytes)buffer, iovp->iod_proc_nr,
|
---|
| 125 | iovp->iod_iovec[ix].iov_addr, bytes);
|
---|
| 126 | buffer += bytes;
|
---|
| 127 |
|
---|
| 128 | if (++ix >= IOVEC_NR) { /* Next buffer of IO vector */
|
---|
| 129 | dp_next_iovec(iovp);
|
---|
| 130 | ix = 0;
|
---|
| 131 | }
|
---|
| 132 | /* Till packet done */
|
---|
| 133 | } while ((pktsize -= bytes) > 0);
|
---|
| 134 | return;
|
---|
| 135 | }
|
---|
| 136 |
|
---|
| 137 | /*
|
---|
| 138 | ** Name: void user2mem(dpeth_t *dep, buff_t *txbuff)
|
---|
| 139 | ** Function: Copies a packet from user area to local buffer.
|
---|
| 140 | */
|
---|
| 141 | PUBLIC void user2mem(dpeth_t *dep, buff_t *txbuff)
|
---|
| 142 | {
|
---|
| 143 | phys_bytes phys_user;
|
---|
| 144 | int bytes, ix = 0;
|
---|
| 145 | iovec_dat_t *iovp = &dep->de_write_iovec;
|
---|
| 146 | int pktsize = txbuff->size;
|
---|
| 147 | char *buffer = txbuff->buffer;
|
---|
| 148 |
|
---|
| 149 | do { /* Reads chuncks of packet from user buffers */
|
---|
| 150 |
|
---|
| 151 | bytes = iovp->iod_iovec[ix].iov_size; /* Size of buffer */
|
---|
| 152 | if (bytes > pktsize) bytes = pktsize;
|
---|
| 153 | sys_datacopy(iovp->iod_proc_nr, iovp->iod_iovec[ix].iov_addr,
|
---|
| 154 | SELF, (vir_bytes)buffer, bytes);
|
---|
| 155 | buffer += bytes;
|
---|
| 156 |
|
---|
| 157 | if (++ix >= IOVEC_NR) { /* Next buffer of IO vector */
|
---|
| 158 | dp_next_iovec(iovp);
|
---|
| 159 | ix = 0;
|
---|
| 160 | }
|
---|
| 161 | /* Till packet done */
|
---|
| 162 | } while ((pktsize -= bytes) > 0);
|
---|
| 163 | return;
|
---|
| 164 | }
|
---|
| 165 |
|
---|
| 166 | #endif /* HAVE_BUFFERS */
|
---|
| 167 |
|
---|
| 168 | /** netbuff.c **/
|
---|