Cleanup in elf.c with .bss section clean; adm command mounts cdrom instead of floppy...
[ZeXOS.git] / kernel / core / net / eth.c
blob96d548467feee4dd6adbdc4a63d1c3406525c23a
1 /*
2 * ZeX/OS
3 * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
4 * Copyright (C) 2009 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include <system.h>
22 #include <string.h>
23 #include <dev.h>
24 #include <net/eth.h>
25 #include <net/if.h>
26 #include <mutex.h>
28 /* Mutex for data queue */
29 MUTEX_CREATE (mutex_queue_rx);
31 unsigned char netdev_count = 0;
33 netdev_t *netdev_create (mac_addr_t addr_mac, unsigned (*read) (char *, unsigned), unsigned (*write) (char *, unsigned), unsigned addr_io)
35 struct netdev_t *dev;
37 /* alloc and init context */
38 dev = (struct netdev_t *) kmalloc (sizeof (struct netdev_t));
40 if (!dev)
41 return 0;
43 memcpy (dev->dev_addr, (void *) addr_mac, sizeof (mac_addr_t));
45 /* assign ethernet id name */
46 dev->name = (unsigned char *) kmalloc (sizeof (unsigned char) * 6);
48 if (!dev->name) {
49 kfree (dev);
50 return 0;
53 sprintf (dev->name, "eth%d", netdev_count);
55 dev->base_addr = addr_io;
57 dev->read = read;
58 dev->write = write;
60 dev->info_rx = 0;
61 dev->info_tx = 0;
63 dev->queue_rx_cnt = 0;
64 dev->queue_tx_cnt = 0;
66 /* alloc structure for received data queue */
67 dev->queue_rx_list.next = &dev->queue_rx_list;
68 dev->queue_rx_list.prev = &dev->queue_rx_list;
70 dev->queue_tx_list.next = &dev->queue_tx_list;
71 dev->queue_tx_list.prev = &dev->queue_tx_list;
73 if (!netif_create (dev)) {
74 kfree (dev->name);
75 kfree (dev);
76 return 0;
79 netdev_count ++;
81 return dev;
84 unsigned netdev_rx_add_queue (struct netdev_t *dev, char *buffer, unsigned len)
86 mutex_lock (&mutex_queue_rx);
88 if (!dev)
89 goto unlock;
91 dev->info_rx += len;
93 netdev_buffer_queue_t *queue;
95 /* alloc and init context */
96 queue = (netdev_buffer_queue_t *) kmalloc (sizeof (netdev_buffer_queue_t));
98 if (!queue)
99 goto unlock;
101 queue->len = len;
102 queue->buf = (char *) kmalloc (sizeof (char) * (len + 1));
104 if (!queue->buf) {
105 kfree (queue);
106 goto unlock;
109 memcpy (queue->buf, buffer, len);
110 queue->buf[len] = '\0';
112 /* add into list */
113 queue->next = &dev->queue_rx_list;
114 queue->prev = dev->queue_rx_list.prev;
115 queue->prev->next = queue;
116 queue->next->prev = queue;
118 mutex_unlock (&mutex_queue_rx);
120 return 1;
121 unlock:
122 mutex_unlock (&mutex_queue_rx);
124 return 0;
127 netdev_buffer_queue_t *netdev_rx_queue (struct netdev_t *dev)
129 if (!dev)
130 return 0;
132 netdev_buffer_queue_t *queue;
133 for (queue = dev->queue_rx_list.next; queue != &dev->queue_rx_list; queue = queue->next)
134 return queue;
136 return 0;
139 unsigned netdev_rx_queue_flush (struct netdev_t *dev, netdev_buffer_queue_t *queue)
141 if (!dev)
142 return 0;
144 queue->next->prev = queue->prev;
145 queue->prev->next = queue->next;
147 kfree (queue->buf);
148 kfree (queue);
150 return 1;
153 int netdev_rx (struct netdev_t *dev, char *buf, unsigned len)
155 if (!dev)
156 return 0;
158 /* are there any available data in queue ? */
159 netdev_buffer_queue_t *queue = netdev_rx_queue (dev);
161 if (!queue)
162 return 0;
164 unsigned l = queue->len;
166 if (l >= len) /* TODO - received packet is longer then len (> ~MTU) */
167 return -1;
169 /* copy available data from queue to our buffer */
170 memcpy (buf, queue->buf, l);
172 buf[l] = '\0';
174 /* clean old queue entry */
175 netdev_rx_queue_flush (dev, queue);
177 /* return available data */
178 return l;