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 10 #include <minix/drivers.h> 11 #include <minix/netdriver.h> 12 #include <net/gen/ether.h> 13 #include <net/gen/eth_io.h> 14 #include "dp.h" 15 16 #if (HAVE_BUFFERS == 1) 17 18 static m_hdr_t *allocptr = NULL; 19 static char tx_rx_buff[8192]; 20 21 /* 22 ** Name: alloc_buff 23 ** Function: Allocates a buffer from the common pool. 24 */ 25 void *alloc_buff(dpeth_t *dep, int size) 26 { 27 m_hdr_t *ptr, *wrk = allocptr; 28 int units = ((size + sizeof(m_hdr_t) - 1) / sizeof(m_hdr_t)) + 1; 29 30 for (ptr = wrk->next;; wrk = ptr, ptr = ptr->next) { 31 if (ptr->size >= units) { 32 /* Memory is available, carve requested size from pool */ 33 if (ptr->size == units) { 34 wrk->next = ptr->next; 35 } else { 36 /* Get memory from top address */ 37 ptr->size -= units; 38 ptr += ptr->size; 39 ptr->size = units; 40 } 41 allocptr = wrk; 42 return ptr + 1; 43 } 44 if (ptr == allocptr) break; 45 } 46 return NULL; /* No memory available */ 47 } 48 49 /* 50 ** Name: free_buff 51 ** Function: Returns a buffer to the common pool. 52 */ 53 void free_buff(dpeth_t *dep, void *blk) 54 { 55 m_hdr_t *wrk, *ptr = (m_hdr_t *) blk - 1; 56 57 /* Scan linked list for the correct place */ 58 for (wrk = allocptr; !(ptr > wrk && ptr < wrk->next); wrk = wrk->next) 59 if (wrk >= wrk->next && (ptr > wrk || ptr < wrk->next)) break; 60 61 /* Check if adjacent block is free and join blocks */ 62 if (ptr + ptr->size == wrk->next) { 63 ptr->size += wrk->next->size; 64 ptr->next = wrk->next->next; 65 } else 66 ptr->next = wrk->next; 67 if (wrk + wrk->size == ptr) { 68 wrk->size += ptr->size; 69 wrk->next = ptr->next; 70 } else 71 wrk->next = ptr; 72 allocptr = wrk; /* Point allocptr to block just released */ 73 } 74 75 /* 76 ** Name: init_buff 77 ** Function: Initalizes driver data structures. 78 */ 79 void init_buff(dpeth_t *dep, buff_t **tx_buff) 80 { 81 82 /* Initializes buffer pool */ 83 if (allocptr == NULL) { 84 m_hdr_t *rx = (m_hdr_t *) tx_rx_buff; 85 rx->next = allocptr = rx; 86 rx->size = 0; 87 rx += 1; 88 rx->next = NULL; 89 rx->size = (sizeof(tx_rx_buff) / sizeof(m_hdr_t)) - 1; 90 free_buff(dep, rx + 1); 91 dep->de_recvq_tail = dep->de_recvq_head = NULL; 92 if (tx_buff != NULL) { 93 *tx_buff = alloc_buff(dep, ETH_MAX_PACK_SIZE + sizeof(buff_t)); 94 (*tx_buff)->size = 0; 95 } 96 } 97 } 98 99 #endif /* HAVE_BUFFERS */ 100 101 /** netbuff.c **/ 102