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 #include <ipxe/pcimsix.h>
00015 
00016 struct intelxl_nic;
00017 
00018 /** BAR size */
00019 #define INTELXL_BAR_SIZE 0x200000
00020 
00021 /** Alignment
00022  *
00023  * No data structure requires greater than 256 byte alignment.
00024  */
00025 #define INTELXL_ALIGN 256
00026 
00027 /******************************************************************************
00028  *
00029  * Admin queue
00030  *
00031  ******************************************************************************
00032  */
00033 
00034 /** PF Admin Command Queue register block */
00035 #define INTELXL_ADMIN_CMD 0x080000
00036 
00037 /** PF Admin Event Queue register block */
00038 #define INTELXL_ADMIN_EVT 0x080080
00039 
00040 /** Admin Queue Base Address Low Register (offset) */
00041 #define INTELXL_ADMIN_BAL 0x000
00042 
00043 /** Admin Queue Base Address High Register (offset) */
00044 #define INTELXL_ADMIN_BAH 0x100
00045 
00046 /** Admin Queue Length Register (offset) */
00047 #define INTELXL_ADMIN_LEN 0x200
00048 #define INTELXL_ADMIN_LEN_LEN(x)        ( (x) << 0 )    /**< Queue length */
00049 #define INTELXL_ADMIN_LEN_ENABLE        0x80000000UL    /**< Queue enable */
00050 
00051 /** Admin Queue Head Register (offset) */
00052 #define INTELXL_ADMIN_HEAD 0x300
00053 
00054 /** Admin Queue Tail Register (offset) */
00055 #define INTELXL_ADMIN_TAIL 0x400
00056 
00057 /** Admin queue register offsets
00058  *
00059  * The physical and virtual function register maps have no discernible
00060  * relationship.
00061  */
00062 struct intelxl_admin_offsets {
00063         /** Base Address Low Register offset */
00064         unsigned int bal;
00065         /** Base Address High Register offset */
00066         unsigned int bah;
00067         /** Length Register offset */
00068         unsigned int len;
00069         /** Head Register offset */
00070         unsigned int head;
00071         /** Tail Register offset */
00072         unsigned int tail;
00073 };
00074 
00075 /** Admin queue data buffer command parameters */
00076 struct intelxl_admin_buffer_params {
00077         /** Reserved */
00078         uint8_t reserved[8];
00079         /** Buffer address high */
00080         uint32_t high;
00081         /** Buffer address low */
00082         uint32_t low;
00083 } __attribute__ (( packed ));
00084 
00085 /** Admin queue Get Version command */
00086 #define INTELXL_ADMIN_VERSION 0x0001
00087 
00088 /** Admin queue version number */
00089 struct intelxl_admin_version {
00090         /** Major version number */
00091         uint16_t major;
00092         /** Minor version number */
00093         uint16_t minor;
00094 } __attribute__ (( packed ));
00095 
00096 /** Admin queue Get Version command parameters */
00097 struct intelxl_admin_version_params {
00098         /** ROM version */
00099         uint32_t rom;
00100         /** Firmware build ID */
00101         uint32_t build;
00102         /** Firmware version */
00103         struct intelxl_admin_version firmware;
00104         /** API version */
00105         struct intelxl_admin_version api;
00106 } __attribute__ (( packed ));
00107 
00108 /** Admin queue Driver Version command */
00109 #define INTELXL_ADMIN_DRIVER 0x0002
00110 
00111 /** Admin queue Driver Version command parameters */
00112 struct intelxl_admin_driver_params {
00113         /** Driver version */
00114         uint8_t major;
00115         /** Minor version */
00116         uint8_t minor;
00117         /** Build version */
00118         uint8_t build;
00119         /** Sub-build version */
00120         uint8_t sub;
00121         /** Reserved */
00122         uint8_t reserved[4];
00123         /** Data buffer address */
00124         uint64_t address;
00125 } __attribute__ (( packed ));
00126 
00127 /** Admin queue Driver Version data buffer */
00128 struct intelxl_admin_driver_buffer {
00129         /** Driver name */
00130         char name[32];
00131 } __attribute__ (( packed ));
00132 
00133 /** Admin queue Shutdown command */
00134 #define INTELXL_ADMIN_SHUTDOWN 0x0003
00135 
00136 /** Admin queue Shutdown command parameters */
00137 struct intelxl_admin_shutdown_params {
00138         /** Driver unloading */
00139         uint8_t unloading;
00140         /** Reserved */
00141         uint8_t reserved[15];
00142 } __attribute__ (( packed ));
00143 
00144 /** Driver is unloading */
00145 #define INTELXL_ADMIN_SHUTDOWN_UNLOADING 0x01
00146 
00147 /** Admin queue Clear PXE Mode command */
00148 #define INTELXL_ADMIN_CLEAR_PXE 0x0110
00149 
00150 /** Admin queue Clear PXE Mode command parameters */
00151 struct intelxl_admin_clear_pxe_params {
00152         /** Magic value */
00153         uint8_t magic;
00154         /** Reserved */
00155         uint8_t reserved[15];
00156 } __attribute__ (( packed ));
00157 
00158 /** Clear PXE Mode magic value */
00159 #define INTELXL_ADMIN_CLEAR_PXE_MAGIC 0x02
00160 
00161 /** Admin queue Get Switch Configuration command */
00162 #define INTELXL_ADMIN_SWITCH 0x0200
00163 
00164 /** Switching element configuration */
00165 struct intelxl_admin_switch_config {
00166         /** Switching element type */
00167         uint8_t type;
00168         /** Revision */
00169         uint8_t revision;
00170         /** Switching element ID */
00171         uint16_t seid;
00172         /** Uplink switching element ID */
00173         uint16_t uplink;
00174         /** Downlink switching element ID */
00175         uint16_t downlink;
00176         /** Reserved */
00177         uint8_t reserved_b[3];
00178         /** Connection type */
00179         uint8_t connection;
00180         /** Reserved */
00181         uint8_t reserved_c[2];
00182         /** Element specific information */
00183         uint16_t info;
00184 } __attribute__ (( packed ));
00185 
00186 /** Virtual Station Inferface element type */
00187 #define INTELXL_ADMIN_SWITCH_TYPE_VSI 19
00188 
00189 /** Admin queue Get Switch Configuration command parameters */
00190 struct intelxl_admin_switch_params {
00191         /** Starting switching element identifier */
00192         uint16_t next;
00193         /** Reserved */
00194         uint8_t reserved[6];
00195         /** Data buffer address */
00196         uint64_t address;
00197 } __attribute__ (( packed ));
00198 
00199 /** Admin queue Get Switch Configuration data buffer */
00200 struct intelxl_admin_switch_buffer {
00201         /** Number of switching elements reported */
00202         uint16_t count;
00203         /** Total number of switching elements */
00204         uint16_t total;
00205         /** Reserved */
00206         uint8_t reserved_a[12];
00207         /** Switch configuration */
00208         struct intelxl_admin_switch_config cfg;
00209 } __attribute__ (( packed ));
00210 
00211 /** Admin queue Get VSI Parameters command */
00212 #define INTELXL_ADMIN_VSI 0x0212
00213 
00214 /** Admin queue Get VSI Parameters command parameters */
00215 struct intelxl_admin_vsi_params {
00216         /** VSI switching element ID */
00217         uint16_t vsi;
00218         /** Reserved */
00219         uint8_t reserved[6];
00220         /** Data buffer address */
00221         uint64_t address;
00222 } __attribute__ (( packed ));
00223 
00224 /** Admin queue Get VSI Parameters data buffer */
00225 struct intelxl_admin_vsi_buffer {
00226         /** Reserved */
00227         uint8_t reserved_a[30];
00228         /** Queue numbers */
00229         uint16_t queue[16];
00230         /** Reserved */
00231         uint8_t reserved_b[34];
00232         /** Queue set handles for each traffic class */
00233         uint16_t qset[8];
00234         /** Reserved */
00235         uint8_t reserved_c[16];
00236 } __attribute__ (( packed ));
00237 
00238 /** Admin queue Set VSI Promiscuous Modes command */
00239 #define INTELXL_ADMIN_PROMISC 0x0254
00240 
00241 /** Admin queue Set VSI Promiscuous Modes command parameters */
00242 struct intelxl_admin_promisc_params {
00243         /** Flags */
00244         uint16_t flags;
00245         /** Valid flags */
00246         uint16_t valid;
00247         /** VSI switching element ID */
00248         uint16_t vsi;
00249         /** Reserved */
00250         uint8_t reserved[10];
00251 } __attribute__ (( packed ));
00252 
00253 /** Promiscuous unicast mode */
00254 #define INTELXL_ADMIN_PROMISC_FL_UNICAST 0x0001
00255 
00256 /** Promiscuous multicast mode */
00257 #define INTELXL_ADMIN_PROMISC_FL_MULTICAST 0x0002
00258 
00259 /** Promiscuous broadcast mode */
00260 #define INTELXL_ADMIN_PROMISC_FL_BROADCAST 0x0004
00261 
00262 /** Promiscuous VLAN mode */
00263 #define INTELXL_ADMIN_PROMISC_FL_VLAN 0x0010
00264 
00265 /** Admin queue Restart Autonegotiation command */
00266 #define INTELXL_ADMIN_AUTONEG 0x0605
00267 
00268 /** Admin queue Restart Autonegotiation command parameters */
00269 struct intelxl_admin_autoneg_params {
00270         /** Flags */
00271         uint8_t flags;
00272         /** Reserved */
00273         uint8_t reserved[15];
00274 } __attribute__ (( packed ));
00275 
00276 /** Restart autonegotiation */
00277 #define INTELXL_ADMIN_AUTONEG_FL_RESTART 0x02
00278 
00279 /** Enable link */
00280 #define INTELXL_ADMIN_AUTONEG_FL_ENABLE 0x04
00281 
00282 /** Admin queue Get Link Status command */
00283 #define INTELXL_ADMIN_LINK 0x0607
00284 
00285 /** Admin queue Get Link Status command parameters */
00286 struct intelxl_admin_link_params {
00287         /** Link status notification */
00288         uint8_t notify;
00289         /** Reserved */
00290         uint8_t reserved_a;
00291         /** PHY type */
00292         uint8_t phy;
00293         /** Link speed */
00294         uint8_t speed;
00295         /** Link status */
00296         uint8_t status;
00297         /** Reserved */
00298         uint8_t reserved_b[11];
00299 } __attribute__ (( packed ));
00300 
00301 /** Notify driver of link status changes */
00302 #define INTELXL_ADMIN_LINK_NOTIFY 0x03
00303 
00304 /** Link is up */
00305 #define INTELXL_ADMIN_LINK_UP 0x01
00306 
00307 /** Admin queue Send Message to PF command */
00308 #define INTELXL_ADMIN_SEND_TO_PF 0x0801
00309 
00310 /** Admin queue Send Message to VF command */
00311 #define INTELXL_ADMIN_SEND_TO_VF 0x0802
00312 
00313 /** Admin Queue VF Reset opcode */
00314 #define INTELXL_ADMIN_VF_RESET 0x00000002
00315 
00316 /** Admin Queue VF Get Resources opcode */
00317 #define INTELXL_ADMIN_VF_GET_RESOURCES 0x00000003
00318 
00319 /** Admin Queue VF Get Resources data buffer */
00320 struct intelxl_admin_vf_get_resources_buffer {
00321         /** Reserved */
00322         uint8_t reserved_a[20];
00323         /** VSI switching element ID */
00324         uint16_t vsi;
00325         /** Reserved */
00326         uint8_t reserved_b[8];
00327         /** MAC address */
00328         uint8_t mac[ETH_ALEN];
00329 } __attribute__ (( packed ));
00330 
00331 /** Admin Queue VF Status Change Event opcode */
00332 #define INTELXL_ADMIN_VF_STATUS 0x00000011
00333 
00334 /** Link status change event type */
00335 #define INTELXL_ADMIN_VF_STATUS_LINK 0x00000001
00336 
00337 /** Link status change event data */
00338 struct intelxl_admin_vf_status_link {
00339         /** Link speed */
00340         uint32_t speed;
00341         /** Link status */
00342         uint8_t status;
00343         /** Reserved */
00344         uint8_t reserved[3];
00345 } __attribute__ (( packed ));
00346 
00347 /** Admin Queue VF Status Change Event data buffer */
00348 struct intelxl_admin_vf_status_buffer {
00349         /** Event type */
00350         uint32_t event;
00351         /** Event data */
00352         union {
00353                 /** Link change event data */
00354                 struct intelxl_admin_vf_status_link link;
00355         } data;
00356         /** Reserved */
00357         uint8_t reserved[4];
00358 } __attribute__ (( packed ));
00359 
00360 /** Admin Queue VF Configure Queues opcode */
00361 #define INTELXL_ADMIN_VF_CONFIGURE 0x00000006
00362 
00363 /** Admin Queue VF Configure Queues data buffer */
00364 struct intelxl_admin_vf_configure_buffer {
00365         /** VSI switching element ID */
00366         uint16_t vsi;
00367         /** Number of queue pairs */
00368         uint16_t count;
00369         /** Reserved */
00370         uint8_t reserved_a[4];
00371         /** Transmit queue */
00372         struct {
00373                 /** VSI switching element ID */
00374                 uint16_t vsi;
00375                 /** Queue ID */
00376                 uint16_t id;
00377                 /** Queue count */
00378                 uint16_t count;
00379                 /** Reserved */
00380                 uint8_t reserved_a[2];
00381                 /** Base address */
00382                 uint64_t base;
00383                 /** Reserved */
00384                 uint8_t reserved_b[8];
00385         } __attribute__ (( packed )) tx;
00386         /** Receive queue */
00387         struct {
00388                 /** VSI switching element ID */
00389                 uint16_t vsi;
00390                 /** Queue ID */
00391                 uint16_t id;
00392                 /** Queue count */
00393                 uint32_t count;
00394                 /** Reserved */
00395                 uint8_t reserved_a[4];
00396                 /** Data buffer length */
00397                 uint32_t len;
00398                 /** Maximum frame size */
00399                 uint32_t mfs;
00400                 /** Reserved */
00401                 uint8_t reserved_b[4];
00402                 /** Base address */
00403                 uint64_t base;
00404                 /** Reserved */
00405                 uint8_t reserved_c[8];
00406         } __attribute__ (( packed )) rx;
00407         /** Reserved
00408          *
00409          * This field exists only due to a bug in the PF driver's
00410          * message validation logic, which causes it to miscalculate
00411          * the expected message length.
00412          */
00413         uint8_t reserved_b[64];
00414 } __attribute__ (( packed ));
00415 
00416 /** Admin Queue VF IRQ Map opcode */
00417 #define INTELXL_ADMIN_VF_IRQ_MAP 0x00000007
00418 
00419 /** Admin Queue VF IRQ Map data buffer */
00420 struct intelxl_admin_vf_irq_map_buffer {
00421         /** Number of interrupt vectors */
00422         uint16_t count;
00423         /** VSI switching element ID */
00424         uint16_t vsi;
00425         /** Interrupt vector ID */
00426         uint16_t vec;
00427         /** Receive queue bitmap */
00428         uint16_t rxmap;
00429         /** Transmit queue bitmap */
00430         uint16_t txmap;
00431         /** Receive interrupt throttling index */
00432         uint16_t rxitr;
00433         /** Transmit interrupt throttling index */
00434         uint16_t txitr;
00435         /** Reserved
00436          *
00437          * This field exists only due to a bug in the PF driver's
00438          * message validation logic, which causes it to miscalculate
00439          * the expected message length.
00440          */
00441         uint8_t reserved[12];
00442 } __attribute__ (( packed ));
00443 
00444 /** Admin Queue VF Enable Queues opcode */
00445 #define INTELXL_ADMIN_VF_ENABLE 0x00000008
00446 
00447 /** Admin Queue VF Disable Queues opcode */
00448 #define INTELXL_ADMIN_VF_DISABLE 0x00000009
00449 
00450 /** Admin Queue VF Enable/Disable Queues data buffer */
00451 struct intelxl_admin_vf_queues_buffer {
00452         /** VSI switching element ID */
00453         uint16_t vsi;
00454         /** Reserved */
00455         uint8_t reserved[2];
00456         /** Receive queue bitmask */
00457         uint32_t rx;
00458         /** Transmit queue bitmask */
00459         uint32_t tx;
00460 } __attribute__ (( packed ));
00461 
00462 /** Admin Queue VF Configure Promiscuous Mode opcode */
00463 #define INTELXL_ADMIN_VF_PROMISC 0x0000000e
00464 
00465 /** Admin Queue VF Configure Promiscuous Mode data buffer */
00466 struct intelxl_admin_vf_promisc_buffer {
00467         /** VSI switching element ID */
00468         uint16_t vsi;
00469         /** Flags */
00470         uint16_t flags;
00471 } __attribute__ (( packed ));
00472 
00473 /** Admin queue command parameters */
00474 union intelxl_admin_params {
00475         /** Additional data buffer command parameters */
00476         struct intelxl_admin_buffer_params buffer;
00477         /** Get Version command parameters */
00478         struct intelxl_admin_version_params version;
00479         /** Driver Version command parameters */
00480         struct intelxl_admin_driver_params driver;
00481         /** Shutdown command parameters */
00482         struct intelxl_admin_shutdown_params shutdown;
00483         /** Clear PXE Mode command parameters */
00484         struct intelxl_admin_clear_pxe_params pxe;
00485         /** Get Switch Configuration command parameters */
00486         struct intelxl_admin_switch_params sw;
00487         /** Get VSI Parameters command parameters */
00488         struct intelxl_admin_vsi_params vsi;
00489         /** Set VSI Promiscuous Modes command parameters */
00490         struct intelxl_admin_promisc_params promisc;
00491         /** Restart Autonegotiation command parameters */
00492         struct intelxl_admin_autoneg_params autoneg;
00493         /** Get Link Status command parameters */
00494         struct intelxl_admin_link_params link;
00495 } __attribute__ (( packed ));
00496 
00497 /** Admin queue data buffer */
00498 union intelxl_admin_buffer {
00499         /** Driver Version data buffer */
00500         struct intelxl_admin_driver_buffer driver;
00501         /** Get Switch Configuration data buffer */
00502         struct intelxl_admin_switch_buffer sw;
00503         /** Get VSI Parameters data buffer */
00504         struct intelxl_admin_vsi_buffer vsi;
00505         /** VF Get Resources data buffer */
00506         struct intelxl_admin_vf_get_resources_buffer res;
00507         /** VF Status Change Event data buffer */
00508         struct intelxl_admin_vf_status_buffer stat;
00509         /** VF Configure Queues data buffer */
00510         struct intelxl_admin_vf_configure_buffer cfg;
00511         /** VF Enable/Disable Queues data buffer */
00512         struct intelxl_admin_vf_queues_buffer queues;
00513         /** VF Configure Promiscuous Mode data buffer */
00514         struct intelxl_admin_vf_promisc_buffer promisc;
00515         /*** VF IRQ Map data buffer */
00516         struct intelxl_admin_vf_irq_map_buffer irq;
00517         /** Alignment padding */
00518         uint8_t pad[INTELXL_ALIGN];
00519 } __attribute__ (( packed ));
00520 
00521 /** Admin queue descriptor */
00522 struct intelxl_admin_descriptor {
00523         /** Flags */
00524         uint16_t flags;
00525         /** Opcode */
00526         uint16_t opcode;
00527         /** Data length */
00528         uint16_t len;
00529         /** Return value */
00530         uint16_t ret;
00531         /** Opaque cookie / VF opcode */
00532         union {
00533                 /** Cookie */
00534                 uint32_t cookie;
00535                 /** VF opcode */
00536                 uint32_t vopcode;
00537         };
00538         /** VF return value */
00539         int32_t vret;
00540         /** Parameters */
00541         union intelxl_admin_params params;
00542 } __attribute__ (( packed ));
00543 
00544 /** Admin descriptor done */
00545 #define INTELXL_ADMIN_FL_DD 0x0001
00546 
00547 /** Admin descriptor contains a completion */
00548 #define INTELXL_ADMIN_FL_CMP 0x0002
00549 
00550 /** Admin descriptor completed in error */
00551 #define INTELXL_ADMIN_FL_ERR 0x0004
00552 
00553 /** Admin descriptor uses data buffer for command parameters */
00554 #define INTELXL_ADMIN_FL_RD 0x0400
00555 
00556 /** Admin descriptor uses data buffer */
00557 #define INTELXL_ADMIN_FL_BUF 0x1000
00558 
00559 /** Admin queue */
00560 struct intelxl_admin {
00561         /** Descriptors */
00562         struct intelxl_admin_descriptor *desc;
00563         /** Data buffers */
00564         union intelxl_admin_buffer *buf;
00565         /** Queue index */
00566         unsigned int index;
00567 
00568         /** Register block base */
00569         unsigned int base;
00570         /** Register offsets */
00571         const struct intelxl_admin_offsets *regs;
00572 };
00573 
00574 /**
00575  * Initialise admin queue
00576  *
00577  * @v admin             Admin queue
00578  * @v base              Register block base
00579  * @v regs              Register offsets
00580  */
00581 static inline __attribute__ (( always_inline )) void
00582 intelxl_init_admin ( struct intelxl_admin *admin, unsigned int base,
00583                      const struct intelxl_admin_offsets *regs ) {
00584 
00585         admin->base = base;
00586         admin->regs = regs;
00587 }
00588 
00589 /** Number of admin queue descriptors */
00590 #define INTELXL_ADMIN_NUM_DESC 4
00591 
00592 /** Maximum time to wait for an admin request to complete */
00593 #define INTELXL_ADMIN_MAX_WAIT_MS 100
00594 
00595 /** Admin queue API major version */
00596 #define INTELXL_ADMIN_API_MAJOR 1
00597 
00598 /******************************************************************************
00599  *
00600  * Transmit and receive queue context
00601  *
00602  ******************************************************************************
00603  */
00604 
00605 /** CMLAN Context Data Register */
00606 #define INTELXL_PFCM_LANCTXDATA(x) ( 0x10c100 + ( 0x80 * (x) ) )
00607 
00608 /** CMLAN Context Control Register */
00609 #define INTELXL_PFCM_LANCTXCTL 0x10c300
00610 #define INTELXL_PFCM_LANCTXCTL_QUEUE_NUM(x) \
00611         ( (x) << 0 )                                    /**< Queue number */
00612 #define INTELXL_PFCM_LANCTXCTL_SUB_LINE(x) \
00613         ( (x) << 12 )                                   /**< Sub-line */
00614 #define INTELXL_PFCM_LANCTXCTL_TYPE(x) \
00615         ( (x) << 15 )                                   /**< Queue type */
00616 #define INTELXL_PFCM_LANCTXCTL_TYPE_RX \
00617         INTELXL_PFCM_LANCTXCTL_TYPE ( 0x0 )             /**< RX queue type */
00618 #define INTELXL_PFCM_LANCTXCTL_TYPE_TX \
00619         INTELXL_PFCM_LANCTXCTL_TYPE ( 0x1 )             /**< TX queue type */
00620 #define INTELXL_PFCM_LANCTXCTL_OP_CODE(x) \
00621         ( (x) << 17 )                                   /**< Op code */
00622 #define INTELXL_PFCM_LANCTXCTL_OP_CODE_READ \
00623         INTELXL_PFCM_LANCTXCTL_OP_CODE ( 0x0 )          /**< Read context */
00624 #define INTELXL_PFCM_LANCTXCTL_OP_CODE_WRITE \
00625         INTELXL_PFCM_LANCTXCTL_OP_CODE ( 0x1 )          /**< Write context */
00626 
00627 /** CMLAN Context Status Register */
00628 #define INTELXL_PFCM_LANCTXSTAT 0x10c380
00629 #define INTELXL_PFCM_LANCTXSTAT_DONE   0x00000001UL     /**< Complete */
00630 
00631 /** Queue context line */
00632 struct intelxl_context_line {
00633         /** Raw data */
00634         uint32_t raw[4];
00635 } __attribute__ (( packed ));
00636 
00637 /** Transmit queue context */
00638 struct intelxl_context_tx {
00639         /** Head pointer */
00640         uint16_t head;
00641         /** Flags */
00642         uint16_t flags;
00643         /** Base address */
00644         uint64_t base;
00645         /** Reserved */
00646         uint8_t reserved_a[8];
00647         /** Queue count */
00648         uint16_t count;
00649         /** Reserved */
00650         uint8_t reserved_b[100];
00651         /** Queue set */
00652         uint16_t qset;
00653         /** Reserved */
00654         uint8_t reserved_c[4];
00655 } __attribute__ (( packed ));
00656 
00657 /** New transmit queue context */
00658 #define INTELXL_CTX_TX_FL_NEW 0x4000
00659 
00660 /** Transmit queue base address */
00661 #define INTELXL_CTX_TX_BASE( base ) ( (base) >> 7 )
00662 
00663 /** Transmit queue count */
00664 #define INTELXL_CTX_TX_COUNT( count ) ( (count) << 1 )
00665 
00666 /** Transmit queue set */
00667 #define INTELXL_CTX_TX_QSET( qset) ( (qset) << 4 )
00668 
00669 /** Receive queue context */
00670 struct intelxl_context_rx {
00671         /** Head pointer */
00672         uint16_t head;
00673         /** Reserved */
00674         uint8_t reserved_a[2];
00675         /** Base address and queue count */
00676         uint64_t base_count;
00677         /** Data buffer length */
00678         uint16_t len;
00679         /** Flags */
00680         uint8_t flags;
00681         /** Reserved */
00682         uint8_t reserved_b[7];
00683         /** Maximum frame size */
00684         uint16_t mfs;
00685 } __attribute__ (( packed ));
00686 
00687 /** Receive queue base address and queue count */
00688 #define INTELXL_CTX_RX_BASE_COUNT( base, count ) \
00689         ( ( (base) >> 7 ) | ( ( ( uint64_t ) (count) ) << 57 ) )
00690 
00691 /** Receive queue data buffer length */
00692 #define INTELXL_CTX_RX_LEN( len ) ( (len) >> 1 )
00693 
00694 /** Use 32-byte receive descriptors */
00695 #define INTELXL_CTX_RX_FL_DSIZE 0x10
00696 
00697 /** Strip CRC from received packets */
00698 #define INTELXL_CTX_RX_FL_CRCSTRIP 0x20
00699 
00700 /** Receive queue maximum frame size */
00701 #define INTELXL_CTX_RX_MFS( mfs ) ( (mfs) >> 2 )
00702 
00703 /** Maximum time to wait for a context operation to complete */
00704 #define INTELXL_CTX_MAX_WAIT_MS 100
00705 
00706 /** Time to wait for a queue to become enabled */
00707 #define INTELXL_QUEUE_ENABLE_DELAY_US 20
00708 
00709 /** Time to wait for a transmit queue to become pre-disabled */
00710 #define INTELXL_QUEUE_PRE_DISABLE_DELAY_US 400
00711 
00712 /** Maximum time to wait for a queue to become disabled */
00713 #define INTELXL_QUEUE_DISABLE_MAX_WAIT_MS 1000
00714 
00715 /******************************************************************************
00716  *
00717  * Transmit and receive descriptors
00718  *
00719  ******************************************************************************
00720  */
00721 
00722 /** Global Transmit Queue Head register */
00723 #define INTELXL_QTX_HEAD(x) ( 0x0e4000 + ( 0x4 * (x) ) )
00724 
00725 /** Global Transmit Pre Queue Disable register */
00726 #define INTELXL_GLLAN_TXPRE_QDIS(x) ( 0x0e6500 + ( 0x4 * ( (x) / 0x80 ) ) )
00727 #define INTELXL_GLLAN_TXPRE_QDIS_QINDX(x) \
00728         ( (x) << 0 )                                    /**< Queue index */
00729 #define INTELXL_GLLAN_TXPRE_QDIS_SET_QDIS \
00730         0x40000000UL                                    /**< Set disable */
00731 #define INTELXL_GLLAN_TXPRE_QDIS_CLEAR_QDIS                             \
00732         0x80000000UL                                    /**< Clear disable */
00733 
00734 /** Global Transmit Queue register block */
00735 #define INTELXL_QTX(x) ( 0x100000 + ( 0x4 * (x) ) )
00736 
00737 /** Global Receive Queue register block */
00738 #define INTELXL_QRX(x) ( 0x120000 + ( 0x4 * (x) ) )
00739 
00740 /** Queue Enable Register (offset) */
00741 #define INTELXL_QXX_ENA 0x0000
00742 #define INTELXL_QXX_ENA_REQ             0x00000001UL    /**< Enable request */
00743 #define INTELXL_QXX_ENA_STAT            0x00000004UL    /**< Enabled status */
00744 
00745 /** Queue Control Register (offset) */
00746 #define INTELXL_QXX_CTL 0x4000
00747 #define INTELXL_QXX_CTL_PFVF_Q(x)       ( (x) << 0 )    /**< PF/VF queue */
00748 #define INTELXL_QXX_CTL_PFVF_Q_PF \
00749         INTELXL_QXX_CTL_PFVF_Q ( 0x2 )                  /**< PF queue */
00750 #define INTELXL_QXX_CTL_PFVF_PF_INDX(x) ( (x) << 2 )    /**< PF index */
00751 
00752 /** Queue Tail Pointer Register (offset) */
00753 #define INTELXL_QXX_TAIL 0x8000
00754 
00755 /** Global RLAN Control 0 register */
00756 #define INTELXL_GLLAN_RCTL_0 0x12a500
00757 #define INTELXL_GLLAN_RCTL_0_PXE_MODE   0x00000001UL    /**< PXE mode */
00758 
00759 /** Transmit data descriptor */
00760 struct intelxl_tx_data_descriptor {
00761         /** Buffer address */
00762         uint64_t address;
00763         /** Flags */
00764         uint32_t flags;
00765         /** Length */
00766         uint32_t len;
00767 } __attribute__ (( packed ));
00768 
00769 /** Transmit data descriptor type */
00770 #define INTELXL_TX_DATA_DTYP 0x0
00771 
00772 /** Transmit data descriptor end of packet */
00773 #define INTELXL_TX_DATA_EOP 0x10
00774 
00775 /** Transmit data descriptor report status */
00776 #define INTELXL_TX_DATA_RS 0x20
00777 
00778 /** Transmit data descriptor pretty please
00779  *
00780  * This bit is completely missing from older versions of the XL710
00781  * datasheet.  Later versions describe it innocuously as "reserved,
00782  * must be 1".  Without this bit, everything will appear to work (up
00783  * to and including the port "transmit good octets" counter), but no
00784  * packet will actually be sent.
00785  */
00786 #define INTELXL_TX_DATA_JFDI 0x40
00787 
00788 /** Transmit data descriptor length */
00789 #define INTELXL_TX_DATA_LEN( len ) ( (len) << 2 )
00790 
00791 /** Transmit writeback descriptor */
00792 struct intelxl_tx_writeback_descriptor {
00793         /** Reserved */
00794         uint8_t reserved_a[8];
00795         /** Flags */
00796         uint8_t flags;
00797         /** Reserved */
00798         uint8_t reserved_b[7];
00799 } __attribute__ (( packed ));
00800 
00801 /** Transmit writeback descriptor complete */
00802 #define INTELXL_TX_WB_FL_DD 0x01
00803 
00804 /** Transmit descriptor */
00805 union intelxl_tx_descriptor {
00806         /** Transmit data descriptor */
00807         struct intelxl_tx_data_descriptor data;
00808         /** Transmit writeback descriptor */
00809         struct intelxl_tx_writeback_descriptor wb;
00810 };
00811 
00812 /** Receive data descriptor */
00813 struct intelxl_rx_data_descriptor {
00814         /** Buffer address */
00815         uint64_t address;
00816         /** Flags */
00817         uint32_t flags;
00818         /** Reserved */
00819         uint8_t reserved[20];
00820 } __attribute__ (( packed ));
00821 
00822 /** Receive writeback descriptor */
00823 struct intelxl_rx_writeback_descriptor {
00824         /** Reserved */
00825         uint8_t reserved_a[2];
00826         /** VLAN tag */
00827         uint16_t vlan;
00828         /** Reserved */
00829         uint8_t reserved_b[4];
00830         /** Flags */
00831         uint32_t flags;
00832         /** Length */
00833         uint32_t len;
00834         /** Reserved */
00835         uint8_t reserved_c[16];
00836 } __attribute__ (( packed ));
00837 
00838 /** Receive writeback descriptor complete */
00839 #define INTELXL_RX_WB_FL_DD 0x00000001UL
00840 
00841 /** Receive writeback descriptor VLAN tag present */
00842 #define INTELXL_RX_WB_FL_VLAN 0x00000004UL
00843 
00844 /** Receive writeback descriptor error */
00845 #define INTELXL_RX_WB_FL_RXE 0x00080000UL
00846 
00847 /** Receive writeback descriptor length */
00848 #define INTELXL_RX_WB_LEN(len) ( ( (len) >> 6 ) & 0x3fff )
00849 
00850 /** Packet descriptor */
00851 union intelxl_rx_descriptor {
00852         /** Receive data descriptor */
00853         struct intelxl_rx_data_descriptor data;
00854         /** Receive writeback descriptor */
00855         struct intelxl_rx_writeback_descriptor wb;
00856 };
00857 
00858 /** Descriptor ring */
00859 struct intelxl_ring {
00860         /** Descriptors */
00861         union {
00862                 /** Transmit descriptors */
00863                 union intelxl_tx_descriptor *tx;
00864                 /** Receive descriptors */
00865                 union intelxl_rx_descriptor *rx;
00866                 /** Raw data */
00867                 void *raw;
00868         } desc;
00869         /** Producer index */
00870         unsigned int prod;
00871         /** Consumer index */
00872         unsigned int cons;
00873 
00874         /** Register block */
00875         unsigned int reg;
00876         /** Tail register */
00877         unsigned int tail;
00878         /** Length (in bytes) */
00879         size_t len;
00880         /** Program queue context
00881          *
00882          * @v intelxl           Intel device
00883          * @v address           Descriptor ring base address
00884          */
00885         int ( * context ) ( struct intelxl_nic *intelxl, physaddr_t address );
00886 };
00887 
00888 /**
00889  * Initialise descriptor ring
00890  *
00891  * @v ring              Descriptor ring
00892  * @v count             Number of descriptors
00893  * @v len               Length of a single descriptor
00894  * @v context           Method to program queue context
00895  */
00896 static inline __attribute__ (( always_inline)) void
00897 intelxl_init_ring ( struct intelxl_ring *ring, unsigned int count, size_t len,
00898                     int ( * context ) ( struct intelxl_nic *intelxl,
00899                                         physaddr_t address ) ) {
00900 
00901         ring->len = ( count * len );
00902         ring->context = context;
00903 }
00904 
00905 /** Number of transmit descriptors
00906  *
00907  * Chosen to exceed the receive ring fill level, in order to avoid
00908  * running out of transmit descriptors when sending TCP ACKs.
00909  */
00910 #define INTELXL_TX_NUM_DESC 64
00911 
00912 /** Transmit descriptor ring maximum fill level */
00913 #define INTELXL_TX_FILL ( INTELXL_TX_NUM_DESC - 1 )
00914 
00915 /** Number of receive descriptors
00916  *
00917  * Must be a multiple of 32.
00918  */
00919 #define INTELXL_RX_NUM_DESC 32
00920 
00921 /** Receive descriptor ring fill level
00922  *
00923  * Must be a multiple of 8 and greater than 8.
00924  */
00925 #define INTELXL_RX_FILL 16
00926 
00927 /******************************************************************************
00928  *
00929  * Top level
00930  *
00931  ******************************************************************************
00932  */
00933 
00934 /** PF Interrupt Zero Dynamic Control Register */
00935 #define INTELXL_PFINT_DYN_CTL0 0x038480
00936 #define INTELXL_INT_DYN_CTL_INTENA      0x00000001UL    /**< Enable */
00937 #define INTELXL_INT_DYN_CTL_CLEARPBA    0x00000002UL    /**< Acknowledge */
00938 #define INTELXL_INT_DYN_CTL_INTENA_MASK 0x80000000UL    /**< Ignore enable */
00939 
00940 /** PF Interrupt Zero Linked List Register */
00941 #define INTELXL_PFINT_LNKLST0 0x038500
00942 #define INTELXL_PFINT_LNKLST0_FIRSTQ_INDX(x) \
00943         ( (x) << 0 )                                    /**< Queue index */
00944 #define INTELXL_PFINT_LNKLST0_FIRSTQ_INDX_NONE \
00945         INTELXL_PFINT_LNKLST0_FIRSTQ_INDX ( 0x7ff )     /**< End of list */
00946 #define INTELXL_PFINT_LNKLST0_FIRSTQ_TYPE(x) \
00947         ( (x) << 11 )                                   /**< Queue type */
00948 #define INTELXL_PFINT_LNKLST0_FIRSTQ_TYPE_RX \
00949         INTELXL_PFINT_LNKLST0_FIRSTQ_TYPE ( 0x0 )       /**< Receive queue */
00950 #define INTELXL_PFINT_LNKLST0_FIRSTQ_TYPE_TX \
00951         INTELXL_PFINT_LNKLST0_FIRSTQ_TYPE ( 0x1 )       /**< Transmit queue */
00952 
00953 /** PF Interrupt Zero Cause Enablement Register */
00954 #define INTELXL_PFINT_ICR0_ENA 0x038800
00955 #define INTELXL_PFINT_ICR0_ENA_ADMINQ   0x40000000UL    /**< Admin event */
00956 
00957 /** Receive Queue Interrupt Cause Control Register */
00958 #define INTELXL_QINT_RQCTL(x) ( 0x03a000 + ( 0x4 * (x) ) )
00959 #define INTELXL_QINT_RQCTL_NEXTQ_INDX(x) ( (x) << 16 )  /**< Queue index */
00960 #define INTELXL_QINT_RQCTL_NEXTQ_INDX_NONE \
00961         INTELXL_QINT_RQCTL_NEXTQ_INDX ( 0x7ff )         /**< End of list */
00962 #define INTELXL_QINT_RQCTL_NEXTQ_TYPE(x) ( (x) << 27 )  /**< Queue type */
00963 #define INTELXL_QINT_RQCTL_NEXTQ_TYPE_RX \
00964         INTELXL_QINT_RQCTL_NEXTQ_TYPE ( 0x0 )           /**< Receive queue */
00965 #define INTELXL_QINT_RQCTL_NEXTQ_TYPE_TX \
00966         INTELXL_QINT_RQCTL_NEXTQ_TYPE ( 0x1 )           /**< Transmit queue */
00967 #define INTELXL_QINT_RQCTL_CAUSE_ENA    0x40000000UL    /**< Enable */
00968 
00969 /** Transmit Queue Interrupt Cause Control Register */
00970 #define INTELXL_QINT_TQCTL(x) ( 0x03c000 + ( 0x4 * (x) ) )
00971 #define INTELXL_QINT_TQCTL_NEXTQ_INDX(x) ( (x) << 16 )  /**< Queue index */
00972 #define INTELXL_QINT_TQCTL_NEXTQ_INDX_NONE \
00973         INTELXL_QINT_TQCTL_NEXTQ_INDX ( 0x7ff )         /**< End of list */
00974 #define INTELXL_QINT_TQCTL_NEXTQ_TYPE(x) ( (x) << 27 )  /**< Queue type */
00975 #define INTELXL_QINT_TQCTL_NEXTQ_TYPE_RX \
00976         INTELXL_QINT_TQCTL_NEXTQ_TYPE ( 0x0 )           /**< Receive queue */
00977 #define INTELXL_QINT_TQCTL_NEXTQ_TYPE_TX \
00978         INTELXL_QINT_TQCTL_NEXTQ_TYPE ( 0x1 )           /**< Transmit queue */
00979 #define INTELXL_QINT_TQCTL_CAUSE_ENA    0x40000000UL    /**< Enable */
00980 
00981 /** PF Control Register */
00982 #define INTELXL_PFGEN_CTRL 0x092400
00983 #define INTELXL_PFGEN_CTRL_PFSWR        0x00000001UL    /**< Software Reset */
00984 
00985 /** Time to delay for device reset, in milliseconds */
00986 #define INTELXL_RESET_DELAY_MS 100
00987 
00988 /** PF Queue Allocation Register */
00989 #define INTELXL_PFLAN_QALLOC 0x1c0400
00990 #define INTELXL_PFLAN_QALLOC_FIRSTQ(x) \
00991         ( ( (x) >> 0 ) & 0x7ff )                        /**< First queue */
00992 #define INTELXL_PFLAN_QALLOC_LASTQ(x) \
00993         ( ( (x) >> 16 ) & 0x7ff )                       /**< Last queue */
00994 
00995 /** PF LAN Port Number Register */
00996 #define INTELXL_PFGEN_PORTNUM 0x1c0480
00997 #define INTELXL_PFGEN_PORTNUM_PORT_NUM(x) \
00998         ( ( (x) >> 0 ) & 0x3 )                          /**< Port number */
00999 
01000 /** Port MAC Address Low Register */
01001 #define INTELXL_PRTGL_SAL 0x1e2120
01002 
01003 /** Port MAC Address High Register */
01004 #define INTELXL_PRTGL_SAH 0x1e2140
01005 #define INTELXL_PRTGL_SAH_MFS_GET(x)    ( (x) >> 16 )   /**< Max frame size */
01006 #define INTELXL_PRTGL_SAH_MFS_SET(x)    ( (x) << 16 )   /**< Max frame size */
01007 
01008 /** Receive address */
01009 union intelxl_receive_address {
01010         struct {
01011                 uint32_t low;
01012                 uint32_t high;
01013         } __attribute__ (( packed )) reg;
01014         uint8_t raw[ETH_ALEN];
01015 };
01016 
01017 /** An Intel 40Gigabit network card */
01018 struct intelxl_nic {
01019         /** Registers */
01020         void *regs;
01021         /** Maximum frame size */
01022         size_t mfs;
01023 
01024         /** Physical function number */
01025         unsigned int pf;
01026         /** Absolute queue number base */
01027         unsigned int base;
01028         /** Port number */
01029         unsigned int port;
01030         /** Queue number */
01031         unsigned int queue;
01032         /** Virtual Station Interface switching element ID */
01033         unsigned int vsi;
01034         /** Queue set handle */
01035         unsigned int qset;
01036         /** Interrupt control register */
01037         unsigned int intr;
01038         /** MSI-X capability */
01039         struct pci_msix msix;
01040         /** MSI-X dummy interrupt target */
01041         uint32_t msg;
01042         /** PCI Express capability offset */
01043         unsigned int exp;
01044 
01045         /** Admin command queue */
01046         struct intelxl_admin command;
01047         /** Admin event queue */
01048         struct intelxl_admin event;
01049 
01050         /** Current VF opcode */
01051         unsigned int vopcode;
01052         /** Current VF return value */
01053         int vret;
01054         /** Current VF event data buffer */
01055         union intelxl_admin_buffer vbuf;
01056 
01057         /** Transmit descriptor ring */
01058         struct intelxl_ring tx;
01059         /** Receive descriptor ring */
01060         struct intelxl_ring rx;
01061         /** Receive I/O buffers */
01062         struct io_buffer *rx_iobuf[INTELXL_RX_NUM_DESC];
01063 };
01064 
01065 extern int intelxl_msix_enable ( struct intelxl_nic *intelxl,
01066                                  struct pci_device *pci );
01067 extern void intelxl_msix_disable ( struct intelxl_nic *intelxl,
01068                                    struct pci_device *pci );
01069 extern struct intelxl_admin_descriptor *
01070 intelxl_admin_command_descriptor ( struct intelxl_nic *intelxl );
01071 extern union intelxl_admin_buffer *
01072 intelxl_admin_command_buffer ( struct intelxl_nic *intelxl );
01073 extern int intelxl_admin_command ( struct intelxl_nic *intelxl );
01074 extern void intelxl_poll_admin ( struct net_device *netdev );
01075 extern int intelxl_open_admin ( struct intelxl_nic *intelxl );
01076 extern void intelxl_reopen_admin ( struct intelxl_nic *intelxl );
01077 extern void intelxl_close_admin ( struct intelxl_nic *intelxl );
01078 extern int intelxl_alloc_ring ( struct intelxl_nic *intelxl,
01079                                 struct intelxl_ring *ring );
01080 extern void intelxl_free_ring ( struct intelxl_nic *intelxl,
01081                                 struct intelxl_ring *ring );
01082 extern void intelxl_empty_rx ( struct intelxl_nic *intelxl );
01083 extern int intelxl_transmit ( struct net_device *netdev,
01084                               struct io_buffer *iobuf );
01085 extern void intelxl_poll ( struct net_device *netdev );
01086 
01087 extern void intelxlvf_admin_event ( struct net_device *netdev,
01088                                     struct intelxl_admin_descriptor *evt,
01089                                     union intelxl_admin_buffer *buf );
01090 
01091 #endif /* _INTELXL_H */