2 ** File: dp.c Version 1.01, Oct. 17, 2007
3 ** Original: eth.c Version 1.00, Jan. 14, 1997
5 ** Author: Giovanni Falzoni <gfalzoni@inwind.it>
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>
25 static dpeth_t de_state
;
27 typedef struct dp_conf
{ /* Configuration description structure */
33 /* Device default configuration */
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
= {
57 .ndr_set_mode
= do_set_mode
,
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";
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);
88 val
= dcp
->dpc_mem
; /* Get shared memory address */
89 env_parse(ec_key
, dpc_fmt
, 2, &val
, 0L, LONG_MAX
);
95 ** Function: Displays statistics on screen (SFx key from console)
97 static void do_dump(void)
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);
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
);
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
)
158 int confnr
, fkeys
, sfkeys
;
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
);
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 */
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
)
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
);
217 ** Function: Send a packet, if possible.
219 static int do_send(struct netdriver_data
*data
, size_t size
)
225 return (*dep
->de_sendf
)(dep
, data
, size
);
230 ** Function: Receive a packet, if possible.
232 static ssize_t
do_recv(struct netdriver_data
*data
, size_t max
)
238 return (*dep
->de_recvf
)(dep
, data
, max
);
243 ** Function: Stops network interface.
245 static void do_stop(void)
252 (dep
->de_stopf
)(dep
);
257 ** Function; Handles interrupts.
259 static void do_intr(unsigned int __unused mask
)
265 /* If device is enabled and interrupt pending */
266 (*dep
->de_interruptf
)(dep
);
267 sys_irqenable(&dep
->de_hook
);
272 ** Function: perform regular processing.
274 static void do_tick(void)
280 if (dep
->de_getstatsf
!= NULL
)
281 (*dep
->de_getstatsf
)(dep
);
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
)
297 ** Function: Main entry for dp task
299 int main(int argc
, char **argv
)
302 env_setargs(argc
, argv
);
304 netdriver_task(&dp_table
);