Ejemplo n.º 1
0
struct net_device_stats *islpci_statistics(struct net_device *nwdev)
{
    islpci_private *private_config = nwdev->priv;
    char firmware[64];

    DEBUG(SHOW_FUNCTION_CALLS, "islpci_statistics \n");

#ifdef CONFIG_ARCH_ISL3893
    
    if ( ! firmware_uploaded ) {

        if( private_config->pci_dev_id == PCIDEVICE_ISL3890 )
            strcpy( firmware, ISL3890_IMAGE_FILE );
        else
            strcpy( firmware, ISL3877_IMAGE_FILE );

#if VERBOSE > SHOW_ERROR_MESSAGES 
    DEBUG(SHOW_TRACING, "Upload firmware: %s, %p, %p \n", 
          firmware, private_config->remapped_device_base, private_config->device_host_address );
#endif

        if (isl38xx_upload_firmware( firmware, private_config->remapped_device_base,
            private_config->device_host_address ) == -1)
        {
            DEBUG(SHOW_ERROR_MESSAGES, "ERROR: %s could not upload the firmware \n", DRIVER_NAME );
        }
        else 
        {       
            /* set the firmware uploaded flag for skipping the firmware upload
               the next time this function is called and for activating the
               device on the open call */
            firmware_uploaded = 1;
        }
    }
#endif

