Annotation of qemu/roms/ipxe/src/drivers/net/phantom/phantom.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (C) 2008 Michael Brown <[email protected]>.
                      3:  * Copyright (C) 2008 NetXen, Inc.
                      4:  *
                      5:  * This program is free software; you can redistribute it and/or
                      6:  * modify it under the terms of the GNU General Public License as
                      7:  * published by the Free Software Foundation; either version 2 of the
                      8:  * License, or any later version.
                      9:  *
                     10:  * This program is distributed in the hope that it will be useful, but
                     11:  * WITHOUT ANY WARRANTY; without even the implied warranty of
                     12:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     13:  * General Public License for more details.
                     14:  *
                     15:  * You should have received a copy of the GNU General Public License
                     16:  * along with this program; if not, write to the Free Software
                     17:  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
                     18:  */
                     19: 
                     20: FILE_LICENCE ( GPL2_OR_LATER );
                     21: 
                     22: #include <stdint.h>
                     23: #include <stdlib.h>
                     24: #include <string.h>
                     25: #include <unistd.h>
                     26: #include <errno.h>
                     27: #include <assert.h>
                     28: #include <byteswap.h>
                     29: #include <ipxe/pci.h>
                     30: #include <ipxe/io.h>
                     31: #include <ipxe/malloc.h>
                     32: #include <ipxe/iobuf.h>
                     33: #include <ipxe/netdevice.h>
                     34: #include <ipxe/if_ether.h>
                     35: #include <ipxe/ethernet.h>
                     36: #include <ipxe/spi.h>
                     37: #include <ipxe/settings.h>
                     38: #include "phantom.h"
                     39: 
                     40: /**
                     41:  * @file
                     42:  *
                     43:  * NetXen Phantom NICs
                     44:  *
                     45:  */
                     46: 
                     47: /** Maximum number of ports */
                     48: #define PHN_MAX_NUM_PORTS 8
                     49: 
                     50: /** Maximum time to wait for command PEG to initialise
                     51:  *
                     52:  * BUGxxxx
                     53:  *
                     54:  * The command PEG will currently report initialisation complete only
                     55:  * when at least one PHY has detected a link (so that the global PHY
                     56:  * clock can be set to 10G/1G as appropriate).  This can take a very,
                     57:  * very long time.
                     58:  *
                     59:  * A future firmware revision should decouple PHY initialisation from
                     60:  * firmware initialisation, at which point the command PEG will report
                     61:  * initialisation complete much earlier, and this timeout can be
                     62:  * reduced.
                     63:  */
                     64: #define PHN_CMDPEG_INIT_TIMEOUT_SEC 50
                     65: 
                     66: /** Maximum time to wait for receive PEG to initialise */
                     67: #define PHN_RCVPEG_INIT_TIMEOUT_SEC 2
                     68: 
                     69: /** Maximum time to wait for firmware to accept a command */
                     70: #define PHN_ISSUE_CMD_TIMEOUT_MS 2000
                     71: 
                     72: /** Maximum time to wait for test memory */
                     73: #define PHN_TEST_MEM_TIMEOUT_MS 100
                     74: 
                     75: /** Maximum time to wait for CLP command to be issued */
                     76: #define PHN_CLP_CMD_TIMEOUT_MS 500
                     77: 
                     78: /** Link state poll frequency
                     79:  *
                     80:  * The link state will be checked once in every N calls to poll().
                     81:  */
                     82: #define PHN_LINK_POLL_FREQUENCY 4096
                     83: 
                     84: /** Number of RX descriptors */
                     85: #define PHN_NUM_RDS 32
                     86: 
                     87: /** RX maximum fill level.  Must be strictly less than PHN_NUM_RDS. */
                     88: #define PHN_RDS_MAX_FILL 16
                     89: 
                     90: /** RX buffer size */
                     91: #define PHN_RX_BUFSIZE ( 32 /* max LL padding added by card */ + \
                     92:                         ETH_FRAME_LEN )
                     93: 
                     94: /** Number of RX status descriptors */
                     95: #define PHN_NUM_SDS 32
                     96: 
                     97: /** Number of TX descriptors */
                     98: #define PHN_NUM_CDS 8
                     99: 
                    100: /** A Phantom descriptor ring set */
                    101: struct phantom_descriptor_rings {
                    102:        /** RX descriptors */
                    103:        struct phantom_rds rds[PHN_NUM_RDS];
                    104:        /** RX status descriptors */
                    105:        struct phantom_sds sds[PHN_NUM_SDS];
                    106:        /** TX descriptors */
                    107:        union phantom_cds cds[PHN_NUM_CDS];
                    108:        /** TX consumer index */
                    109:        volatile uint32_t cmd_cons;
                    110: };
                    111: 
                    112: /** RX context creation request and response buffers */
                    113: struct phantom_create_rx_ctx_rqrsp {
                    114:        struct {
                    115:                struct nx_hostrq_rx_ctx_s rx_ctx;
                    116:                struct nx_hostrq_rds_ring_s rds;
                    117:                struct nx_hostrq_sds_ring_s sds;
                    118:        } __unm_dma_aligned hostrq;
                    119:        struct {
                    120:                struct nx_cardrsp_rx_ctx_s rx_ctx;
                    121:                struct nx_cardrsp_rds_ring_s rds;
                    122:                struct nx_cardrsp_sds_ring_s sds;
                    123:        } __unm_dma_aligned cardrsp;
                    124: };
                    125: 
                    126: /** TX context creation request and response buffers */
                    127: struct phantom_create_tx_ctx_rqrsp {
                    128:        struct {
                    129:                struct nx_hostrq_tx_ctx_s tx_ctx;
                    130:        } __unm_dma_aligned hostrq;
                    131:        struct {
                    132:                struct nx_cardrsp_tx_ctx_s tx_ctx;
                    133:        } __unm_dma_aligned cardrsp;
                    134: };
                    135: 
                    136: /** A Phantom NIC */
                    137: struct phantom_nic {
                    138:        /** BAR 0 */
                    139:        void *bar0;
                    140:        /** Current CRB window */
                    141:        unsigned long crb_window;
                    142:        /** CRB window access method */
                    143:        unsigned long ( *crb_access ) ( struct phantom_nic *phantom,
                    144:                                        unsigned long reg );
                    145: 
                    146: 
                    147:        /** Port number */
                    148:        unsigned int port;
                    149: 
                    150: 
                    151:        /** RX context ID */
                    152:        uint16_t rx_context_id;
                    153:        /** RX descriptor producer CRB offset */
                    154:        unsigned long rds_producer_crb;
                    155:        /** RX status descriptor consumer CRB offset */
                    156:        unsigned long sds_consumer_crb;
                    157:        /** RX interrupt mask CRB offset */
                    158:        unsigned long sds_irq_mask_crb;
                    159:        /** RX interrupts enabled */
                    160:        unsigned int sds_irq_enabled;
                    161: 
                    162:        /** RX producer index */
                    163:        unsigned int rds_producer_idx;
                    164:        /** RX consumer index */
                    165:        unsigned int rds_consumer_idx;
                    166:        /** RX status consumer index */
                    167:        unsigned int sds_consumer_idx;
                    168:        /** RX I/O buffers */
                    169:        struct io_buffer *rds_iobuf[PHN_RDS_MAX_FILL];
                    170: 
                    171: 
                    172:        /** TX context ID */
                    173:        uint16_t tx_context_id;
                    174:        /** TX descriptor producer CRB offset */
                    175:        unsigned long cds_producer_crb;
                    176: 
                    177:        /** TX producer index */
                    178:        unsigned int cds_producer_idx;
                    179:        /** TX consumer index */
                    180:        unsigned int cds_consumer_idx;
                    181:        /** TX I/O buffers */
                    182:        struct io_buffer *cds_iobuf[PHN_NUM_CDS];
                    183: 
                    184: 
                    185:        /** Descriptor rings */
                    186:        struct phantom_descriptor_rings *desc;
                    187: 
                    188: 
                    189:        /** Last known link state */
                    190:        uint32_t link_state;
                    191:        /** Link state poll timer */
                    192:        unsigned long link_poll_timer;
                    193: 
                    194: 
                    195:        /** Non-volatile settings */
                    196:        struct settings settings;
                    197: };
                    198: 
                    199: /** Interrupt mask registers */
                    200: static const unsigned long phantom_irq_mask_reg[PHN_MAX_NUM_PORTS] = {
                    201:        UNM_PCIE_IRQ_MASK_F0,
                    202:        UNM_PCIE_IRQ_MASK_F1,
                    203:        UNM_PCIE_IRQ_MASK_F2,
                    204:        UNM_PCIE_IRQ_MASK_F3,
                    205:        UNM_PCIE_IRQ_MASK_F4,
                    206:        UNM_PCIE_IRQ_MASK_F5,
                    207:        UNM_PCIE_IRQ_MASK_F6,
                    208:        UNM_PCIE_IRQ_MASK_F7,
                    209: };
                    210: 
                    211: /** Interrupt status registers */
                    212: static const unsigned long phantom_irq_status_reg[PHN_MAX_NUM_PORTS] = {
                    213:        UNM_PCIE_IRQ_STATUS_F0,
                    214:        UNM_PCIE_IRQ_STATUS_F1,
                    215:        UNM_PCIE_IRQ_STATUS_F2,
                    216:        UNM_PCIE_IRQ_STATUS_F3,
                    217:        UNM_PCIE_IRQ_STATUS_F4,
                    218:        UNM_PCIE_IRQ_STATUS_F5,
                    219:        UNM_PCIE_IRQ_STATUS_F6,
                    220:        UNM_PCIE_IRQ_STATUS_F7,
                    221: };
                    222: 
                    223: /***************************************************************************
                    224:  *
                    225:  * CRB register access
                    226:  *
                    227:  */
                    228: 
                    229: /**
                    230:  * Prepare for access to CRB register via 128MB BAR
                    231:  *
                    232:  * @v phantom          Phantom NIC
                    233:  * @v reg              Register offset within abstract address space
                    234:  * @ret offset         Register offset within PCI BAR0
                    235:  */
                    236: static unsigned long phantom_crb_access_128m ( struct phantom_nic *phantom,
                    237:                                               unsigned long reg ) {
                    238:        unsigned long offset = ( 0x6000000 + ( reg & 0x1ffffff ) );
                    239:        uint32_t window = ( reg & 0x2000000 );
                    240:        uint32_t verify_window;
                    241: 
                    242:        if ( phantom->crb_window != window ) {
                    243: 
                    244:                /* Write to the CRB window register */
                    245:                writel ( window, phantom->bar0 + UNM_128M_CRB_WINDOW );
                    246: 
                    247:                /* Ensure that the write has reached the card */
                    248:                verify_window = readl ( phantom->bar0 + UNM_128M_CRB_WINDOW );
                    249:                assert ( verify_window == window );
                    250: 
                    251:                /* Record new window */
                    252:                phantom->crb_window = window;
                    253:        }
                    254: 
                    255:        return offset;
                    256: }
                    257: 
                    258: /**
                    259:  * Prepare for access to CRB register via 32MB BAR
                    260:  *
                    261:  * @v phantom          Phantom NIC
                    262:  * @v reg              Register offset within abstract address space
                    263:  * @ret offset         Register offset within PCI BAR0
                    264:  */
                    265: static unsigned long phantom_crb_access_32m ( struct phantom_nic *phantom,
                    266:                                              unsigned long reg ) {
                    267:        unsigned long offset = ( reg & 0x1ffffff );
                    268:        uint32_t window = ( reg & 0x2000000 );
                    269:        uint32_t verify_window;
                    270: 
                    271:        if ( phantom->crb_window != window ) {
                    272: 
                    273:                /* Write to the CRB window register */
                    274:                writel ( window, phantom->bar0 + UNM_32M_CRB_WINDOW );
                    275: 
                    276:                /* Ensure that the write has reached the card */
                    277:                verify_window = readl ( phantom->bar0 + UNM_32M_CRB_WINDOW );
                    278:                assert ( verify_window == window );
                    279: 
                    280:                /* Record new window */
                    281:                phantom->crb_window = window;
                    282:        }
                    283: 
                    284:        return offset;
                    285: }
                    286: 
                    287: /**
                    288:  * Prepare for access to CRB register via 2MB BAR
                    289:  *
                    290:  * @v phantom          Phantom NIC
                    291:  * @v reg              Register offset within abstract address space
                    292:  * @ret offset         Register offset within PCI BAR0
                    293:  */
                    294: static unsigned long phantom_crb_access_2m ( struct phantom_nic *phantom,
                    295:                                             unsigned long reg ) {
                    296:        static const struct {
                    297:                uint8_t block;
                    298:                uint16_t window_hi;
                    299:        } reg_window_hi[] = {
                    300:                { UNM_CRB_BLK_PCIE,     0x773 },
                    301:                { UNM_CRB_BLK_CAM,      0x416 },
                    302:                { UNM_CRB_BLK_ROMUSB,   0x421 },
                    303:                { UNM_CRB_BLK_TEST,     0x295 },
                    304:                { UNM_CRB_BLK_PEG_0,    0x340 },
                    305:                { UNM_CRB_BLK_PEG_1,    0x341 },
                    306:                { UNM_CRB_BLK_PEG_2,    0x342 },
                    307:                { UNM_CRB_BLK_PEG_3,    0x343 },
                    308:                { UNM_CRB_BLK_PEG_4,    0x34b },
                    309:        };
                    310:        unsigned int block = UNM_CRB_BLK ( reg );
                    311:        unsigned long offset = UNM_CRB_OFFSET ( reg );
                    312:        uint32_t window;
                    313:        uint32_t verify_window;
                    314:        unsigned int i;
                    315: 
                    316:        for ( i = 0 ; i < ( sizeof ( reg_window_hi ) /
                    317:                            sizeof ( reg_window_hi[0] ) ) ; i++ ) {
                    318: 
                    319:                if ( reg_window_hi[i].block != block )
                    320:                        continue;
                    321: 
                    322:                window = ( ( reg_window_hi[i].window_hi << 20 ) |
                    323:                           ( offset & 0x000f0000 ) );
                    324: 
                    325:                if ( phantom->crb_window != window ) {
                    326: 
                    327:                        /* Write to the CRB window register */
                    328:                        writel ( window, phantom->bar0 + UNM_2M_CRB_WINDOW );
                    329: 
                    330:                        /* Ensure that the write has reached the card */
                    331:                        verify_window = readl ( phantom->bar0 +
                    332:                                                UNM_2M_CRB_WINDOW );
                    333:                        assert ( verify_window == window );
                    334: 
                    335:                        /* Record new window */
                    336:                        phantom->crb_window = window;
                    337:                }
                    338: 
                    339:                return ( 0x1e0000 + ( offset & 0xffff ) );
                    340:        }
                    341: 
                    342:        assert ( 0 );
                    343:        return 0;
                    344: }
                    345: 
                    346: /**
                    347:  * Read from Phantom CRB register
                    348:  *
                    349:  * @v phantom          Phantom NIC
                    350:  * @v reg              Register offset within abstract address space
                    351:  * @ret        value           Register value
                    352:  */
                    353: static uint32_t phantom_readl ( struct phantom_nic *phantom,
                    354:                                unsigned long reg ) {
                    355:        unsigned long offset;
                    356: 
                    357:        offset = phantom->crb_access ( phantom, reg );
                    358:        return readl ( phantom->bar0 + offset );
                    359: }
                    360: 
                    361: /**
                    362:  * Write to Phantom CRB register
                    363:  *
                    364:  * @v phantom          Phantom NIC
                    365:  * @v value            Register value
                    366:  * @v reg              Register offset within abstract address space
                    367:  */
                    368: static void phantom_writel ( struct phantom_nic *phantom, uint32_t value,
                    369:                             unsigned long reg ) {
                    370:        unsigned long offset;
                    371: 
                    372:        offset = phantom->crb_access ( phantom, reg );
                    373:        writel ( value, phantom->bar0 + offset );
                    374: }
                    375: 
                    376: /**
                    377:  * Write to Phantom CRB HI/LO register pair
                    378:  *
                    379:  * @v phantom          Phantom NIC
                    380:  * @v value            Register value
                    381:  * @v lo_offset                LO register offset within CRB
                    382:  * @v hi_offset                HI register offset within CRB
                    383:  */
                    384: static inline void phantom_write_hilo ( struct phantom_nic *phantom,
                    385:                                        uint64_t value,
                    386:                                        unsigned long lo_offset,
                    387:                                        unsigned long hi_offset ) {
                    388:        uint32_t lo = ( value & 0xffffffffUL );
                    389:        uint32_t hi = ( value >> 32 );
                    390: 
                    391:        phantom_writel ( phantom, lo, lo_offset );
                    392:        phantom_writel ( phantom, hi, hi_offset );
                    393: }
                    394: 
                    395: /***************************************************************************
                    396:  *
                    397:  * Firmware message buffer access (for debug)
                    398:  *
                    399:  */
                    400: 
                    401: /**
                    402:  * Read from Phantom test memory
                    403:  *
                    404:  * @v phantom          Phantom NIC
                    405:  * @v offset           Offset within test memory
                    406:  * @v buf              8-byte buffer to fill
                    407:  * @ret rc             Return status code
                    408:  */
                    409: static int phantom_read_test_mem_block ( struct phantom_nic *phantom,
                    410:                                         unsigned long offset,
                    411:                                         uint32_t buf[2] ) {
                    412:        unsigned int retries;
                    413:        uint32_t test_control;
                    414: 
                    415:        phantom_write_hilo ( phantom, offset, UNM_TEST_ADDR_LO,
                    416:                             UNM_TEST_ADDR_HI );
                    417:        phantom_writel ( phantom, UNM_TEST_CONTROL_ENABLE, UNM_TEST_CONTROL );
                    418:        phantom_writel ( phantom,
                    419:                         ( UNM_TEST_CONTROL_ENABLE | UNM_TEST_CONTROL_START ),
                    420:                         UNM_TEST_CONTROL );
                    421:        
                    422:        for ( retries = 0 ; retries < PHN_TEST_MEM_TIMEOUT_MS ; retries++ ) {
                    423:                test_control = phantom_readl ( phantom, UNM_TEST_CONTROL );
                    424:                if ( ( test_control & UNM_TEST_CONTROL_BUSY ) == 0 ) {
                    425:                        buf[0] = phantom_readl ( phantom, UNM_TEST_RDDATA_LO );
                    426:                        buf[1] = phantom_readl ( phantom, UNM_TEST_RDDATA_HI );
                    427:                        return 0;
                    428:                }
                    429:                mdelay ( 1 );
                    430:        }
                    431: 
                    432:        DBGC ( phantom, "Phantom %p timed out waiting for test memory\n",
                    433:               phantom );
                    434:        return -ETIMEDOUT;
                    435: }
                    436: 
                    437: /**
                    438:  * Read single byte from Phantom test memory
                    439:  *
                    440:  * @v phantom          Phantom NIC
                    441:  * @v offset           Offset within test memory
                    442:  * @ret byte           Byte read, or negative error
                    443:  */
                    444: static int phantom_read_test_mem ( struct phantom_nic *phantom,
                    445:                                   unsigned long offset ) {
                    446:        static union {
                    447:                uint8_t bytes[8];
                    448:                uint32_t dwords[2];
                    449:        } cache;
                    450:        static unsigned long cache_offset = -1UL;
                    451:        unsigned long sub_offset;
                    452:        int rc;
                    453: 
                    454:        sub_offset = ( offset & ( sizeof ( cache ) - 1 ) );
                    455:        offset = ( offset & ~( sizeof ( cache ) - 1 ) );
                    456: 
                    457:        if ( cache_offset != offset ) {
                    458:                if ( ( rc = phantom_read_test_mem_block ( phantom, offset,
                    459:                                                          cache.dwords )) !=0 )
                    460:                        return rc;
                    461:                cache_offset = offset;
                    462:        }
                    463: 
                    464:        return cache.bytes[sub_offset];
                    465: }
                    466: 
                    467: /**
                    468:  * Dump Phantom firmware dmesg log
                    469:  *
                    470:  * @v phantom          Phantom NIC
                    471:  * @v log              Log number
                    472:  * @v max_lines                Maximum number of lines to show, or -1 to show all
                    473:  * @ret rc             Return status code
                    474:  */
                    475: static int phantom_dmesg ( struct phantom_nic *phantom, unsigned int log,
                    476:                            unsigned int max_lines ) {
                    477:        uint32_t head;
                    478:        uint32_t tail;
                    479:        uint32_t sig;
                    480:        uint32_t offset;
                    481:        int byte;
                    482: 
                    483:        /* Optimise out for non-debug builds */
                    484:        if ( ! DBG_LOG )
                    485:                return 0;
                    486: 
                    487:        /* Locate log */
                    488:        head = phantom_readl ( phantom, UNM_CAM_RAM_DMESG_HEAD ( log ) );
                    489:        tail = phantom_readl ( phantom, UNM_CAM_RAM_DMESG_TAIL ( log ) );
                    490:        sig = phantom_readl ( phantom, UNM_CAM_RAM_DMESG_SIG ( log ) );
                    491:        DBGC ( phantom, "Phantom %p firmware dmesg buffer %d (%08x-%08x)\n",
                    492:               phantom, log, head, tail );
                    493:        assert ( ( head & 0x07 ) == 0 );
                    494:        if ( sig != UNM_CAM_RAM_DMESG_SIG_MAGIC ) {
                    495:                DBGC ( phantom, "Warning: bad signature %08x (want %08lx)\n",
                    496:                       sig, UNM_CAM_RAM_DMESG_SIG_MAGIC );
                    497:        }
                    498: 
                    499:        /* Locate start of last (max_lines) lines */
                    500:        for ( offset = tail ; offset > head ; offset-- ) {
                    501:                if ( ( byte = phantom_read_test_mem ( phantom,
                    502:                                                      ( offset - 1 ) ) ) < 0 )
                    503:                        return byte;
                    504:                if ( ( byte == '\n' ) && ( max_lines-- == 0 ) )
                    505:                        break;
                    506:        }
                    507: 
                    508:        /* Print lines */
                    509:        for ( ; offset < tail ; offset++ ) {
                    510:                if ( ( byte = phantom_read_test_mem ( phantom, offset ) ) < 0 )
                    511:                        return byte;
                    512:                DBG ( "%c", byte );
                    513:        }
                    514:        DBG ( "\n" );
                    515:        return 0;
                    516: }
                    517: 
                    518: /**
                    519:  * Dump Phantom firmware dmesg logs
                    520:  *
                    521:  * @v phantom          Phantom NIC
                    522:  * @v max_lines                Maximum number of lines to show, or -1 to show all
                    523:  */
                    524: static void __attribute__ (( unused ))
                    525: phantom_dmesg_all ( struct phantom_nic *phantom, unsigned int max_lines ) {
                    526:        unsigned int i;
                    527: 
                    528:        for ( i = 0 ; i < UNM_CAM_RAM_NUM_DMESG_BUFFERS ; i++ )
                    529:                phantom_dmesg ( phantom, i, max_lines );
                    530: }
                    531: 
                    532: /***************************************************************************
                    533:  *
                    534:  * Firmware interface
                    535:  *
                    536:  */
                    537: 
                    538: /**
                    539:  * Wait for firmware to accept command
                    540:  *
                    541:  * @v phantom          Phantom NIC
                    542:  * @ret rc             Return status code
                    543:  */
                    544: static int phantom_wait_for_cmd ( struct phantom_nic *phantom ) {
                    545:        unsigned int retries;
                    546:        uint32_t cdrp;
                    547: 
                    548:        for ( retries = 0 ; retries < PHN_ISSUE_CMD_TIMEOUT_MS ; retries++ ) {
                    549:                mdelay ( 1 );
                    550:                cdrp = phantom_readl ( phantom, UNM_NIC_REG_NX_CDRP );
                    551:                if ( NX_CDRP_IS_RSP ( cdrp ) ) {
                    552:                        switch ( NX_CDRP_FORM_RSP ( cdrp ) ) {
                    553:                        case NX_CDRP_RSP_OK:
                    554:                                return 0;
                    555:                        case NX_CDRP_RSP_FAIL:
                    556:                                return -EIO;
                    557:                        case NX_CDRP_RSP_TIMEOUT:
                    558:                                return -ETIMEDOUT;
                    559:                        default:
                    560:                                return -EPROTO;
                    561:                        }
                    562:                }
                    563:        }
                    564: 
                    565:        DBGC ( phantom, "Phantom %p timed out waiting for firmware to accept "
                    566:               "command\n", phantom );
                    567:        return -ETIMEDOUT;
                    568: }
                    569: 
                    570: /**
                    571:  * Issue command to firmware
                    572:  *
                    573:  * @v phantom          Phantom NIC
                    574:  * @v command          Firmware command
                    575:  * @v arg1             Argument 1
                    576:  * @v arg2             Argument 2
                    577:  * @v arg3             Argument 3
                    578:  * @ret rc             Return status code
                    579:  */
                    580: static int phantom_issue_cmd ( struct phantom_nic *phantom,
                    581:                               uint32_t command, uint32_t arg1, uint32_t arg2,
                    582:                               uint32_t arg3 ) {
                    583:        uint32_t signature;
                    584:        int rc;
                    585: 
                    586:        /* Issue command */
                    587:        signature = NX_CDRP_SIGNATURE_MAKE ( phantom->port,
                    588:                                             NXHAL_VERSION );
                    589:        DBGC2 ( phantom, "Phantom %p issuing command %08x (%08x, %08x, "
                    590:                "%08x)\n", phantom, command, arg1, arg2, arg3 );
                    591:        phantom_writel ( phantom, signature, UNM_NIC_REG_NX_SIGN );
                    592:        phantom_writel ( phantom, arg1, UNM_NIC_REG_NX_ARG1 );
                    593:        phantom_writel ( phantom, arg2, UNM_NIC_REG_NX_ARG2 );
                    594:        phantom_writel ( phantom, arg3, UNM_NIC_REG_NX_ARG3 );
                    595:        phantom_writel ( phantom, NX_CDRP_FORM_CMD ( command ),
                    596:                         UNM_NIC_REG_NX_CDRP );
                    597: 
                    598:        /* Wait for command to be accepted */
                    599:        if ( ( rc = phantom_wait_for_cmd ( phantom ) ) != 0 ) {
                    600:                DBGC ( phantom, "Phantom %p could not issue command: %s\n",
                    601:                       phantom, strerror ( rc ) );
                    602:                return rc;
                    603:        }
                    604: 
                    605:        return 0;
                    606: }
                    607: 
                    608: /**
                    609:  * Issue buffer-format command to firmware
                    610:  *
                    611:  * @v phantom          Phantom NIC
                    612:  * @v command          Firmware command
                    613:  * @v buffer           Buffer to pass to firmware
                    614:  * @v len              Length of buffer
                    615:  * @ret rc             Return status code
                    616:  */
                    617: static int phantom_issue_buf_cmd ( struct phantom_nic *phantom,
                    618:                                   uint32_t command, void *buffer,
                    619:                                   size_t len ) {
                    620:        uint64_t physaddr;
                    621: 
                    622:        physaddr = virt_to_bus ( buffer );
                    623:        return phantom_issue_cmd ( phantom, command, ( physaddr >> 32 ),
                    624:                                   ( physaddr & 0xffffffffUL ), len );
                    625: }
                    626: 
                    627: /**
                    628:  * Create Phantom RX context
                    629:  *
                    630:  * @v phantom          Phantom NIC
                    631:  * @ret rc             Return status code
                    632:  */
                    633: static int phantom_create_rx_ctx ( struct phantom_nic *phantom ) {
                    634:        struct phantom_create_rx_ctx_rqrsp *buf;
                    635:        int rc;
                    636: 
                    637:        /* Allocate context creation buffer */
                    638:        buf = malloc_dma ( sizeof ( *buf ), UNM_DMA_BUFFER_ALIGN );
                    639:        if ( ! buf ) {
                    640:                rc = -ENOMEM;
                    641:                goto out;
                    642:        }
                    643:        memset ( buf, 0, sizeof ( *buf ) );
                    644:        
                    645:        /* Prepare request */
                    646:        buf->hostrq.rx_ctx.host_rsp_dma_addr =
                    647:                cpu_to_le64 ( virt_to_bus ( &buf->cardrsp ) );
                    648:        buf->hostrq.rx_ctx.capabilities[0] =
                    649:                cpu_to_le32 ( NX_CAP0_LEGACY_CONTEXT | NX_CAP0_LEGACY_MN );
                    650:        buf->hostrq.rx_ctx.host_int_crb_mode =
                    651:                cpu_to_le32 ( NX_HOST_INT_CRB_MODE_SHARED );
                    652:        buf->hostrq.rx_ctx.host_rds_crb_mode =
                    653:                cpu_to_le32 ( NX_HOST_RDS_CRB_MODE_UNIQUE );
                    654:        buf->hostrq.rx_ctx.rds_ring_offset = cpu_to_le32 ( 0 );
                    655:        buf->hostrq.rx_ctx.sds_ring_offset =
                    656:                cpu_to_le32 ( sizeof ( buf->hostrq.rds ) );
                    657:        buf->hostrq.rx_ctx.num_rds_rings = cpu_to_le16 ( 1 );
                    658:        buf->hostrq.rx_ctx.num_sds_rings = cpu_to_le16 ( 1 );
                    659:        buf->hostrq.rds.host_phys_addr =
                    660:                cpu_to_le64 ( virt_to_bus ( phantom->desc->rds ) );
                    661:        buf->hostrq.rds.buff_size = cpu_to_le64 ( PHN_RX_BUFSIZE );
                    662:        buf->hostrq.rds.ring_size = cpu_to_le32 ( PHN_NUM_RDS );
                    663:        buf->hostrq.rds.ring_kind = cpu_to_le32 ( NX_RDS_RING_TYPE_NORMAL );
                    664:        buf->hostrq.sds.host_phys_addr =
                    665:                cpu_to_le64 ( virt_to_bus ( phantom->desc->sds ) );
                    666:        buf->hostrq.sds.ring_size = cpu_to_le32 ( PHN_NUM_SDS );
                    667: 
                    668:        DBGC ( phantom, "Phantom %p creating RX context\n", phantom );
                    669:        DBGC2_HDA ( phantom, virt_to_bus ( &buf->hostrq ),
                    670:                    &buf->hostrq, sizeof ( buf->hostrq ) );
                    671: 
                    672:        /* Issue request */
                    673:        if ( ( rc = phantom_issue_buf_cmd ( phantom,
                    674:                                            NX_CDRP_CMD_CREATE_RX_CTX,
                    675:                                            &buf->hostrq,
                    676:                                            sizeof ( buf->hostrq ) ) ) != 0 ) {
                    677:                DBGC ( phantom, "Phantom %p could not create RX context: "
                    678:                       "%s\n", phantom, strerror ( rc ) );
                    679:                DBGC ( phantom, "Request:\n" );
                    680:                DBGC_HDA ( phantom, virt_to_bus ( &buf->hostrq ),
                    681:                           &buf->hostrq, sizeof ( buf->hostrq ) );
                    682:                DBGC ( phantom, "Response:\n" );
                    683:                DBGC_HDA ( phantom, virt_to_bus ( &buf->cardrsp ),
                    684:                           &buf->cardrsp, sizeof ( buf->cardrsp ) );
                    685:                goto out;
                    686:        }
                    687: 
                    688:        /* Retrieve context parameters */
                    689:        phantom->rx_context_id =
                    690:                le16_to_cpu ( buf->cardrsp.rx_ctx.context_id );
                    691:        phantom->rds_producer_crb =
                    692:                ( UNM_CAM_RAM +
                    693:                  le32_to_cpu ( buf->cardrsp.rds.host_producer_crb ) );
                    694:        phantom->sds_consumer_crb =
                    695:                ( UNM_CAM_RAM +
                    696:                  le32_to_cpu ( buf->cardrsp.sds.host_consumer_crb ) );
                    697:        phantom->sds_irq_mask_crb =
                    698:                ( UNM_CAM_RAM +
                    699:                  le32_to_cpu ( buf->cardrsp.sds.interrupt_crb ) );
                    700: 
                    701:        DBGC ( phantom, "Phantom %p created RX context (id %04x, port phys "
                    702:               "%02x virt %02x)\n", phantom, phantom->rx_context_id,
                    703:               buf->cardrsp.rx_ctx.phys_port, buf->cardrsp.rx_ctx.virt_port );
                    704:        DBGC2_HDA ( phantom, virt_to_bus ( &buf->cardrsp ),
                    705:                    &buf->cardrsp, sizeof ( buf->cardrsp ) );
                    706:        DBGC ( phantom, "Phantom %p RDS producer CRB is %08lx\n",
                    707:               phantom, phantom->rds_producer_crb );
                    708:        DBGC ( phantom, "Phantom %p SDS consumer CRB is %08lx\n",
                    709:               phantom, phantom->sds_consumer_crb );
                    710:        DBGC ( phantom, "Phantom %p SDS interrupt mask CRB is %08lx\n",
                    711:               phantom, phantom->sds_irq_mask_crb );
                    712: 
                    713:  out:
                    714:        free_dma ( buf, sizeof ( *buf ) );
                    715:        return rc;
                    716: }
                    717: 
                    718: /**
                    719:  * Destroy Phantom RX context
                    720:  *
                    721:  * @v phantom          Phantom NIC
                    722:  * @ret rc             Return status code
                    723:  */
                    724: static void phantom_destroy_rx_ctx ( struct phantom_nic *phantom ) {
                    725:        int rc;
                    726:        
                    727:        DBGC ( phantom, "Phantom %p destroying RX context (id %04x)\n",
                    728:               phantom, phantom->rx_context_id );
                    729: 
                    730:        /* Issue request */
                    731:        if ( ( rc = phantom_issue_cmd ( phantom,
                    732:                                        NX_CDRP_CMD_DESTROY_RX_CTX,
                    733:                                        phantom->rx_context_id,
                    734:                                        NX_DESTROY_CTX_RESET, 0 ) ) != 0 ) {
                    735:                DBGC ( phantom, "Phantom %p could not destroy RX context: "
                    736:                       "%s\n", phantom, strerror ( rc ) );
                    737:                /* We're probably screwed */
                    738:                return;
                    739:        }
                    740: 
                    741:        /* Clear context parameters */
                    742:        phantom->rx_context_id = 0;
                    743:        phantom->rds_producer_crb = 0;
                    744:        phantom->sds_consumer_crb = 0;
                    745: 
                    746:        /* Reset software counters */
                    747:        phantom->rds_producer_idx = 0;
                    748:        phantom->rds_consumer_idx = 0;
                    749:        phantom->sds_consumer_idx = 0;
                    750: }
                    751: 
                    752: /**
                    753:  * Create Phantom TX context
                    754:  *
                    755:  * @v phantom          Phantom NIC
                    756:  * @ret rc             Return status code
                    757:  */
                    758: static int phantom_create_tx_ctx ( struct phantom_nic *phantom ) {
                    759:        struct phantom_create_tx_ctx_rqrsp *buf;
                    760:        int rc;
                    761: 
                    762:        /* Allocate context creation buffer */
                    763:        buf = malloc_dma ( sizeof ( *buf ), UNM_DMA_BUFFER_ALIGN );
                    764:        if ( ! buf ) {
                    765:                rc = -ENOMEM;
                    766:                goto out;
                    767:        }
                    768:        memset ( buf, 0, sizeof ( *buf ) );
                    769: 
                    770:        /* Prepare request */
                    771:        buf->hostrq.tx_ctx.host_rsp_dma_addr =
                    772:                cpu_to_le64 ( virt_to_bus ( &buf->cardrsp ) );
                    773:        buf->hostrq.tx_ctx.cmd_cons_dma_addr =
                    774:                cpu_to_le64 ( virt_to_bus ( &phantom->desc->cmd_cons ) );
                    775:        buf->hostrq.tx_ctx.capabilities[0] =
                    776:                cpu_to_le32 ( NX_CAP0_LEGACY_CONTEXT | NX_CAP0_LEGACY_MN );
                    777:        buf->hostrq.tx_ctx.host_int_crb_mode =
                    778:                cpu_to_le32 ( NX_HOST_INT_CRB_MODE_SHARED );
                    779:        buf->hostrq.tx_ctx.cds_ring.host_phys_addr =
                    780:                cpu_to_le64 ( virt_to_bus ( phantom->desc->cds ) );
                    781:        buf->hostrq.tx_ctx.cds_ring.ring_size = cpu_to_le32 ( PHN_NUM_CDS );
                    782: 
                    783:        DBGC ( phantom, "Phantom %p creating TX context\n", phantom );
                    784:        DBGC2_HDA ( phantom, virt_to_bus ( &buf->hostrq ),
                    785:                    &buf->hostrq, sizeof ( buf->hostrq ) );
                    786: 
                    787:        /* Issue request */
                    788:        if ( ( rc = phantom_issue_buf_cmd ( phantom,
                    789:                                            NX_CDRP_CMD_CREATE_TX_CTX,
                    790:                                            &buf->hostrq,
                    791:                                            sizeof ( buf->hostrq ) ) ) != 0 ) {
                    792:                DBGC ( phantom, "Phantom %p could not create TX context: "
                    793:                       "%s\n", phantom, strerror ( rc ) );
                    794:                DBGC ( phantom, "Request:\n" );
                    795:                DBGC_HDA ( phantom, virt_to_bus ( &buf->hostrq ),
                    796:                           &buf->hostrq, sizeof ( buf->hostrq ) );
                    797:                DBGC ( phantom, "Response:\n" );
                    798:                DBGC_HDA ( phantom, virt_to_bus ( &buf->cardrsp ),
                    799:                           &buf->cardrsp, sizeof ( buf->cardrsp ) );
                    800:                goto out;
                    801:        }
                    802: 
                    803:        /* Retrieve context parameters */
                    804:        phantom->tx_context_id =
                    805:                le16_to_cpu ( buf->cardrsp.tx_ctx.context_id );
                    806:        phantom->cds_producer_crb =
                    807:                ( UNM_CAM_RAM +
                    808:                  le32_to_cpu(buf->cardrsp.tx_ctx.cds_ring.host_producer_crb));
                    809: 
                    810:        DBGC ( phantom, "Phantom %p created TX context (id %04x, port phys "
                    811:               "%02x virt %02x)\n", phantom, phantom->tx_context_id,
                    812:               buf->cardrsp.tx_ctx.phys_port, buf->cardrsp.tx_ctx.virt_port );
                    813:        DBGC2_HDA ( phantom, virt_to_bus ( &buf->cardrsp ),
                    814:                    &buf->cardrsp, sizeof ( buf->cardrsp ) );
                    815:        DBGC ( phantom, "Phantom %p CDS producer CRB is %08lx\n",
                    816:               phantom, phantom->cds_producer_crb );
                    817: 
                    818:  out:
                    819:        free_dma ( buf, sizeof ( *buf ) );
                    820:        return rc;
                    821: }
                    822: 
                    823: /**
                    824:  * Destroy Phantom TX context
                    825:  *
                    826:  * @v phantom          Phantom NIC
                    827:  * @ret rc             Return status code
                    828:  */
                    829: static void phantom_destroy_tx_ctx ( struct phantom_nic *phantom ) {
                    830:        int rc;
                    831:        
                    832:        DBGC ( phantom, "Phantom %p destroying TX context (id %04x)\n",
                    833:               phantom, phantom->tx_context_id );
                    834: 
                    835:        /* Issue request */
                    836:        if ( ( rc = phantom_issue_cmd ( phantom,
                    837:                                        NX_CDRP_CMD_DESTROY_TX_CTX,
                    838:                                        phantom->tx_context_id,
                    839:                                        NX_DESTROY_CTX_RESET, 0 ) ) != 0 ) {
                    840:                DBGC ( phantom, "Phantom %p could not destroy TX context: "
                    841:                       "%s\n", phantom, strerror ( rc ) );
                    842:                /* We're probably screwed */
                    843:                return;
                    844:        }
                    845: 
                    846:        /* Clear context parameters */
                    847:        phantom->tx_context_id = 0;
                    848:        phantom->cds_producer_crb = 0;
                    849: 
                    850:        /* Reset software counters */
                    851:        phantom->cds_producer_idx = 0;
                    852:        phantom->cds_consumer_idx = 0;
                    853: }
                    854: 
                    855: /***************************************************************************
                    856:  *
                    857:  * Descriptor ring management
                    858:  *
                    859:  */
                    860: 
                    861: /**
                    862:  * Allocate Phantom RX descriptor
                    863:  *
                    864:  * @v phantom          Phantom NIC
                    865:  * @ret index          RX descriptor index, or negative error
                    866:  */
                    867: static int phantom_alloc_rds ( struct phantom_nic *phantom ) {
                    868:        unsigned int rds_producer_idx;
                    869:        unsigned int next_rds_producer_idx;
                    870: 
                    871:        /* Check for space in the ring.  RX descriptors are consumed
                    872:         * out of order, but they are *read* by the hardware in strict
                    873:         * order.  We maintain a pessimistic consumer index, which is
                    874:         * guaranteed never to be an overestimate of the number of
                    875:         * descriptors read by the hardware.
                    876:         */
                    877:        rds_producer_idx = phantom->rds_producer_idx;
                    878:        next_rds_producer_idx = ( ( rds_producer_idx + 1 ) % PHN_NUM_RDS );
                    879:        if ( next_rds_producer_idx == phantom->rds_consumer_idx ) {
                    880:                DBGC ( phantom, "Phantom %p RDS ring full (index %d not "
                    881:                       "consumed)\n", phantom, next_rds_producer_idx );
                    882:                return -ENOBUFS;
                    883:        }
                    884: 
                    885:        return rds_producer_idx;
                    886: }
                    887: 
                    888: /**
                    889:  * Post Phantom RX descriptor
                    890:  *
                    891:  * @v phantom          Phantom NIC
                    892:  * @v rds              RX descriptor
                    893:  */
                    894: static void phantom_post_rds ( struct phantom_nic *phantom,
                    895:                               struct phantom_rds *rds ) {
                    896:        unsigned int rds_producer_idx;
                    897:        unsigned int next_rds_producer_idx;
                    898:        struct phantom_rds *entry;
                    899: 
                    900:        /* Copy descriptor to ring */
                    901:        rds_producer_idx = phantom->rds_producer_idx;
                    902:        entry = &phantom->desc->rds[rds_producer_idx];
                    903:        memcpy ( entry, rds, sizeof ( *entry ) );
                    904:        DBGC2 ( phantom, "Phantom %p posting RDS %ld (slot %d):\n",
                    905:                phantom, NX_GET ( rds, handle ), rds_producer_idx );
                    906:        DBGC2_HDA ( phantom, virt_to_bus ( entry ), entry, sizeof ( *entry ) );
                    907: 
                    908:        /* Update producer index */
                    909:        next_rds_producer_idx = ( ( rds_producer_idx + 1 ) % PHN_NUM_RDS );
                    910:        phantom->rds_producer_idx = next_rds_producer_idx;
                    911:        wmb();
                    912:        phantom_writel ( phantom, phantom->rds_producer_idx,
                    913:                         phantom->rds_producer_crb );
                    914: }
                    915: 
                    916: /**
                    917:  * Allocate Phantom TX descriptor
                    918:  *
                    919:  * @v phantom          Phantom NIC
                    920:  * @ret index          TX descriptor index, or negative error
                    921:  */
                    922: static int phantom_alloc_cds ( struct phantom_nic *phantom ) {
                    923:        unsigned int cds_producer_idx;
                    924:        unsigned int next_cds_producer_idx;
                    925: 
                    926:        /* Check for space in the ring.  TX descriptors are consumed
                    927:         * in strict order, so we just check for a collision against
                    928:         * the consumer index.
                    929:         */
                    930:        cds_producer_idx = phantom->cds_producer_idx;
                    931:        next_cds_producer_idx = ( ( cds_producer_idx + 1 ) % PHN_NUM_CDS );
                    932:        if ( next_cds_producer_idx == phantom->cds_consumer_idx ) {
                    933:                DBGC ( phantom, "Phantom %p CDS ring full (index %d not "
                    934:                       "consumed)\n", phantom, next_cds_producer_idx );
                    935:                return -ENOBUFS;
                    936:        }
                    937: 
                    938:        return cds_producer_idx;
                    939: }
                    940: 
                    941: /**
                    942:  * Post Phantom TX descriptor
                    943:  *
                    944:  * @v phantom          Phantom NIC
                    945:  * @v cds              TX descriptor
                    946:  */
                    947: static void phantom_post_cds ( struct phantom_nic *phantom,
                    948:                               union phantom_cds *cds ) {
                    949:        unsigned int cds_producer_idx;
                    950:        unsigned int next_cds_producer_idx;
                    951:        union phantom_cds *entry;
                    952: 
                    953:        /* Copy descriptor to ring */
                    954:        cds_producer_idx = phantom->cds_producer_idx;
                    955:        entry = &phantom->desc->cds[cds_producer_idx];
                    956:        memcpy ( entry, cds, sizeof ( *entry ) );
                    957:        DBGC2 ( phantom, "Phantom %p posting CDS %d:\n",
                    958:                phantom, cds_producer_idx );
                    959:        DBGC2_HDA ( phantom, virt_to_bus ( entry ), entry, sizeof ( *entry ) );
                    960: 
                    961:        /* Update producer index */
                    962:        next_cds_producer_idx = ( ( cds_producer_idx + 1 ) % PHN_NUM_CDS );
                    963:        phantom->cds_producer_idx = next_cds_producer_idx;
                    964:        wmb();
                    965:        phantom_writel ( phantom, phantom->cds_producer_idx,
                    966:                         phantom->cds_producer_crb );
                    967: }
                    968: 
                    969: /***************************************************************************
                    970:  *
                    971:  * MAC address management
                    972:  *
                    973:  */
                    974: 
                    975: /**
                    976:  * Add/remove MAC address
                    977:  *
                    978:  * @v phantom          Phantom NIC
                    979:  * @v ll_addr          MAC address to add or remove
                    980:  * @v opcode           MAC request opcode
                    981:  * @ret rc             Return status code
                    982:  */
                    983: static int phantom_update_macaddr ( struct phantom_nic *phantom,
                    984:                                    const uint8_t *ll_addr,
                    985:                                    unsigned int opcode ) {
                    986:        union phantom_cds cds;
                    987:        int index;
                    988: 
                    989:        /* Get descriptor ring entry */
                    990:        index = phantom_alloc_cds ( phantom );
                    991:        if ( index < 0 )
                    992:                return index;
                    993: 
                    994:        /* Fill descriptor ring entry */
                    995:        memset ( &cds, 0, sizeof ( cds ) );
                    996:        NX_FILL_1 ( &cds, 0,
                    997:                    nic_request.common.opcode, UNM_NIC_REQUEST );
                    998:        NX_FILL_2 ( &cds, 1,
                    999:                    nic_request.header.opcode, UNM_MAC_EVENT,
                   1000:                    nic_request.header.context_id, phantom->port );
                   1001:        NX_FILL_7 ( &cds, 2,
                   1002:                    nic_request.body.mac_request.opcode, opcode,
                   1003:                    nic_request.body.mac_request.mac_addr_0, ll_addr[0],
                   1004:                    nic_request.body.mac_request.mac_addr_1, ll_addr[1],
                   1005:                    nic_request.body.mac_request.mac_addr_2, ll_addr[2],
                   1006:                    nic_request.body.mac_request.mac_addr_3, ll_addr[3],
                   1007:                    nic_request.body.mac_request.mac_addr_4, ll_addr[4],
                   1008:                    nic_request.body.mac_request.mac_addr_5, ll_addr[5] );
                   1009: 
                   1010:        /* Post descriptor */
                   1011:        phantom_post_cds ( phantom, &cds );
                   1012: 
                   1013:        return 0;
                   1014: }
                   1015: 
                   1016: /**
                   1017:  * Add MAC address
                   1018:  *
                   1019:  * @v phantom          Phantom NIC
                   1020:  * @v ll_addr          MAC address to add or remove
                   1021:  * @ret rc             Return status code
                   1022:  */
                   1023: static inline int phantom_add_macaddr ( struct phantom_nic *phantom,
                   1024:                                        const uint8_t *ll_addr ) {
                   1025: 
                   1026:        DBGC ( phantom, "Phantom %p adding MAC address %s\n",
                   1027:               phantom, eth_ntoa ( ll_addr ) );
                   1028: 
                   1029:        return phantom_update_macaddr ( phantom, ll_addr, UNM_MAC_ADD );
                   1030: }
                   1031: 
                   1032: /**
                   1033:  * Remove MAC address
                   1034:  *
                   1035:  * @v phantom          Phantom NIC
                   1036:  * @v ll_addr          MAC address to add or remove
                   1037:  * @ret rc             Return status code
                   1038:  */
                   1039: static inline int phantom_del_macaddr ( struct phantom_nic *phantom,
                   1040:                                        const uint8_t *ll_addr ) {
                   1041: 
                   1042:        DBGC ( phantom, "Phantom %p removing MAC address %s\n",
                   1043:               phantom, eth_ntoa ( ll_addr ) );
                   1044: 
                   1045:        return phantom_update_macaddr ( phantom, ll_addr, UNM_MAC_DEL );
                   1046: }
                   1047: 
                   1048: /***************************************************************************
                   1049:  *
                   1050:  * Link state detection
                   1051:  *
                   1052:  */
                   1053: 
                   1054: /**
                   1055:  * Poll link state
                   1056:  *
                   1057:  * @v netdev           Network device
                   1058:  */
                   1059: static void phantom_poll_link_state ( struct net_device *netdev ) {
                   1060:        struct phantom_nic *phantom = netdev_priv ( netdev );
                   1061:        uint32_t xg_state_p3;
                   1062:        unsigned int link;
                   1063: 
                   1064:        /* Read link state */
                   1065:        xg_state_p3 = phantom_readl ( phantom, UNM_NIC_REG_XG_STATE_P3 );
                   1066: 
                   1067:        /* If there is no change, do nothing */
                   1068:        if ( phantom->link_state == xg_state_p3 )
                   1069:                return;
                   1070: 
                   1071:        /* Record new link state */
                   1072:        DBGC ( phantom, "Phantom %p new link state %08x (was %08x)\n",
                   1073:               phantom, xg_state_p3, phantom->link_state );
                   1074:        phantom->link_state = xg_state_p3;
                   1075: 
                   1076:        /* Indicate link state to iPXE */
                   1077:        link = UNM_NIC_REG_XG_STATE_P3_LINK ( phantom->port,
                   1078:                                              phantom->link_state );
                   1079:        switch ( link ) {
                   1080:        case UNM_NIC_REG_XG_STATE_P3_LINK_UP:
                   1081:                DBGC ( phantom, "Phantom %p link is up\n", phantom );
                   1082:                netdev_link_up ( netdev );
                   1083:                break;
                   1084:        case UNM_NIC_REG_XG_STATE_P3_LINK_DOWN:
                   1085:                DBGC ( phantom, "Phantom %p link is down\n", phantom );
                   1086:                netdev_link_down ( netdev );
                   1087:                break;
                   1088:        default:
                   1089:                DBGC ( phantom, "Phantom %p bad link state %d\n",
                   1090:                       phantom, link );
                   1091:                break;
                   1092:        }
                   1093: }
                   1094: 
                   1095: /***************************************************************************
                   1096:  *
                   1097:  * Main driver body
                   1098:  *
                   1099:  */
                   1100: 
                   1101: /**
                   1102:  * Refill descriptor ring
                   1103:  *
                   1104:  * @v netdev           Net device
                   1105:  */
                   1106: static void phantom_refill_rx_ring ( struct net_device *netdev ) {
                   1107:        struct phantom_nic *phantom = netdev_priv ( netdev );
                   1108:        struct io_buffer *iobuf;
                   1109:        struct phantom_rds rds;
                   1110:        unsigned int handle;
                   1111:        int index;
                   1112: 
                   1113:        for ( handle = 0 ; handle < PHN_RDS_MAX_FILL ; handle++ ) {
                   1114: 
                   1115:                /* Skip this index if the descriptor has not yet been
                   1116:                 * consumed.
                   1117:                 */
                   1118:                if ( phantom->rds_iobuf[handle] != NULL )
                   1119:                        continue;
                   1120: 
                   1121:                /* Allocate descriptor ring entry */
                   1122:                index = phantom_alloc_rds ( phantom );
                   1123:                assert ( PHN_RDS_MAX_FILL < PHN_NUM_RDS );
                   1124:                assert ( index >= 0 ); /* Guaranteed by MAX_FILL < NUM_RDS ) */
                   1125: 
                   1126:                /* Try to allocate an I/O buffer */
                   1127:                iobuf = alloc_iob ( PHN_RX_BUFSIZE );
                   1128:                if ( ! iobuf ) {
                   1129:                        /* Failure is non-fatal; we will retry later */
                   1130:                        netdev_rx_err ( netdev, NULL, -ENOMEM );
                   1131:                        break;
                   1132:                }
                   1133: 
                   1134:                /* Fill descriptor ring entry */
                   1135:                memset ( &rds, 0, sizeof ( rds ) );
                   1136:                NX_FILL_2 ( &rds, 0,
                   1137:                            handle, handle,
                   1138:                            length, iob_len ( iobuf ) );
                   1139:                NX_FILL_1 ( &rds, 1,
                   1140:                            dma_addr, virt_to_bus ( iobuf->data ) );
                   1141: 
                   1142:                /* Record I/O buffer */
                   1143:                assert ( phantom->rds_iobuf[handle] == NULL );
                   1144:                phantom->rds_iobuf[handle] = iobuf;
                   1145: 
                   1146:                /* Post descriptor */
                   1147:                phantom_post_rds ( phantom, &rds );
                   1148:        }
                   1149: }
                   1150: 
                   1151: /**
                   1152:  * Open NIC
                   1153:  *
                   1154:  * @v netdev           Net device
                   1155:  * @ret rc             Return status code
                   1156:  */
                   1157: static int phantom_open ( struct net_device *netdev ) {
                   1158:        struct phantom_nic *phantom = netdev_priv ( netdev );
                   1159:        int rc;
                   1160: 
                   1161:        /* Allocate and zero descriptor rings */
                   1162:        phantom->desc = malloc_dma ( sizeof ( *(phantom->desc) ),
                   1163:                                          UNM_DMA_BUFFER_ALIGN );
                   1164:        if ( ! phantom->desc ) {
                   1165:                rc = -ENOMEM;
                   1166:                goto err_alloc_desc;
                   1167:        }
                   1168:        memset ( phantom->desc, 0, sizeof ( *(phantom->desc) ) );
                   1169: 
                   1170:        /* Create RX context */
                   1171:        if ( ( rc = phantom_create_rx_ctx ( phantom ) ) != 0 )
                   1172:                goto err_create_rx_ctx;
                   1173: 
                   1174:        /* Create TX context */
                   1175:        if ( ( rc = phantom_create_tx_ctx ( phantom ) ) != 0 )
                   1176:                goto err_create_tx_ctx;
                   1177: 
                   1178:        /* Fill the RX descriptor ring */
                   1179:        phantom_refill_rx_ring ( netdev );
                   1180: 
                   1181:        /* Add MAC addresses
                   1182:         *
                   1183:         * BUG5583
                   1184:         *
                   1185:         * We would like to be able to enable receiving all multicast
                   1186:         * packets (or, failing that, promiscuous mode), but the
                   1187:         * firmware doesn't currently support this.
                   1188:         */
                   1189:        if ( ( rc = phantom_add_macaddr ( phantom,
                   1190:                                          netdev->ll_broadcast ) ) != 0 )
                   1191:                goto err_add_macaddr_broadcast;
                   1192:        if ( ( rc = phantom_add_macaddr ( phantom,
                   1193:                                          netdev->ll_addr ) ) != 0 )
                   1194:                goto err_add_macaddr_unicast;
                   1195: 
                   1196:        return 0;
                   1197: 
                   1198:        phantom_del_macaddr ( phantom, netdev->ll_addr );
                   1199:  err_add_macaddr_unicast:
                   1200:        phantom_del_macaddr ( phantom, netdev->ll_broadcast );
                   1201:  err_add_macaddr_broadcast:
                   1202:        phantom_destroy_tx_ctx ( phantom );
                   1203:  err_create_tx_ctx:
                   1204:        phantom_destroy_rx_ctx ( phantom );
                   1205:  err_create_rx_ctx:
                   1206:        free_dma ( phantom->desc, sizeof ( *(phantom->desc) ) );
                   1207:        phantom->desc = NULL;
                   1208:  err_alloc_desc:
                   1209:        return rc;
                   1210: }
                   1211: 
                   1212: /**
                   1213:  * Close NIC
                   1214:  *
                   1215:  * @v netdev           Net device
                   1216:  */
                   1217: static void phantom_close ( struct net_device *netdev ) {
                   1218:        struct phantom_nic *phantom = netdev_priv ( netdev );
                   1219:        struct io_buffer *iobuf;
                   1220:        unsigned int i;
                   1221: 
                   1222:        /* Shut down the port */
                   1223:        phantom_del_macaddr ( phantom, netdev->ll_addr );
                   1224:        phantom_del_macaddr ( phantom, netdev->ll_broadcast );
                   1225:        phantom_destroy_tx_ctx ( phantom );
                   1226:        phantom_destroy_rx_ctx ( phantom );
                   1227:        free_dma ( phantom->desc, sizeof ( *(phantom->desc) ) );
                   1228:        phantom->desc = NULL;
                   1229: 
                   1230:        /* Flush any uncompleted descriptors */
                   1231:        for ( i = 0 ; i < PHN_RDS_MAX_FILL ; i++ ) {
                   1232:                iobuf = phantom->rds_iobuf[i];
                   1233:                if ( iobuf ) {
                   1234:                        free_iob ( iobuf );
                   1235:                        phantom->rds_iobuf[i] = NULL;
                   1236:                }
                   1237:        }
                   1238:        for ( i = 0 ; i < PHN_NUM_CDS ; i++ ) {
                   1239:                iobuf = phantom->cds_iobuf[i];
                   1240:                if ( iobuf ) {
                   1241:                        netdev_tx_complete_err ( netdev, iobuf, -ECANCELED );
                   1242:                        phantom->cds_iobuf[i] = NULL;
                   1243:                }
                   1244:        }
                   1245: }
                   1246: 
                   1247: /** 
                   1248:  * Transmit packet
                   1249:  *
                   1250:  * @v netdev   Network device
                   1251:  * @v iobuf    I/O buffer
                   1252:  * @ret rc     Return status code
                   1253:  */
                   1254: static int phantom_transmit ( struct net_device *netdev,
                   1255:                              struct io_buffer *iobuf ) {
                   1256:        struct phantom_nic *phantom = netdev_priv ( netdev );
                   1257:        union phantom_cds cds;
                   1258:        int index;
                   1259: 
                   1260:        /* Get descriptor ring entry */
                   1261:        index = phantom_alloc_cds ( phantom );
                   1262:        if ( index < 0 )
                   1263:                return index;
                   1264: 
                   1265:        /* Fill descriptor ring entry */
                   1266:        memset ( &cds, 0, sizeof ( cds ) );
                   1267:        NX_FILL_3 ( &cds, 0,
                   1268:                    tx.opcode, UNM_TX_ETHER_PKT,
                   1269:                    tx.num_buffers, 1,
                   1270:                    tx.length, iob_len ( iobuf ) );
                   1271:        NX_FILL_2 ( &cds, 2,
                   1272:                    tx.port, phantom->port,
                   1273:                    tx.context_id, phantom->port );
                   1274:        NX_FILL_1 ( &cds, 4,
                   1275:                    tx.buffer1_dma_addr, virt_to_bus ( iobuf->data ) );
                   1276:        NX_FILL_1 ( &cds, 5,
                   1277:                    tx.buffer1_length, iob_len ( iobuf ) );
                   1278: 
                   1279:        /* Record I/O buffer */
                   1280:        assert ( phantom->cds_iobuf[index] == NULL );
                   1281:        phantom->cds_iobuf[index] = iobuf;
                   1282: 
                   1283:        /* Post descriptor */
                   1284:        phantom_post_cds ( phantom, &cds );
                   1285: 
                   1286:        return 0;
                   1287: }
                   1288: 
                   1289: /**
                   1290:  * Poll for received packets
                   1291:  *
                   1292:  * @v netdev   Network device
                   1293:  */
                   1294: static void phantom_poll ( struct net_device *netdev ) {
                   1295:        struct phantom_nic *phantom = netdev_priv ( netdev );
                   1296:        struct io_buffer *iobuf;
                   1297:        unsigned int irq_vector;
                   1298:        unsigned int irq_state;
                   1299:        unsigned int cds_consumer_idx;
                   1300:        unsigned int raw_new_cds_consumer_idx;
                   1301:        unsigned int new_cds_consumer_idx;
                   1302:        unsigned int rds_consumer_idx;
                   1303:        unsigned int sds_consumer_idx;
                   1304:        struct phantom_sds *sds;
                   1305:        unsigned int sds_handle;
                   1306:        unsigned int sds_opcode;
                   1307: 
                   1308:        /* Occasionally poll the link state */
                   1309:        if ( phantom->link_poll_timer-- == 0 ) {
                   1310:                phantom_poll_link_state ( netdev );
                   1311:                /* Reset the link poll timer */
                   1312:                phantom->link_poll_timer = PHN_LINK_POLL_FREQUENCY;
                   1313:        }
                   1314: 
                   1315:        /* Check for interrupts */
                   1316:        if ( phantom->sds_irq_enabled ) {
                   1317: 
                   1318:                /* Do nothing unless an interrupt is asserted */
                   1319:                irq_vector = phantom_readl ( phantom, UNM_PCIE_IRQ_VECTOR );
                   1320:                if ( ! ( irq_vector & UNM_PCIE_IRQ_VECTOR_BIT( phantom->port )))
                   1321:                        return;
                   1322: 
                   1323:                /* Do nothing unless interrupt state machine has stabilised */
                   1324:                irq_state = phantom_readl ( phantom, UNM_PCIE_IRQ_STATE );
                   1325:                if ( ! UNM_PCIE_IRQ_STATE_TRIGGERED ( irq_state ) )
                   1326:                        return;
                   1327: 
                   1328:                /* Acknowledge interrupt */
                   1329:                phantom_writel ( phantom, UNM_PCIE_IRQ_STATUS_MAGIC,
                   1330:                                 phantom_irq_status_reg[phantom->port] );
                   1331:                phantom_readl ( phantom, UNM_PCIE_IRQ_VECTOR );
                   1332:        }
                   1333: 
                   1334:        /* Check for TX completions */
                   1335:        cds_consumer_idx = phantom->cds_consumer_idx;
                   1336:        raw_new_cds_consumer_idx = phantom->desc->cmd_cons;
                   1337:        new_cds_consumer_idx = le32_to_cpu ( raw_new_cds_consumer_idx );
                   1338:        while ( cds_consumer_idx != new_cds_consumer_idx ) {
                   1339:                DBGC2 ( phantom, "Phantom %p CDS %d complete\n",
                   1340:                        phantom, cds_consumer_idx );
                   1341:                /* Completions may be for commands other than TX, so
                   1342:                 * there may not always be an associated I/O buffer.
                   1343:                 */
                   1344:                if ( ( iobuf = phantom->cds_iobuf[cds_consumer_idx] ) ) {
                   1345:                        netdev_tx_complete ( netdev, iobuf );
                   1346:                        phantom->cds_iobuf[cds_consumer_idx] = NULL;
                   1347:                }
                   1348:                cds_consumer_idx = ( ( cds_consumer_idx + 1 ) % PHN_NUM_CDS );
                   1349:                phantom->cds_consumer_idx = cds_consumer_idx;
                   1350:        }
                   1351: 
                   1352:        /* Check for received packets */
                   1353:        rds_consumer_idx = phantom->rds_consumer_idx;
                   1354:        sds_consumer_idx = phantom->sds_consumer_idx;
                   1355:        while ( 1 ) {
                   1356:                sds = &phantom->desc->sds[sds_consumer_idx];
                   1357:                if ( NX_GET ( sds, owner ) == 0 )
                   1358:                        break;
                   1359: 
                   1360:                DBGC2 ( phantom, "Phantom %p SDS %d status:\n",
                   1361:                        phantom, sds_consumer_idx );
                   1362:                DBGC2_HDA ( phantom, virt_to_bus ( sds ), sds, sizeof (*sds) );
                   1363: 
                   1364:                /* Check received opcode */
                   1365:                sds_opcode = NX_GET ( sds, opcode );
                   1366:                if ( ( sds_opcode == UNM_RXPKT_DESC ) ||
                   1367:                     ( sds_opcode == UNM_SYN_OFFLOAD ) ) {
                   1368: 
                   1369:                        /* Sanity check: ensure that all of the SDS
                   1370:                         * descriptor has been written.
                   1371:                         */
                   1372:                        if ( NX_GET ( sds, total_length ) == 0 ) {
                   1373:                                DBGC ( phantom, "Phantom %p SDS %d "
                   1374:                                       "incomplete; deferring\n",
                   1375:                                       phantom, sds_consumer_idx );
                   1376:                                /* Leave for next poll() */
                   1377:                                break;
                   1378:                        }
                   1379: 
                   1380:                        /* Process received packet */
                   1381:                        sds_handle = NX_GET ( sds, handle );
                   1382:                        iobuf = phantom->rds_iobuf[sds_handle];
                   1383:                        assert ( iobuf != NULL );
                   1384:                        iob_put ( iobuf, NX_GET ( sds, total_length ) );
                   1385:                        iob_pull ( iobuf, NX_GET ( sds, pkt_offset ) );
                   1386:                        DBGC2 ( phantom, "Phantom %p RDS %d complete\n",
                   1387:                                phantom, sds_handle );
                   1388:                        netdev_rx ( netdev, iobuf );
                   1389:                        phantom->rds_iobuf[sds_handle] = NULL;
                   1390: 
                   1391:                        /* Update RDS consumer counter.  This is a
                   1392:                         * lower bound for the number of descriptors
                   1393:                         * that have been read by the hardware, since
                   1394:                         * the hardware must have read at least one
                   1395:                         * descriptor for each completion that we
                   1396:                         * receive.
                   1397:                         */
                   1398:                        rds_consumer_idx =
                   1399:                                ( ( rds_consumer_idx + 1 ) % PHN_NUM_RDS );
                   1400:                        phantom->rds_consumer_idx = rds_consumer_idx;
                   1401: 
                   1402:                } else {
                   1403: 
                   1404:                        DBGC ( phantom, "Phantom %p unexpected SDS opcode "
                   1405:                               "%02x\n", phantom, sds_opcode );
                   1406:                        DBGC_HDA ( phantom, virt_to_bus ( sds ),
                   1407:                                   sds, sizeof ( *sds ) );
                   1408:                }
                   1409:                        
                   1410:                /* Clear status descriptor */
                   1411:                memset ( sds, 0, sizeof ( *sds ) );
                   1412: 
                   1413:                /* Update SDS consumer index */
                   1414:                sds_consumer_idx = ( ( sds_consumer_idx + 1 ) % PHN_NUM_SDS );
                   1415:                phantom->sds_consumer_idx = sds_consumer_idx;
                   1416:                wmb();
                   1417:                phantom_writel ( phantom, phantom->sds_consumer_idx,
                   1418:                                 phantom->sds_consumer_crb );
                   1419:        }
                   1420: 
                   1421:        /* Refill the RX descriptor ring */
                   1422:        phantom_refill_rx_ring ( netdev );
                   1423: }
                   1424: 
                   1425: /**
                   1426:  * Enable/disable interrupts
                   1427:  *
                   1428:  * @v netdev   Network device
                   1429:  * @v enable   Interrupts should be enabled
                   1430:  */
                   1431: static void phantom_irq ( struct net_device *netdev, int enable ) {
                   1432:        struct phantom_nic *phantom = netdev_priv ( netdev );
                   1433: 
                   1434:        phantom_writel ( phantom, ( enable ? 1 : 0 ),
                   1435:                         phantom->sds_irq_mask_crb );
                   1436:        phantom_writel ( phantom, UNM_PCIE_IRQ_MASK_MAGIC,
                   1437:                         phantom_irq_mask_reg[phantom->port] );
                   1438:        phantom->sds_irq_enabled = enable;
                   1439: }
                   1440: 
                   1441: /** Phantom net device operations */
                   1442: static struct net_device_operations phantom_operations = {
                   1443:        .open           = phantom_open,
                   1444:        .close          = phantom_close,
                   1445:        .transmit       = phantom_transmit,
                   1446:        .poll           = phantom_poll,
                   1447:        .irq            = phantom_irq,
                   1448: };
                   1449: 
                   1450: /***************************************************************************
                   1451:  *
                   1452:  * CLP settings
                   1453:  *
                   1454:  */
                   1455: 
                   1456: /** Phantom CLP settings tag magic */
                   1457: #define PHN_CLP_TAG_MAGIC 0xc19c1900UL
                   1458: 
                   1459: /** Phantom CLP settings tag magic mask */
                   1460: #define PHN_CLP_TAG_MAGIC_MASK 0xffffff00UL
                   1461: 
                   1462: /** Phantom CLP data
                   1463:  *
                   1464:  */
                   1465: union phantom_clp_data {
                   1466:        /** Data bytes
                   1467:         *
                   1468:         * This field is right-aligned; if only N bytes are present
                   1469:         * then bytes[0]..bytes[7-N] should be zero, and the data
                   1470:         * should be in bytes[7-N+1] to bytes[7];
                   1471:         */
                   1472:        uint8_t bytes[8];
                   1473:        /** Dwords for the CLP interface */
                   1474:        struct {
                   1475:                /** High dword, in network byte order */
                   1476:                uint32_t hi;
                   1477:                /** Low dword, in network byte order */
                   1478:                uint32_t lo;
                   1479:        } dwords;
                   1480: };
                   1481: #define PHN_CLP_BLKSIZE ( sizeof ( union phantom_clp_data ) )
                   1482: 
                   1483: /**
                   1484:  * Wait for Phantom CLP command to complete
                   1485:  *
                   1486:  * @v phantom          Phantom NIC
                   1487:  * @ret rc             Return status code
                   1488:  */
                   1489: static int phantom_clp_wait ( struct phantom_nic *phantom ) {
                   1490:        unsigned int retries;
                   1491:        uint32_t status;
                   1492: 
                   1493:        for ( retries = 0 ; retries < PHN_CLP_CMD_TIMEOUT_MS ; retries++ ) {
                   1494:                status = phantom_readl ( phantom, UNM_CAM_RAM_CLP_STATUS );
                   1495:                if ( status & UNM_CAM_RAM_CLP_STATUS_DONE )
                   1496:                        return 0;
                   1497:                mdelay ( 1 );
                   1498:        }
                   1499: 
                   1500:        DBGC ( phantom, "Phantom %p timed out waiting for CLP command\n",
                   1501:               phantom );
                   1502:        return -ETIMEDOUT;
                   1503: }
                   1504: 
                   1505: /**
                   1506:  * Issue Phantom CLP command
                   1507:  *
                   1508:  * @v phantom          Phantom NIC
                   1509:  * @v port             Virtual port number
                   1510:  * @v opcode           Opcode
                   1511:  * @v data_in          Data in, or NULL
                   1512:  * @v data_out         Data out, or NULL
                   1513:  * @v offset           Offset within data
                   1514:  * @v len              Data buffer length
                   1515:  * @ret len            Total transfer length (for reads), or negative error
                   1516:  */
                   1517: static int phantom_clp_cmd ( struct phantom_nic *phantom, unsigned int port,
                   1518:                             unsigned int opcode, const void *data_in,
                   1519:                             void *data_out, size_t offset, size_t len ) {
                   1520:        union phantom_clp_data data;
                   1521:        unsigned int index = ( offset / sizeof ( data ) );
                   1522:        unsigned int last = 0;
                   1523:        size_t in_frag_len;
                   1524:        uint8_t *in_frag;
                   1525:        uint32_t command;
                   1526:        uint32_t status;
                   1527:        size_t read_len;
                   1528:        unsigned int error;
                   1529:        size_t out_frag_len;
                   1530:        uint8_t *out_frag;
                   1531:        int rc;
                   1532: 
                   1533:        /* Sanity checks */
                   1534:        assert ( ( offset % sizeof ( data ) ) == 0 );
                   1535:        if ( len > 255 ) {
                   1536:                DBGC ( phantom, "Phantom %p invalid CLP length %zd\n",
                   1537:                       phantom, len );
                   1538:                return -EINVAL;
                   1539:        }
                   1540: 
                   1541:        /* Check that CLP interface is ready */
                   1542:        if ( ( rc = phantom_clp_wait ( phantom ) ) != 0 )
                   1543:                return rc;
                   1544: 
                   1545:        /* Copy data in */
                   1546:        memset ( &data, 0, sizeof ( data ) );
                   1547:        if ( data_in ) {
                   1548:                assert ( offset < len );
                   1549:                in_frag_len = ( len - offset );
                   1550:                if ( in_frag_len > sizeof ( data ) ) {
                   1551:                        in_frag_len = sizeof ( data );
                   1552:                } else {
                   1553:                        last = 1;
                   1554:                }
                   1555:                in_frag = &data.bytes[ sizeof ( data ) - in_frag_len ];
                   1556:                memcpy ( in_frag, ( data_in + offset ), in_frag_len );
                   1557:                phantom_writel ( phantom, be32_to_cpu ( data.dwords.lo ),
                   1558:                                 UNM_CAM_RAM_CLP_DATA_LO );
                   1559:                phantom_writel ( phantom, be32_to_cpu ( data.dwords.hi ),
                   1560:                                 UNM_CAM_RAM_CLP_DATA_HI );
                   1561:        }
                   1562: 
                   1563:        /* Issue CLP command */
                   1564:        command = ( ( index << 24 ) | ( ( data_in ? len : 0 ) << 16 ) |
                   1565:                    ( port << 8 ) | ( last << 7 ) | ( opcode << 0 ) );
                   1566:        phantom_writel ( phantom, command, UNM_CAM_RAM_CLP_COMMAND );
                   1567:        mb();
                   1568:        phantom_writel ( phantom, UNM_CAM_RAM_CLP_STATUS_START,
                   1569:                         UNM_CAM_RAM_CLP_STATUS );
                   1570: 
                   1571:        /* Wait for command to complete */
                   1572:        if ( ( rc = phantom_clp_wait ( phantom ) ) != 0 )
                   1573:                return rc;
                   1574: 
                   1575:        /* Get command status */
                   1576:        status = phantom_readl ( phantom, UNM_CAM_RAM_CLP_STATUS );
                   1577:        read_len = ( ( status >> 16 ) & 0xff );
                   1578:        error = ( ( status >> 8 ) & 0xff );
                   1579:        if ( error ) {
                   1580:                DBGC ( phantom, "Phantom %p CLP command error %02x\n",
                   1581:                       phantom, error );
                   1582:                return -EIO;
                   1583:        }
                   1584: 
                   1585:        /* Copy data out */
                   1586:        if ( data_out ) {
                   1587:                data.dwords.lo = cpu_to_be32 ( phantom_readl ( phantom,
                   1588:                                                  UNM_CAM_RAM_CLP_DATA_LO ) );
                   1589:                data.dwords.hi = cpu_to_be32 ( phantom_readl ( phantom,
                   1590:                                                  UNM_CAM_RAM_CLP_DATA_HI ) );
                   1591:                out_frag_len = ( read_len - offset );
                   1592:                if ( out_frag_len > sizeof ( data ) )
                   1593:                        out_frag_len = sizeof ( data );
                   1594:                out_frag = &data.bytes[ sizeof ( data ) - out_frag_len ];
                   1595:                if ( out_frag_len > ( len - offset ) )
                   1596:                        out_frag_len = ( len - offset );
                   1597:                memcpy ( ( data_out + offset ), out_frag, out_frag_len );
                   1598:        }
                   1599: 
                   1600:        return read_len;
                   1601: }
                   1602: 
                   1603: /**
                   1604:  * Store Phantom CLP setting
                   1605:  *
                   1606:  * @v phantom          Phantom NIC
                   1607:  * @v port             Virtual port number
                   1608:  * @v setting          Setting number
                   1609:  * @v data             Data buffer
                   1610:  * @v len              Length of data buffer
                   1611:  * @ret rc             Return status code
                   1612:  */
                   1613: static int phantom_clp_store ( struct phantom_nic *phantom, unsigned int port,
                   1614:                               unsigned int setting, const void *data,
                   1615:                               size_t len ) {
                   1616:        unsigned int opcode = setting;
                   1617:        size_t offset;
                   1618:        int rc;
                   1619: 
                   1620:        for ( offset = 0 ; offset < len ; offset += PHN_CLP_BLKSIZE ) {
                   1621:                if ( ( rc = phantom_clp_cmd ( phantom, port, opcode, data,
                   1622:                                              NULL, offset, len ) ) < 0 )
                   1623:                        return rc;
                   1624:        }
                   1625:        return 0;
                   1626: }
                   1627: 
                   1628: /**
                   1629:  * Fetch Phantom CLP setting
                   1630:  *
                   1631:  * @v phantom          Phantom NIC
                   1632:  * @v port             Virtual port number
                   1633:  * @v setting          Setting number
                   1634:  * @v data             Data buffer
                   1635:  * @v len              Length of data buffer
                   1636:  * @ret len            Length of setting, or negative error
                   1637:  */
                   1638: static int phantom_clp_fetch ( struct phantom_nic *phantom, unsigned int port,
                   1639:                               unsigned int setting, void *data, size_t len ) {
                   1640:        unsigned int opcode = ( setting + 1 );
                   1641:        size_t offset = 0;
                   1642:        int read_len;
                   1643: 
                   1644:        while ( 1 ) {
                   1645:                read_len = phantom_clp_cmd ( phantom, port, opcode, NULL,
                   1646:                                             data, offset, len );
                   1647:                if ( read_len < 0 )
                   1648:                        return read_len;
                   1649:                offset += PHN_CLP_BLKSIZE;
                   1650:                if ( offset >= ( unsigned ) read_len )
                   1651:                        break;
                   1652:                if ( offset >= len )
                   1653:                        break;
                   1654:        }
                   1655:        return read_len;
                   1656: }
                   1657: 
                   1658: /** A Phantom CLP setting */
                   1659: struct phantom_clp_setting {
                   1660:        /** iPXE setting */
                   1661:        struct setting *setting;
                   1662:        /** Setting number */
                   1663:        unsigned int clp_setting;
                   1664: };
                   1665: 
                   1666: /** Phantom CLP settings */
                   1667: static struct phantom_clp_setting clp_settings[] = {
                   1668:        { &mac_setting, 0x01 },
                   1669: };
                   1670: 
                   1671: /**
                   1672:  * Find Phantom CLP setting
                   1673:  *
                   1674:  * @v setting          iPXE setting
                   1675:  * @v clp_setting      Setting number, or 0 if not found
                   1676:  */
                   1677: static unsigned int
                   1678: phantom_clp_setting ( struct phantom_nic *phantom, struct setting *setting ) {
                   1679:        struct phantom_clp_setting *clp_setting;
                   1680:        unsigned int i;
                   1681: 
                   1682:        /* Search the list of explicitly-defined settings */
                   1683:        for ( i = 0 ; i < ( sizeof ( clp_settings ) /
                   1684:                            sizeof ( clp_settings[0] ) ) ; i++ ) {
                   1685:                clp_setting = &clp_settings[i];
                   1686:                if ( setting_cmp ( setting, clp_setting->setting ) == 0 )
                   1687:                        return clp_setting->clp_setting;
                   1688:        }
                   1689: 
                   1690:        /* Allow for use of numbered settings */
                   1691:        if ( ( setting->tag & PHN_CLP_TAG_MAGIC_MASK ) == PHN_CLP_TAG_MAGIC )
                   1692:                return ( setting->tag & ~PHN_CLP_TAG_MAGIC_MASK );
                   1693: 
                   1694:        DBGC2 ( phantom, "Phantom %p has no \"%s\" setting\n",
                   1695:                phantom, setting->name );
                   1696: 
                   1697:        return 0;
                   1698: }
                   1699: 
                   1700: /**
                   1701:  * Check applicability of Phantom CLP setting
                   1702:  *
                   1703:  * @v settings         Settings block
                   1704:  * @v setting          Setting
                   1705:  * @ret applies                Setting applies within this settings block
                   1706:  */
                   1707: static int phantom_setting_applies ( struct settings *settings,
                   1708:                                     struct setting *setting ) {
                   1709:        struct phantom_nic *phantom =
                   1710:                container_of ( settings, struct phantom_nic, settings );
                   1711:        unsigned int clp_setting;
                   1712: 
                   1713:        /* Find Phantom setting equivalent to iPXE setting */
                   1714:        clp_setting = phantom_clp_setting ( phantom, setting );
                   1715:        return ( clp_setting != 0 );
                   1716: }
                   1717: 
                   1718: /**
                   1719:  * Store Phantom CLP setting
                   1720:  *
                   1721:  * @v settings         Settings block
                   1722:  * @v setting          Setting to store
                   1723:  * @v data             Setting data, or NULL to clear setting
                   1724:  * @v len              Length of setting data
                   1725:  * @ret rc             Return status code
                   1726:  */
                   1727: static int phantom_store_setting ( struct settings *settings,
                   1728:                                   struct setting *setting,
                   1729:                                   const void *data, size_t len ) {
                   1730:        struct phantom_nic *phantom =
                   1731:                container_of ( settings, struct phantom_nic, settings );
                   1732:        unsigned int clp_setting;
                   1733:        int rc;
                   1734: 
                   1735:        /* Find Phantom setting equivalent to iPXE setting */
                   1736:        clp_setting = phantom_clp_setting ( phantom, setting );
                   1737:        assert ( clp_setting != 0 );
                   1738: 
                   1739:        /* Store setting */
                   1740:        if ( ( rc = phantom_clp_store ( phantom, phantom->port,
                   1741:                                        clp_setting, data, len ) ) != 0 ) {
                   1742:                DBGC ( phantom, "Phantom %p could not store setting \"%s\": "
                   1743:                       "%s\n", phantom, setting->name, strerror ( rc ) );
                   1744:                return rc;
                   1745:        }
                   1746: 
                   1747:        return 0;
                   1748: }
                   1749: 
                   1750: /**
                   1751:  * Fetch Phantom CLP setting
                   1752:  *
                   1753:  * @v settings         Settings block
                   1754:  * @v setting          Setting to fetch
                   1755:  * @v data             Buffer to fill with setting data
                   1756:  * @v len              Length of buffer
                   1757:  * @ret len            Length of setting data, or negative error
                   1758:  */
                   1759: static int phantom_fetch_setting ( struct settings *settings,
                   1760:                                   struct setting *setting,
                   1761:                                   void *data, size_t len ) {
                   1762:        struct phantom_nic *phantom =
                   1763:                container_of ( settings, struct phantom_nic, settings );
                   1764:        unsigned int clp_setting;
                   1765:        int read_len;
                   1766:        int rc;
                   1767: 
                   1768:        /* Find Phantom setting equivalent to iPXE setting */
                   1769:        clp_setting = phantom_clp_setting ( phantom, setting );
                   1770:        assert ( clp_setting != 0 );
                   1771: 
                   1772:        /* Fetch setting */
                   1773:        if ( ( read_len = phantom_clp_fetch ( phantom, phantom->port,
                   1774:                                              clp_setting, data, len ) ) < 0 ){
                   1775:                rc = read_len;
                   1776:                DBGC ( phantom, "Phantom %p could not fetch setting \"%s\": "
                   1777:                       "%s\n", phantom, setting->name, strerror ( rc ) );
                   1778:                return rc;
                   1779:        }
                   1780: 
                   1781:        return read_len;
                   1782: }
                   1783: 
                   1784: /** Phantom CLP settings operations */
                   1785: static struct settings_operations phantom_settings_operations = {
                   1786:        .applies        = phantom_setting_applies,
                   1787:        .store          = phantom_store_setting,
                   1788:        .fetch          = phantom_fetch_setting,
                   1789: };
                   1790: 
                   1791: /***************************************************************************
                   1792:  *
                   1793:  * Initialisation
                   1794:  *
                   1795:  */
                   1796: 
                   1797: /**
                   1798:  * Map Phantom CRB window
                   1799:  *
                   1800:  * @v phantom          Phantom NIC
                   1801:  * @ret rc             Return status code
                   1802:  */
                   1803: static int phantom_map_crb ( struct phantom_nic *phantom,
                   1804:                             struct pci_device *pci ) {
                   1805:        unsigned long bar0_start;
                   1806:        unsigned long bar0_size;
                   1807: 
                   1808:        bar0_start = pci_bar_start ( pci, PCI_BASE_ADDRESS_0 );
                   1809:        bar0_size = pci_bar_size ( pci, PCI_BASE_ADDRESS_0 );
                   1810:        DBGC ( phantom, "Phantom %p is " PCI_FMT " with BAR0 at %08lx+%lx\n",
                   1811:               phantom, PCI_ARGS ( pci ), bar0_start, bar0_size );
                   1812: 
                   1813:        if ( ! bar0_start ) {
                   1814:                DBGC ( phantom, "Phantom %p BAR not assigned; ignoring\n",
                   1815:                       phantom );
                   1816:                return -EINVAL;
                   1817:        }
                   1818: 
                   1819:        switch ( bar0_size ) {
                   1820:        case ( 128 * 1024 * 1024 ) :
                   1821:                DBGC ( phantom, "Phantom %p has 128MB BAR\n", phantom );
                   1822:                phantom->crb_access = phantom_crb_access_128m;
                   1823:                break;
                   1824:        case ( 32 * 1024 * 1024 ) :
                   1825:                DBGC ( phantom, "Phantom %p has 32MB BAR\n", phantom );
                   1826:                phantom->crb_access = phantom_crb_access_32m;
                   1827:                break;
                   1828:        case ( 2 * 1024 * 1024 ) :
                   1829:                DBGC ( phantom, "Phantom %p has 2MB BAR\n", phantom );
                   1830:                phantom->crb_access = phantom_crb_access_2m;
                   1831:                break;
                   1832:        default:
                   1833:                DBGC ( phantom, "Phantom %p has bad BAR size\n", phantom );
                   1834:                return -EINVAL;
                   1835:        }
                   1836: 
                   1837:        phantom->bar0 = ioremap ( bar0_start, bar0_size );
                   1838:        if ( ! phantom->bar0 ) {
                   1839:                DBGC ( phantom, "Phantom %p could not map BAR0\n", phantom );
                   1840:                return -EIO;
                   1841:        }
                   1842: 
                   1843:        /* Mark current CRB window as invalid, so that the first
                   1844:         * read/write will set the current window.
                   1845:         */
                   1846:        phantom->crb_window = -1UL;
                   1847: 
                   1848:        return 0;
                   1849: }
                   1850: 
                   1851: /**
                   1852:  * Unhalt all PEGs
                   1853:  *
                   1854:  * @v phantom          Phantom NIC
                   1855:  */
                   1856: static void phantom_unhalt_pegs ( struct phantom_nic *phantom ) {
                   1857:        uint32_t halt_status;
                   1858: 
                   1859:        halt_status = phantom_readl ( phantom, UNM_PEG_0_HALT_STATUS );
                   1860:        phantom_writel ( phantom, halt_status, UNM_PEG_0_HALT_STATUS );
                   1861:        halt_status = phantom_readl ( phantom, UNM_PEG_1_HALT_STATUS );
                   1862:        phantom_writel ( phantom, halt_status, UNM_PEG_1_HALT_STATUS );
                   1863:        halt_status = phantom_readl ( phantom, UNM_PEG_2_HALT_STATUS );
                   1864:        phantom_writel ( phantom, halt_status, UNM_PEG_2_HALT_STATUS );
                   1865:        halt_status = phantom_readl ( phantom, UNM_PEG_3_HALT_STATUS );
                   1866:        phantom_writel ( phantom, halt_status, UNM_PEG_3_HALT_STATUS );
                   1867:        halt_status = phantom_readl ( phantom, UNM_PEG_4_HALT_STATUS );
                   1868:        phantom_writel ( phantom, halt_status, UNM_PEG_4_HALT_STATUS );
                   1869: }
                   1870: 
                   1871: /**
                   1872:  * Initialise the Phantom command PEG
                   1873:  *
                   1874:  * @v phantom          Phantom NIC
                   1875:  * @ret rc             Return status code
                   1876:  */
                   1877: static int phantom_init_cmdpeg ( struct phantom_nic *phantom ) {
                   1878:        uint32_t cold_boot;
                   1879:        uint32_t sw_reset;
                   1880:        unsigned int retries;
                   1881:        uint32_t cmdpeg_state;
                   1882:        uint32_t last_cmdpeg_state = 0;
                   1883: 
                   1884:        /* Check for a previous initialisation.  This could have
                   1885:         * happened if, for example, the BIOS used the UNDI API to
                   1886:         * drive the NIC prior to a full PXE boot.
                   1887:         */
                   1888:        cmdpeg_state = phantom_readl ( phantom, UNM_NIC_REG_CMDPEG_STATE );
                   1889:        if ( cmdpeg_state == UNM_NIC_REG_CMDPEG_STATE_INITIALIZE_ACK ) {
                   1890:                DBGC ( phantom, "Phantom %p command PEG already initialized\n",
                   1891:                       phantom );
                   1892:                /* Unhalt the PEGs.  Previous firmware (e.g. BOFM) may
                   1893:                 * have halted the PEGs to prevent internal bus
                   1894:                 * collisions when the BIOS re-reads the expansion ROM.
                   1895:                 */
                   1896:                phantom_unhalt_pegs ( phantom );
                   1897:                return 0;
                   1898:        }
                   1899: 
                   1900:        /* If this was a cold boot, check that the hardware came up ok */
                   1901:        cold_boot = phantom_readl ( phantom, UNM_CAM_RAM_COLD_BOOT );
                   1902:        if ( cold_boot == UNM_CAM_RAM_COLD_BOOT_MAGIC ) {
                   1903:                DBGC ( phantom, "Phantom %p coming up from cold boot\n",
                   1904:                       phantom );
                   1905:                sw_reset = phantom_readl ( phantom, UNM_ROMUSB_GLB_SW_RESET );
                   1906:                if ( sw_reset != UNM_ROMUSB_GLB_SW_RESET_MAGIC ) {
                   1907:                        DBGC ( phantom, "Phantom %p reset failed: %08x\n",
                   1908:                               phantom, sw_reset );
                   1909:                        return -EIO;
                   1910:                }
                   1911:        } else {
                   1912:                DBGC ( phantom, "Phantom %p coming up from warm boot "
                   1913:                       "(%08x)\n", phantom, cold_boot );
                   1914:        }
                   1915:        /* Clear cold-boot flag */
                   1916:        phantom_writel ( phantom, 0, UNM_CAM_RAM_COLD_BOOT );
                   1917: 
                   1918:        /* Set port modes */
                   1919:        phantom_writel ( phantom, UNM_CAM_RAM_PORT_MODE_AUTO_NEG_1G,
                   1920:                         UNM_CAM_RAM_WOL_PORT_MODE );
                   1921: 
                   1922:        /* Pass dummy DMA area to card */
                   1923:        phantom_write_hilo ( phantom, 0,
                   1924:                             UNM_NIC_REG_DUMMY_BUF_ADDR_LO,
                   1925:                             UNM_NIC_REG_DUMMY_BUF_ADDR_HI );
                   1926:        phantom_writel ( phantom, UNM_NIC_REG_DUMMY_BUF_INIT,
                   1927:                         UNM_NIC_REG_DUMMY_BUF );
                   1928: 
                   1929:        /* Tell the hardware that tuning is complete */
                   1930:        phantom_writel ( phantom, UNM_ROMUSB_GLB_PEGTUNE_DONE_MAGIC,
                   1931:                         UNM_ROMUSB_GLB_PEGTUNE_DONE );
                   1932: 
                   1933:        /* Wait for command PEG to finish initialising */
                   1934:        DBGC ( phantom, "Phantom %p initialising command PEG (will take up to "
                   1935:               "%d seconds)...\n", phantom, PHN_CMDPEG_INIT_TIMEOUT_SEC );
                   1936:        for ( retries = 0; retries < PHN_CMDPEG_INIT_TIMEOUT_SEC; retries++ ) {
                   1937:                cmdpeg_state = phantom_readl ( phantom,
                   1938:                                               UNM_NIC_REG_CMDPEG_STATE );
                   1939:                if ( cmdpeg_state != last_cmdpeg_state ) {
                   1940:                        DBGC ( phantom, "Phantom %p command PEG state is "
                   1941:                               "%08x after %d seconds...\n",
                   1942:                               phantom, cmdpeg_state, retries );
                   1943:                        last_cmdpeg_state = cmdpeg_state;
                   1944:                }
                   1945:                if ( cmdpeg_state == UNM_NIC_REG_CMDPEG_STATE_INITIALIZED ) {
                   1946:                        /* Acknowledge the PEG initialisation */
                   1947:                        phantom_writel ( phantom,
                   1948:                                       UNM_NIC_REG_CMDPEG_STATE_INITIALIZE_ACK,
                   1949:                                       UNM_NIC_REG_CMDPEG_STATE );
                   1950:                        return 0;
                   1951:                }
                   1952:                mdelay ( 1000 );
                   1953:        }
                   1954: 
                   1955:        DBGC ( phantom, "Phantom %p timed out waiting for command PEG to "
                   1956:               "initialise (status %08x)\n", phantom, cmdpeg_state );
                   1957:        return -ETIMEDOUT;
                   1958: }
                   1959: 
                   1960: /**
                   1961:  * Read Phantom MAC address
                   1962:  *
                   1963:  * @v phanton_port     Phantom NIC
                   1964:  * @v hw_addr          Buffer to fill with MAC address
                   1965:  */
                   1966: static void phantom_get_macaddr ( struct phantom_nic *phantom,
                   1967:                                  uint8_t *hw_addr ) {
                   1968:        union {
                   1969:                uint8_t mac_addr[2][ETH_ALEN];
                   1970:                uint32_t dwords[3];
                   1971:        } u;
                   1972:        unsigned long offset;
                   1973:        int i;
                   1974: 
                   1975:        /* Read the three dwords that include this MAC address and one other */
                   1976:        offset = ( UNM_CAM_RAM_MAC_ADDRS +
                   1977:                   ( 12 * ( phantom->port / 2 ) ) );
                   1978:        for ( i = 0 ; i < 3 ; i++, offset += 4 ) {
                   1979:                u.dwords[i] = phantom_readl ( phantom, offset );
                   1980:        }
                   1981: 
                   1982:        /* Copy out the relevant MAC address */
                   1983:        for ( i = 0 ; i < ETH_ALEN ; i++ ) {
                   1984:                hw_addr[ ETH_ALEN - i - 1 ] =
                   1985:                        u.mac_addr[ phantom->port & 1 ][i];
                   1986:        }
                   1987:        DBGC ( phantom, "Phantom %p MAC address is %s\n",
                   1988:               phantom, eth_ntoa ( hw_addr ) );
                   1989: }
                   1990: 
                   1991: /**
                   1992:  * Check Phantom is enabled for boot
                   1993:  *
                   1994:  * @v phanton_port     Phantom NIC
                   1995:  * @ret rc             Return status code
                   1996:  *
                   1997:  * This is something of an ugly hack to accommodate an OEM
                   1998:  * requirement.  The NIC has only one expansion ROM BAR, rather than
                   1999:  * one per port.  To allow individual ports to be selectively
                   2000:  * enabled/disabled for PXE boot (as required), we must therefore
                   2001:  * leave the expansion ROM always enabled, and place the per-port
                   2002:  * enable/disable logic within the iPXE driver.
                   2003:  */
                   2004: static int phantom_check_boot_enable ( struct phantom_nic *phantom ) {
                   2005:        unsigned long boot_enable;
                   2006: 
                   2007:        boot_enable = phantom_readl ( phantom, UNM_CAM_RAM_BOOT_ENABLE );
                   2008:        if ( ! ( boot_enable & ( 1 << phantom->port ) ) ) {
                   2009:                DBGC ( phantom, "Phantom %p PXE boot is disabled\n",
                   2010:                       phantom );
                   2011:                return -ENOTSUP;
                   2012:        }
                   2013: 
                   2014:        return 0;
                   2015: }
                   2016: 
                   2017: /**
                   2018:  * Initialise Phantom receive PEG
                   2019:  *
                   2020:  * @v phantom          Phantom NIC
                   2021:  * @ret rc             Return status code
                   2022:  */
                   2023: static int phantom_init_rcvpeg ( struct phantom_nic *phantom ) {
                   2024:        unsigned int retries;
                   2025:        uint32_t rcvpeg_state;
                   2026:        uint32_t last_rcvpeg_state = 0;
                   2027: 
                   2028:        DBGC ( phantom, "Phantom %p initialising receive PEG (will take up to "
                   2029:               "%d seconds)...\n", phantom, PHN_RCVPEG_INIT_TIMEOUT_SEC );
                   2030:        for ( retries = 0; retries < PHN_RCVPEG_INIT_TIMEOUT_SEC; retries++ ) {
                   2031:                rcvpeg_state = phantom_readl ( phantom,
                   2032:                                               UNM_NIC_REG_RCVPEG_STATE );
                   2033:                if ( rcvpeg_state != last_rcvpeg_state ) {
                   2034:                        DBGC ( phantom, "Phantom %p receive PEG state is "
                   2035:                               "%08x after %d seconds...\n",
                   2036:                               phantom, rcvpeg_state, retries );
                   2037:                        last_rcvpeg_state = rcvpeg_state;
                   2038:                }
                   2039:                if ( rcvpeg_state == UNM_NIC_REG_RCVPEG_STATE_INITIALIZED )
                   2040:                        return 0;
                   2041:                mdelay ( 1000 );
                   2042:        }
                   2043: 
                   2044:        DBGC ( phantom, "Phantom %p timed out waiting for receive PEG to "
                   2045:               "initialise (status %08x)\n", phantom, rcvpeg_state );
                   2046:        return -ETIMEDOUT;
                   2047: }
                   2048: 
                   2049: /**
                   2050:  * Probe PCI device
                   2051:  *
                   2052:  * @v pci              PCI device
                   2053:  * @v id               PCI ID
                   2054:  * @ret rc             Return status code
                   2055:  */
                   2056: static int phantom_probe ( struct pci_device *pci ) {
                   2057:        struct net_device *netdev;
                   2058:        struct phantom_nic *phantom;
                   2059:        struct settings *parent_settings;
                   2060:        int rc;
                   2061: 
                   2062:        /* Allocate Phantom device */
                   2063:        netdev = alloc_etherdev ( sizeof ( *phantom ) );
                   2064:        if ( ! netdev ) {
                   2065:                rc = -ENOMEM;
                   2066:                goto err_alloc_etherdev;
                   2067:        }
                   2068:        netdev_init ( netdev, &phantom_operations );
                   2069:        phantom = netdev_priv ( netdev );
                   2070:        pci_set_drvdata ( pci, netdev );
                   2071:        netdev->dev = &pci->dev;
                   2072:        memset ( phantom, 0, sizeof ( *phantom ) );
                   2073:        phantom->port = PCI_FUNC ( pci->busdevfn );
                   2074:        assert ( phantom->port < PHN_MAX_NUM_PORTS );
                   2075:        settings_init ( &phantom->settings,
                   2076:                        &phantom_settings_operations,
                   2077:                        &netdev->refcnt, PHN_CLP_TAG_MAGIC );
                   2078: 
                   2079:        /* Fix up PCI device */
                   2080:        adjust_pci_device ( pci );
                   2081: 
                   2082:        /* Map CRB */
                   2083:        if ( ( rc = phantom_map_crb ( phantom, pci ) ) != 0 )
                   2084:                goto err_map_crb;
                   2085: 
                   2086:        /* BUG5945 - need to hack PCI config space on P3 B1 silicon.
                   2087:         * B2 will have this fixed; remove this hack when B1 is no
                   2088:         * longer in use.
                   2089:         */
                   2090:        if ( PCI_FUNC ( pci->busdevfn ) == 0 ) {
                   2091:                unsigned int i;
                   2092:                for ( i = 0 ; i < 8 ; i++ ) {
                   2093:                        uint32_t temp;
                   2094:                        pci->busdevfn =
                   2095:                                PCI_BUSDEVFN ( PCI_BUS ( pci->busdevfn ),
                   2096:                                               PCI_SLOT ( pci->busdevfn ), i );
                   2097:                        pci_read_config_dword ( pci, 0xc8, &temp );
                   2098:                        pci_read_config_dword ( pci, 0xc8, &temp );
                   2099:                        pci_write_config_dword ( pci, 0xc8, 0xf1000 );
                   2100:                }
                   2101:                pci->busdevfn = PCI_BUSDEVFN ( PCI_BUS ( pci->busdevfn ),
                   2102:                                               PCI_SLOT ( pci->busdevfn ), 0 );
                   2103:        }
                   2104: 
                   2105:        /* Initialise the command PEG */
                   2106:        if ( ( rc = phantom_init_cmdpeg ( phantom ) ) != 0 )
                   2107:                goto err_init_cmdpeg;
                   2108: 
                   2109:        /* Initialise the receive PEG */
                   2110:        if ( ( rc = phantom_init_rcvpeg ( phantom ) ) != 0 )
                   2111:                goto err_init_rcvpeg;
                   2112: 
                   2113:        /* Read MAC addresses */
                   2114:        phantom_get_macaddr ( phantom, netdev->hw_addr );
                   2115: 
                   2116:        /* Skip if boot disabled on NIC */
                   2117:        if ( ( rc = phantom_check_boot_enable ( phantom ) ) != 0 )
                   2118:                goto err_check_boot_enable;
                   2119: 
                   2120:        /* Register network devices */
                   2121:        if ( ( rc = register_netdev ( netdev ) ) != 0 ) {
                   2122:                DBGC ( phantom, "Phantom %p could not register net device: "
                   2123:                       "%s\n", phantom, strerror ( rc ) );
                   2124:                goto err_register_netdev;
                   2125:        }
                   2126: 
                   2127:        /* Register settings blocks */
                   2128:        parent_settings = netdev_settings ( netdev );
                   2129:        if ( ( rc = register_settings ( &phantom->settings,
                   2130:                                        parent_settings, "clp" ) ) != 0 ) {
                   2131:                DBGC ( phantom, "Phantom %p could not register settings: "
                   2132:                       "%s\n", phantom, strerror ( rc ) );
                   2133:                goto err_register_settings;
                   2134:        }
                   2135: 
                   2136:        return 0;
                   2137: 
                   2138:        unregister_settings ( &phantom->settings );
                   2139:  err_register_settings:
                   2140:        unregister_netdev ( netdev );
                   2141:  err_register_netdev:
                   2142:  err_check_boot_enable:
                   2143:  err_init_rcvpeg:
                   2144:  err_init_cmdpeg:
                   2145:  err_map_crb:
                   2146:        netdev_nullify ( netdev );
                   2147:        netdev_put ( netdev );
                   2148:  err_alloc_etherdev:
                   2149:        return rc;
                   2150: }
                   2151: 
                   2152: /**
                   2153:  * Remove PCI device
                   2154:  *
                   2155:  * @v pci              PCI device
                   2156:  */
                   2157: static void phantom_remove ( struct pci_device *pci ) {
                   2158:        struct net_device *netdev = pci_get_drvdata ( pci );
                   2159:        struct phantom_nic *phantom = netdev_priv ( netdev );
                   2160: 
                   2161:        unregister_settings ( &phantom->settings );
                   2162:        unregister_netdev ( netdev );
                   2163:        netdev_nullify ( netdev );
                   2164:        netdev_put ( netdev );
                   2165: }
                   2166: 
                   2167: /** Phantom PCI IDs */
                   2168: static struct pci_device_id phantom_nics[] = {
                   2169:        PCI_ROM ( 0x4040, 0x0100, "nx", "NX", 0 ),
                   2170: };
                   2171: 
                   2172: /** Phantom PCI driver */
                   2173: struct pci_driver phantom_driver __pci_driver = {
                   2174:        .ids = phantom_nics,
                   2175:        .id_count = ( sizeof ( phantom_nics ) / sizeof ( phantom_nics[0] ) ),
                   2176:        .probe = phantom_probe,
                   2177:        .remove = phantom_remove,
                   2178: };

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.