1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License as
4 * published by the Free Software Foundation; either version 2, or (at
5 * your option) any later version.
6 */
7
8FILE_LICENCE ( GPL2_OR_LATER );
9
10#ifndef	NIC_H
11#define NIC_H
12
13#include <stdint.h>
14#include <string.h>
15#include <stdio.h>
16#include <byteswap.h>
17#include <gpxe/pci.h>
18#include <gpxe/isapnp.h>
19#include <gpxe/isa.h>
20#include <gpxe/eisa.h>
21#include <gpxe/mca.h>
22#include <gpxe/io.h>
23
24typedef enum {
25	DISABLE = 0,
26	ENABLE,
27	FORCE
28} irq_action_t;
29
30typedef enum duplex {
31	HALF_DUPLEX = 1,
32	FULL_DUPLEX
33} duplex_t;
34
35/*
36 *	Structure returned from eth_probe and passed to other driver
37 *	functions.
38 */
39struct nic {
40	struct nic_operations	*nic_op;
41	int			flags;	/* driver specific flags */
42	unsigned char		*node_addr;
43	unsigned char		*packet;
44	unsigned int		packetlen;
45	unsigned int		ioaddr;
46	unsigned char		irqno;
47	unsigned int		mbps;
48	duplex_t		duplex;
49	void			*priv_data;	/* driver private data */
50};
51
52struct nic_operations {
53	int ( *connect ) ( struct nic * );
54	int ( *poll ) ( struct nic *, int retrieve );
55	void ( *transmit ) ( struct nic *, const char *,
56			     unsigned int, unsigned int, const char * );
57	void ( *irq ) ( struct nic *, irq_action_t );
58};
59
60extern struct nic nic;
61
62static inline int eth_poll ( int retrieve ) {
63	return nic.nic_op->poll ( &nic, retrieve );
64}
65
66static inline void eth_transmit ( const char *dest, unsigned int type,
67				  unsigned int size, const void *packet ) {
68	nic.nic_op->transmit ( &nic, dest, type, size, packet );
69}
70
71/*
72 * Function prototypes
73 *
74 */
75extern int dummy_connect ( struct nic *nic );
76extern void dummy_irq ( struct nic *nic, irq_action_t irq_action );
77extern int legacy_probe ( void *hwdev,
78			  void ( * set_drvdata ) ( void *hwdev, void *priv ),
79			  struct device *dev,
80			  int ( * probe ) ( struct nic *nic, void *hwdev ),
81			  void ( * disable ) ( struct nic *nic, void *hwdev ));
82void legacy_remove ( void *hwdev,
83		     void * ( * get_drvdata ) ( void *hwdev ),
84		     void ( * disable ) ( struct nic *nic, void *hwdev ) );
85
86#define PCI_DRIVER(_name,_ids,_class) 					  \
87	static inline int						  \
88	_name ## _pci_legacy_probe ( struct pci_device *pci,		  \
89				     const struct pci_device_id *id );	  \
90	static inline void						  \
91	_name ## _pci_legacy_remove ( struct pci_device *pci );		  \
92	struct pci_driver _name __pci_driver = {			  \
93		.ids = _ids,						  \
94		.id_count = sizeof ( _ids ) / sizeof ( _ids[0] ),	  \
95		.probe = _name ## _pci_legacy_probe,			  \
96		.remove = _name ## _pci_legacy_remove,			  \
97	};								  \
98	REQUIRE_OBJECT ( pci );
99
100static inline void legacy_pci_set_drvdata ( void *hwdev, void *priv ) {
101	pci_set_drvdata ( hwdev, priv );
102}
103static inline void * legacy_pci_get_drvdata ( void *hwdev ) {
104	return pci_get_drvdata ( hwdev );
105}
106
107#define ISAPNP_DRIVER(_name,_ids)					  \
108	static inline int						  \
109	_name ## _isapnp_legacy_probe ( struct isapnp_device *isapnp,	  \
110					const struct isapnp_device_id *id ); \
111	static inline void						  \
112	_name ## _isapnp_legacy_remove ( struct isapnp_device *isapnp );  \
113	struct isapnp_driver _name __isapnp_driver = {			  \
114		.ids = _ids,						  \
115		.id_count = sizeof ( _ids ) / sizeof ( _ids[0] ),	  \
116		.probe = _name ## _isapnp_legacy_probe,			  \
117		.remove = _name ## _isapnp_legacy_remove,		  \
118	};								  \
119	REQUIRE_OBJECT ( isapnp );
120
121static inline void legacy_isapnp_set_drvdata ( void *hwdev, void *priv ) {
122	isapnp_set_drvdata ( hwdev, priv );
123}
124static inline void * legacy_isapnp_get_drvdata ( void *hwdev ) {
125	return isapnp_get_drvdata ( hwdev );
126}
127
128#define EISA_DRIVER(_name,_ids)						  \
129	static inline int						  \
130	_name ## _eisa_legacy_probe ( struct eisa_device *eisa,		  \
131				      const struct eisa_device_id *id );  \
132	static inline void						  \
133	_name ## _eisa_legacy_remove ( struct eisa_device *eisa );	  \
134	struct eisa_driver _name __eisa_driver = {			  \
135		.ids = _ids,						  \
136		.id_count = sizeof ( _ids ) / sizeof ( _ids[0] ),	  \
137		.probe = _name ## _eisa_legacy_probe,			  \
138		.remove = _name ## _eisa_legacy_remove,			  \
139	};								  \
140	REQUIRE_OBJECT ( eisa );
141
142static inline void legacy_eisa_set_drvdata ( void *hwdev, void *priv ) {
143	eisa_set_drvdata ( hwdev, priv );
144}
145static inline void * legacy_eisa_get_drvdata ( void *hwdev ) {
146	return eisa_get_drvdata ( hwdev );
147}
148
149#define MCA_DRIVER(_name,_ids)						  \
150	static inline int						  \
151	_name ## _mca_legacy_probe ( struct mca_device *mca,		  \
152				     const struct mca_device_id *id );	  \
153	static inline void						  \
154	_name ## _mca_legacy_remove ( struct mca_device *mca );		  \
155	struct mca_driver _name __mca_driver = {			  \
156		.ids = _ids,						  \
157		.id_count = sizeof ( _ids ) / sizeof ( _ids[0] ),	  \
158		.probe = _name ## _mca_legacy_probe,			  \
159		.remove = _name ## _mca_legacy_remove,			  \
160	};								  \
161	REQUIRE_OBJECT ( mca );
162
163static inline void legacy_mca_set_drvdata ( void *hwdev, void *priv ) {
164	mca_set_drvdata ( hwdev, priv );
165}
166static inline void * legacy_mca_get_drvdata ( void *hwdev ) {
167	return mca_get_drvdata ( hwdev );
168}
169
170#define ISA_DRIVER(_name,_probe_addrs,_probe_addr,_vendor_id,_prod_id)	  \
171	static inline int						  \
172	_name ## _isa_legacy_probe ( struct isa_device *isa );		  \
173	static inline int						  \
174	_name ## _isa_legacy_probe_at_addr ( struct isa_device *isa ) {	  \
175		if ( ! _probe_addr ( isa->ioaddr ) )			  \
176			return -ENODEV; 				  \
177		return _name ## _isa_legacy_probe ( isa );		  \
178	}								  \
179	static inline void						  \
180	_name ## _isa_legacy_remove ( struct isa_device *isa );		  \
181	static const char _name ## _text[];				  \
182	struct isa_driver _name __isa_driver = {			  \
183		.name = _name ## _text,					  \
184		.probe_addrs = _probe_addrs,				  \
185		.addr_count = ( sizeof ( _probe_addrs ) /		  \
186				sizeof ( _probe_addrs[0] ) ),		  \
187		.vendor_id = _vendor_id,				  \
188		.prod_id = _prod_id,					  \
189		.probe = _name ## _isa_legacy_probe_at_addr,		  \
190		.remove = _name ## _isa_legacy_remove,			  \
191	};								  \
192	REQUIRE_OBJECT ( isa );
193
194static inline void legacy_isa_set_drvdata ( void *hwdev, void *priv ) {
195	isa_set_drvdata ( hwdev, priv );
196}
197static inline void * legacy_isa_get_drvdata ( void *hwdev ) {
198	return isa_get_drvdata ( hwdev );
199}
200
201#undef DRIVER
202#define DRIVER(_name_text,_unused2,_unused3,_name,_probe,_disable)	  \
203	static const char _name ## _text[] = _name_text;		  \
204	static inline int						  \
205	_name ## _probe ( struct nic *nic, void *hwdev ) {		  \
206		return _probe ( nic, hwdev );				  \
207	}								  \
208	static inline void						  \
209	_name ## _disable ( struct nic *nic, void *hwdev ) {		  \
210		void ( * _unsafe_disable ) () = _disable;		  \
211		_unsafe_disable ( nic, hwdev );				  \
212	}								  \
213	static inline int						  \
214	_name ## _pci_legacy_probe ( struct pci_device *pci,		  \
215			    const struct pci_device_id *id __unused ) {	  \
216		return legacy_probe ( pci, legacy_pci_set_drvdata,	  \
217				      &pci->dev, _name ## _probe,	  \
218				      _name ## _disable );		  \
219	}								  \
220	static inline void						  \
221	_name ## _pci_legacy_remove ( struct pci_device *pci ) {	  \
222		return legacy_remove ( pci, legacy_pci_get_drvdata,	  \
223				       _name ## _disable );		  \
224	}								  \
225	static inline int						  \
226	_name ## _isapnp_legacy_probe ( struct isapnp_device *isapnp,	  \
227			 const struct isapnp_device_id *id __unused ) {	  \
228		return legacy_probe ( isapnp, legacy_isapnp_set_drvdata,  \
229				      &isapnp->dev, _name ## _probe,	  \
230				      _name ## _disable );		  \
231	}								  \
232	static inline void						  \
233	_name ## _isapnp_legacy_remove ( struct isapnp_device *isapnp ) { \
234		return legacy_remove ( isapnp, legacy_isapnp_get_drvdata, \
235				       _name ## _disable );		  \
236	}								  \
237	static inline int						  \
238	_name ## _eisa_legacy_probe ( struct eisa_device *eisa,		  \
239			     const struct eisa_device_id *id __unused ) { \
240		return legacy_probe ( eisa, legacy_eisa_set_drvdata,	  \
241				      &eisa->dev, _name ## _probe,	  \
242				      _name ## _disable );		  \
243	}								  \
244	static inline void						  \
245	_name ## _eisa_legacy_remove ( struct eisa_device *eisa ) {	  \
246		return legacy_remove ( eisa, legacy_eisa_get_drvdata,	  \
247				       _name ## _disable );		  \
248	}								  \
249	static inline int						  \
250	_name ## _mca_legacy_probe ( struct mca_device *mca,		  \
251			      const struct mca_device_id *id __unused ) { \
252		return legacy_probe ( mca, legacy_mca_set_drvdata,	  \
253				      &mca->dev, _name ## _probe,	  \
254				      _name ## _disable );		  \
255	}								  \
256	static inline void						  \
257	_name ## _mca_legacy_remove ( struct mca_device *mca ) {	  \
258		return legacy_remove ( mca, legacy_mca_get_drvdata,	  \
259				       _name ## _disable );		  \
260	}								  \
261	static inline int						  \
262	_name ## _isa_legacy_probe ( struct isa_device *isa ) {		  \
263		return legacy_probe ( isa, legacy_isa_set_drvdata,	  \
264				      &isa->dev, _name ## _probe,	  \
265				      _name ## _disable );		  \
266	}								  \
267	static inline void						  \
268	_name ## _isa_legacy_remove ( struct isa_device *isa ) {	  \
269		return legacy_remove ( isa, legacy_isa_get_drvdata,	  \
270				       _name ## _disable );		  \
271	}
272
273#endif	/* NIC_H */
274