iPXE
intelxl.h
Go to the documentation of this file.
00001 #ifndef _INTELX_H
00002 #define _INTELX_H
00003 
00004 /** @file
00005  *
00006  * Intel 40 Gigabit Ethernet network card driver
00007  *
00008  */
00009 
00010 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
00011 
00012 #include <stdint.h>
00013 #include <ipxe/if_ether.h>
00014 
00015 struct intelxl_nic;
00016 
00017 /** BAR size */
00018 #define INTELXL_BAR_SIZE 0x200000
00019 
00020 /** Alignment
00021  *
00022  * No data structure requires greater than 128 byte alignment.
00023  */
00024 #define INTELXL_ALIGN 128
00025 
00026 /******************************************************************************
00027  *
00028  * Admin queue
00029  *
00030  ******************************************************************************
00031  */
00032 
00033 /** PF Admin Command Queue register block */
00034 #define INTELXL_ADMIN_CMD 0x080000
00035 
00036 /** PF Admin Event Queue register block */
00037 #define INTELXL_ADMIN_EVT 0x080080
00038 
00039 /** Admin Queue Base Address Low Register (offset) */
00040 #define INTELXL_ADMIN_BAL 0x000
00041 
00042 /** Admin Queue Base Address High Register (offset) */
00043 #define INTELXL_ADMIN_BAH 0x100
00044 
00045 /** Admin Queue Length Register (offset) */
00046 #define INTELXL_ADMIN_LEN 0x200
00047 #define INTELXL_ADMIN_LEN_LEN(x)        ( (x) << 0 )    /**< Queue length */
00048 #define INTELXL_ADMIN_LEN_ENABLE        0x80000000UL    /**< Queue enable */
00049 
00050 /** Admin Queue Head Register (offset) */
00051 #define INTELXL_ADMIN_HEAD 0x300
00052 
00053 /** Admin Queue Tail Register (offset) */
00054 #define INTELXL_ADMIN_TAIL 0x400
00055 
00056 /** Admin queue data buffer command parameters */
00057 struct intelxl_admin_buffer_params {
00058         /** Reserved */
00059         uint8_t reserved[8];
00060         /** Buffer address high */
00061         uint32_t high;
00062         /** Buffer address low */
00063         uint32_t low;
00064 } __attribute__ (( packed ));
00065 
00066 /** Admin queue Get Version command */
00067 #define INTELXL_ADMIN_VERSION 0x0001
00068 
00069 /** Admin queue version number */
00070 struct intelxl_admin_version {
00071         /** Major version number */
00072         uint16_t major;
00073         /** Minor version number */
00074         uint16_t minor;
00075 } __attribute__ (( packed ));
00076 
00077 /** Admin queue Get Version command parameters */
00078 struct intelxl_admin_version_params {
00079         /** ROM version */
00080         uint32_t rom;
00081         /** Firmware build ID */
00082         uint32_t build;
00083         /** Firmware version */
00084         struct intelxl_admin_version firmware;
00085         /** API version */
00086         struct intelxl_admin_version api;
00087 } __attribute__ (( packed ));
00088 
00089 /** Admin queue Driver Version command */
00090 #define INTELXL_ADMIN_DRIVER 0x0002
00091 
00092 /** Admin queue Driver Version command parameters */
00093 struct intelxl_admin_driver_params {
00094         /** Driver version */
00095         uint8_t major;
00096         /** Minor version */
00097         uint8_t minor;
00098         /** Build version */
00099         uint8_t build;
00100         /** Sub-build version */
00101         uint8_t sub;
00102         /** Reserved */
00103         uint8_t reserved[4];
00104         /** Data buffer address */
00105         uint64_t address;
00106 } __attribute__ (( packed ));
00107 
00108 /** Admin queue Driver Version data buffer */
00109 struct intelxl_admin_driver_buffer {
00110         /** Driver name */
00111         char name[32];
00112 } __attribute__ (( packed ));
00113 
00114 /** Admin queue Shutdown command */
00115 #define INTELXL_ADMIN_SHUTDOWN 0x0003
00116 
00117 /** Admin queue Shutdown command parameters */
00118 struct intelxl_admin_shutdown_params {
00119         /** Driver unloading */
00120         uint8_t unloading;
00121         /** Reserved */
00122         uint8_t reserved[15];
00123 } __attribute__ (( packed ));
00124 
00125 /** Driver is unloading */
00126 #define INTELXL_ADMIN_SHUTDOWN_UNLOADING 0x01
00127 
00128 /** Admin queue Get Switch Configuration command */
00129 #define INTELXL_ADMIN_SWITCH 0x0200
00130 
00131 /** Switching element configuration */
00132 struct intelxl_admin_switch_config {
00133         /** Switching element type */
00134         uint8_t type;
00135         /** Revision */
00136         uint8_t revision;
00137         /** Switching element ID */
00138         uint16_t seid;
00139         /** Uplink switching element ID */
00140         uint16_t uplink;
00141         /** Downlink switching element ID */
00142         uint16_t downlink;
00143         /** Reserved */
00144         uint8_t reserved_b[3];
00145         /** Connection type */
00146         uint8_t connection;
00147         /** Reserved */
00148         uint8_t reserved_c[2];
00149         /** Element specific information */
00150         uint16_t info;
00151 } __attribute__ (( packed ));
00152 
00153 /** Virtual Station Inferface element type */
00154 #define INTELXL_ADMIN_SWITCH_TYPE_VSI 19
00155 
00156 /** Admin queue Get Switch Configuration command parameters */
00157 struct intelxl_admin_switch_params {
00158         /** Starting switching element identifier */
00159         uint16_t next;
00160         /** Reserved */
00161         uint8_t reserved[6];
00162         /** Data buffer address */
00163         uint64_t address;
00164 } __attribute__ (( packed ));
00165 
00166 /** Admin queue Get Switch Configuration data buffer */
00167 struct intelxl_admin_switch_buffer {
00168         /** Number of switching elements reported */
00169         uint16_t count;
00170         /** Total number of switching elements */
00171         uint16_t total;
00172         /** Reserved */
00173         uint8_t reserved_a[12];
00174         /** Switch configuration */
00175         struct intelxl_admin_switch_config cfg;
00176 } __attribute__ (( packed ));
00177 
00178 /** Admin queue Get VSI Parameters command */
00179 #define INTELXL_ADMIN_VSI 0x0212
00180 
00181 /** Admin queue Get VSI Parameters command parameters */
00182 struct intelxl_admin_vsi_params {
00183         /** VSI switching element ID */
00184         uint16_t vsi;
00185         /** Reserved */
00186         uint8_t reserved[6];
00187         /** Data buffer address */
00188         uint64_t address;
00189 } __attribute__ (( packed ));
00190 
00191 /** Admin queue Get VSI Parameters data buffer */
00192 struct intelxl_admin_vsi_buffer {
00193         /** Reserved */
00194         uint8_t reserved_a[30];
00195         /** Queue numbers */
00196         uint16_t queue[16];
00197         /** Reserved */
00198         uint8_t reserved_b[34];
00199         /** Queue set handles for each traffic class */
00200         uint16_t qset[8];
00201         /** Reserved */
00202         uint8_t reserved_c[16];
00203 } __attribute__ (( packed ));
00204 
00205 /** Admin queue Set VSI Promiscuous Modes command */
00206 #define INTELXL_ADMIN_PROMISC 0x0254
00207 
00208 /** Admin queue Set VSI Promiscuous Modes command parameters */
00209 struct intelxl_admin_promisc_params {
00210         /** Flags */
00211         uint16_t flags;
00212         /** Valid flags */
00213         uint16_t valid;
00214         /** VSI switching element ID */
00215         uint16_t vsi;
00216         /** Reserved */
00217         uint8_t reserved[10];
00218 } __attribute__ (( packed ));
00219 
00220 /** Promiscuous unicast mode */
00221 #define INTELXL_ADMIN_PROMISC_FL_UNICAST 0x0001
00222 
00223 /** Promiscuous multicast mode */
00224 #define INTELXL_ADMIN_PROMISC_FL_MULTICAST 0x0002
00225 
00226 /** Promiscuous broadcast mode */
00227 #define INTELXL_ADMIN_PROMISC_FL_BROADCAST 0x0004
00228 
00229 /** Promiscuous VLAN mode */
00230 #define INTELXL_ADMIN_PROMISC_FL_VLAN 0x0010
00231 
00232 /** Admin queue Restart Autonegotiation command */
00233 #define INTELXL_ADMIN_AUTONEG 0x0605
00234 
00235 /** Admin queue Restart Autonegotiation command parameters */
00236 struct intelxl_admin_autoneg_params {
00237         /** Flags */
00238         uint8_t flags;
00239         /** Reserved */
00240         uint8_t reserved[15];
00241 } __attribute__ (( packed ));
00242 
00243 /** Restart autonegotiation */
00244 #define INTELXL_ADMIN_AUTONEG_FL_RESTART 0x02
00245 
00246 /** Enable link */
00247 #define INTELXL_ADMIN_AUTONEG_FL_ENABLE 0x04
00248 
00249 /** Admin queue Get Link Status command */
00250 #define INTELXL_ADMIN_LINK 0x0607
00251 
00252 /** Admin queue Get Link Status command parameters */
00253 struct intelxl_admin_link_params {
00254         /** Link status notification */
00255         uint8_t notify;
00256         /** Reserved */
00257         uint8_t reserved_a;
00258         /** PHY type */
00259         uint8_t phy;
00260         /** Link speed */
00261         uint8_t speed;
00262         /** Link status */
00263         uint8_t status;
00264         /** Reserved */
00265         uint8_t reserved_b[11];
00266 } __attribute__ (( packed ));
00267 
00268 /** Notify driver of link status changes */
00269 #define INTELXL_ADMIN_LINK_NOTIFY 0x03
00270 
00271 /** Link is up */
00272 #define INTELXL_ADMIN_LINK_UP 0x01
00273 
00274 /** Admin queue command parameters */
00275 union intelxl_admin_params {
00276         /** Additional data buffer command parameters */
00277         struct intelxl_admin_buffer_params buffer;
00278         /** Get Version command parameters */
00279         struct intelxl_admin_version_params version;
00280         /** Driver Version command parameters */
00281         struct intelxl_admin_driver_params driver;
00282         /** Shutdown command parameters */
00283         struct intelxl_admin_shutdown_params shutdown;
00284         /** Get Switch Configuration command parameters */
00285         struct intelxl_admin_switch_params sw;
00286         /** Get VSI Parameters command parameters */
00287         struct intelxl_admin_vsi_params vsi;
00288         /** Set VSI Promiscuous Modes command parameters */
00289         struct intelxl_admin_promisc_params promisc;
00290         /** Restart Autonegotiation command parameters */
00291         struct intelxl_admin_autoneg_params autoneg;
00292         /** Get Link Status command parameters */
00293         struct intelxl_admin_link_params link;
00294 } __attribute__ (( packed ));
00295 
00296 /** Admin queue data buffer */
00297 union intelxl_admin_buffer {
00298         /** Driver Version data buffer */
00299         struct intelxl_admin_driver_buffer driver;
00300         /** Get Switch Configuration data buffer */
00301         struct intelxl_admin_switch_buffer sw;
00302         /** Get VSI Parameters data buffer */
00303         struct intelxl_admin_vsi_buffer vsi;
00304 } __attribute__ (( packed ));
00305 
00306 /** Admin queue descriptor */
00307 struct intelxl_admin_descriptor {
00308         /** Flags */
00309         uint16_t flags;
00310         /** Opcode */
00311         uint16_t opcode;
00312         /** Data length */
00313         uint16_t len;
00314         /** Return value */
00315         uint16_t ret;
00316         /** Cookie */
00317         uint32_t cookie;
00318         /** Reserved */
00319         uint32_t reserved;
00320         /** Parameters */
00321         union intelxl_admin_params params;
00322 } __attribute__ (( packed ));
00323 
00324 /** Admin descriptor done */
00325 #define INTELXL_ADMIN_FL_DD 0x0001
00326 
00327 /** Admin descriptor contains a completion */
00328 #define INTELXL_ADMIN_FL_CMP 0x0002
00329 
00330 /** Admin descriptor completed in error */
00331 #define INTELXL_ADMIN_FL_ERR 0x0004
00332 
00333 /** Admin descriptor uses data buffer for command parameters */
00334 #define INTELXL_ADMIN_FL_RD 0x0400
00335 
00336 /** Admin descriptor uses data buffer */
00337 #define INTELXL_ADMIN_FL_BUF 0x1000
00338 
00339 /** Admin queue */
00340 struct intelxl_admin {
00341         /** Descriptors */
00342         struct intelxl_admin_descriptor *desc;
00343         /** Queue index */
00344         unsigned int index;
00345 
00346         /** Register block */
00347         unsigned int reg;
00348         /** Data buffer */
00349         union intelxl_admin_buffer *buffer;
00350 };
00351 
00352 /**
00353  * Initialise admin queue
00354  *
00355  * @v admin             Admin queue
00356  * @v reg               Register block
00357  */
00358 static inline __attribute__ (( always_inline )) void
00359 intelxl_init_admin ( struct intelxl_admin *admin, unsigned int reg ) {
00360 
00361         admin->reg = reg;
00362 }
00363 
00364 /** Number of admin queue descriptors */
00365 #define INTELXL_ADMIN_NUM_DESC 4
00366 
00367 /** Maximum time to wait for an admin request to complete */
00368 #define INTELXL_ADMIN_MAX_WAIT_MS 100
00369 
00370 /** Admin queue API major version */
00371 #define INTELXL_ADMIN_API_MAJOR 1
00372 
00373 /******************************************************************************
00374  *
00375  * Transmit and receive queue context
00376  *
00377  ******************************************************************************
00378  */
00379 
00380 /** CMLAN Context Data Register */
00381 #define INTELXL_PFCM_LANCTXDATA(x) ( 0x10c100 + ( 0x80 * (x) ) )
00382 
00383 /** CMLAN Context Control Register */
00384 #define INTELXL_PFCM_LANCTXCTL 0x10c300
00385 #define INTELXL_PFCM_LANCTXCTL_QUEUE_NUM(x) \
00386         ( (x) << 0 )                                    /**< Queue number */
00387 #define INTELXL_PFCM_LANCTXCTL_SUB_LINE(x) \
00388         ( (x) << 12 )                                   /**< Sub-line */
00389 #define INTELXL_PFCM_LANCTXCTL_TYPE(x) \
00390         ( (x) << 15 )                                   /**< Queue type */
00391 #define INTELXL_PFCM_LANCTXCTL_TYPE_RX \
00392         INTELXL_PFCM_LANCTXCTL_TYPE ( 0x0 )             /**< RX queue type */
00393 #define INTELXL_PFCM_LANCTXCTL_TYPE_TX \
00394         INTELXL_PFCM_LANCTXCTL_TYPE ( 0x1 )             /**< TX queue type */
00395 #define INTELXL_PFCM_LANCTXCTL_OP_CODE(x) \
00396         ( (x) << 17 )                                   /**< Op code */
00397 #define INTELXL_PFCM_LANCTXCTL_OP_CODE_READ \
00398         INTELXL_PFCM_LANCTXCTL_OP_CODE ( 0x0 )          /**< Read context */
00399 #define INTELXL_PFCM_LANCTXCTL_OP_CODE_WRITE \
00400         INTELXL_PFCM_LANCTXCTL_OP_CODE ( 0x1 )          /**< Write context */
00401 
00402 /** CMLAN Context Status Register */
00403 #define INTELXL_PFCM_LANCTXSTAT 0x10c380
00404 #define INTELXL_PFCM_LANCTXSTAT_DONE   0x00000001UL     /**< Complete */
00405 
00406 /** Queue context line */
00407 struct intelxl_context_line {
00408         /** Raw data */
00409         uint32_t raw[4];
00410 } __attribute__ (( packed ));
00411 
00412 /** Transmit queue context */
00413 struct intelxl_context_tx {
00414         /** Head pointer */
00415         uint16_t head;
00416         /** Flags */
00417         uint16_t flags;
00418         /** Base address */
00419         uint64_t base;
00420         /** Reserved */
00421         uint8_t reserved_a[8];
00422         /** Queue count */
00423         uint16_t count;
00424         /** Reserved */
00425         uint8_t reserved_b[100];
00426         /** Queue set */
00427         uint16_t qset;
00428         /** Reserved */
00429         uint8_t reserved_c[4];
00430 } __attribute__ (( packed ));
00431 
00432 /** New transmit queue context */
00433 #define INTELXL_CTX_TX_FL_NEW 0x4000
00434 
00435 /** Transmit queue base address */
00436 #define INTELXL_CTX_TX_BASE( base ) ( (base) >> 7 )
00437 
00438 /** Transmit queue count */
00439 #define INTELXL_CTX_TX_COUNT( count ) ( (count) << 1 )
00440 
00441 /** Transmit queue set */
00442 #define INTELXL_CTX_TX_QSET( qset) ( (qset) << 4 )
00443 
00444 /** Receive queue context */
00445 struct intelxl_context_rx {
00446         /** Head pointer */
00447         uint16_t head;
00448         /** Reserved */
00449         uint8_t reserved_a[2];
00450         /** Base address and queue count */
00451         uint64_t base_count;
00452         /** Data buffer length */
00453         uint16_t len;
00454         /** Flags */
00455         uint8_t flags;
00456         /** Reserved */
00457         uint8_t reserved_b[7];
00458         /** Maximum frame size */
00459         uint16_t mfs;
00460 } __attribute__ (( packed ));
00461 
00462 /** Receive queue base address and queue count */
00463 #define INTELXL_CTX_RX_BASE_COUNT( base, count ) \
00464         ( ( (base) >> 7 ) | ( ( ( uint64_t ) (count) ) << 57 ) )
00465 
00466 /** Receive queue data buffer length */
00467 #define INTELXL_CTX_RX_LEN( len ) ( (len) >> 1 )
00468 
00469 /** Strip CRC from received packets */
00470 #define INTELXL_CTX_RX_FL_CRCSTRIP 0x20
00471 
00472 /** Receive queue maximum frame size */
00473 #define INTELXL_CTX_RX_MFS( mfs ) ( (mfs) >> 2 )
00474 
00475 /** Maximum time to wait for a context operation to complete */
00476 #define INTELXL_CTX_MAX_WAIT_MS 100
00477 
00478 /** Time to wait for a queue to become enabled */
00479 #define INTELXL_QUEUE_ENABLE_DELAY_US 20
00480 
00481 /** Time to wait for a transmit queue to become pre-disabled */
00482 #define INTELXL_QUEUE_PRE_DISABLE_DELAY_US 400
00483 
00484 /** Maximum time to wait for a queue to become disabled */
00485 #define INTELXL_QUEUE_DISABLE_MAX_WAIT_MS 1000
00486 
00487 /******************************************************************************
00488  *
00489  * Transmit and receive descriptors
00490  *
00491  ******************************************************************************
00492  */
00493 
00494 /** Global Transmit Queue Head register */
00495 #define INTELXL_QTX_HEAD(x) ( 0x0e4000 + ( 0x4 * (x) ) )
00496 
00497 /** Global Transmit Pre Queue Disable register */
00498 #define INTELXL_GLLAN_TXPRE_QDIS(x) ( 0x0e6500 + ( 0x4 * ( (x) / 0x80 ) ) )
00499 #define INTELXL_GLLAN_TXPRE_QDIS_QINDX(x) \
00500         ( (x) << 0 )                                    /**< Queue index */
00501 #define INTELXL_GLLAN_TXPRE_QDIS_SET_QDIS \
00502         0x40000000UL                                    /**< Set disable */
00503 #define INTELXL_GLLAN_TXPRE_QDIS_CLEAR_QDIS                             \
00504         0x80000000UL                                    /**< Clear disable */
00505 
00506 /** Global Transmit Queue register block */
00507 #define INTELXL_QTX(x) ( 0x100000 + ( 0x4 * (x) ) )
00508 
00509 /** Global Receive Queue register block */
00510 #define INTELXL_QRX(x) ( 0x120000 + ( 0x4 * (x) ) )
00511 
00512 /** Queue Enable Register (offset) */
00513 #define INTELXL_QXX_ENA 0x0000
00514 #define INTELXL_QXX_ENA_REQ             0x00000001UL    /**< Enable request */
00515 #define INTELXL_QXX_ENA_STAT            0x00000004UL    /**< Enabled status */
00516 
00517 /** Queue Control Register (offset) */
00518 #define INTELXL_QXX_CTL 0x4000
00519 #define INTELXL_QXX_CTL_PFVF_Q(x)       ( (x) << 0 )    /**< PF/VF queue */
00520 #define INTELXL_QXX_CTL_PFVF_Q_PF \
00521         INTELXL_QXX_CTL_PFVF_Q ( 0x2 )                  /**< PF queue */
00522 #define INTELXL_QXX_CTL_PFVF_PF_INDX(x) ( (x) << 2 )    /**< PF index */
00523 
00524 /** Queue Tail Pointer Register (offset) */
00525 #define INTELXL_QXX_TAIL 0x8000
00526 
00527 /** Transmit data descriptor */
00528 struct intelxl_tx_data_descriptor {
00529         /** Buffer address */
00530         uint64_t address;
00531         /** Flags */
00532         uint32_t flags;
00533         /** Length */
00534         uint32_t len;
00535 } __attribute__ (( packed ));
00536 
00537 /** Transmit data descriptor type */
00538 #define INTELXL_TX_DATA_DTYP 0x0
00539 
00540 /** Transmit data descriptor end of packet */
00541 #define INTELXL_TX_DATA_EOP 0x10
00542 
00543 /** Transmit data descriptor report status */
00544 #define INTELXL_TX_DATA_RS 0x20
00545 
00546 /** Transmit data descriptor pretty please
00547  *
00548  * This bit is completely missing from older versions of the XL710
00549  * datasheet.  Later versions describe it innocuously as "reserved,
00550  * must be 1".  Without this bit, everything will appear to work (up
00551  * to and including the port "transmit good octets" counter), but no
00552  * packet will actually be sent.
00553  */
00554 #define INTELXL_TX_DATA_JFDI 0x40
00555 
00556 /** Transmit data descriptor length */
00557 #define INTELXL_TX_DATA_LEN( len ) ( (len) << 2 )
00558 
00559 /** Transmit writeback descriptor */
00560 struct intelxl_tx_writeback_descriptor {
00561         /** Reserved */
00562         uint8_t reserved_a[8];
00563         /** Flags */
00564         uint8_t flags;
00565         /** Reserved */
00566         uint8_t reserved_b[7];
00567 } __attribute__ (( packed ));
00568 
00569 /** Transmit writeback descriptor complete */
00570 #define INTELXL_TX_WB_FL_DD 0x01
00571 
00572 /** Receive data descriptor */
00573 struct intelxl_rx_data_descriptor {
00574         /** Buffer address */
00575         uint64_t address;
00576         /** Flags */
00577         uint32_t flags;
00578         /** Reserved */
00579         uint8_t reserved[4];
00580 } __attribute__ (( packed ));
00581 
00582 /** Receive writeback descriptor */
00583 struct intelxl_rx_writeback_descriptor {
00584         /** Reserved */
00585         uint8_t reserved[8];
00586         /** Flags */
00587         uint32_t flags;
00588         /** Length */
00589         uint32_t len;
00590 } __attribute__ (( packed ));
00591 
00592 /** Receive writeback descriptor complete */
00593 #define INTELXL_RX_WB_FL_DD 0x00000001UL
00594 
00595 /** Receive writeback descriptor error */
00596 #define INTELXL_RX_WB_FL_RXE 0x00080000UL
00597 
00598 /** Receive writeback descriptor length */
00599 #define INTELXL_RX_WB_LEN(len) ( ( (len) >> 6 ) & 0x3fff )
00600 
00601 /** Packet descriptor */
00602 union intelxl_descriptor {
00603         /** Transmit data descriptor */
00604         struct intelxl_tx_data_descriptor tx;
00605         /** Transmit writeback descriptor */
00606         struct intelxl_tx_writeback_descriptor tx_wb;
00607         /** Receive data descriptor */
00608         struct intelxl_rx_data_descriptor rx;
00609         /** Receive writeback descriptor */
00610         struct intelxl_rx_writeback_descriptor rx_wb;
00611 };
00612 
00613 /** Descriptor ring */
00614 struct intelxl_ring {
00615         /** Descriptors */
00616         union intelxl_descriptor *desc;
00617         /** Producer index */
00618         unsigned int prod;
00619         /** Consumer index */
00620         unsigned int cons;
00621 
00622         /** Register block */
00623         unsigned int reg;
00624         /** Length (in bytes) */
00625         size_t len;
00626         /** Program queue context
00627          *
00628          * @v intelxl           Intel device
00629          * @v address           Descriptor ring base address
00630          */
00631         int ( * context ) ( struct intelxl_nic *intelxl, physaddr_t address );
00632 };
00633 
00634 /**
00635  * Initialise descriptor ring
00636  *
00637  * @v ring              Descriptor ring
00638  * @v count             Number of descriptors
00639  * @v context           Method to program queue context
00640  */
00641 static inline __attribute__ (( always_inline)) void
00642 intelxl_init_ring ( struct intelxl_ring *ring, unsigned int count,
00643                     int ( * context ) ( struct intelxl_nic *intelxl,
00644                                         physaddr_t address ) ) {
00645 
00646         ring->len = ( count * sizeof ( ring->desc[0] ) );
00647         ring->context = context;
00648 }
00649 
00650 /** Number of transmit descriptors */
00651 #define INTELXL_TX_NUM_DESC 16
00652 
00653 /** Transmit descriptor ring maximum fill level */
00654 #define INTELXL_TX_FILL ( INTELXL_TX_NUM_DESC - 1 )
00655 
00656 /** Number of receive descriptors
00657  *
00658  * In PXE mode (i.e. able to post single receive descriptors), 8
00659  * descriptors is the only permitted value covering all possible
00660  * numbers of PFs.
00661  */
00662 #define INTELXL_RX_NUM_DESC 8
00663 
00664 /** Receive descriptor ring fill level */
00665 #define INTELXL_RX_FILL ( INTELXL_RX_NUM_DESC - 1 )
00666 
00667 /******************************************************************************
00668  *
00669  * Top level
00670  *
00671  ******************************************************************************
00672  */
00673 
00674 /** PF Interrupt Zero Dynamic Control Register */
00675 #define INTELXL_PFINT_DYN_CTL0 0x038480
00676 #define INTELXL_PFINT_DYN_CTL0_INTENA   0x00000001UL    /**< Enable */
00677 #define INTELXL_PFINT_DYN_CTL0_CLEARPBA 0x00000002UL    /**< Acknowledge */
00678 #define INTELXL_PFINT_DYN_CTL0_INTENA_MASK 0x80000000UL /**< Ignore enable */
00679 
00680 /** PF Interrupt Zero Linked List Register */
00681 #define INTELXL_PFINT_LNKLST0 0x038500
00682 #define INTELXL_PFINT_LNKLST0_FIRSTQ_INDX(x) \
00683         ( (x) << 0 )                                    /**< Queue index */
00684 #define INTELXL_PFINT_LNKLST0_FIRSTQ_INDX_NONE \
00685         INTELXL_PFINT_LNKLST0_FIRSTQ_INDX ( 0x7ff )     /**< End of list */
00686 #define INTELXL_PFINT_LNKLST0_FIRSTQ_TYPE(x) \
00687         ( (x) << 11 )                                   /**< Queue type */
00688 #define INTELXL_PFINT_LNKLST0_FIRSTQ_TYPE_RX \
00689         INTELXL_PFINT_LNKLST0_FIRSTQ_TYPE ( 0x0 )       /**< Receive queue */
00690 #define INTELXL_PFINT_LNKLST0_FIRSTQ_TYPE_TX \
00691         INTELXL_PFINT_LNKLST0_FIRSTQ_TYPE ( 0x1 )       /**< Transmit queue */
00692 
00693 /** PF Interrupt Zero Cause Enablement Register */
00694 #define INTELXL_PFINT_ICR0_ENA 0x038800
00695 #define INTELXL_PFINT_ICR0_ENA_ADMINQ   0x40000000UL    /**< Admin event */
00696 
00697 /** Receive Queue Interrupt Cause Control Register */
00698 #define INTELXL_QINT_RQCTL(x) ( 0x03a000 + ( 0x4 * (x) ) )
00699 #define INTELXL_QINT_RQCTL_NEXTQ_INDX(x) ( (x) << 16 )  /**< Queue index */
00700 #define INTELXL_QINT_RQCTL_NEXTQ_INDX_NONE \
00701         INTELXL_QINT_RQCTL_NEXTQ_INDX ( 0x7ff )         /**< End of list */
00702 #define INTELXL_QINT_RQCTL_NEXTQ_TYPE(x) ( (x) << 27 )  /**< Queue type */
00703 #define INTELXL_QINT_RQCTL_NEXTQ_TYPE_RX \
00704         INTELXL_QINT_RQCTL_NEXTQ_TYPE ( 0x0 )           /**< Receive queue */
00705 #define INTELXL_QINT_RQCTL_NEXTQ_TYPE_TX \
00706         INTELXL_QINT_RQCTL_NEXTQ_TYPE ( 0x1 )           /**< Transmit queue */
00707 #define INTELXL_QINT_RQCTL_CAUSE_ENA    0x40000000UL    /**< Enable */
00708 
00709 /** Transmit Queue Interrupt Cause Control Register */
00710 #define INTELXL_QINT_TQCTL(x) ( 0x03c000 + ( 0x4 * (x) ) )
00711 #define INTELXL_QINT_TQCTL_NEXTQ_INDX(x) ( (x) << 16 )  /**< Queue index */
00712 #define INTELXL_QINT_TQCTL_NEXTQ_INDX_NONE \
00713         INTELXL_QINT_TQCTL_NEXTQ_INDX ( 0x7ff )         /**< End of list */
00714 #define INTELXL_QINT_TQCTL_NEXTQ_TYPE(x) ( (x) << 27 )  /**< Queue type */
00715 #define INTELXL_QINT_TQCTL_NEXTQ_TYPE_RX \
00716         INTELXL_QINT_TQCTL_NEXTQ_TYPE ( 0x0 )           /**< Receive queue */
00717 #define INTELXL_QINT_TQCTL_NEXTQ_TYPE_TX \
00718         INTELXL_QINT_TQCTL_NEXTQ_TYPE ( 0x1 )           /**< Transmit queue */
00719 #define INTELXL_QINT_TQCTL_CAUSE_ENA    0x40000000UL    /**< Enable */
00720 
00721 /** PF Control Register */
00722 #define INTELXL_PFGEN_CTRL 0x092400
00723 #define INTELXL_PFGEN_CTRL_PFSWR        0x00000001UL    /**< Software Reset */
00724 
00725 /** Time to delay for device reset, in milliseconds */
00726 #define INTELXL_RESET_DELAY_MS 100
00727 
00728 /** PF Queue Allocation Register */
00729 #define INTELXL_PFLAN_QALLOC 0x1c0400
00730 #define INTELXL_PFLAN_QALLOC_FIRSTQ(x) \
00731         ( ( (x) >> 0 ) & 0x7ff )                        /**< First queue */
00732 #define INTELXL_PFLAN_QALLOC_LASTQ(x) \
00733         ( ( (x) >> 16 ) & 0x7ff )                       /**< Last queue */
00734 
00735 /** PF LAN Port Number Register */
00736 #define INTELXL_PFGEN_PORTNUM 0x1c0480
00737 #define INTELXL_PFGEN_PORTNUM_PORT_NUM(x) \
00738         ( ( (x) >> 0 ) & 0x3 )                          /**< Port number */
00739 
00740 /** Port MAC Address Low Register */
00741 #define INTELXL_PRTGL_SAL 0x1e2120
00742 
00743 /** Port MAC Address High Register */
00744 #define INTELXL_PRTGL_SAH 0x1e2140
00745 #define INTELXL_PRTGL_SAH_MFS_GET(x)    ( (x) >> 16 )   /**< Max frame size */
00746 #define INTELXL_PRTGL_SAH_MFS_SET(x)    ( (x) << 16 )   /**< Max frame size */
00747 
00748 /** Receive address */
00749 union intelxl_receive_address {
00750         struct {
00751                 uint32_t low;
00752                 uint32_t high;
00753         } __attribute__ (( packed )) reg;
00754         uint8_t raw[ETH_ALEN];
00755 };
00756 
00757 /** An Intel 40Gigabit network card */
00758 struct intelxl_nic {
00759         /** Registers */
00760         void *regs;
00761         /** Maximum frame size */
00762         size_t mfs;
00763 
00764         /** Physical function number */
00765         unsigned int pf;
00766         /** Absolute queue number base */
00767         unsigned int base;
00768         /** Port number */
00769         unsigned int port;
00770         /** Queue number */
00771         unsigned int queue;
00772         /** Virtual Station Interface switching element ID */
00773         unsigned int vsi;
00774         /** Queue set handle */
00775         unsigned int qset;
00776 
00777         /** Admin command queue */
00778         struct intelxl_admin command;
00779         /** Admin event queue */
00780         struct intelxl_admin event;
00781 
00782         /** Transmit descriptor ring */
00783         struct intelxl_ring tx;
00784         /** Receive descriptor ring */
00785         struct intelxl_ring rx;
00786         /** Receive I/O buffers */
00787         struct io_buffer *rx_iobuf[INTELXL_RX_NUM_DESC];
00788 };
00789 
00790 #endif /* _INTELXL_H */