iPXE
nic.h
Go to the documentation of this file.
00001 /*
00002  * This program is free software; you can redistribute it and/or
00003  * modify it under the terms of the GNU General Public License as
00004  * published by the Free Software Foundation; either version 2 of the
00005  * License, or (at your option) any later version.
00006  *
00007  * This program is distributed in the hope that it will be useful, but
00008  * WITHOUT ANY WARRANTY; without even the implied warranty of
00009  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00010  * General Public License for more details.
00011  *
00012  * You should have received a copy of the GNU General Public License
00013  * along with this program; if not, write to the Free Software
00014  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00015  * 02110-1301, USA.
00016  */
00017 
00018 FILE_LICENCE ( GPL2_OR_LATER );
00019 
00020 #ifndef NIC_H
00021 #define NIC_H
00022 
00023 #include <stdint.h>
00024 #include <string.h>
00025 #include <stdio.h>
00026 #include <byteswap.h>
00027 #include <ipxe/pci.h>
00028 #include <ipxe/isapnp.h>
00029 #include <ipxe/isa.h>
00030 #include <ipxe/eisa.h>
00031 #include <ipxe/mca.h>
00032 #include <ipxe/io.h>
00033 
00034 typedef enum {
00035         DISABLE = 0,
00036         ENABLE,
00037         FORCE
00038 } irq_action_t;
00039 
00040 typedef enum duplex {
00041         HALF_DUPLEX = 1,
00042         FULL_DUPLEX
00043 } duplex_t;
00044 
00045 /*
00046  *      Structure returned from eth_probe and passed to other driver
00047  *      functions.
00048  */
00049 struct nic {
00050         struct nic_operations   *nic_op;
00051         int                     flags;  /* driver specific flags */
00052         unsigned char           *node_addr;
00053         unsigned char           *packet;
00054         unsigned int            packetlen;
00055         unsigned int            ioaddr;
00056         unsigned char           irqno;
00057         unsigned int            mbps;
00058         duplex_t                duplex;
00059         void                    *priv_data;     /* driver private data */
00060 };
00061 
00062 struct nic_operations {
00063         int ( *connect ) ( struct nic * );
00064         int ( *poll ) ( struct nic *, int retrieve );
00065         void ( *transmit ) ( struct nic *, const char *,
00066                              unsigned int, unsigned int, const char * );
00067         void ( *irq ) ( struct nic *, irq_action_t );
00068 };
00069 
00070 extern struct nic nic;
00071 
00072 static inline int eth_poll ( int retrieve ) {
00073         return nic.nic_op->poll ( &nic, retrieve );
00074 }
00075 
00076 static inline void eth_transmit ( const char *dest, unsigned int type,
00077                                   unsigned int size, const void *packet ) {
00078         nic.nic_op->transmit ( &nic, dest, type, size, packet );
00079 }
00080 
00081 /*
00082  * Function prototypes
00083  *
00084  */
00085 extern int dummy_connect ( struct nic *nic );
00086 extern void dummy_irq ( struct nic *nic, irq_action_t irq_action );
00087 extern int legacy_probe ( void *hwdev,
00088                           void ( * set_drvdata ) ( void *hwdev, void *priv ),
00089                           struct device *dev,
00090                           int ( * probe ) ( struct nic *nic, void *hwdev ),
00091                           void ( * disable ) ( struct nic *nic, void *hwdev ));
00092 void legacy_remove ( void *hwdev,
00093                      void * ( * get_drvdata ) ( void *hwdev ),
00094                      void ( * disable ) ( struct nic *nic, void *hwdev ) );
00095 
00096 #define PCI_DRIVER(_name,_ids,_class)                                     \
00097         static inline int                                                 \
00098         _name ## _pci_legacy_probe ( struct pci_device *pci );            \
00099         static inline void                                                \
00100         _name ## _pci_legacy_remove ( struct pci_device *pci );           \
00101         struct pci_driver _name __pci_driver = {                          \
00102                 .ids = _ids,                                              \
00103                 .id_count = sizeof ( _ids ) / sizeof ( _ids[0] ),         \
00104                 .probe = _name ## _pci_legacy_probe,                      \
00105                 .remove = _name ## _pci_legacy_remove,                    \
00106         };                                                                \
00107         REQUIRE_OBJECT ( pci );
00108 
00109 static inline void legacy_pci_set_drvdata ( void *hwdev, void *priv ) {
00110         pci_set_drvdata ( hwdev, priv );
00111 }
00112 static inline void * legacy_pci_get_drvdata ( void *hwdev ) {
00113         return pci_get_drvdata ( hwdev );
00114 }
00115 
00116 #define ISAPNP_DRIVER(_name,_ids)                                         \
00117         static inline int                                                 \
00118         _name ## _isapnp_legacy_probe ( struct isapnp_device *isapnp,     \
00119                                         const struct isapnp_device_id *id ); \
00120         static inline void                                                \
00121         _name ## _isapnp_legacy_remove ( struct isapnp_device *isapnp );  \
00122         struct isapnp_driver _name __isapnp_driver = {                    \
00123                 .ids = _ids,                                              \
00124                 .id_count = sizeof ( _ids ) / sizeof ( _ids[0] ),         \
00125                 .probe = _name ## _isapnp_legacy_probe,                   \
00126                 .remove = _name ## _isapnp_legacy_remove,                 \
00127         };                                                                \
00128         REQUIRE_OBJECT ( isapnp );
00129 
00130 static inline void legacy_isapnp_set_drvdata ( void *hwdev, void *priv ) {
00131         isapnp_set_drvdata ( hwdev, priv );
00132 }
00133 static inline void * legacy_isapnp_get_drvdata ( void *hwdev ) {
00134         return isapnp_get_drvdata ( hwdev );
00135 }
00136 
00137 #define EISA_DRIVER(_name,_ids)                                           \
00138         static inline int                                                 \
00139         _name ## _eisa_legacy_probe ( struct eisa_device *eisa,           \
00140                                       const struct eisa_device_id *id );  \
00141         static inline void                                                \
00142         _name ## _eisa_legacy_remove ( struct eisa_device *eisa );        \
00143         struct eisa_driver _name __eisa_driver = {                        \
00144                 .ids = _ids,                                              \
00145                 .id_count = sizeof ( _ids ) / sizeof ( _ids[0] ),         \
00146                 .probe = _name ## _eisa_legacy_probe,                     \
00147                 .remove = _name ## _eisa_legacy_remove,                   \
00148         };                                                                \
00149         REQUIRE_OBJECT ( eisa );
00150 
00151 static inline void legacy_eisa_set_drvdata ( void *hwdev, void *priv ) {
00152         eisa_set_drvdata ( hwdev, priv );
00153 }
00154 static inline void * legacy_eisa_get_drvdata ( void *hwdev ) {
00155         return eisa_get_drvdata ( hwdev );
00156 }
00157 
00158 #define MCA_DRIVER(_name,_ids)                                            \
00159         static inline int                                                 \
00160         _name ## _mca_legacy_probe ( struct mca_device *mca,              \
00161                                      const struct mca_device_id *id );    \
00162         static inline void                                                \
00163         _name ## _mca_legacy_remove ( struct mca_device *mca );           \
00164         struct mca_driver _name __mca_driver = {                          \
00165                 .ids = _ids,                                              \
00166                 .id_count = sizeof ( _ids ) / sizeof ( _ids[0] ),         \
00167                 .probe = _name ## _mca_legacy_probe,                      \
00168                 .remove = _name ## _mca_legacy_remove,                    \
00169         };                                                                \
00170         REQUIRE_OBJECT ( mca );
00171 
00172 static inline void legacy_mca_set_drvdata ( void *hwdev, void *priv ) {
00173         mca_set_drvdata ( hwdev, priv );
00174 }
00175 static inline void * legacy_mca_get_drvdata ( void *hwdev ) {
00176         return mca_get_drvdata ( hwdev );
00177 }
00178 
00179 #define ISA_DRIVER(_name,_probe_addrs,_probe_addr,_vendor_id,_prod_id)    \
00180         static inline int                                                 \
00181         _name ## _isa_legacy_probe ( struct isa_device *isa );            \
00182         static inline int                                                 \
00183         _name ## _isa_legacy_probe_at_addr ( struct isa_device *isa ) {   \
00184                 if ( ! _probe_addr ( isa->ioaddr ) )                      \
00185                         return -ENODEV;                                   \
00186                 return _name ## _isa_legacy_probe ( isa );                \
00187         }                                                                 \
00188         static inline void                                                \
00189         _name ## _isa_legacy_remove ( struct isa_device *isa );           \
00190         static const char _name ## _text[];                               \
00191         struct isa_driver _name __isa_driver = {                          \
00192                 .name = _name ## _text,                                   \
00193                 .probe_addrs = _probe_addrs,                              \
00194                 .addr_count = ( sizeof ( _probe_addrs ) /                 \
00195                                 sizeof ( _probe_addrs[0] ) ),             \
00196                 .vendor_id = _vendor_id,                                  \
00197                 .prod_id = _prod_id,                                      \
00198                 .probe = _name ## _isa_legacy_probe_at_addr,              \
00199                 .remove = _name ## _isa_legacy_remove,                    \
00200         };                                                                \
00201         REQUIRE_OBJECT ( isa );
00202 
00203 static inline void legacy_isa_set_drvdata ( void *hwdev, void *priv ) {
00204         isa_set_drvdata ( hwdev, priv );
00205 }
00206 static inline void * legacy_isa_get_drvdata ( void *hwdev ) {
00207         return isa_get_drvdata ( hwdev );
00208 }
00209 
00210 #undef DRIVER
00211 #define DRIVER(_name_text,_unused2,_unused3,_name,_probe,_disable)        \
00212         static __attribute__ (( unused )) const char                      \
00213         _name ## _text[] = _name_text;                                    \
00214         static inline int                                                 \
00215         _name ## _probe ( struct nic *nic, void *hwdev ) {                \
00216                 return _probe ( nic, hwdev );                             \
00217         }                                                                 \
00218         static inline void                                                \
00219         _name ## _disable ( struct nic *nic, void *hwdev ) {              \
00220                 void ( * _unsafe_disable ) () = _disable;                 \
00221                 _unsafe_disable ( nic, hwdev );                           \
00222         }                                                                 \
00223         static inline int                                                 \
00224         _name ## _pci_legacy_probe ( struct pci_device *pci ) {           \
00225                 return legacy_probe ( pci, legacy_pci_set_drvdata,        \
00226                                       &pci->dev, _name ## _probe,         \
00227                                       _name ## _disable );                \
00228         }                                                                 \
00229         static inline void                                                \
00230         _name ## _pci_legacy_remove ( struct pci_device *pci ) {          \
00231                 return legacy_remove ( pci, legacy_pci_get_drvdata,       \
00232                                        _name ## _disable );               \
00233         }                                                                 \
00234         static inline int                                                 \
00235         _name ## _isapnp_legacy_probe ( struct isapnp_device *isapnp,     \
00236                          const struct isapnp_device_id *id __unused ) {   \
00237                 return legacy_probe ( isapnp, legacy_isapnp_set_drvdata,  \
00238                                       &isapnp->dev, _name ## _probe,      \
00239                                       _name ## _disable );                \
00240         }                                                                 \
00241         static inline void                                                \
00242         _name ## _isapnp_legacy_remove ( struct isapnp_device *isapnp ) { \
00243                 return legacy_remove ( isapnp, legacy_isapnp_get_drvdata, \
00244                                        _name ## _disable );               \
00245         }                                                                 \
00246         static inline int                                                 \
00247         _name ## _eisa_legacy_probe ( struct eisa_device *eisa,           \
00248                              const struct eisa_device_id *id __unused ) { \
00249                 return legacy_probe ( eisa, legacy_eisa_set_drvdata,      \
00250                                       &eisa->dev, _name ## _probe,        \
00251                                       _name ## _disable );                \
00252         }                                                                 \
00253         static inline void                                                \
00254         _name ## _eisa_legacy_remove ( struct eisa_device *eisa ) {       \
00255                 return legacy_remove ( eisa, legacy_eisa_get_drvdata,     \
00256                                        _name ## _disable );               \
00257         }                                                                 \
00258         static inline int                                                 \
00259         _name ## _mca_legacy_probe ( struct mca_device *mca,              \
00260                               const struct mca_device_id *id __unused ) { \
00261                 return legacy_probe ( mca, legacy_mca_set_drvdata,        \
00262                                       &mca->dev, _name ## _probe,         \
00263                                       _name ## _disable );                \
00264         }                                                                 \
00265         static inline void                                                \
00266         _name ## _mca_legacy_remove ( struct mca_device *mca ) {          \
00267                 return legacy_remove ( mca, legacy_mca_get_drvdata,       \
00268                                        _name ## _disable );               \
00269         }                                                                 \
00270         static inline int                                                 \
00271         _name ## _isa_legacy_probe ( struct isa_device *isa ) {           \
00272                 return legacy_probe ( isa, legacy_isa_set_drvdata,        \
00273                                       &isa->dev, _name ## _probe,         \
00274                                       _name ## _disable );                \
00275         }                                                                 \
00276         static inline void                                                \
00277         _name ## _isa_legacy_remove ( struct isa_device *isa ) {          \
00278                 return legacy_remove ( isa, legacy_isa_get_drvdata,       \
00279                                        _name ## _disable );               \
00280         }                                                                 \
00281         PROVIDE_REQUIRING_SYMBOL()
00282 
00283 #endif  /* NIC_H */