sbin/newfs_msdos: sync with NetBSD-8
[minix3.git] / minix / drivers / net / dpeth / dp.c
blobf3d2025886be82e1ce281d1353f729f6b8216e0b
1 /*
2 ** File: dp.c Version 1.01, Oct. 17, 2007
3 ** Original: eth.c Version 1.00, Jan. 14, 1997
4 **
5 ** Author: Giovanni Falzoni <gfalzoni@inwind.it>
6 **
7 ** This file contains the ethernet device driver main task.
8 ** It has to be integrated with the board specific drivers.
9 ** It is a rewriting of Minix 2.0.0 ethernet driver (dp8390.c)
10 ** to remove bord specific code. It should operate (I hope)
11 ** with any board driver.
14 #include <minix/drivers.h>
15 #include <minix/netdriver.h>
16 #include <minix/endpoint.h>
17 #include <sys/mman.h>
18 #include <assert.h>
20 #include "dp.h"
23 ** Local data
25 static dpeth_t de_state;
27 typedef struct dp_conf { /* Configuration description structure */
28 port_t dpc_port;
29 int dpc_irq;
30 phys_bytes dpc_mem;
31 } dp_conf_t;
33 /* Device default configuration */
34 #define DP_CONF_NR 3
35 static dp_conf_t dp_conf[DP_CONF_NR] = {
36 /* I/O port, IRQ, Buff addr, Env. var */
37 { 0x300, 5, 0xC8000, },
38 { 0x280, 10, 0xCC000, },
39 { 0x000, 0, 0x00000, },
42 static int do_init(unsigned int instance, netdriver_addr_t *addr,
43 uint32_t *caps, unsigned int *ticks);
44 static void do_stop(void);
45 static void do_set_mode(unsigned int mode, const netdriver_addr_t *mcast_list,
46 unsigned int mcast_count);
47 static int do_send(struct netdriver_data *data, size_t size);
48 static ssize_t do_recv(struct netdriver_data *data, size_t max);
49 static void do_intr(unsigned int mask);
50 static void do_tick(void);
51 static void do_other(const message *m_ptr, int ipc_status);
53 static const struct netdriver dp_table = {
54 .ndr_name = "dpe",
55 .ndr_init = do_init,
56 .ndr_stop = do_stop,
57 .ndr_set_mode = do_set_mode,
58 .ndr_recv = do_recv,
59 .ndr_send = do_send,
60 .ndr_intr = do_intr,
61 .ndr_tick = do_tick,
62 .ndr_other = do_other
66 ** Name: update_conf
67 ** Function: Gets the default settings from 'dp_conf' table and
68 ** modifies them from the environment.
70 static void update_conf(dpeth_t * dep, const dp_conf_t * dcp,
71 unsigned int instance)
73 static char dpc_fmt[] = "x:d:x";
74 char ec_key[16];
75 long val;
77 strlcpy(ec_key, "DPETH0", sizeof(ec_key));
78 ec_key[5] += instance;
80 val = dcp->dpc_port; /* Get I/O port address */
81 env_parse(ec_key, dpc_fmt, 0, &val, 0x000L, 0x3FFL);
82 dep->de_base_port = val;
84 val = dcp->dpc_irq | DEI_DEFAULT; /* Get Interrupt line (IRQ) */
85 env_parse(ec_key, dpc_fmt, 1, &val, 0L, (long) NR_IRQ_VECTORS - 1);
86 dep->de_irq = val;
88 val = dcp->dpc_mem; /* Get shared memory address */
89 env_parse(ec_key, dpc_fmt, 2, &val, 0L, LONG_MAX);
90 dep->de_linmem = val;
94 ** Name: do_dump
95 ** Function: Displays statistics on screen (SFx key from console)
97 static void do_dump(void)
99 dpeth_t *dep;
101 dep = &de_state;
103 printf("\n\n");
105 printf("%s statistics:\t\t", netdriver_name());
107 /* Network interface status */
108 printf("Status: 0x%04x\n\n", dep->de_flags);
110 (*dep->de_dumpstatsf)(dep);
112 /* Transmitted/received bytes */
113 printf("Tx bytes:%10ld\t", dep->bytes_Tx);
114 printf("Rx bytes:%10ld\n", dep->bytes_Rx);
118 ** Name: do_first_init
119 ** Function: Init action to setup task
121 static void do_first_init(dpeth_t *dep, const dp_conf_t *dcp)
124 dep->de_linmem = 0xFFFF0000; /* FIXME: this overrides update_conf, why? */
126 /* Device specific initialization */
127 (*dep->de_initf)(dep);
129 /* Map memory if requested */
130 if (dep->de_linmem != 0) {
131 assert(dep->de_ramsize > 0);
132 dep->de_locmem =
133 vm_map_phys(SELF, (void *)dep->de_linmem, dep->de_ramsize);
134 if (dep->de_locmem == MAP_FAILED)
135 panic("unable to map memory");
138 /* Set the interrupt handler policy. Request interrupts not to be reenabled
139 * automatically. Return the IRQ line number when an interrupt occurs.
141 dep->de_hook = dep->de_irq;
142 if (sys_irqsetpolicy(dep->de_irq, 0 /*IRQ_REENABLE*/, &dep->de_hook) != OK)
143 panic("unable to set IRQ policy");
144 sys_irqenable(&dep->de_hook);
148 ** Name: do_init
149 ** Function: Checks for hardware presence.
150 ** Initialize hardware and data structures.
151 ** Return status and ethernet address.
153 static int do_init(unsigned int instance, netdriver_addr_t *addr,
154 uint32_t *caps, unsigned int *ticks)
156 dpeth_t *dep;
157 dp_conf_t *dcp;
158 int confnr, fkeys, sfkeys;
160 dep = &de_state;
162 /* Pick a default configuration for this instance. */
163 confnr = MIN(instance, DP_CONF_NR-1);
165 dcp = &dp_conf[confnr];
167 update_conf(dep, dcp, instance);
169 if (!el1_probe(dep) && /* Probe for 3c501 */
170 !wdeth_probe(dep) && /* Probe for WD80x3 */
171 !ne_probe(dep) && /* Probe for NEx000 */
172 !el2_probe(dep) && /* Probe for 3c503 */
173 !el3_probe(dep)) { /* Probe for 3c509 */
174 printf("%s: warning no ethernet card found at 0x%04X\n",
175 netdriver_name(), dep->de_base_port);
176 return ENXIO;
179 do_first_init(dep, dcp);
181 /* Request function key for debug dumps */
182 fkeys = sfkeys = 0; bit_set(sfkeys, 7);
183 if (fkey_map(&fkeys, &sfkeys) != OK)
184 printf("%s: couldn't bind Shift+F7 key (%d)\n",
185 netdriver_name(), errno);
187 memcpy(addr, dep->de_address.na_addr, sizeof(*addr));
188 *caps = NDEV_CAP_MCAST | NDEV_CAP_BCAST; /* ..is this even accurate? */
189 *ticks = sys_hz(); /* update statistics once a second */
190 return OK;
194 ** Name: de_set_mode
195 ** Function: Sets packet receipt mode.
197 static void do_set_mode(unsigned int mode,
198 const netdriver_addr_t * mcast_list __unused,
199 unsigned int mcast_count __unused)
201 dpeth_t *dep;
203 dep = &de_state;
205 dep->de_flags &= NOT(DEF_PROMISC | DEF_MULTI | DEF_BROAD);
206 if (mode & NDEV_MODE_PROMISC)
207 dep->de_flags |= DEF_PROMISC | DEF_MULTI | DEF_BROAD;
208 if (mode & (NDEV_MODE_MCAST_LIST | NDEV_MODE_MCAST_ALL))
209 dep->de_flags |= DEF_MULTI;
210 if (mode & NDEV_MODE_BCAST)
211 dep->de_flags |= DEF_BROAD;
212 (*dep->de_flagsf)(dep);
216 ** Name: do_send
217 ** Function: Send a packet, if possible.
219 static int do_send(struct netdriver_data *data, size_t size)
221 dpeth_t *dep;
223 dep = &de_state;
225 return (*dep->de_sendf)(dep, data, size);
229 ** Name: do_recv
230 ** Function: Receive a packet, if possible.
232 static ssize_t do_recv(struct netdriver_data *data, size_t max)
234 dpeth_t *dep;
236 dep = &de_state;
238 return (*dep->de_recvf)(dep, data, max);
242 ** Name: do_stop
243 ** Function: Stops network interface.
245 static void do_stop(void)
247 dpeth_t *dep;
249 dep = &de_state;
251 /* Stop device */
252 (dep->de_stopf)(dep);
256 ** Name: do_intr
257 ** Function; Handles interrupts.
259 static void do_intr(unsigned int __unused mask)
261 dpeth_t *dep;
263 dep = &de_state;
265 /* If device is enabled and interrupt pending */
266 (*dep->de_interruptf)(dep);
267 sys_irqenable(&dep->de_hook);
271 ** Name: do_tick
272 ** Function: perform regular processing.
274 static void do_tick(void)
276 dpeth_t *dep;
278 dep = &de_state;
280 if (dep->de_getstatsf != NULL)
281 (*dep->de_getstatsf)(dep);
285 ** Name: do_other
286 ** Function: Processes miscellaneous messages.
288 static void do_other(const message *m_ptr, int ipc_status)
291 if (is_ipc_notify(ipc_status) && m_ptr->m_source == TTY_PROC_NR)
292 do_dump();
296 ** Name: main
297 ** Function: Main entry for dp task
299 int main(int argc, char **argv)
302 env_setargs(argc, argv);
304 netdriver_task(&dp_table);
306 return 0;