示例#1
0
static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev)
{
	int retval;

	rt2x00dev->priv = (void *)&rt2800pci_rt2800_ops;

	/*
	 * Allocate eeprom data.
	 */
	retval = rt2800pci_validate_eeprom(rt2x00dev);
	if (retval)
		return retval;

	retval = rt2800_init_eeprom(rt2x00dev);
	if (retval)
		return retval;

	/*
	 * Initialize hw specifications.
	 */
	retval = rt2800_probe_hw_mode(rt2x00dev);
	if (retval)
		return retval;

	/*
	 * This device has multiple filters for control frames
	 * and has a separate filter for PS Poll frames.
	 */
	__set_bit(DRIVER_SUPPORT_CONTROL_FILTERS, &rt2x00dev->flags);
	__set_bit(DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL, &rt2x00dev->flags);

	/*
	 * This device requires firmware.
	 */
	if (!rt2x00_rt(&rt2x00dev->chip, RT2880) &&
	    !rt2x00_rt(&rt2x00dev->chip, RT3052))
		__set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags);
	__set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags);
	__set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags);
	if (!modparam_nohwcrypt)
		__set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);

	/*
	 * Set the rssi offset.
	 */
	rt2x00dev->rssi_offset = DEFAULT_RSSI_OFFSET;

	return 0;
}
static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev,
				    const u8 *data, const size_t len)
{
	int status;
	u32 offset;
	u32 length;

	/*
	 * Check which section of the firmware we need.
	 */
	if (rt2x00_rt(rt2x00dev, RT2860) ||
	    rt2x00_rt(rt2x00dev, RT2872) ||
	    rt2x00_rt(rt2x00dev, RT3070)) {
		offset = 0;
		length = 4096;
	} else {
		offset = 4096;
		length = 4096;
	}

	/*
	 * Write firmware to device.
	 */
	rt2x00usb_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE,
				      data + offset, length);

	rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
	rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);

	/*
	 * Send firmware request to device to load firmware,
	 * we need to specify a long timeout time.
	 */
	status = rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE,
					     0, USB_MODE_FIRMWARE,
					     REGISTER_TIMEOUT_FIRMWARE);
	if (status < 0) {
		ERROR(rt2x00dev, "Failed to write Firmware to device.\n");
		return status;
	}

	msleep(10);
	rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);

	return 0;
}
/*
 * Firmware functions
 */