    return &private_config->statistics;
}
Ejemplo n.º 2
0
int islpci_probe_pci(struct net_device *nw_device, struct pci_dev *pci_device,
                     const struct pci_device_id *id)
{
#else
int  islpci_probe_pci(struct pci_dev *pci_device, const struct pci_device_id *id)
{
    struct net_device *nw_device=NULL;
#endif
    void *phymem;
    u16 irq;
    u8 bus, devfn, latency_tmr;
    islpci_private *private_config;
    int rvalue, dev_id;
    int dma_mask = 0xffffffff;
    char firmware[256];

#if VERBOSE > SHOW_ERROR_MESSAGES 
    DEBUG(SHOW_FUNCTION_CALLS, "islpci_probe_pci\n");
#endif

    // Enable the pci device
    if (pci_enable_device(pci_device))
    {
        DEBUG(SHOW_ERROR_MESSAGES, "%s: pci_enable_device() failed.\n",
            DRIVER_NAME );
        return -EIO;
    }
    // Figure out our resources
    irq = pci_device->irq;
    bus = pci_device->bus->number;
    devfn = pci_device->devfn;
    dev_id = pci_device->device;

	// check whether the latency timer is set correctly
#ifdef CONFIG_ARCH_ISL3893
    pcibios_write_config_byte(bus, devfn, PCI_TRDY_TIMEOUT_VALUE, 0 );
    pcibios_write_config_byte(bus, devfn, PCI_RETRY_TIMEOUT_VALUE, 0 );
#else
    pcibios_read_config_byte(bus, devfn, PCI_LATENCY_TIMER, &latency_tmr);
#if VERBOSE > SHOW_ERROR_MESSAGES 
	DEBUG( SHOW_TRACING, "latency timer: %x\n", latency_tmr );
#endif
	if( latency_tmr < PCIDEVICE_LATENCY_TIMER_MIN )
	{
		// set the latency timer
		pcibios_write_config_byte(bus, devfn, PCI_LATENCY_TIMER, 
			PCIDEVICE_LATENCY_TIMER_VAL );
	}
#endif

    // determine what the supported DMA memory region is
    while( pci_set_dma_mask( pci_device, dma_mask ) != 0 )
    {
        // range not supported, shift the mask and check again
        if( dma_mask >>=  1, dma_mask == 0 )
        {
            // mask is zero, DMA memory not supported by PCI
            DEBUG(SHOW_ERROR_MESSAGES, "DMA Memory not supported\n" );
            return -EIO;
        }
    }

#if VERBOSE > SHOW_ERROR_MESSAGES 
    DEBUG(SHOW_TRACING, "DMA Memory support mask is 0x%x \n", dma_mask );
#endif

    // call for the physical address to address the PCI device
    phymem = (void *) pci_resource_start(pci_device, 0);
#ifdef CONFIG_ARCH_ISL3893
    // FIXme
    printk("!!pci_resource_start = %p, shound be 0x10000000\n", phymem );
    phymem = 0x10000000;
#endif
    // request the pci device for regions ???
    
    if (rvalue = pci_request_regions(pci_device, DRIVER_NAME ), rvalue)
    {
        DEBUG(SHOW_ERROR_MESSAGES, "pci_request_regions failure, rvalue %i\n",
            rvalue );
        return -EIO;
    }
    
    // enable PCI bus-mastering
    pci_set_master(pci_device);

    // Log the device resources information
#if VERBOSE > SHOW_ERROR_MESSAGES 
    DEBUG(SHOW_TRACING, "islpci device: phymem:0x%lx, irq:%d \n",
        (long) phymem, irq);
#endif

    // setup the network device interface and its structure
    if (nw_device = islpci_probe(nw_device, pci_device, (long) phymem, (int) irq),
        nw_device == NULL)
    {
        // error configuring the driver as a network device
        DEBUG(SHOW_ERROR_MESSAGES, "ERROR: %s could not configure "
            "network device \n", DRIVER_NAME );
        return -EIO;
    }

    // save the interrupt request line and use the remapped device base address
    // as the device identification both for uniqueness and parameter passing
    // to the interrupt handler
    private_config = nw_device->priv;
    private_config->pci_irq = irq;
    private_config->pci_dev_id = dev_id;
    private_config->device_id = private_config->remapped_device_base;
	
    spin_lock_init( &private_config->slock );

    // request for the interrupt before uploading the firmware
    printk("request_irq(%d)\n", irq );
    if ( rvalue = request_irq(irq, &islpci_interrupt, SA_INTERRUPT | SA_SHIRQ, DRIVER_NAME, private_config), rvalue != 0 )
    {
        // error, could not hook the handler to the irq
        DEBUG(SHOW_ERROR_MESSAGES, "ERROR: %s could not install IRQ-handler \n", DRIVER_NAME );
        return -EIO;
    }

#ifdef CONFIG_ARCH_ISL3893
    uPCI->ARMIntEnReg = 0x20000FF;
#endif

#ifndef CONFIG_ARCH_ISL3893
    // select the firmware file depending on the device id, take for default
    // the 3877 firmware file
    if( dev_id == PCIDEVICE_ISL3890 )
    	strcpy( firmware, ISL3890_IMAGE_FILE );
    else
    	strcpy( firmware, ISL3877_IMAGE_FILE );

#if VERBOSE > SHOW_ERROR_MESSAGES 
    DEBUG(SHOW_TRACING, "Firmware file: %s \n", firmware );
#endif
	
    if (isl38xx_upload_firmware( firmware, private_config->remapped_device_base,
        private_config->device_host_address ) == -1)
    {
        DEBUG(SHOW_ERROR_MESSAGES, "ERROR: %s could not upload the "
            "firmware \n", DRIVER_NAME );
        return -EIO;
    }
#endif

#ifdef CONFIG_ARCH_ISL3893
    mgt_initialize();
#endif

#ifdef INTERSIL_EVENTS 
    mgt_indication_handler ( DEV_NETWORK, nw_device->name, 0, islpci_mgt_indication );
#endif
#ifdef WDS_LINKS 
    mgt_indication_handler ( DEV_NETWORK, nw_device->name, DOT11_OID_WDSLINKADD, islpci_wdslink_add_hndl );
    mgt_indication_handler ( DEV_NETWORK, nw_device->name, DOT11_OID_WDSLINKREMOVE, islpci_wdslink_del_hndl );
#endif

    return 0;
}

void islpci_remove_pci( struct pci_dev *pci_device )
{
    struct net_device **devp, **next;
    islpci_private *private_config;

#if VERBOSE > SHOW_ERROR_MESSAGES 
    DEBUG(SHOW_FUNCTION_CALLS, "islpci_remove_pci\n");
#endif

    for (devp = &root_islpci_device; *devp; devp = next)
    {
        next = &((islpci_private *) (*devp)->priv)->next_module;
        private_config = (*devp)->priv;

        // free the interrupt request
        writel(0, private_config->remapped_device_base + ISL38XX_INT_EN_REG);
        free_irq(private_config->pci_irq, private_config);
    }

}

int init_module( void )
{
    DEBUG(SHOW_ANYTHING, "Loaded %s, version %s\n", DRIVER_NAME, VERSIONID );

    if (pci_register_driver(&islpci_pci_drv_id) <= 0)
    {
        DEBUG(SHOW_ERROR_MESSAGES, "%s: No devices found, driver not "
            "installed.\n", DRIVER_NAME);
        pci_unregister_driver(&islpci_pci_drv_id);
        return -ENODEV;
    }

    return 0;
}
Ejemplo n.º 3
0
/******************************************************************************
    Module initialization functions
******************************************************************************/
dev_node_t *islpci_attach(dev_locator_t * loc)
{
    u32 io;
    u16 dev_id;
    u8 bus, devfn, irq, latency_tmr;
    struct pci_dev *pci_device;
    struct net_device *nw_device;
    dev_node_t *node;
    islpci_private *private_config;
    int rvalue;
    int dma_mask = 0xffffffff;
    char firmware[256];

    // perform some initial setting checks
    if (loc->bus != LOC_PCI)
        return NULL;
    bus = loc->b.pci.bus;
    devfn = loc->b.pci.devfn;

#if VERBOSE > SHOW_ERROR_MESSAGES 
    DEBUG(SHOW_FUNCTION_CALLS, "islpci_attach(bus %d, function %d)\n",
        bus, devfn);
#endif

    // get some pci settings for verification
    pcibios_read_config_dword(bus, devfn, PCI_BASE_ADDRESS_0, &io);
    pcibios_read_config_byte(bus, devfn, PCI_INTERRUPT_LINE, &irq);
    pcibios_read_config_word(bus, devfn, PCI_DEVICE_ID, &dev_id);

	// check whether the latency timer is set correctly
    pcibios_read_config_byte(bus, devfn, PCI_LATENCY_TIMER, &latency_tmr);
#if VERBOSE > SHOW_ERROR_MESSAGES 
	DEBUG( SHOW_TRACING, "latency timer: %x\n", latency_tmr );
#endif
	if( latency_tmr < PCIDEVICE_LATENCY_TIMER_MIN )
	{
		// set the latency timer
		pcibios_write_config_byte(bus, devfn, PCI_LATENCY_TIMER, 
			PCIDEVICE_LATENCY_TIMER_VAL );
	}

    if (io &= ~3, io == 0 || irq == 0)
    {
        DEBUG(SHOW_ERROR_MESSAGES, "The ISL38XX Ethernet interface was not "
        "assigned an %s.\n" KERN_ERR "  It will not be activated.\n",
        io == 0 ? "I/O address" : "IRQ");
        return NULL;
    }
    // get pci device information by loading the pci_dev structure
    if (pci_device = pci_find_slot(bus, devfn), pci_device == NULL)
    {
        // error reading the pci device structure
        DEBUG(SHOW_ERROR_MESSAGES, "ERROR: %s could not get PCI device "
            "information \n", DRIVER_NAME );
        return NULL;
    }

    // determine what the supported DMA memory region is
    while( pci_set_dma_mask( pci_device, dma_mask ) != 0 )
    {
        // range not supported, shift the mask and check again
        if( dma_mask >>=  1, dma_mask == 0 )
        {
            // mask is zero, DMA memory not supported by PCI
            DEBUG(SHOW_ERROR_MESSAGES, "DMA Memory not supported\n" );
            return NULL;
        }
    }

#if VERBOSE > SHOW_ERROR_MESSAGES 
    DEBUG(SHOW_TRACING, "DMA Memory support mask is 0x%x \n", dma_mask );
#endif

    // setup the network device interface and its structure
    if (nw_device = islpci_probe(NULL, pci_device, (long) io, (int) irq),
        nw_device == NULL)
    {
        // error configuring the driver as a network device
        DEBUG(SHOW_ERROR_MESSAGES, "ERROR: %s could not configure "
        "network device \n", DRIVER_NAME );
        return NULL;
    }

#ifdef WDS_LINKS
    mgt_indication_handler ( DEV_NETWORK, nw_device->name, DOT11_OID_WDSLINKADD, islpci_wdslink_add_hndl );
    mgt_indication_handler ( DEV_NETWORK, nw_device->name, DOT11_OID_WDSLINKREMOVE, islpci_wdslink_del_hndl );
#endif

    // save the interrupt request line and use the remapped device base address
    // as the device identification both for uniqueness and parameter passing
    // to the interrupt handler
    private_config = nw_device->priv;
    private_config->pci_irq = irq;
    private_config->pci_dev_id = dev_id;
    private_config->device_id = private_config->remapped_device_base;
	spin_lock_init( &private_config->slock );

    // request for the interrupt before uploading the firmware
    if (rvalue = request_irq(irq, &islpci_interrupt, SA_INTERRUPT | SA_SHIRQ,
        DRIVER_NAME, private_config), rvalue != 0)
    {
        // error, could not hook the handler to the irq
        DEBUG(SHOW_ERROR_MESSAGES, "ERROR: %s could not install "
            "IRQ-handler \n", DRIVER_NAME );
        return NULL;
    }

    // select the firmware file depending on the device id, take for default
    // the 3877 firmware file
    if( dev_id == PCIDEVICE_ISL3890 )
    	strcpy( firmware, ISL3890_IMAGE_FILE );
    else
    	strcpy( firmware, ISL3877_IMAGE_FILE );

#if VERBOSE > SHOW_ERROR_MESSAGES 
    DEBUG(SHOW_TRACING, "Device %x, firmware file: %s \n", dev_id, firmware );
#endif
	
    if (isl38xx_upload_firmware( firmware, private_config->remapped_device_base,
        private_config->device_host_address  ) == -1)
    {
        // error uploading the firmware
        DEBUG(SHOW_ERROR_MESSAGES, "ERROR: %s could not upload the "
        "firmware \n", DRIVER_NAME );
        return NULL;
    }

    // finally setup the node structure with the device information
    node = kmalloc(sizeof(dev_node_t), GFP_KERNEL);
    strcpy(node->dev_name, nw_device->name);
    node->major = 0;
    node->minor = 0;
    node->next = NULL;
    MOD_INC_USE_COUNT;
    return node;
}
Ejemplo n.º 4
0
int islpci_reset(islpci_private * private_config, char *firmware )
{
    isl38xx_control_block *control_block = private_config->control_block;
    queue_entry *entry;
//	unsigned long flags;

#if VERBOSE > SHOW_ERROR_MESSAGES 
    DEBUG(SHOW_FUNCTION_CALLS, "isl38xx_reset \n");
#endif

    // lock the driver code
    //driver_lock( &private_config->slock, &flags );

    // stop the transmission of network frames to the driver
    netif_stop_queue(private_config->my_module);

    // disable all device interrupts
    writel(0, private_config->remapped_device_base + ISL38XX_INT_EN_REG);

    // flush all management queues
    while( isl38xx_in_queue(control_block, ISL38XX_CB_TX_MGMTQ) != 0 )
    {
        islpci_get_queue(private_config->remapped_device_base,
                &private_config->mgmt_tx_shadowq, &entry);
        islpci_put_queue(private_config->remapped_device_base,
                &private_config->mgmt_tx_freeq, entry);

        // decrement the real management index
        private_config->index_mgmt_tx--;
    }

//    while( isl38xx_in_queue(control_block, ISL38XX_CB_RX_MGMTQ) != 0 )
//    {
//        islpci_get_queue(private_config->remapped_device_base,
//                &private_config->mgmt_rx_shadowq, &entry);
//        islpci_put_queue(private_config->remapped_device_base,
//                &private_config->mgmt_rx_freeq, entry);

        // decrement the real management index
//        private_config->index_mgmt_rx--;
//    }

#if VERBOSE > SHOW_ERROR_MESSAGES 
    DEBUG(SHOW_TRACING, "Firmware file: %s \n", firmware );
#endif
	
    if (isl38xx_upload_firmware( firmware, private_config->remapped_device_base,
        private_config->device_host_address ) == -1)
    {
        // error uploading the firmware
        DEBUG(SHOW_ERROR_MESSAGES, "ERROR: could not upload the firmware \n" );

        // unlock the driver code
        //driver_unlock( &private_config->slock, &flags );
        return -1;
    }
    
    // unlock the driver code
    //driver_unlock( &private_config->slock, &flags );

    return 0;
}