[e16e8f2] | 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 | |
---|
| 8 | FILE_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 | |
---|
| 24 | typedef enum { |
---|
| 25 | DISABLE = 0, |
---|
| 26 | ENABLE, |
---|
| 27 | FORCE |
---|
| 28 | } irq_action_t; |
---|
| 29 | |
---|
| 30 | typedef 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 | */ |
---|
| 39 | struct 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 | |
---|
| 52 | struct 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 | |
---|
| 60 | extern struct nic nic; |
---|
| 61 | |
---|
| 62 | static inline int eth_poll ( int retrieve ) { |
---|
| 63 | return nic.nic_op->poll ( &nic, retrieve ); |
---|
| 64 | } |
---|
| 65 | |
---|
| 66 | static 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 | */ |
---|
| 75 | extern int dummy_connect ( struct nic *nic ); |
---|
| 76 | extern void dummy_irq ( struct nic *nic, irq_action_t irq_action ); |
---|
| 77 | extern 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 )); |
---|
| 82 | void 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 | |
---|
| 100 | static inline void legacy_pci_set_drvdata ( void *hwdev, void *priv ) { |
---|
| 101 | pci_set_drvdata ( hwdev, priv ); |
---|
| 102 | } |
---|
| 103 | static 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 | |
---|
| 121 | static inline void legacy_isapnp_set_drvdata ( void *hwdev, void *priv ) { |
---|
| 122 | isapnp_set_drvdata ( hwdev, priv ); |
---|
| 123 | } |
---|
| 124 | static 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 | |
---|
| 142 | static inline void legacy_eisa_set_drvdata ( void *hwdev, void *priv ) { |
---|
| 143 | eisa_set_drvdata ( hwdev, priv ); |
---|
| 144 | } |
---|
| 145 | static 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 | |
---|
| 163 | static inline void legacy_mca_set_drvdata ( void *hwdev, void *priv ) { |
---|
| 164 | mca_set_drvdata ( hwdev, priv ); |
---|
| 165 | } |
---|
| 166 | static 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 | |
---|
| 194 | static inline void legacy_isa_set_drvdata ( void *hwdev, void *priv ) { |
---|
| 195 | isa_set_drvdata ( hwdev, priv ); |
---|
| 196 | } |
---|
| 197 | static 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 */ |
---|