static char *rt2800pci_get_firmware_name(struct rt2x00_dev *rt2x00dev)
{
    /*
     * Chip rt3290 use specific 4KB firmware named rt3290.bin.
     */
    if (rt2x00_rt(rt2x00dev, RT3290))
        return FIRMWARE_RT3290;
    else
        return FIRMWARE_RT2860;
}
static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev)
{
    u32 reg;

    /*
     * Reset DMA indexes
     */
    rt2x00pci_register_read(rt2x00dev, WPDMA_RST_IDX, &reg);
    rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX0, 1);
    rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX1, 1);
    rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX2, 1);
    rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX3, 1);
    rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX4, 1);
    rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX5, 1);
    rt2x00_set_field32(&reg, WPDMA_RST_IDX_DRX_IDX0, 1);
    rt2x00pci_register_write(rt2x00dev, WPDMA_RST_IDX, reg);

    rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f);
    rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00);

    if (rt2x00_is_pcie(rt2x00dev) &&
            (rt2x00_rt(rt2x00dev, RT3572) ||
             rt2x00_rt(rt2x00dev, RT5390) ||
             rt2x00_rt(rt2x00dev, RT5392))) {
        rt2x00pci_register_read(rt2x00dev, AUX_CTRL, &reg);
        rt2x00_set_field32(&reg, AUX_CTRL_FORCE_PCIE_CLK, 1);
        rt2x00_set_field32(&reg, AUX_CTRL_WAKE_PCIE_EN, 1);
        rt2x00pci_register_write(rt2x00dev, AUX_CTRL, reg);
    }

    rt2x00pci_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);

    reg = 0;
    rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_CSR, 1);
    rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_BBP, 1);
    rt2x00pci_register_write(rt2x00dev, MAC_SYS_CTRL, reg);

    rt2x00pci_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000);

    return 0;
}
示例#5
0
static int rt2800usb_check_firmware(struct rt2x00_dev *rt2x00dev,
				    const u8 *data, const size_t len)
{
	size_t offset = 0;

	/*
	 * Firmware files:
	 * There are 2 variations of the rt2870 firmware.
	 * a) size: 4kb
	 * b) size: 8kb
	 * Note that (b) contains 2 separate firmware blobs of 4k
	 * within the file. The first blob is the same firmware as (a),
	 * but the second blob is for the additional chipsets.
	 */
	if (len != 4096 && len != 8192)
		return FW_BAD_LENGTH;

	/*
	 * Check if we need the upper 4kb firmware data or not.
	 */
	if ((len == 4096) &&
	    !rt2x00_rt(rt2x00dev, RT2860) &&
	    !rt2x00_rt(rt2x00dev, RT2872) &&
	    !rt2x00_rt(rt2x00dev, RT3070))
		return FW_BAD_VERSION;

	/*
	 * 8kb firmware files must be checked as if it were
	 * 2 separate firmware files.
	 */
	while (offset < len) {
		if (!rt2800usb_check_crc(data + offset, 4096))
			return FW_BAD_CRC;

		offset += 4096;
	}

	return FW_OK;
}
示例#6
0
static int rt2800usb_load_firmware(struct rt2x00_dev *rt2x00dev,
				   const u8 *data, const size_t len)
{
	unsigned int i;
	int status;
	u32 reg;
	u32 offset;
	u32 length;

	/*
	 * Check which section of the firmware we need.
	 */
	if (rt2x00_rt(rt2x00dev, RT2860) ||
	    rt2x00_rt(rt2x00dev, RT2872) ||
	    rt2x00_rt(rt2x00dev, RT3070)) {
		offset = 0;
		length = 4096;
	} else {
		offset = 4096;
		length = 4096;
	}

	/*
	 * Wait for stable hardware.
	 */
	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
		rt2800_register_read(rt2x00dev, MAC_CSR0, &reg);
		if (reg && reg != ~0)
			break;
		msleep(1);
	}

	if (i == REGISTER_BUSY_COUNT) {
		ERROR(rt2x00dev, "Unstable hardware.\n");
		return -EBUSY;
	}

	/*
	 * Write firmware to device.
	 */
	rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE,
					    USB_VENDOR_REQUEST_OUT,
					    FIRMWARE_IMAGE_BASE,
					    data + offset, length,
					    REGISTER_TIMEOUT32(length));

	rt2800_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
	rt2800_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);

	/*
	 * Send firmware request to device to load firmware,
	 * we need to specify a long timeout time.
	 */
	status = rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE,
					     0, USB_MODE_FIRMWARE,
					     REGISTER_TIMEOUT_FIRMWARE);
	if (status < 0) {
		ERROR(rt2x00dev, "Failed to write Firmware to device.\n");
		return status;
	}

	msleep(10);
	rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);

	/*
	 * Send signal to firmware during boot time.
	 */
	rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0xff, 0, 0);

	if (rt2x00_rt(rt2x00dev, RT3070) ||
	    rt2x00_rt(rt2x00dev, RT3071) ||
	    rt2x00_rt(rt2x00dev, RT3572)) {
		udelay(200);
		rt2800_mcu_request(rt2x00dev, MCU_CURRENT, 0, 0, 0);
		udelay(10);
	}

	/*
	 * Wait for device to stabilize.
	 */
	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
		rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
		if (rt2x00_get_field32(reg, PBF_SYS_CTRL_READY))
			break;
		msleep(1);
	}

	if (i == REGISTER_BUSY_COUNT) {
		ERROR(rt2x00dev, "PBF system register not ready.\n");
		return -EBUSY;
	}

	/*
	 * Initialize firmware.
	 */
	rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
	rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
	msleep(1);

	return 0;
}
示例#7
0
int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops)
{
	struct ieee80211_hw *hw;
	struct rt2x00_dev *rt2x00dev;
	int retval;
	u16 chip;

	retval = pci_enable_device(pci_dev);
	if (retval) {
		rt2x00_probe_err("Enable device failed\n");
		return retval;
	}

	retval = pci_request_regions(pci_dev, pci_name(pci_dev));
	if (retval) {
		rt2x00_probe_err("PCI request regions failed\n");
		goto exit_disable_device;
	}

	pci_set_master(pci_dev);

	if (pci_set_mwi(pci_dev))
		rt2x00_probe_err("MWI not available\n");

	if (dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(32))) {
		rt2x00_probe_err("PCI DMA not supported\n");
		retval = -EIO;
		goto exit_release_regions;
	}

	hw = ieee80211_alloc_hw(sizeof(struct rt2x00_dev), ops->hw);
	if (!hw) {
		rt2x00_probe_err("Failed to allocate hardware\n");
		retval = -ENOMEM;
		goto exit_release_regions;
	}

	pci_set_drvdata(pci_dev, hw);

	rt2x00dev = hw->priv;
	rt2x00dev->dev = &pci_dev->dev;
	rt2x00dev->ops = ops;
	rt2x00dev->hw = hw;
	rt2x00dev->irq = pci_dev->irq;
	rt2x00dev->name = pci_name(pci_dev);

	if (pci_is_pcie(pci_dev))
		rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCIE);
	else
		rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCI);

	retval = rt2x00pci_alloc_reg(rt2x00dev);
	if (retval)
		goto exit_free_device;

	/*
	 * Because rt3290 chip use different efuse offset to read efuse data.
	 * So before read efuse it need to indicate it is the
	 * rt3290 or not.
	 */
	pci_read_config_word(pci_dev, PCI_DEVICE_ID, &chip);
	rt2x00dev->chip.rt = chip;

	if (rt2x00_rt(rt2x00dev, MT7630))
		MT76x0_WLAN_ChipOnOff(rt2x00dev, 1, 1);
	
	retval = rt2x00lib_probe_dev(rt2x00dev);
	if (retval)
		goto exit_free_reg;

	if (rt2x00_rt(rt2x00dev, MT7630))
	{
		rt2x00dev->TXWISize=20;
		rt2x00dev->bscan=0;

		NdisAllocateSpinLock(rt2x00dev, &rt2x00dev->CtrlRingLock);
		NdisAllocateSpinLock(rt2x00dev, &rt2x00dev->CalLock);
		retval = RTMPAllocTxRxRingMemory(rt2x00dev);
		if (retval != NDIS_STATUS_SUCCESS)
			goto exit_free_reg;
	}

	
	return 0;

exit_free_reg:
	rt2x00pci_free_reg(rt2x00dev);

exit_free_device:
	ieee80211_free_hw(hw);

exit_release_regions:
	pci_release_regions(pci_dev);

exit_disable_device:
	pci_disable_device(pci_dev);

	pci_set_drvdata(pci_dev, NULL);

	return retval;
}