btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / add-ons / kernel / drivers / network / ipro1000 / if_compat.c
blobeade03d59219a43883f20258c8d79f901d74dad5
1 /* Intel PRO/1000 Family Driver
2 * Copyright (C) 2004 Marcus Overhagen <marcus@overhagen.de>. All rights reserved.
4 * Permission to use, copy, modify and distribute this software and its
5 * documentation for any purpose and without fee is hereby granted, provided
6 * that the above copyright notice appear in all copies, and that both the
7 * copyright notice and this permission notice appear in supporting documentation.
9 * Marcus Overhagen makes no representations about the suitability of this software
10 * for any purpose. It is provided "as is" without express or implied warranty.
12 * MARCUS OVERHAGEN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
13 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL MARCUS
14 * OVERHAGEN BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
15 * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
17 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 #include "if_compat.h"
20 #include "if_em.h"
21 #include "device.h"
22 #include "debug.h"
23 #include "mempool.h"
25 #undef malloc
26 #undef free
28 spinlock mbuf_lock = 0;
30 struct mbuf *
31 m_gethdr(int how, int type)
33 struct mbuf *m = mbuf_pool_get();
34 if (!m)
35 return m;
36 memset(m, 0, sizeof(m));
37 m->m_flags = M_PKTHDR;
38 return m;
41 void
42 m_clget(struct mbuf * m, int how)
44 // TRACE("m_clget\n");
46 m->m_ext.ext_buf = chunk_pool_get();
47 m->m_data = m->m_ext.ext_buf;
48 if (m->m_ext.ext_buf)
49 m->m_flags |= M_EXT;
52 void
53 m_adj(struct mbuf *mp, int bytes)
55 mp->m_data = (char *)mp->m_data + bytes;
58 void
59 m_freem(struct mbuf *mp)
61 struct mbuf *m, *c;
62 // TRACE("m_freem\n");
64 for (m = mp; m; ) {
65 if (m->m_flags & M_EXT)
66 chunk_pool_put(m->m_ext.ext_buf);
67 c = m;
68 m = m->m_next;
69 mbuf_pool_put(c);
73 static void
74 ether_input(struct ifnet *ifp, struct mbuf *m)
77 uint8 *buf;
78 int len;
80 buf = mtod(m, uint8 *);
81 len = m->m_len;
82 TRACE("ether_input: received packet with %d bytes\n", len);
83 TRACE("%02x %02x %02x %02x . %02x %02x %02x %02x . %02x %02x %02x %02x \n",
84 buf[0], buf[1], buf[2], buf[3], buf[4], buf[5],
85 buf[6], buf[7], buf[8], buf[8], buf[10], buf[11]);
87 m_freem(m);
88 return;
91 IF_APPEND(&ifp->if_rcv, m);
92 release_sem_etc(ifp->if_rcv_sem, 1, B_DO_NOT_RESCHEDULE);
95 void
96 ether_ifattach(struct ifnet *ifp, const uint8 *etheraddr)
98 ipro1000_device *dev = ifp->if_softc->dev;
100 INIT_DEBUGOUT("ether_ifattach");
102 TAILQ_INIT(&ifp->if_multiaddrs);
104 memcpy(dev->macaddr, etheraddr, 6);
106 ifp->if_input = ether_input;
108 ifp->if_rcv_sem = create_sem(0, "ifp->if_rcv_sem");
109 set_sem_owner(ifp->if_rcv_sem, B_SYSTEM_TEAM);
111 INIT_DEBUGOUT("calling if_init...");
112 ifp->if_init(ifp->if_softc);
113 INIT_DEBUGOUT("done calling if_init!");
117 static struct ifmultiaddr *
118 ether_find_multi(struct ifnet *ifp, const struct sockaddr *_address)
120 const struct sockaddr_dl *address = (const struct sockaddr_dl *)_address;
121 struct ifmultiaddr *ifma;
123 TAILQ_FOREACH (ifma, &ifp->if_multiaddrs, ifma_link) {
124 if (memcmp(LLADDR(address),
125 LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
126 ETHER_ADDR_LEN) == 0)
127 return ifma;
130 return NULL;
135 ether_add_multi(struct ifnet *ifp, const struct sockaddr *address)
137 struct ifmultiaddr *addr = ether_find_multi(ifp, address);
139 if (addr != NULL) {
140 addr->ifma_refcount++;
141 return 0;
144 addr = (struct ifmultiaddr *)malloc(sizeof(struct ifmultiaddr));
145 if (addr == NULL)
146 return ENOBUFS;
148 memcpy(&addr->ifma_addr_storage, address, sizeof(struct sockaddr_dl));
149 addr->ifma_addr = (struct sockaddr *)&addr->ifma_addr_storage;
151 addr->ifma_refcount = 1;
153 TAILQ_INSERT_HEAD(&ifp->if_multiaddrs, addr, ifma_link);
155 return ifp->if_ioctl(ifp, SIOCADDMULTI, NULL);
159 static void
160 ether_delete_multi(struct ifnet *ifp, struct ifmultiaddr *ifma)
162 TAILQ_REMOVE(&ifp->if_multiaddrs, ifma, ifma_link);
163 free(ifma);
168 ether_rem_multi(struct ifnet *ifp, const struct sockaddr *address)
170 struct ifmultiaddr *addr = ether_find_multi(ifp, address);
171 if (addr == NULL)
172 return EADDRNOTAVAIL;
174 addr->ifma_refcount--;
175 if (addr->ifma_refcount == 0) {
176 ether_delete_multi(ifp, addr);
177 return ifp->if_ioctl(ifp, SIOCDELMULTI, NULL);
180 return 0;
184 void
185 ether_ifdetach(struct ifnet *ifp)
187 struct ifmultiaddr *ifma, *next;
189 INIT_DEBUGOUT("ether_ifdetach");
191 delete_sem(ifp->if_rcv_sem);
193 TAILQ_FOREACH_SAFE(ifma, &ifp->if_multiaddrs, ifma_link, next)
194 ether_delete_multi(ifp, ifma);
197 struct mbuf *
198 if_dequeue(struct if_queue *queue)
200 cpu_status s;
201 struct mbuf *m;
203 // TRACE("IF_DEQUEUE\n");
205 s = disable_interrupts();
206 acquire_spinlock(&mbuf_lock);
208 m = (struct mbuf *) queue->ifq_head;
209 if (m) {
210 queue->ifq_head = m->m_nextq;
211 if (!queue->ifq_head)
212 queue->ifq_tail = 0;
213 m->m_nextq = 0;
216 release_spinlock(&mbuf_lock);
217 restore_interrupts(s);
219 return m;
222 void
223 if_prepend(struct if_queue *queue, struct mbuf *mb)
225 cpu_status s;
226 // TRACE("IF_PREPEND\n");
228 s = disable_interrupts();
229 acquire_spinlock(&mbuf_lock);
231 mb->m_nextq = (struct mbuf *) queue->ifq_head;
232 queue->ifq_head = mb;
233 if (!queue->ifq_tail)
234 queue->ifq_tail = mb;
236 release_spinlock(&mbuf_lock);
237 restore_interrupts(s);
240 void
241 if_append(struct if_queue *queue, struct mbuf *mb)
243 cpu_status s;
244 // TRACE("IF_APPEND\n");
246 s = disable_interrupts();
247 acquire_spinlock(&mbuf_lock);
249 mb->m_nextq = 0;
250 if (!queue->ifq_tail) {
251 queue->ifq_tail = mb;
252 queue->ifq_head = mb;
253 } else {
254 queue->ifq_tail->m_nextq = mb;
255 queue->ifq_tail = mb;
258 release_spinlock(&mbuf_lock);
259 restore_interrupts(s);