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