diff options
Diffstat (limited to 'drivers')
489 files changed, 6737 insertions, 5027 deletions
diff --git a/drivers/acpi/acpi_ipmi.c b/drivers/acpi/acpi_ipmi.c index f40acef80269..a6977e12d574 100644 --- a/drivers/acpi/acpi_ipmi.c +++ b/drivers/acpi/acpi_ipmi.c @@ -39,6 +39,7 @@ #include <linux/ipmi.h> #include <linux/device.h> #include <linux/pnp.h> +#include <linux/spinlock.h> MODULE_AUTHOR("Zhao Yakui"); MODULE_DESCRIPTION("ACPI IPMI Opregion driver"); @@ -57,7 +58,7 @@ struct acpi_ipmi_device { struct list_head head; /* the IPMI request message list */ struct list_head tx_msg_list; - struct mutex tx_msg_lock; + spinlock_t tx_msg_lock; acpi_handle handle; struct pnp_dev *pnp_dev; ipmi_user_t user_interface; @@ -147,6 +148,7 @@ static void acpi_format_ipmi_msg(struct acpi_ipmi_msg *tx_msg, struct kernel_ipmi_msg *msg; struct acpi_ipmi_buffer *buffer; struct acpi_ipmi_device *device; + unsigned long flags; msg = &tx_msg->tx_message; /* @@ -177,10 +179,10 @@ static void acpi_format_ipmi_msg(struct acpi_ipmi_msg *tx_msg, /* Get the msgid */ device = tx_msg->device; - mutex_lock(&device->tx_msg_lock); + spin_lock_irqsave(&device->tx_msg_lock, flags); device->curr_msgid++; tx_msg->tx_msgid = device->curr_msgid; - mutex_unlock(&device->tx_msg_lock); + spin_unlock_irqrestore(&device->tx_msg_lock, flags); } static void acpi_format_ipmi_response(struct acpi_ipmi_msg *msg, @@ -242,6 +244,7 @@ static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) int msg_found = 0; struct acpi_ipmi_msg *tx_msg; struct pnp_dev *pnp_dev = ipmi_device->pnp_dev; + unsigned long flags; if (msg->user != ipmi_device->user_interface) { dev_warn(&pnp_dev->dev, "Unexpected response is returned. " @@ -250,7 +253,7 @@ static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) ipmi_free_recv_msg(msg); return; } - mutex_lock(&ipmi_device->tx_msg_lock); + spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags); list_for_each_entry(tx_msg, &ipmi_device->tx_msg_list, head) { if (msg->msgid == tx_msg->tx_msgid) { msg_found = 1; @@ -258,7 +261,7 @@ static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) } } - mutex_unlock(&ipmi_device->tx_msg_lock); + spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags); if (!msg_found) { dev_warn(&pnp_dev->dev, "Unexpected response (msg id %ld) is " "returned.\n", msg->msgid); @@ -378,6 +381,7 @@ acpi_ipmi_space_handler(u32 function, acpi_physical_address address, struct acpi_ipmi_device *ipmi_device = handler_context; int err, rem_time; acpi_status status; + unsigned long flags; /* * IPMI opregion message. * IPMI message is firstly written to the BMC and system software @@ -395,9 +399,9 @@ acpi_ipmi_space_handler(u32 function, acpi_physical_address address, return AE_NO_MEMORY; acpi_format_ipmi_msg(tx_msg, address, value); - mutex_lock(&ipmi_device->tx_msg_lock); + spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags); list_add_tail(&tx_msg->head, &ipmi_device->tx_msg_list); - mutex_unlock(&ipmi_device->tx_msg_lock); + spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags); err = ipmi_request_settime(ipmi_device->user_interface, &tx_msg->addr, tx_msg->tx_msgid, @@ -413,9 +417,9 @@ acpi_ipmi_space_handler(u32 function, acpi_physical_address address, status = AE_OK; end_label: - mutex_lock(&ipmi_device->tx_msg_lock); + spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags); list_del(&tx_msg->head); - mutex_unlock(&ipmi_device->tx_msg_lock); + spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags); kfree(tx_msg); return status; } @@ -457,7 +461,7 @@ static void acpi_add_ipmi_device(struct acpi_ipmi_device *ipmi_device) INIT_LIST_HEAD(&ipmi_device->head); - mutex_init(&ipmi_device->tx_msg_lock); + spin_lock_init(&ipmi_device->tx_msg_lock); INIT_LIST_HEAD(&ipmi_device->tx_msg_list); ipmi_install_space_handler(ipmi_device); diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index fbdb82e70d10..611ce9061dc5 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1121,7 +1121,7 @@ int acpi_bus_register_driver(struct acpi_driver *driver) EXPORT_SYMBOL(acpi_bus_register_driver); /** - * acpi_bus_unregister_driver - unregisters a driver with the APIC bus + * acpi_bus_unregister_driver - unregisters a driver with the ACPI bus * @driver: driver to unregister * * Unregisters a driver with the ACPI bus. Searches the namespace for all diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index 958ba2a420c3..97f4acb54ad6 100644 --- a/drivers/ata/sata_promise.c +++ b/drivers/ata/sata_promise.c @@ -2,7 +2,7 @@ * sata_promise.c - Promise SATA * * Maintained by: Tejun Heo <tj@kernel.org> - * Mikael Pettersson <mikpe@it.uu.se> + * Mikael Pettersson * Please ALWAYS copy linux-ide@vger.kernel.org * on emails. * diff --git a/drivers/base/core.c b/drivers/base/core.c index c7cfadcf6752..34abf4d8a45f 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -2017,7 +2017,7 @@ EXPORT_SYMBOL_GPL(device_move); */ void device_shutdown(void) { - struct device *dev; + struct device *dev, *parent; spin_lock(&devices_kset->list_lock); /* @@ -2034,7 +2034,7 @@ void device_shutdown(void) * prevent it from being freed because parent's * lock is to be held */ - get_device(dev->parent); + parent = get_device(dev->parent); get_device(dev); /* * Make sure the device is off the kset list, in the @@ -2044,8 +2044,8 @@ void device_shutdown(void) spin_unlock(&devices_kset->list_lock); /* hold lock to avoid race with probe/release */ - if (dev->parent) - device_lock(dev->parent); + if (parent) + device_lock(parent); device_lock(dev); /* Don't allow any more runtime suspends */ @@ -2063,11 +2063,11 @@ void device_shutdown(void) } device_unlock(dev); - if (dev->parent) - device_unlock(dev->parent); + if (parent) + device_unlock(parent); put_device(dev); - put_device(dev->parent); + put_device(parent); spin_lock(&devices_kset->list_lock); } diff --git a/drivers/bcma/driver_pci.c b/drivers/bcma/driver_pci.c index c9fd6943ce45..50329d1057ed 100644 --- a/drivers/bcma/driver_pci.c +++ b/drivers/bcma/driver_pci.c @@ -210,25 +210,6 @@ static void bcma_core_pci_config_fixup(struct bcma_drv_pci *pc) } } -static void bcma_core_pci_power_save(struct bcma_drv_pci *pc, bool up) -{ - u16 data; - - if (pc->core->id.rev >= 15 && pc->core->id.rev <= 20) { - data = up ? 0x74 : 0x7C; - bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1, - BCMA_CORE_PCI_MDIO_BLK1_MGMT1, 0x7F64); - bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1, - BCMA_CORE_PCI_MDIO_BLK1_MGMT3, data); - } else if (pc->core->id.rev >= 21 && pc->core->id.rev <= 22) { - data = up ? 0x75 : 0x7D; - bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1, - BCMA_CORE_PCI_MDIO_BLK1_MGMT1, 0x7E65); - bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1, - BCMA_CORE_PCI_MDIO_BLK1_MGMT3, data); - } -} - /************************************************** * Init. **************************************************/ @@ -255,6 +236,32 @@ void bcma_core_pci_init(struct bcma_drv_pci *pc) bcma_core_pci_clientmode_init(pc); } +void bcma_core_pci_power_save(struct bcma_bus *bus, bool up) +{ + struct bcma_drv_pci *pc; + u16 data; + + if (bus->hosttype != BCMA_HOSTTYPE_PCI) + return; + + pc = &bus->drv_pci[0]; + + if (pc->core->id.rev >= 15 && pc->core->id.rev <= 20) { + data = up ? 0x74 : 0x7C; + bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1, + BCMA_CORE_PCI_MDIO_BLK1_MGMT1, 0x7F64); + bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1, + BCMA_CORE_PCI_MDIO_BLK1_MGMT3, data); + } else if (pc->core->id.rev >= 21 && pc->core->id.rev <= 22) { + data = up ? 0x75 : 0x7D; + bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1, + BCMA_CORE_PCI_MDIO_BLK1_MGMT1, 0x7E65); + bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1, + BCMA_CORE_PCI_MDIO_BLK1_MGMT3, data); + } +} +EXPORT_SYMBOL_GPL(bcma_core_pci_power_save); + int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core, bool enable) { @@ -310,8 +317,6 @@ void bcma_core_pci_up(struct bcma_bus *bus) pc = &bus->drv_pci[0]; - bcma_core_pci_power_save(pc, true); - bcma_core_pci_extend_L1timer(pc, true); } EXPORT_SYMBOL_GPL(bcma_core_pci_up); @@ -326,7 +331,5 @@ void bcma_core_pci_down(struct bcma_bus *bus) pc = &bus->drv_pci[0]; bcma_core_pci_extend_L1timer(pc, false); - - bcma_core_pci_power_save(pc, false); } EXPORT_SYMBOL_GPL(bcma_core_pci_down); diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index d2d95ff5353b..edfa2515bc86 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -1189,6 +1189,7 @@ static int cciss_ioctl32_passthru(struct block_device *bdev, fmode_t mode, int err; u32 cp; + memset(&arg64, 0, sizeof(arg64)); err = 0; err |= copy_from_user(&arg64.LUN_info, &arg32->LUN_info, diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c index 639d26b90b91..2b9440384536 100644 --- a/drivers/block/cpqarray.c +++ b/drivers/block/cpqarray.c @@ -1193,6 +1193,7 @@ out_passthru: ida_pci_info_struct pciinfo; if (!arg) return -EINVAL; + memset(&pciinfo, 0, sizeof(pciinfo)); pciinfo.bus = host->pci_dev->bus->number; pciinfo.dev_fn = host->pci_dev->devfn; pciinfo.board_id = host->board_id; diff --git a/drivers/char/tpm/xen-tpmfront.c b/drivers/char/tpm/xen-tpmfront.c index 7a7929ba2658..06189e55b4e5 100644 --- a/drivers/char/tpm/xen-tpmfront.c +++ b/drivers/char/tpm/xen-tpmfront.c @@ -142,32 +142,6 @@ static int vtpm_recv(struct tpm_chip *chip, u8 *buf, size_t count) return length; } -ssize_t tpm_show_locality(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct tpm_chip *chip = dev_get_drvdata(dev); - struct tpm_private *priv = TPM_VPRIV(chip); - u8 locality = priv->shr->locality; - - return sprintf(buf, "%d\n", locality); -} - -ssize_t tpm_store_locality(struct device *dev, struct device_attribute *attr, - const char *buf, size_t len) -{ - struct tpm_chip *chip = dev_get_drvdata(dev); - struct tpm_private *priv = TPM_VPRIV(chip); - u8 val; - - int rv = kstrtou8(buf, 0, &val); - if (rv) - return rv; - - priv->shr->locality = val; - - return len; -} - static const struct file_operations vtpm_ops = { .owner = THIS_MODULE, .llseek = no_llseek, @@ -188,8 +162,6 @@ static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL); static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL); -static DEVICE_ATTR(locality, S_IRUGO | S_IWUSR, tpm_show_locality, - tpm_store_locality); static struct attribute *vtpm_attrs[] = { &dev_attr_pubek.attr, @@ -202,7 +174,6 @@ static struct attribute *vtpm_attrs[] = { &dev_attr_cancel.attr, &dev_attr_durations.attr, &dev_attr_timeouts.attr, - &dev_attr_locality.attr, NULL, }; @@ -210,8 +181,6 @@ static struct attribute_group vtpm_attr_grp = { .attrs = vtpm_attrs, }; -#define TPM_LONG_TIMEOUT (10 * 60 * HZ) - static const struct tpm_vendor_specific tpm_vtpm = { .status = vtpm_status, .recv = vtpm_recv, @@ -224,11 +193,6 @@ static const struct tpm_vendor_specific tpm_vtpm = { .miscdev = { .fops = &vtpm_ops, }, - .duration = { - TPM_LONG_TIMEOUT, - TPM_LONG_TIMEOUT, - TPM_LONG_TIMEOUT, - }, }; static irqreturn_t tpmif_interrupt(int dummy, void *dev_id) diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 41c69469ce20..971d796e071d 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -26,6 +26,7 @@ config DW_APB_TIMER_OF config ARMADA_370_XP_TIMER bool + select CLKSRC_OF config ORION_TIMER select CLKSRC_OF diff --git a/drivers/clocksource/clksrc-of.c b/drivers/clocksource/clksrc-of.c index 37f5325bec95..b9ddd9e3a2f5 100644 --- a/drivers/clocksource/clksrc-of.c +++ b/drivers/clocksource/clksrc-of.c @@ -30,6 +30,9 @@ void __init clocksource_of_init(void) clocksource_of_init_fn init_func; for_each_matching_node_and_match(np, __clksrc_of_table, &match) { + if (!of_device_is_available(np)) + continue; + init_func = match->data; init_func(np); } diff --git a/drivers/clocksource/em_sti.c b/drivers/clocksource/em_sti.c index b9c81b7c3a3b..3a5909c12d42 100644 --- a/drivers/clocksource/em_sti.c +++ b/drivers/clocksource/em_sti.c @@ -301,7 +301,7 @@ static void em_sti_register_clockevent(struct em_sti_priv *p) ced->name = dev_name(&p->pdev->dev); ced->features = CLOCK_EVT_FEAT_ONESHOT; ced->rating = 200; - ced->cpumask = cpumask_of(0); + ced->cpumask = cpu_possible_mask; ced->set_next_event = em_sti_clock_event_next; ced->set_mode = em_sti_clock_event_mode; diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c index 5b34768f4d7c..62b0de6a1837 100644 --- a/drivers/clocksource/exynos_mct.c +++ b/drivers/clocksource/exynos_mct.c @@ -428,7 +428,6 @@ static int exynos4_local_timer_setup(struct clock_event_device *evt) evt->irq); return -EIO; } - irq_set_affinity(evt->irq, cpumask_of(cpu)); } else { enable_percpu_irq(mct_irqs[MCT_L0_IRQ], 0); } @@ -449,6 +448,7 @@ static int exynos4_mct_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) { struct mct_clock_event_device *mevt; + unsigned int cpu; /* * Grab cpu pointer in each case to avoid spurious @@ -459,6 +459,12 @@ static int exynos4_mct_cpu_notify(struct notifier_block *self, mevt = this_cpu_ptr(&percpu_mct_tick); exynos4_local_timer_setup(&mevt->evt); break; + case CPU_ONLINE: + cpu = (unsigned long)hcpu; + if (mct_int_type == MCT_INT_SPI) + irq_set_affinity(mct_irqs[MCT_L0_IRQ + cpu], + cpumask_of(cpu)); + break; case CPU_DYING: mevt = this_cpu_ptr(&percpu_mct_tick); exynos4_local_timer_stop(&mevt->evt); @@ -500,6 +506,8 @@ static void __init exynos4_timer_resources(struct device_node *np, void __iomem &percpu_mct_tick); WARN(err, "MCT: can't request IRQ %d (%d)\n", mct_irqs[MCT_L0_IRQ], err); + } else { + irq_set_affinity(mct_irqs[MCT_L0_IRQ], cpumask_of(0)); } err = register_cpu_notifier(&exynos4_mct_cpu_nb); diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index a1260b4549db..d2c3253e015e 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c @@ -986,6 +986,10 @@ static int __init acpi_cpufreq_init(void) { int ret; + /* don't keep reloading if cpufreq_driver exists */ + if (cpufreq_get_current_driver()) + return 0; + if (acpi_disabled) return 0; diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c index cbfffa91ebdd..78c49d8e0f4a 100644 --- a/drivers/cpufreq/cpufreq-cpu0.c +++ b/drivers/cpufreq/cpufreq-cpu0.c @@ -12,6 +12,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/clk.h> +#include <linux/cpu.h> #include <linux/cpufreq.h> #include <linux/err.h> #include <linux/module.h> @@ -177,7 +178,11 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev) struct device_node *np; int ret; - cpu_dev = &pdev->dev; + cpu_dev = get_cpu_device(0); + if (!cpu_dev) { + pr_err("failed to get cpu0 device\n"); + return -ENODEV; + } np = of_node_get(cpu_dev->of_node); if (!np) { diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 43c24aa756f6..04548f7023af 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -952,9 +952,20 @@ static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu) if (cpu == policy->cpu) return; + /* + * Take direct locks as lock_policy_rwsem_write wouldn't work here. + * Also lock for last cpu is enough here as contention will happen only + * after policy->cpu is changed and after it is changed, other threads + * will try to acquire lock for new cpu. And policy is already updated + * by then. + */ + down_write(&per_cpu(cpu_policy_rwsem, policy->cpu)); + policy->last_cpu = policy->cpu; policy->cpu = cpu; + up_write(&per_cpu(cpu_policy_rwsem, policy->last_cpu)); + #ifdef CONFIG_CPU_FREQ_TABLE cpufreq_frequency_table_update_policy_cpu(policy); #endif @@ -1125,7 +1136,7 @@ static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *policy, int ret; /* first sibling now owns the new sysfs dir */ - cpu_dev = get_cpu_device(cpumask_first(policy->cpus)); + cpu_dev = get_cpu_device(cpumask_any_but(policy->cpus, old_cpu)); /* Don't touch sysfs files during light-weight tear-down */ if (frozen) @@ -1189,12 +1200,9 @@ static int __cpufreq_remove_dev_prepare(struct device *dev, policy->governor->name, CPUFREQ_NAME_LEN); #endif - WARN_ON(lock_policy_rwsem_write(cpu)); + lock_policy_rwsem_read(cpu); cpus = cpumask_weight(policy->cpus); - - if (cpus > 1) - cpumask_clear_cpu(cpu, policy->cpus); - unlock_policy_rwsem_write(cpu); + unlock_policy_rwsem_read(cpu); if (cpu != policy->cpu) { if (!frozen) @@ -1203,9 +1211,7 @@ static int __cpufreq_remove_dev_prepare(struct device *dev, new_cpu = cpufreq_nominate_new_policy_cpu(policy, cpu, frozen); if (new_cpu >= 0) { - WARN_ON(lock_policy_rwsem_write(cpu)); update_policy_cpu(policy, new_cpu); - unlock_policy_rwsem_write(cpu); if (!frozen) { pr_debug("%s: policy Kobject moved to cpu: %d " @@ -1237,9 +1243,12 @@ static int __cpufreq_remove_dev_finish(struct device *dev, return -EINVAL; } - lock_policy_rwsem_read(cpu); + WARN_ON(lock_policy_rwsem_write(cpu)); cpus = cpumask_weight(policy->cpus); - unlock_policy_rwsem_read(cpu); + + if (cpus > 1) + cpumask_clear_cpu(cpu, policy->cpus); + unlock_policy_rwsem_write(cpu); /* If cpu is last user of policy, free policy */ if (cpus == 1) { @@ -1451,6 +1460,9 @@ unsigned int cpufreq_get(unsigned int cpu) { unsigned int ret_freq = 0; + if (cpufreq_disabled() || !cpufreq_driver) + return -ENOENT; + if (!down_read_trylock(&cpufreq_rwsem)) return 0; @@ -2095,7 +2107,7 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data) write_lock_irqsave(&cpufreq_driver_lock, flags); if (cpufreq_driver) { write_unlock_irqrestore(&cpufreq_driver_lock, flags); - return -EBUSY; + return -EEXIST; } cpufreq_driver = driver_data; write_unlock_irqrestore(&cpufreq_driver_lock, flags); diff --git a/drivers/cpufreq/exynos5440-cpufreq.c b/drivers/cpufreq/exynos5440-cpufreq.c index d514c152fd1a..be5380ecdcd4 100644 --- a/drivers/cpufreq/exynos5440-cpufreq.c +++ b/drivers/cpufreq/exynos5440-cpufreq.c @@ -457,7 +457,7 @@ err_free_table: opp_free_cpufreq_table(dvfs_info->dev, &dvfs_info->freq_table); err_put_node: of_node_put(np); - dev_err(dvfs_info->dev, "%s: failed initialization\n", __func__); + dev_err(&pdev->dev, "%s: failed initialization\n", __func__); return ret; } diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c index 3e396543aea4..c3fd2a101ca0 100644 --- a/drivers/cpufreq/imx6q-cpufreq.c +++ b/drivers/cpufreq/imx6q-cpufreq.c @@ -7,6 +7,7 @@ */ #include <linux/clk.h> +#include <linux/cpu.h> #include <linux/cpufreq.h> #include <linux/delay.h> #include <linux/err.h> @@ -202,7 +203,11 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev) unsigned long min_volt, max_volt; int num, ret; - cpu_dev = &pdev->dev; + cpu_dev = get_cpu_device(0); + if (!cpu_dev) { + pr_err("failed to get cpu0 device\n"); + return -ENODEV; + } np = of_node_get(cpu_dev->of_node); if (!np) { diff --git a/drivers/gpu/drm/drm_context.c b/drivers/gpu/drm/drm_context.c index b4fb86d89850..224ff965bcf7 100644 --- a/drivers/gpu/drm/drm_context.c +++ b/drivers/gpu/drm/drm_context.c @@ -42,6 +42,10 @@ #include <drm/drmP.h> +/******************************************************************/ +/** \name Context bitmap support */ +/*@{*/ + /** * Free a handle from the context bitmap. * @@ -52,48 +56,13 @@ * in drm_device::ctx_idr, while holding the drm_device::struct_mutex * lock. */ -static void drm_ctxbitmap_free(struct drm_device * dev, int ctx_handle) +void drm_ctxbitmap_free(struct drm_device * dev, int ctx_handle) { - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return; - mutex_lock(&dev->struct_mutex); idr_remove(&dev->ctx_idr, ctx_handle); mutex_unlock(&dev->struct_mutex); } -/******************************************************************/ -/** \name Context bitmap support */ -/*@{*/ - -void drm_legacy_ctxbitmap_release(struct drm_device *dev, - struct drm_file *file_priv) -{ - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return; - - mutex_lock(&dev->ctxlist_mutex); - if (!list_empty(&dev->ctxlist)) { - struct drm_ctx_list *pos, *n; - - list_for_each_entry_safe(pos, n, &dev->ctxlist, head) { - if (pos->tag == file_priv && - pos->handle != DRM_KERNEL_CONTEXT) { - if (dev->driver->context_dtor) - dev->driver->context_dtor(dev, - pos->handle); - - drm_ctxbitmap_free(dev, pos->handle); - - list_del(&pos->head); - kfree(pos); - --dev->ctx_count; - } - } - } - mutex_unlock(&dev->ctxlist_mutex); -} - /** * Context bitmap allocation. * @@ -121,12 +90,10 @@ static int drm_ctxbitmap_next(struct drm_device * dev) * * Initialise the drm_device::ctx_idr */ -void drm_legacy_ctxbitmap_init(struct drm_device * dev) +int drm_ctxbitmap_init(struct drm_device * dev) { - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return; - idr_init(&dev->ctx_idr); + return 0; } /** @@ -137,7 +104,7 @@ void drm_legacy_ctxbitmap_init(struct drm_device * dev) * Free all idr members using drm_ctx_sarea_free helper function * while holding the drm_device::struct_mutex lock. */ -void drm_legacy_ctxbitmap_cleanup(struct drm_device * dev) +void drm_ctxbitmap_cleanup(struct drm_device * dev) { mutex_lock(&dev->struct_mutex); idr_destroy(&dev->ctx_idr); @@ -169,9 +136,6 @@ int drm_getsareactx(struct drm_device *dev, void *data, struct drm_local_map *map; struct drm_map_list *_entry; - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; - mutex_lock(&dev->struct_mutex); map = idr_find(&dev->ctx_idr, request->ctx_id); @@ -216,9 +180,6 @@ int drm_setsareactx(struct drm_device *dev, void *data, struct drm_local_map *map = NULL; struct drm_map_list *r_list = NULL; - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; - mutex_lock(&dev->struct_mutex); list_for_each_entry(r_list, &dev->maplist, head) { if (r_list->map @@ -319,9 +280,6 @@ int drm_resctx(struct drm_device *dev, void *data, struct drm_ctx ctx; int i; - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; - if (res->count >= DRM_RESERVED_CONTEXTS) { memset(&ctx, 0, sizeof(ctx)); for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) { @@ -352,9 +310,6 @@ int drm_addctx(struct drm_device *dev, void *data, struct drm_ctx_list *ctx_entry; struct drm_ctx *ctx = data; - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; - ctx->handle = drm_ctxbitmap_next(dev); if (ctx->handle == DRM_KERNEL_CONTEXT) { /* Skip kernel's context and get a new one. */ @@ -398,9 +353,6 @@ int drm_getctx(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_ctx *ctx = data; - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; - /* This is 0, because we don't handle any context flags */ ctx->flags = 0; @@ -423,9 +375,6 @@ int drm_switchctx(struct drm_device *dev, void *data, { struct drm_ctx *ctx = data; - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; - DRM_DEBUG("%d\n", ctx->handle); return drm_context_switch(dev, dev->last_context, ctx->handle); } @@ -446,9 +395,6 @@ int drm_newctx(struct drm_device *dev, void *data, { struct drm_ctx *ctx = data; - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; - DRM_DEBUG("%d\n", ctx->handle); drm_context_switch_complete(dev, file_priv, ctx->handle); @@ -471,9 +417,6 @@ int drm_rmctx(struct drm_device *dev, void *data, { struct drm_ctx *ctx = data; - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; - DRM_DEBUG("%d\n", ctx->handle); if (ctx->handle != DRM_KERNEL_CONTEXT) { if (dev->driver->context_dtor) diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 4be8e09a32ef..3f84277d7036 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c @@ -439,7 +439,26 @@ int drm_release(struct inode *inode, struct file *filp) if (dev->driver->driver_features & DRIVER_GEM) drm_gem_release(dev, file_priv); - drm_legacy_ctxbitmap_release(dev, file_priv); + mutex_lock(&dev->ctxlist_mutex); + if (!list_empty(&dev->ctxlist)) { + struct drm_ctx_list *pos, *n; + + list_for_each_entry_safe(pos, n, &dev->ctxlist, head) { + if (pos->tag == file_priv && + pos->handle != DRM_KERNEL_CONTEXT) { + if (dev->driver->context_dtor) + dev->driver->context_dtor(dev, + pos->handle); + + drm_ctxbitmap_free(dev, pos->handle); + + list_del(&pos->head); + kfree(pos); + --dev->ctx_count; + } + } + } + mutex_unlock(&dev->ctxlist_mutex); mutex_lock(&dev->struct_mutex); diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index e7eb0276f7f1..39d864576be4 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c @@ -292,7 +292,13 @@ int drm_fill_in_dev(struct drm_device *dev, goto error_out_unreg; } - drm_legacy_ctxbitmap_init(dev); + + + retcode = drm_ctxbitmap_init(dev); + if (retcode) { + DRM_ERROR("Cannot allocate memory for context bitmap.\n"); + goto error_out_unreg; + } if (driver->driver_features & DRIVER_GEM) { retcode = drm_gem_init(dev); @@ -446,7 +452,7 @@ void drm_put_dev(struct drm_device *dev) drm_rmmap(dev, r_list->map); drm_ht_remove(&dev->map_hash); - drm_legacy_ctxbitmap_cleanup(dev); + drm_ctxbitmap_cleanup(dev); if (drm_core_check_feature(dev, DRIVER_MODESET)) drm_put_minor(&dev->control); diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig index 4752f223e5b2..45b6ef595965 100644 --- a/drivers/gpu/drm/exynos/Kconfig +++ b/drivers/gpu/drm/exynos/Kconfig @@ -56,7 +56,7 @@ config DRM_EXYNOS_IPP config DRM_EXYNOS_FIMC bool "Exynos DRM FIMC" - depends on DRM_EXYNOS_IPP && MFD_SYSCON && OF + depends on DRM_EXYNOS_IPP && MFD_SYSCON help Choose this option if you want to use Exynos FIMC for DRM. diff --git a/drivers/gpu/drm/exynos/exynos_drm_buf.c b/drivers/gpu/drm/exynos/exynos_drm_buf.c index 3445a0f3a6b2..9c8088462c26 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_buf.c +++ b/drivers/gpu/drm/exynos/exynos_drm_buf.c @@ -63,7 +63,8 @@ static int lowlevel_buffer_allocate(struct drm_device *dev, return -ENOMEM; } - buf->kvaddr = dma_alloc_attrs(dev->dev, buf->size, + buf->kvaddr = (void __iomem *)dma_alloc_attrs(dev->dev, + buf->size, &buf->dma_addr, GFP_KERNEL, &buf->dma_attrs); if (!buf->kvaddr) { @@ -90,9 +91,9 @@ static int lowlevel_buffer_allocate(struct drm_device *dev, } buf->sgt = drm_prime_pages_to_sg(buf->pages, nr_pages); - if (!buf->sgt) { + if (IS_ERR(buf->sgt)) { DRM_ERROR("failed to get sg table.\n"); - ret = -ENOMEM; + ret = PTR_ERR(buf->sgt); goto err_free_attrs; } diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index 78e868bcf1ec..e7c2f2d07f19 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c @@ -99,12 +99,13 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper, if (is_drm_iommu_supported(dev)) { unsigned int nr_pages = buffer->size >> PAGE_SHIFT; - buffer->kvaddr = vmap(buffer->pages, nr_pages, VM_MAP, + buffer->kvaddr = (void __iomem *) vmap(buffer->pages, + nr_pages, VM_MAP, pgprot_writecombine(PAGE_KERNEL)); } else { phys_addr_t dma_addr = buffer->dma_addr; if (dma_addr) - buffer->kvaddr = phys_to_virt(dma_addr); + buffer->kvaddr = (void __iomem *)phys_to_virt(dma_addr); else buffer->kvaddr = (void __iomem *)NULL; } diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index b1f8fc69023f..60e84043aa34 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -707,8 +707,7 @@ tda998x_encoder_dpms(struct drm_encoder *encoder, int mode) reg_write(encoder, REG_VIP_CNTRL_2, priv->vip_cntrl_2); break; case DRM_MODE_DPMS_OFF: - /* disable audio and video ports */ - reg_write(encoder, REG_ENA_AP, 0x00); + /* disable video ports */ reg_write(encoder, REG_ENA_VP_0, 0x00); reg_write(encoder, REG_ENA_VP_1, 0x00); reg_write(encoder, REG_ENA_VP_2, 0x00); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 8507c6d1e642..cdfb9da0e4ce 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1392,14 +1392,11 @@ out: if (i915_terminally_wedged(&dev_priv->gpu_error)) return VM_FAULT_SIGBUS; case -EAGAIN: - /* Give the error handler a chance to run and move the - * objects off the GPU active list. Next time we service the - * fault, we should be able to transition the page into the - * GTT without touching the GPU (and so avoid further - * EIO/EGAIN). If the GPU is wedged, then there is no issue - * with coherency, just lost writes. + /* + * EAGAIN means the gpu is hung and we'll wait for the error + * handler to reset everything when re-faulting in + * i915_mutex_lock_interruptible. */ - set_need_resched(); case 0: case -ERESTARTSYS: case -EINTR: @@ -4803,10 +4800,10 @@ i915_gem_inactive_count(struct shrinker *shrinker, struct shrink_control *sc) if (!mutex_trylock(&dev->struct_mutex)) { if (!mutex_is_locked_by(&dev->struct_mutex, current)) - return SHRINK_STOP; + return 0; if (dev_priv->mm.shrinker_no_lock_stealing) - return SHRINK_STOP; + return 0; unlock = false; } @@ -4904,10 +4901,10 @@ i915_gem_inactive_scan(struct shrinker *shrinker, struct shrink_control *sc) if (!mutex_trylock(&dev->struct_mutex)) { if (!mutex_is_locked_by(&dev->struct_mutex, current)) - return 0; + return SHRINK_STOP; if (dev_priv->mm.shrinker_no_lock_stealing) - return 0; + return SHRINK_STOP; unlock = false; } diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index aba9d7498996..dae364f0028c 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -143,8 +143,10 @@ static void i915_error_vprintf(struct drm_i915_error_state_buf *e, /* Seek the first printf which is hits start position */ if (e->pos < e->start) { - len = vsnprintf(NULL, 0, f, args); - if (!__i915_error_seek(e, len)) + va_list tmp; + + va_copy(tmp, args); + if (!__i915_error_seek(e, vsnprintf(NULL, 0, f, tmp))) return; } diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 83cce0cdb769..4b91228fd9bd 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1469,6 +1469,34 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg) return ret; } +static void i915_error_wake_up(struct drm_i915_private *dev_priv, + bool reset_completed) +{ + struct intel_ring_buffer *ring; + int i; + + /* + * Notify all waiters for GPU completion events that reset state has + * been changed, and that they need to restart their wait after + * checking for potential errors (and bail out to drop locks if there is + * a gpu reset pending so that i915_error_work_func can acquire them). + */ + + /* Wake up __wait_seqno, potentially holding dev->struct_mutex. */ + for_each_ring(ring, dev_priv, i) + wake_up_all(&ring->irq_queue); + + /* Wake up intel_crtc_wait_for_pending_flips, holding crtc->mutex. */ + wake_up_all(&dev_priv->pending_flip_queue); + + /* + * Signal tasks blocked in i915_gem_wait_for_error that the pending + * reset state is cleared. + */ + if (reset_completed) + wake_up_all(&dev_priv->gpu_error.reset_queue); +} + /** * i915_error_work_func - do process context error handling work * @work: work struct @@ -1483,11 +1511,10 @@ static void i915_error_work_func(struct work_struct *work) drm_i915_private_t *dev_priv = container_of(error, drm_i915_private_t, gpu_error); struct drm_device *dev = dev_priv->dev; - struct intel_ring_buffer *ring; char *error_event[] = { I915_ERROR_UEVENT "=1", NULL }; char *reset_event[] = { I915_RESET_UEVENT "=1", NULL }; char *reset_done_event[] = { I915_ERROR_UEVENT "=0", NULL }; - int i, ret; + int ret; kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, error_event); @@ -1506,8 +1533,16 @@ static void i915_error_work_func(struct work_struct *work) kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, reset_event); + /* + * All state reset _must_ be completed before we update the + * reset counter, for otherwise waiters might miss the reset + * pending state and not properly drop locks, resulting in + * deadlocks with the reset work. + */ ret = i915_reset(dev); + intel_display_handle_reset(dev); + if (ret == 0) { /* * After all the gem state is reset, increment the reset @@ -1528,12 +1563,11 @@ static void i915_error_work_func(struct work_struct *work) atomic_set(&error->reset_counter, I915_WEDGED); } - for_each_ring(ring, dev_priv, i) - wake_up_all(&ring->irq_queue); - - intel_display_handle_reset(dev); - - wake_up_all(&dev_priv->gpu_error.reset_queue); + /* + * Note: The wake_up also serves as a memory barrier so that + * waiters see the update value of the reset counter atomic_t. + */ + i915_error_wake_up(dev_priv, true); } } @@ -1642,8 +1676,6 @@ static void i915_report_and_clear_eir(struct drm_device *dev) void i915_handle_error(struct drm_device *dev, bool wedged) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_ring_buffer *ring; - int i; i915_capture_error_state(dev); i915_report_and_clear_eir(dev); @@ -1653,11 +1685,19 @@ void i915_handle_error(struct drm_device *dev, bool wedged) &dev_priv->gpu_error.reset_counter); /* - * Wakeup waiting processes so that the reset work item - * doesn't deadlock trying to grab various locks. + * Wakeup waiting processes so that the reset work function + * i915_error_work_func doesn't deadlock trying to grab various + * locks. By bumping the reset counter first, the woken + * processes will see a reset in progress and back off, + * releasing their locks and then wait for the reset completion. + * We must do this for _all_ gpu waiters that might hold locks + * that the reset work needs to acquire. + * + * Note: The wake_up serves as the required memory barrier to + * ensure that the waiters see the updated value of the reset + * counter atomic_t. */ - for_each_ring(ring, dev_priv, i) - wake_up_all(&ring->irq_queue); + i915_error_wake_up(dev_priv, false); } /* diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 63aca49d11a8..63de2701b974 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -778,7 +778,7 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc) /* Can only use the always-on power well for eDP when * not using the panel fitter, and when not using motion * blur mitigation (which we don't support). */ - if (intel_crtc->config.pch_pfit.size) + if (intel_crtc->config.pch_pfit.enabled) temp |= TRANS_DDI_EDP_INPUT_A_ONOFF; else temp |= TRANS_DDI_EDP_INPUT_A_ON; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 2489d0b4c7d2..e5822e79f912 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2249,7 +2249,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, I915_WRITE(PIPESRC(intel_crtc->pipe), ((crtc->mode.hdisplay - 1) << 16) | (crtc->mode.vdisplay - 1)); - if (!intel_crtc->config.pch_pfit.size && + if (!intel_crtc->config.pch_pfit.enabled && (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) || intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))) { I915_WRITE(PF_CTL(intel_crtc->pipe), 0); @@ -3203,7 +3203,7 @@ static void ironlake_pfit_enable(struct intel_crtc *crtc) struct drm_i915_private *dev_priv = dev->dev_private; int pipe = crtc->pipe; - if (crtc->config.pch_pfit.size) { + if (crtc->config.pch_pfit.enabled) { /* Force use of hard-coded filter coefficients * as some pre-programmed values are broken, * e.g. x201. @@ -3428,7 +3428,7 @@ static void ironlake_pfit_disable(struct intel_crtc *crtc) /* To avoid upsetting the power well on haswell only disable the pfit if * it's in use. The hw state code will make sure we get this right. */ - if (crtc->config.pch_pfit.size) { + if (crtc->config.pch_pfit.enabled) { I915_WRITE(PF_CTL(pipe), 0); I915_WRITE(PF_WIN_POS(pipe), 0); I915_WRITE(PF_WIN_SZ(pipe), 0); @@ -4775,6 +4775,10 @@ static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc) pipeconf = 0; + if (dev_priv->quirks & QUIRK_PIPEA_FORCE && + I915_READ(PIPECONF(intel_crtc->pipe)) & PIPECONF_ENABLE) + pipeconf |= PIPECONF_ENABLE; + if (intel_crtc->pipe == 0 && INTEL_INFO(dev)->gen < 4) { /* Enable pixel doubling when the dot clock is > 90% of the (display) * core speed. @@ -4877,9 +4881,6 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, return -EINVAL; } - /* Ensure that the cursor is valid for the new mode before changing... */ - intel_crtc_update_cursor(crtc, true); - if (is_lvds && dev_priv->lvds_downclock_avail) { /* * Ensure we match the reduced clock's P to the target clock. @@ -5768,9 +5769,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, intel_crtc->config.dpll.p2 = clock.p2; } - /* Ensure that the cursor is valid for the new mode before changing... */ - intel_crtc_update_cursor(crtc, true); - /* CPU eDP is the only output that doesn't need a PCH PLL of its own. */ if (intel_crtc->config.has_pch_encoder) { fp = i9xx_dpll_compute_fp(&intel_crtc->config.dpll); @@ -5859,6 +5857,7 @@ static void ironlake_get_pfit_config(struct intel_crtc *crtc, tmp = I915_READ(PF_CTL(crtc->pipe)); if (tmp & PF_ENABLE) { + pipe_config->pch_pfit.enabled = true; pipe_config->pch_pfit.pos = I915_READ(PF_WIN_POS(crtc->pipe)); pipe_config->pch_pfit.size = I915_READ(PF_WIN_SZ(crtc->pipe)); @@ -6236,7 +6235,7 @@ static void haswell_modeset_global_resources(struct drm_device *dev) if (!crtc->base.enabled) continue; - if (crtc->pipe != PIPE_A || crtc->config.pch_pfit.size || + if (crtc->pipe != PIPE_A || crtc->config.pch_pfit.enabled || crtc->config.cpu_transcoder != TRANSCODER_EDP) enable = true; } @@ -6259,9 +6258,6 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc, if (!intel_ddi_pll_mode_set(crtc)) return -EINVAL; - /* Ensure that the cursor is valid for the new mode before changing... */ - intel_crtc_update_cursor(crtc, true); - if (intel_crtc->config.has_dp_encoder) intel_dp_set_m_n(intel_crtc); @@ -6494,15 +6490,15 @@ static void haswell_write_eld(struct drm_connector *connector, /* Set ELD valid state */ tmp = I915_READ(aud_cntrl_st2); - DRM_DEBUG_DRIVER("HDMI audio: pin eld vld status=0x%8x\n", tmp); + DRM_DEBUG_DRIVER("HDMI audio: pin eld vld status=0x%08x\n", tmp); tmp |= (AUDIO_ELD_VALID_A << (pipe * 4)); I915_WRITE(aud_cntrl_st2, tmp); tmp = I915_READ(aud_cntrl_st2); - DRM_DEBUG_DRIVER("HDMI audio: eld vld status=0x%8x\n", tmp); + DRM_DEBUG_DRIVER("HDMI audio: eld vld status=0x%08x\n", tmp); /* Enable HDMI mode */ tmp = I915_READ(aud_config); - DRM_DEBUG_DRIVER("HDMI audio: audio conf: 0x%8x\n", tmp); + DRM_DEBUG_DRIVER("HDMI audio: audio conf: 0x%08x\n", tmp); /* clear N_programing_enable and N_value_index */ tmp &= ~(AUD_CONFIG_N_VALUE_INDEX | AUD_CONFIG_N_PROG_ENABLE); I915_WRITE(aud_config, tmp); @@ -6937,7 +6933,8 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, intel_crtc->cursor_width = width; intel_crtc->cursor_height = height; - intel_crtc_update_cursor(crtc, intel_crtc->cursor_bo != NULL); + if (intel_crtc->active) + intel_crtc_update_cursor(crtc, intel_crtc->cursor_bo != NULL); return 0; fail_unpin: @@ -6956,7 +6953,8 @@ static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) intel_crtc->cursor_x = x; intel_crtc->cursor_y = y; - intel_crtc_update_cursor(crtc, intel_crtc->cursor_bo != NULL); + if (intel_crtc->active) + intel_crtc_update_cursor(crtc, intel_crtc->cursor_bo != NULL); return 0; } @@ -8205,9 +8203,10 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc, pipe_config->gmch_pfit.control, pipe_config->gmch_pfit.pgm_ratios, pipe_config->gmch_pfit.lvds_border_bits); - DRM_DEBUG_KMS("pch pfit: pos: 0x%08x, size: 0x%08x\n", + DRM_DEBUG_KMS("pch pfit: pos: 0x%08x, size: 0x%08x, %s\n", pipe_config->pch_pfit.pos, - pipe_config->pch_pfit.size); + pipe_config->pch_pfit.size, + pipe_config->pch_pfit.enabled ? "enabled" : "disabled"); DRM_DEBUG_KMS("ips: %i\n", pipe_config->ips_enabled); } @@ -8603,8 +8602,11 @@ intel_pipe_config_compare(struct drm_device *dev, if (INTEL_INFO(dev)->gen < 4) PIPE_CONF_CHECK_I(gmch_pfit.pgm_ratios); PIPE_CONF_CHECK_I(gmch_pfit.lvds_border_bits); - PIPE_CONF_CHECK_I(pch_pfit.pos); - PIPE_CONF_CHECK_I(pch_pfit.size); + PIPE_CONF_CHECK_I(pch_pfit.enabled); + if (current_config->pch_pfit.enabled) { + PIPE_CONF_CHECK_I(pch_pfit.pos); + PIPE_CONF_CHECK_I(pch_pfit.size); + } PIPE_CONF_CHECK_I(ips_enabled); diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 2151d13772b8..79c14e298ba6 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -588,7 +588,18 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, DRM_DEBUG_KMS("aux_ch native nack\n"); return -EREMOTEIO; case AUX_NATIVE_REPLY_DEFER: - udelay(100); + /* + * For now, just give more slack to branch devices. We + * could check the DPCD for I2C bit rate capabilities, + * and if available, adjust the interval. We could also + * be more careful with DP-to-Legacy adapters where a + * long legacy cable may force very low I2C bit rates. + */ + if (intel_dp->dpcd[DP_DOWNSTREAMPORT_PRESENT] & + DP_DWN_STRM_PORT_PRESENT) + usleep_range(500, 600); + else + usleep_range(300, 400); continue; default: DRM_ERROR("aux_ch invalid native reply 0x%02x\n", diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index a47799e832c6..28cae80495e2 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -280,6 +280,7 @@ struct intel_crtc_config { struct { u32 pos; u32 size; + bool enabled; } pch_pfit; /* FDI configuration, only valid if has_pch_encoder is set. */ diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index 406303b509c1..7fa7df546c1e 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c @@ -263,6 +263,8 @@ static bool intel_dvo_compute_config(struct intel_encoder *encoder, C(vtotal); C(clock); #undef C + + drm_mode_set_crtcinfo(adjusted_mode, 0); } if (intel_dvo->dev.dev_ops->mode_fixup) diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 42114ecbae0e..293564a2896a 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -112,6 +112,7 @@ intel_pch_panel_fitting(struct intel_crtc *intel_crtc, done: pipe_config->pch_pfit.pos = (x << 16) | y; pipe_config->pch_pfit.size = (width << 16) | height; + pipe_config->pch_pfit.enabled = pipe_config->pch_pfit.size != 0; } static void diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 0c115cc4899f..dd176b7296c1 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2096,16 +2096,16 @@ static uint32_t ilk_pipe_pixel_rate(struct drm_device *dev, struct drm_crtc *crtc) { struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - uint32_t pixel_rate, pfit_size; + uint32_t pixel_rate; pixel_rate = intel_crtc->config.adjusted_mode.clock; /* We only use IF-ID interlacing. If we ever use PF-ID we'll need to * adjust the pixel_rate here. */ - pfit_size = intel_crtc->config.pch_pfit.size; - if (pfit_size) { + if (intel_crtc->config.pch_pfit.enabled) { uint64_t pipe_w, pipe_h, pfit_w, pfit_h; + uint32_t pfit_size = intel_crtc->config.pch_pfit.size; pipe_w = intel_crtc->config.requested_mode.hdisplay; pipe_h = intel_crtc->config.requested_mode.vdisplay; diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 85037b9d4934..49482fd5b76c 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -788,6 +788,8 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, uint16_t h_sync_offset, v_sync_offset; int mode_clock; + memset(dtd, 0, sizeof(*dtd)); + width = mode->hdisplay; height = mode->vdisplay; @@ -830,44 +832,51 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, if (mode->flags & DRM_MODE_FLAG_PVSYNC) dtd->part2.dtd_flags |= DTD_FLAG_VSYNC_POSITIVE; - dtd->part2.sdvo_flags = 0; dtd->part2.v_sync_off_high = v_sync_offset & 0xc0; - dtd->part2.reserved = 0; } -static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode, +static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode *pmode, const struct intel_sdvo_dtd *dtd) { - mode->hdisplay = dtd->part1.h_active; - mode->hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8; - mode->hsync_start = mode->hdisplay + dtd->part2.h_sync_off; - mode->hsync_start += (dtd->part2.sync_off_width_high & 0xc0) << 2; - mode->hsync_end = mode->hsync_start + dtd->part2.h_sync_width; - mode->hsync_end += (dtd->part2.sync_off_width_high & 0x30) << 4; - mode->htotal = mode->hdisplay + dtd->part1.h_blank; - mode->htotal += (dtd->part1.h_high & 0xf) << 8; - - mode->vdisplay = dtd->part1.v_active; - mode->vdisplay += ((dtd->part1.v_high >> 4) & 0x0f) << 8; - mode->vsync_start = mode->vdisplay; - mode->vsync_start += (dtd->part2.v_sync_off_width >> 4) & 0xf; - mode->vsync_start += (dtd->part2.sync_off_width_high & 0x0c) << 2; - mode->vsync_start += dtd->part2.v_sync_off_high & 0xc0; - mode->vsync_end = mode->vsync_start + + struct drm_display_mode mode = {}; + + mode.hdisplay = dtd->part1.h_active; + mode.hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8; + mode.hsync_start = mode.hdisplay + dtd->part2.h_sync_off; + mode.hsync_start += (dtd->part2.sync_off_width_high & 0xc0) << 2; + mode.hsync_end = mode.hsync_start + dtd->part2.h_sync_width; + mode.hsync_end += (dtd->part2.sync_off_width_high & 0x30) << 4; + mode.htotal = mode.hdisplay + dtd->part1.h_blank; + mode.htotal += (dtd->part1.h_high & 0xf) << 8; + + mode.vdisplay = dtd->part1.v_active; + mode.vdisplay += ((dtd->part1.v_high >> 4) & 0x0f) << 8; + mode.vsync_start = mode.vdisplay; + mode.vsync_start += (dtd->part2.v_sync_off_width >> 4) & 0xf; + mode.vsync_start += (dtd->part2.sync_off_width_high & 0x0c) << 2; + mode.vsync_start += dtd->part2.v_sync_off_high & 0xc0; + mode.vsync_end = mode.vsync_start + (dtd->part2.v_sync_off_width & 0xf); - mode->vsync_end += (dtd->part2.sync_off_width_high & 0x3) << 4; - mode->vtotal = mode->vdisplay + dtd->part1.v_blank; - mode->vtotal += (dtd->part1.v_high & 0xf) << 8; + mode.vsync_end += (dtd->part2.sync_off_width_high & 0x3) << 4; + mode.vtotal = mode.vdisplay + dtd->part1.v_blank; + mode.vtotal += (dtd->part1.v_high & 0xf) << 8; - mode->clock = dtd->part1.clock * 10; + mode.clock = dtd->part1.clock * 10; - mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC); if (dtd->part2.dtd_flags & DTD_FLAG_INTERLACE) - mode->flags |= DRM_MODE_FLAG_INTERLACE; + mode.flags |= DRM_MODE_FLAG_INTERLACE; if (dtd->part2.dtd_flags & DTD_FLAG_HSYNC_POSITIVE) - mode->flags |= DRM_MODE_FLAG_PHSYNC; + mode.flags |= DRM_MODE_FLAG_PHSYNC; + else + mode.flags |= DRM_MODE_FLAG_NHSYNC; if (dtd->part2.dtd_flags & DTD_FLAG_VSYNC_POSITIVE) - mode->flags |= DRM_MODE_FLAG_PVSYNC; + mode.flags |= DRM_MODE_FLAG_PVSYNC; + else + mode.flags |= DRM_MODE_FLAG_NVSYNC; + + drm_mode_set_crtcinfo(&mode, 0); + + drm_mode_copy(pmode, &mode); } static bool intel_sdvo_check_supp_encode(struct intel_sdvo *intel_sdvo) diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index f2c6d7909ae2..dd6f84bf6c22 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c @@ -916,6 +916,14 @@ intel_tv_compute_config(struct intel_encoder *encoder, DRM_DEBUG_KMS("forcing bpc to 8 for TV\n"); pipe_config->pipe_bpp = 8*3; + /* TV has it's own notion of sync and other mode flags, so clear them. */ + pipe_config->adjusted_mode.flags = 0; + + /* + * FIXME: We don't check whether the input mode is actually what we want + * or whether userspace is doing something stupid. + */ + return true; } diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index a60584763b61..a0b9d8a95b16 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -124,6 +124,8 @@ void adreno_recover(struct msm_gpu *gpu) /* reset completed fence seqno, just discard anything pending: */ adreno_gpu->memptrs->fence = gpu->submitted_fence; + adreno_gpu->memptrs->rptr = 0; + adreno_gpu->memptrs->wptr = 0; gpu->funcs->pm_resume(gpu); ret = gpu->funcs->hw_init(gpu); @@ -229,7 +231,7 @@ void adreno_idle(struct msm_gpu *gpu) return; } while(time_before(jiffies, t)); - DRM_ERROR("timeout waiting for %s to drain ringbuffer!\n", gpu->name); + DRM_ERROR("%s: timeout waiting to drain ringbuffer!\n", gpu->name); /* TODO maybe we need to reset GPU here to recover from hang? */ } @@ -256,11 +258,17 @@ void adreno_wait_ring(struct msm_gpu *gpu, uint32_t ndwords) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); uint32_t freedwords; + unsigned long t = jiffies + ADRENO_IDLE_TIMEOUT; do { uint32_t size = gpu->rb->size / 4; uint32_t wptr = get_wptr(gpu->rb); uint32_t rptr = adreno_gpu->memptrs->rptr; freedwords = (rptr + (size - 1) - wptr) % size; + + if (time_after(jiffies, t)) { + DRM_ERROR("%s: timeout waiting for ringbuffer space\n", gpu->name); + break; + } } while(freedwords < ndwords); } diff --git a/drivers/gpu/drm/msm/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/mdp4/mdp4_kms.c index 5db5bbaedae2..bc7fd11ad8be 100644 --- a/drivers/gpu/drm/msm/mdp4/mdp4_kms.c +++ b/drivers/gpu/drm/msm/mdp4/mdp4_kms.c @@ -19,8 +19,6 @@ #include "msm_drv.h" #include "mdp4_kms.h" -#include <mach/iommu.h> - static struct mdp4_platform_config *mdp4_get_config(struct platform_device *dev); static int mdp4_hw_init(struct msm_kms *kms) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 864c9773636b..b3a2f1629041 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -18,8 +18,6 @@ #include "msm_drv.h" #include "msm_gpu.h" -#include <mach/iommu.h> - static void msm_fb_output_poll_changed(struct drm_device *dev) { struct msm_drm_private *priv = dev->dev_private; @@ -62,6 +60,8 @@ int msm_iommu_attach(struct drm_device *dev, struct iommu_domain *iommu, int i, ret; for (i = 0; i < cnt; i++) { + /* TODO maybe some day msm iommu won't require this hack: */ + struct device *msm_iommu_get_ctx(const char *ctx_name); struct device *ctx = msm_iommu_get_ctx(names[i]); if (!ctx) continue; @@ -199,7 +199,7 @@ static int msm_load(struct drm_device *dev, unsigned long flags) * imx drm driver on iMX5 */ dev_err(dev->dev, "failed to load kms\n"); - ret = PTR_ERR(priv->kms); + ret = PTR_ERR(kms); goto fail; } @@ -499,25 +499,41 @@ int msm_wait_fence_interruptable(struct drm_device *dev, uint32_t fence, struct timespec *timeout) { struct msm_drm_private *priv = dev->dev_private; - unsigned long timeout_jiffies = timespec_to_jiffies(timeout); - unsigned long start_jiffies = jiffies; - unsigned long remaining_jiffies; int ret; - if (time_after(start_jiffies, timeout_jiffies)) - remaining_jiffies = 0; - else - remaining_jiffies = timeout_jiffies - start_jiffies; - - ret = wait_event_interruptible_timeout(priv->fence_event, - priv->completed_fence >= fence, - remaining_jiffies); - if (ret == 0) { - DBG("timeout waiting for fence: %u (completed: %u)", - fence, priv->completed_fence); - ret = -ETIMEDOUT; - } else if (ret != -ERESTARTSYS) { - ret = 0; + if (!priv->gpu) + return 0; + + if (fence > priv->gpu->submitted_fence) { + DRM_ERROR("waiting on invalid fence: %u (of %u)\n", + fence, priv->gpu->submitted_fence); + return -EINVAL; + } + + if (!timeout) { + /* no-wait: */ + ret = fence_completed(dev, fence) ? 0 : -EBUSY; + } else { + unsigned long timeout_jiffies = timespec_to_jiffies(timeout); + unsigned long start_jiffies = jiffies; + unsigned long remaining_jiffies; + + if (time_after(start_jiffies, timeout_jiffies)) + remaining_jiffies = 0; + else + remaining_jiffies = timeout_jiffies - start_jiffies; + + ret = wait_event_interruptible_timeout(priv->fence_event, + fence_completed(dev, fence), + remaining_jiffies); + + if (ret == 0) { + DBG("timeout waiting for fence: %u (completed: %u)", + fence, priv->completed_fence); + ret = -ETIMEDOUT; + } else if (ret != -ERESTARTSYS) { + ret = 0; + } } return ret; @@ -681,7 +697,7 @@ static struct drm_driver msm_driver = { .gem_vm_ops = &vm_ops, .dumb_create = msm_gem_dumb_create, .dumb_map_offset = msm_gem_dumb_map_offset, - .dumb_destroy = msm_gem_dumb_destroy, + .dumb_destroy = drm_gem_dumb_destroy, #ifdef CONFIG_DEBUG_FS .debugfs_init = msm_debugfs_init, .debugfs_cleanup = msm_debugfs_cleanup, diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 80d75094bf0a..df8f1d084bc1 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -153,7 +153,7 @@ void *msm_gem_vaddr(struct drm_gem_object *obj); int msm_gem_queue_inactive_work(struct drm_gem_object *obj, struct work_struct *work); void msm_gem_move_to_active(struct drm_gem_object *obj, - struct msm_gpu *gpu, uint32_t fence); + struct msm_gpu *gpu, bool write, uint32_t fence); void msm_gem_move_to_inactive(struct drm_gem_object *obj); int msm_gem_cpu_prep(struct drm_gem_object *obj, uint32_t op, struct timespec *timeout); @@ -191,6 +191,12 @@ u32 msm_readl(const void __iomem *addr); #define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__) #define VERB(fmt, ...) if (0) DRM_DEBUG(fmt"\n", ##__VA_ARGS__) +static inline bool fence_completed(struct drm_device *dev, uint32_t fence) +{ + struct msm_drm_private *priv = dev->dev_private; + return priv->completed_fence >= fence; +} + static inline int align_pitch(int width, int bpp) { int bytespp = (bpp + 7) / 8; diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 6b5a6c8c7658..2bae46c66a30 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -40,9 +40,9 @@ static struct page **get_pages(struct drm_gem_object *obj) } msm_obj->sgt = drm_prime_pages_to_sg(p, npages); - if (!msm_obj->sgt) { + if (IS_ERR(msm_obj->sgt)) { dev_err(dev->dev, "failed to allocate sgt\n"); - return ERR_PTR(-ENOMEM); + return ERR_CAST(msm_obj->sgt); } msm_obj->pages = p; @@ -159,7 +159,6 @@ out_unlock: out: switch (ret) { case -EAGAIN: - set_need_resched(); case 0: case -ERESTARTSYS: case -EINTR: @@ -320,13 +319,6 @@ int msm_gem_dumb_create(struct drm_file *file, struct drm_device *dev, MSM_BO_SCANOUT | MSM_BO_WC, &args->handle); } -int msm_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev, - uint32_t handle) -{ - /* No special work needed, drop the reference and see what falls out */ - return drm_gem_handle_delete(file, handle); -} - int msm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev, uint32_t handle, uint64_t *offset) { @@ -393,11 +385,14 @@ int msm_gem_queue_inactive_work(struct drm_gem_object *obj, } void msm_gem_move_to_active(struct drm_gem_object *obj, - struct msm_gpu *gpu, uint32_t fence) + struct msm_gpu *gpu, bool write, uint32_t fence) { struct msm_gem_object *msm_obj = to_msm_bo(obj); msm_obj->gpu = gpu; - msm_obj->fence = fence; + if (write) + msm_obj->write_fence = fence; + else + msm_obj->read_fence = fence; list_del_init(&msm_obj->mm_list); list_add_tail(&msm_obj->mm_list, &gpu->active_list); } @@ -411,7 +406,8 @@ void msm_gem_move_to_inactive(struct drm_gem_object *obj) WARN_ON(!mutex_is_locked(&dev->struct_mutex)); msm_obj->gpu = NULL; - msm_obj->fence = 0; + msm_obj->read_fence = 0; + msm_obj->write_fence = 0; list_del_init(&msm_obj->mm_list); list_add_tail(&msm_obj->mm_list, &priv->inactive_list); @@ -433,8 +429,18 @@ int msm_gem_cpu_prep(struct drm_gem_object *obj, uint32_t op, struct msm_gem_object *msm_obj = to_msm_bo(obj); int ret = 0; - if (is_active(msm_obj) && !(op & MSM_PREP_NOSYNC)) - ret = msm_wait_fence_interruptable(dev, msm_obj->fence, timeout); + if (is_active(msm_obj)) { + uint32_t fence = 0; + + if (op & MSM_PREP_READ) + fence = msm_obj->write_fence; + if (op & MSM_PREP_WRITE) + fence = max(fence, msm_obj->read_fence); + if (op & MSM_PREP_NOSYNC) + timeout = NULL; + + ret = msm_wait_fence_interruptable(dev, fence, timeout); + } /* TODO cache maintenance */ @@ -455,9 +461,10 @@ void msm_gem_describe(struct drm_gem_object *obj, struct seq_file *m) uint64_t off = drm_vma_node_start(&obj->vma_node); WARN_ON(!mutex_is_locked(&dev->struct_mutex)); - seq_printf(m, "%08x: %c(%d) %2d (%2d) %08llx %p %d\n", + seq_printf(m, "%08x: %c(r=%u,w=%u) %2d (%2d) %08llx %p %d\n", msm_obj->flags, is_active(msm_obj) ? 'A' : 'I', - msm_obj->fence, obj->name, obj->refcount.refcount.counter, + msm_obj->read_fence, msm_obj->write_fence, + obj->name, obj->refcount.refcount.counter, off, msm_obj->vaddr, obj->size); } diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h index d746f13d283c..0676f32e2c6a 100644 --- a/drivers/gpu/drm/msm/msm_gem.h +++ b/drivers/gpu/drm/msm/msm_gem.h @@ -36,7 +36,7 @@ struct msm_gem_object { */ struct list_head mm_list; struct msm_gpu *gpu; /* non-null if active */ - uint32_t fence; + uint32_t read_fence, write_fence; /* Transiently in the process of submit ioctl, objects associated * with the submit are on submit->bo_list.. this only lasts for diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index 3e1ef3a00f60..5281d4bc37f7 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -78,7 +78,7 @@ static int submit_lookup_objects(struct msm_gem_submit *submit, } if (submit_bo.flags & BO_INVALID_FLAGS) { - DBG("invalid flags: %x", submit_bo.flags); + DRM_ERROR("invalid flags: %x\n", submit_bo.flags); ret = -EINVAL; goto out_unlock; } @@ -92,7 +92,7 @@ static int submit_lookup_objects(struct msm_gem_submit *submit, */ obj = idr_find(&file->object_idr, submit_bo.handle); if (!obj) { - DBG("invalid handle %u at index %u", submit_bo.handle, i); + DRM_ERROR("invalid handle %u at index %u\n", submit_bo.handle, i); ret = -EINVAL; goto out_unlock; } @@ -100,7 +100,7 @@ static int submit_lookup_objects(struct msm_gem_submit *submit, msm_obj = to_msm_bo(obj); if (!list_empty(&msm_obj->submit_entry)) { - DBG("handle %u at index %u already on submit list", + DRM_ERROR("handle %u at index %u already on submit list\n", submit_bo.handle, i); ret = -EINVAL; goto out_unlock; @@ -216,8 +216,9 @@ static int submit_bo(struct msm_gem_submit *submit, uint32_t idx, struct msm_gem_object **obj, uint32_t *iova, bool *valid) { if (idx >= submit->nr_bos) { - DBG("invalid buffer index: %u (out of %u)", idx, submit->nr_bos); - return EINVAL; + DRM_ERROR("invalid buffer index: %u (out of %u)\n", + idx, submit->nr_bos); + return -EINVAL; } if (obj) @@ -239,7 +240,7 @@ static int submit_reloc(struct msm_gem_submit *submit, struct msm_gem_object *ob int ret; if (offset % 4) { - DBG("non-aligned cmdstream buffer: %u", offset); + DRM_ERROR("non-aligned cmdstream buffer: %u\n", offset); return -EINVAL; } @@ -266,7 +267,7 @@ static int submit_reloc(struct msm_gem_submit *submit, struct msm_gem_object *ob return -EFAULT; if (submit_reloc.submit_offset % 4) { - DBG("non-aligned reloc offset: %u", + DRM_ERROR("non-aligned reloc offset: %u\n", submit_reloc.submit_offset); return -EINVAL; } @@ -276,7 +277,7 @@ static int submit_reloc(struct msm_gem_submit *submit, struct msm_gem_object *ob if ((off >= (obj->base.size / 4)) || (off < last_offset)) { - DBG("invalid offset %u at reloc %u", off, i); + DRM_ERROR("invalid offset %u at reloc %u\n", off, i); return -EINVAL; } @@ -374,14 +375,15 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, goto out; if (submit_cmd.size % 4) { - DBG("non-aligned cmdstream buffer size: %u", + DRM_ERROR("non-aligned cmdstream buffer size: %u\n", submit_cmd.size); ret = -EINVAL; goto out; } - if (submit_cmd.size >= msm_obj->base.size) { - DBG("invalid cmdstream size: %u", submit_cmd.size); + if ((submit_cmd.size + submit_cmd.submit_offset) >= + msm_obj->base.size) { + DRM_ERROR("invalid cmdstream size: %u\n", submit_cmd.size); ret = -EINVAL; goto out; } diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index e1e1ec9321ff..3bab937965d1 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -29,13 +29,14 @@ static void bs_init(struct msm_gpu *gpu, struct platform_device *pdev) { struct drm_device *dev = gpu->dev; - struct kgsl_device_platform_data *pdata = pdev->dev.platform_data; + struct kgsl_device_platform_data *pdata; if (!pdev) { dev_err(dev->dev, "could not find dtv pdata\n"); return; } + pdata = pdev->dev.platform_data; if (pdata->bus_scale_table) { gpu->bsc = msm_bus_scale_register_client(pdata->bus_scale_table); DBG("bus scale client: %08x", gpu->bsc); @@ -230,6 +231,8 @@ static void hangcheck_timer_reset(struct msm_gpu *gpu) static void hangcheck_handler(unsigned long data) { struct msm_gpu *gpu = (struct msm_gpu *)data; + struct drm_device *dev = gpu->dev; + struct msm_drm_private *priv = dev->dev_private; uint32_t fence = gpu->funcs->last_fence(gpu); if (fence != gpu->hangcheck_fence) { @@ -237,14 +240,22 @@ static void hangcheck_handler(unsigned long data) gpu->hangcheck_fence = fence; } else if (fence < gpu->submitted_fence) { /* no progress and not done.. hung! */ - struct msm_drm_private *priv = gpu->dev->dev_private; gpu->hangcheck_fence = fence; + dev_err(dev->dev, "%s: hangcheck detected gpu lockup!\n", + gpu->name); + dev_err(dev->dev, "%s: completed fence: %u\n", + gpu->name, fence); + dev_err(dev->dev, "%s: submitted fence: %u\n", + gpu->name, gpu->submitted_fence); queue_work(priv->wq, &gpu->recover_work); } /* if still more pending work, reset the hangcheck timer: */ if (gpu->submitted_fence > gpu->hangcheck_fence) hangcheck_timer_reset(gpu); + + /* workaround for missing irq: */ + queue_work(priv->wq, &gpu->retire_work); } /* @@ -265,7 +276,8 @@ static void retire_worker(struct work_struct *work) obj = list_first_entry(&gpu->active_list, struct msm_gem_object, mm_list); - if (obj->fence <= fence) { + if ((obj->read_fence <= fence) && + (obj->write_fence <= fence)) { /* move to inactive: */ msm_gem_move_to_inactive(&obj->base); msm_gem_put_iova(&obj->base, gpu->id); @@ -321,7 +333,11 @@ int msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, submit->gpu->id, &iova); } - msm_gem_move_to_active(&msm_obj->base, gpu, submit->fence); + if (submit->bos[i].flags & MSM_SUBMIT_BO_READ) + msm_gem_move_to_active(&msm_obj->base, gpu, false, submit->fence); + + if (submit->bos[i].flags & MSM_SUBMIT_BO_WRITE) + msm_gem_move_to_active(&msm_obj->base, gpu, true, submit->fence); } hangcheck_timer_reset(gpu); mutex_unlock(&dev->struct_mutex); diff --git a/drivers/gpu/drm/radeon/btc_dpm.c b/drivers/gpu/drm/radeon/btc_dpm.c index 05ff315e8e9e..b162e98a2953 100644 --- a/drivers/gpu/drm/radeon/btc_dpm.c +++ b/drivers/gpu/drm/radeon/btc_dpm.c @@ -1168,6 +1168,23 @@ static const struct radeon_blacklist_clocks btc_blacklist_clocks[] = { 25000, 30000, RADEON_SCLK_UP } }; +void btc_get_max_clock_from_voltage_dependency_table(struct radeon_clock_voltage_dependency_table *table, + u32 *max_clock) +{ + u32 i, clock = 0; + + if ((table == NULL) || (table->count == 0)) { + *max_clock = clock; + return; + } + + for (i = 0; i < table->count; i++) { + if (clock < table->entries[i].clk) + clock = table->entries[i].clk; + } + *max_clock = clock; +} + void btc_apply_voltage_dependency_rules(struct radeon_clock_voltage_dependency_table *table, u32 clock, u16 max_voltage, u16 *voltage) { @@ -2080,6 +2097,7 @@ static void btc_apply_state_adjust_rules(struct radeon_device *rdev, bool disable_mclk_switching; u32 mclk, sclk; u16 vddc, vddci; + u32 max_sclk_vddc, max_mclk_vddci, max_mclk_vddc; if ((rdev->pm.dpm.new_active_crtc_count > 1) || btc_dpm_vblank_too_short(rdev)) @@ -2121,6 +2139,39 @@ static void btc_apply_state_adjust_rules(struct radeon_device *rdev, ps->low.vddci = max_limits->vddci; } + /* limit clocks to max supported clocks based on voltage dependency tables */ + btc_get_max_clock_from_voltage_dependency_table(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk, + &max_sclk_vddc); + btc_get_max_clock_from_voltage_dependency_table(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk, + &max_mclk_vddci); + btc_get_max_clock_from_voltage_dependency_table(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk, + &max_mclk_vddc); + + if (max_sclk_vddc) { + if (ps->low.sclk > max_sclk_vddc) + ps->low.sclk = max_sclk_vddc; + if (ps->medium.sclk > max_sclk_vddc) + ps->medium.sclk = max_sclk_vddc; + if (ps->high.sclk > max_sclk_vddc) + ps->high.sclk = max_sclk_vddc; + } + if (max_mclk_vddci) { + if (ps->low.mclk > max_mclk_vddci) + ps->low.mclk = max_mclk_vddci; + if (ps->medium.mclk > max_mclk_vddci) + ps->medium.mclk = max_mclk_vddci; + if (ps->high.mclk > max_mclk_vddci) + ps->high.mclk = max_mclk_vddci; + } + if (max_mclk_vddc) { + if (ps->low.mclk > max_mclk_vddc) + ps->low.mclk = max_mclk_vddc; + if (ps->medium.mclk > max_mclk_vddc) + ps->medium.mclk = max_mclk_vddc; + if (ps->high.mclk > max_mclk_vddc) + ps->high.mclk = max_mclk_vddc; + } + /* XXX validate the min clocks required for display */ if (disable_mclk_switching) { diff --git a/drivers/gpu/drm/radeon/btc_dpm.h b/drivers/gpu/drm/radeon/btc_dpm.h index 1a15e0e41950..3b6f12b7760b 100644 --- a/drivers/gpu/drm/radeon/btc_dpm.h +++ b/drivers/gpu/drm/radeon/btc_dpm.h @@ -46,6 +46,8 @@ void btc_adjust_clock_combinations(struct radeon_device *rdev, struct rv7xx_pl *pl); void btc_apply_voltage_dependency_rules(struct radeon_clock_voltage_dependency_table *table, u32 clock, u16 max_voltage, u16 *voltage); +void btc_get_max_clock_from_voltage_dependency_table(struct radeon_clock_voltage_dependency_table *table, + u32 *max_clock); void btc_apply_voltage_delta_rules(struct radeon_device *rdev, u16 max_vddc, u16 max_vddci, u16 *vddc, u16 *vddci); diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c index 899627443030..51e947a97edf 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.c +++ b/drivers/gpu/drm/radeon/ci_dpm.c @@ -146,6 +146,8 @@ static const struct ci_pt_config_reg didt_config_ci[] = }; extern u8 rv770_get_memory_module_index(struct radeon_device *rdev); +extern void btc_get_max_clock_from_voltage_dependency_table(struct radeon_clock_voltage_dependency_table *table, + u32 *max_clock); extern int ni_copy_and_switch_arb_sets(struct radeon_device *rdev, u32 arb_freq_src, u32 arb_freq_dest); extern u8 si_get_ddr3_mclk_frequency_ratio(u32 memory_clock); @@ -712,6 +714,7 @@ static void ci_apply_state_adjust_rules(struct radeon_device *rdev, struct radeon_clock_and_voltage_limits *max_limits; bool disable_mclk_switching; u32 sclk, mclk; + u32 max_sclk_vddc, max_mclk_vddci, max_mclk_vddc; int i; if ((rdev->pm.dpm.new_active_crtc_count > 1) || @@ -739,6 +742,29 @@ static void ci_apply_state_adjust_rules(struct radeon_device *rdev, } } + /* limit clocks to max supported clocks based on voltage dependency tables */ + btc_get_max_clock_from_voltage_dependency_table(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk, + &max_sclk_vddc); + btc_get_max_clock_from_voltage_dependency_table(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk, + &max_mclk_vddci); + btc_get_max_clock_from_voltage_dependency_table(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk, + &max_mclk_vddc); + + for (i = 0; i < ps->performance_level_count; i++) { + if (max_sclk_vddc) { + if (ps->performance_levels[i].sclk > max_sclk_vddc) + ps->performance_levels[i].sclk = max_sclk_vddc; + } + if (max_mclk_vddci) { + if (ps->performance_levels[i].mclk > max_mclk_vddci) + ps->performance_levels[i].mclk = max_mclk_vddci; + } + if (max_mclk_vddc) { + if (ps->performance_levels[i].mclk > max_mclk_vddc) + ps->performance_levels[i].mclk = max_mclk_vddc; + } + } + /* XXX validate the min clocks required for display */ if (disable_mclk_switching) { diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index adbdb6503b05..d02fd1c045d5 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -2845,10 +2845,8 @@ static void cik_gpu_init(struct radeon_device *rdev) rdev->config.cik.tile_config |= (3 << 0); break; } - if ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) - rdev->config.cik.tile_config |= 1 << 4; - else - rdev->config.cik.tile_config |= 0 << 4; + rdev->config.cik.tile_config |= + ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) << 4; rdev->config.cik.tile_config |= ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8; rdev->config.cik.tile_config |= @@ -4456,8 +4454,8 @@ static int cik_mc_init(struct radeon_device *rdev) rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); /* size in MB on si */ - rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; - rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; + rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL; + rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL; rdev->mc.visible_vram_size = rdev->mc.aper_size; si_vram_gtt_location(rdev, &rdev->mc); radeon_update_bandwidth_info(rdev); @@ -4735,12 +4733,13 @@ static void cik_vm_decode_fault(struct radeon_device *rdev, u32 mc_id = (status & MEMORY_CLIENT_ID_MASK) >> MEMORY_CLIENT_ID_SHIFT; u32 vmid = (status & FAULT_VMID_MASK) >> FAULT_VMID_SHIFT; u32 protections = (status & PROTECTIONS_MASK) >> PROTECTIONS_SHIFT; - char *block = (char *)&mc_client; + char block[5] = { mc_client >> 24, (mc_client >> 16) & 0xff, + (mc_client >> 8) & 0xff, mc_client & 0xff, 0 }; - printk("VM fault (0x%02x, vmid %d) at page %u, %s from %s (%d)\n", + printk("VM fault (0x%02x, vmid %d) at page %u, %s from '%s' (0x%08x) (%d)\n", protections, vmid, addr, (status & MEMORY_CLIENT_RW_MASK) ? "write" : "read", - block, mc_id); + block, mc_client, mc_id); } /** diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c index 6c398a456d78..f26339028154 100644 --- a/drivers/gpu/drm/radeon/ni_dpm.c +++ b/drivers/gpu/drm/radeon/ni_dpm.c @@ -787,6 +787,7 @@ static void ni_apply_state_adjust_rules(struct radeon_device *rdev, bool disable_mclk_switching; u32 mclk, sclk; u16 vddc, vddci; + u32 max_sclk_vddc, max_mclk_vddci, max_mclk_vddc; int i; if ((rdev->pm.dpm.new_active_crtc_count > 1) || @@ -813,6 +814,29 @@ static void ni_apply_state_adjust_rules(struct radeon_device *rdev, } } + /* limit clocks to max supported clocks based on voltage dependency tables */ + btc_get_max_clock_from_voltage_dependency_table(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk, + &max_sclk_vddc); + btc_get_max_clock_from_voltage_dependency_table(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk, + &max_mclk_vddci); + btc_get_max_clock_from_voltage_dependency_table(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk, + &max_mclk_vddc); + + for (i = 0; i < ps->performance_level_count; i++) { + if (max_sclk_vddc) { + if (ps->performance_levels[i].sclk > max_sclk_vddc) + ps->performance_levels[i].sclk = max_sclk_vddc; + } + if (max_mclk_vddci) { + if (ps->performance_levels[i].mclk > max_mclk_vddci) + ps->performance_levels[i].mclk = max_mclk_vddci; + } + if (max_mclk_vddc) { + if (ps->performance_levels[i].mclk > max_mclk_vddc) + ps->performance_levels[i].mclk = max_mclk_vddc; + } + } + /* XXX validate the min clocks required for display */ if (disable_mclk_switching) { diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 24175717307b..d71333033b2b 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -2933,9 +2933,11 @@ static int r100_debugfs_cp_ring_info(struct seq_file *m, void *data) seq_printf(m, "CP_RB_RPTR 0x%08x\n", rdp); seq_printf(m, "%u free dwords in ring\n", ring->ring_free_dw); seq_printf(m, "%u dwords in ring\n", count); - for (j = 0; j <= count; j++) { - i = (rdp + j) & ring->ptr_mask; - seq_printf(m, "r[%04d]=0x%08x\n", i, ring->ring[i]); + if (ring->ready) { + for (j = 0; j <= count; j++) { + i = (rdp + j) & ring->ptr_mask; + seq_printf(m, "r[%04d]=0x%08x\n", i, ring->ring[i]); + } } return 0; } diff --git a/drivers/gpu/drm/radeon/r600_dpm.c b/drivers/gpu/drm/radeon/r600_dpm.c index e65f211a7be0..5513d8f06252 100644 --- a/drivers/gpu/drm/radeon/r600_dpm.c +++ b/drivers/gpu/drm/radeon/r600_dpm.c @@ -1084,7 +1084,7 @@ int r600_parse_extended_power_table(struct radeon_device *rdev) rdev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries[i].dclk = le16_to_cpu(uvd_clk->usDClkLow) | (uvd_clk->ucDClkHigh << 16); rdev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries[i].v = - le16_to_cpu(limits->entries[i].usVoltage); + le16_to_cpu(entry->usVoltage); entry = (ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record *) ((u8 *)entry + sizeof(ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record)); } diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index f443010ce90b..b0fa6002af3e 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c @@ -257,10 +257,7 @@ void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock) * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator */ - if (ASIC_IS_DCE3(rdev)) { - /* according to the reg specs, this should DCE3.2 only, but in - * practice it seems to cover DCE3.0 as well. - */ + if (ASIC_IS_DCE32(rdev)) { if (dig->dig_encoder == 0) { dto_cntl = RREG32(DCCG_AUDIO_DTO0_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK; dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio); @@ -276,8 +273,21 @@ void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock) WREG32(DCCG_AUDIO_DTO1_MODULE, dto_modulo); WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */ } + } else if (ASIC_IS_DCE3(rdev)) { + /* according to the reg specs, this should DCE3.2 only, but in + * practice it seems to cover DCE3.0/3.1 as well. + */ + if (dig->dig_encoder == 0) { + WREG32(DCCG_AUDIO_DTO0_PHASE, base_rate * 100); + WREG32(DCCG_AUDIO_DTO0_MODULE, clock * 100); + WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */ + } else { + WREG32(DCCG_AUDIO_DTO1_PHASE, base_rate * 100); + WREG32(DCCG_AUDIO_DTO1_MODULE, clock * 100); + WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */ + } } else { - /* according to the reg specs, this should be DCE2.0 and DCE3.0 */ + /* according to the reg specs, this should be DCE2.0 and DCE3.0/3.1 */ WREG32(AUDIO_DTO, AUDIO_DTO_PHASE(base_rate / 10) | AUDIO_DTO_MODULE(clock / 10)); } diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 5003385a7512..8f7e04538fd6 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -1004,6 +1004,8 @@ static struct radeon_asic rv6xx_asic = { .wait_for_vblank = &avivo_wait_for_vblank, .set_backlight_level = &atombios_set_backlight_level, .get_backlight_level = &atombios_get_backlight_level, + .hdmi_enable = &r600_hdmi_enable, + .hdmi_setmode = &r600_hdmi_setmode, }, .copy = { .blit = &r600_copy_cpdma, diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 404e25d285ba..f79ee184ffd5 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -1367,6 +1367,7 @@ bool radeon_atombios_get_ppll_ss_info(struct radeon_device *rdev, int index = GetIndexIntoMasterTable(DATA, PPLL_SS_Info); uint16_t data_offset, size; struct _ATOM_SPREAD_SPECTRUM_INFO *ss_info; + struct _ATOM_SPREAD_SPECTRUM_ASSIGNMENT *ss_assign; uint8_t frev, crev; int i, num_indices; @@ -1378,18 +1379,21 @@ bool radeon_atombios_get_ppll_ss_info(struct radeon_device *rdev, num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / sizeof(ATOM_SPREAD_SPECTRUM_ASSIGNMENT); - + ss_assign = (struct _ATOM_SPREAD_SPECTRUM_ASSIGNMENT*) + ((u8 *)&ss_info->asSS_Info[0]); for (i = 0; i < num_indices; i++) { - if (ss_info->asSS_Info[i].ucSS_Id == id) { + if (ss_assign->ucSS_Id == id) { ss->percentage = - le16_to_cpu(ss_info->asSS_Info[i].usSpreadSpectrumPercentage); - ss->type = ss_info->asSS_Info[i].ucSpreadSpectrumType; - ss->step = ss_info->asSS_Info[i].ucSS_Step; - ss->delay = ss_info->asSS_Info[i].ucSS_Delay; - ss->range = ss_info->asSS_Info[i].ucSS_Range; - ss->refdiv = ss_info->asSS_Info[i].ucRecommendedRef_Div; + le16_to_cpu(ss_assign->usSpreadSpectrumPercentage); + ss->type = ss_assign->ucSpreadSpectrumType; + ss->step = ss_assign->ucSS_Step; + ss->delay = ss_assign->ucSS_Delay; + ss->range = ss_assign->ucSS_Range; + ss->refdiv = ss_assign->ucRecommendedRef_Div; return true; } + ss_assign = (struct _ATOM_SPREAD_SPECTRUM_ASSIGNMENT*) + ((u8 *)ss_assign + sizeof(struct _ATOM_SPREAD_SPECTRUM_ASSIGNMENT)); } } return false; @@ -1477,6 +1481,12 @@ union asic_ss_info { struct _ATOM_ASIC_INTERNAL_SS_INFO_V3 info_3; }; +union asic_ss_assignment { + struct _ATOM_ASIC_SS_ASSIGNMENT v1; + struct _ATOM_ASIC_SS_ASSIGNMENT_V2 v2; + struct _ATOM_ASIC_SS_ASSIGNMENT_V3 v3; +}; + bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev, struct radeon_atom_ss *ss, int id, u32 clock) @@ -1485,6 +1495,7 @@ bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev, int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info); uint16_t data_offset, size; union asic_ss_info *ss_info; + union asic_ss_assignment *ss_assign; uint8_t frev, crev; int i, num_indices; @@ -1509,45 +1520,52 @@ bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev, num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / sizeof(ATOM_ASIC_SS_ASSIGNMENT); + ss_assign = (union asic_ss_assignment *)((u8 *)&ss_info->info.asSpreadSpectrum[0]); for (i = 0; i < num_indices; i++) { - if ((ss_info->info.asSpreadSpectrum[i].ucClockIndication == id) && - (clock <= le32_to_cpu(ss_info->info.asSpreadSpectrum[i].ulTargetClockRange))) { + if ((ss_assign->v1.ucClockIndication == id) && + (clock <= le32_to_cpu(ss_assign->v1.ulTargetClockRange))) { ss->percentage = - le16_to_cpu(ss_info->info.asSpreadSpectrum[i].usSpreadSpectrumPercentage); - ss->type = ss_info->info.asSpreadSpectrum[i].ucSpreadSpectrumMode; - ss->rate = le16_to_cpu(ss_info->info.asSpreadSpectrum[i].usSpreadRateInKhz); + le16_to_cpu(ss_assign->v1.usSpreadSpectrumPercentage); + ss->type = ss_assign->v1.ucSpreadSpectrumMode; + ss->rate = le16_to_cpu(ss_assign->v1.usSpreadRateInKhz); return true; } + ss_assign = (union asic_ss_assignment *) + ((u8 *)ss_assign + sizeof(ATOM_ASIC_SS_ASSIGNMENT)); } break; case 2: num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / sizeof(ATOM_ASIC_SS_ASSIGNMENT_V2); + ss_assign = (union asic_ss_assignment *)((u8 *)&ss_info->info_2.asSpreadSpectrum[0]); for (i = 0; i < num_indices; i++) { - if ((ss_info->info_2.asSpreadSpectrum[i].ucClockIndication == id) && - (clock <= le32_to_cpu(ss_info->info_2.asSpreadSpectrum[i].ulTargetClockRange))) { + if ((ss_assign->v2.ucClockIndication == id) && + (clock <= le32_to_cpu(ss_assign->v2.ulTargetClockRange))) { ss->percentage = - le16_to_cpu(ss_info->info_2.asSpreadSpectrum[i].usSpreadSpectrumPercentage); - ss->type = ss_info->info_2.asSpreadSpectrum[i].ucSpreadSpectrumMode; - ss->rate = le16_to_cpu(ss_info->info_2.asSpreadSpectrum[i].usSpreadRateIn10Hz); + le16_to_cpu(ss_assign->v2.usSpreadSpectrumPercentage); + ss->type = ss_assign->v2.ucSpreadSpectrumMode; + ss->rate = le16_to_cpu(ss_assign->v2.usSpreadRateIn10Hz); if ((crev == 2) && ((id == ASIC_INTERNAL_ENGINE_SS) || (id == ASIC_INTERNAL_MEMORY_SS))) ss->rate /= 100; return true; } + ss_assign = (union asic_ss_assignment *) + ((u8 *)ss_assign + sizeof(ATOM_ASIC_SS_ASSIGNMENT_V2)); } break; case 3: num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / sizeof(ATOM_ASIC_SS_ASSIGNMENT_V3); + ss_assign = (union asic_ss_assignment *)((u8 *)&ss_info->info_3.asSpreadSpectrum[0]); for (i = 0; i < num_indices; i++) { - if ((ss_info->info_3.asSpreadSpectrum[i].ucClockIndication == id) && - (clock <= le32_to_cpu(ss_info->info_3.asSpreadSpectrum[i].ulTargetClockRange))) { + if ((ss_assign->v3.ucClockIndication == id) && + (clock <= le32_to_cpu(ss_assign->v3.ulTargetClockRange))) { ss->percentage = - le16_to_cpu(ss_info->info_3.asSpreadSpectrum[i].usSpreadSpectrumPercentage); - ss->type = ss_info->info_3.asSpreadSpectrum[i].ucSpreadSpectrumMode; - ss->rate = le16_to_cpu(ss_info->info_3.asSpreadSpectrum[i].usSpreadRateIn10Hz); + le16_to_cpu(ss_assign->v3.usSpreadSpectrumPercentage); + ss->type = ss_assign->v3.ucSpreadSpectrumMode; + ss->rate = le16_to_cpu(ss_assign->v3.usSpreadRateIn10Hz); if ((id == ASIC_INTERNAL_ENGINE_SS) || (id == ASIC_INTERNAL_MEMORY_SS)) ss->rate /= 100; @@ -1555,6 +1573,8 @@ bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev, radeon_atombios_get_igp_ss_overrides(rdev, ss, id); return true; } + ss_assign = (union asic_ss_assignment *) + ((u8 *)ss_assign + sizeof(ATOM_ASIC_SS_ASSIGNMENT_V3)); } break; default: diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index ac6ece61a476..66c222836631 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -85,8 +85,9 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p) VRAM, also but everything into VRAM on AGP cards to avoid image corruptions */ if (p->ring == R600_RING_TYPE_UVD_INDEX && - (i == 0 || p->rdev->flags & RADEON_IS_AGP)) { - /* TODO: is this still needed for NI+ ? */ + p->rdev->family < CHIP_PALM && + (i == 0 || drm_pci_device_is_agp(p->rdev->ddev))) { + p->relocs[i].lobj.domain = RADEON_GEM_DOMAIN_VRAM; diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index e29faa73b574..841d0e09be3e 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -1320,13 +1320,22 @@ int radeon_device_init(struct radeon_device *rdev, return r; } if ((radeon_testing & 1)) { - radeon_test_moves(rdev); + if (rdev->accel_working) + radeon_test_moves(rdev); + else + DRM_INFO("radeon: acceleration disabled, skipping move tests\n"); } if ((radeon_testing & 2)) { - radeon_test_syncing(rdev); + if (rdev->accel_working) + radeon_test_syncing(rdev); + else + DRM_INFO("radeon: acceleration disabled, skipping sync tests\n"); } if (radeon_benchmarking) { - radeon_benchmark(rdev, radeon_benchmarking); + if (rdev->accel_working) + radeon_benchmark(rdev, radeon_benchmarking); + else + DRM_INFO("radeon: acceleration disabled, skipping benchmarks\n"); } return 0; } diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 87e1d69e8fdb..ac07ad1d4f8c 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -1002,7 +1002,7 @@ static void radeon_pm_resume_old(struct radeon_device *rdev) { /* set up the default clocks if the MC ucode is loaded */ if ((rdev->family >= CHIP_BARTS) && - (rdev->family <= CHIP_HAINAN) && + (rdev->family <= CHIP_CAYMAN) && rdev->mc_fw) { if (rdev->pm.default_vddc) radeon_atom_set_voltage(rdev, rdev->pm.default_vddc, @@ -1046,7 +1046,7 @@ static void radeon_pm_resume_dpm(struct radeon_device *rdev) if (ret) { DRM_ERROR("radeon: dpm resume failed\n"); if ((rdev->family >= CHIP_BARTS) && - (rdev->family <= CHIP_HAINAN) && + (rdev->family <= CHIP_CAYMAN) && rdev->mc_fw) { if (rdev->pm.default_vddc) radeon_atom_set_voltage(rdev, rdev->pm.default_vddc, @@ -1097,7 +1097,7 @@ static int radeon_pm_init_old(struct radeon_device *rdev) radeon_pm_init_profile(rdev); /* set up the default clocks if the MC ucode is loaded */ if ((rdev->family >= CHIP_BARTS) && - (rdev->family <= CHIP_HAINAN) && + (rdev->family <= CHIP_CAYMAN) && rdev->mc_fw) { if (rdev->pm.default_vddc) radeon_atom_set_voltage(rdev, rdev->pm.default_vddc, @@ -1183,7 +1183,7 @@ static int radeon_pm_init_dpm(struct radeon_device *rdev) if (ret) { rdev->pm.dpm_enabled = false; if ((rdev->family >= CHIP_BARTS) && - (rdev->family <= CHIP_HAINAN) && + (rdev->family <= CHIP_CAYMAN) && rdev->mc_fw) { if (rdev->pm.default_vddc) radeon_atom_set_voltage(rdev, rdev->pm.default_vddc, diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index 46a25f037b84..18254e1c3e71 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c @@ -839,9 +839,11 @@ static int radeon_debugfs_ring_info(struct seq_file *m, void *data) * packet that is the root issue */ i = (ring->rptr + ring->ptr_mask + 1 - 32) & ring->ptr_mask; - for (j = 0; j <= (count + 32); j++) { - seq_printf(m, "r[%5d]=0x%08x\n", i, ring->ring[i]); - i = (i + 1) & ring->ptr_mask; + if (ring->ready) { + for (j = 0; j <= (count + 32); j++) { + seq_printf(m, "r[%5d]=0x%08x\n", i, ring->ring[i]); + i = (i + 1) & ring->ptr_mask; + } } return 0; } diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index 1a01bbff9bfa..a0f11856ddde 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c @@ -476,8 +476,7 @@ static int radeon_uvd_cs_reloc(struct radeon_cs_parser *p, return -EINVAL; } - /* TODO: is this still necessary on NI+ ? */ - if ((cmd == 0 || cmd == 0x3) && + if (p->rdev->family < CHIP_PALM && (cmd == 0 || cmd == 0x3) && (start >> 28) != (p->rdev->uvd.gpu_addr >> 28)) { DRM_ERROR("msg/fb buffer %LX-%LX out of 256MB segment!\n", start, end); diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index cfe5d4d28915..9ace28702c76 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c @@ -2910,6 +2910,7 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev, bool disable_sclk_switching = false; u32 mclk, sclk; u16 vddc, vddci; + u32 max_sclk_vddc, max_mclk_vddci, max_mclk_vddc; int i; if ((rdev->pm.dpm.new_active_crtc_count > 1) || @@ -2943,6 +2944,29 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev, } } + /* limit clocks to max supported clocks based on voltage dependency tables */ + btc_get_max_clock_from_voltage_dependency_table(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk, + &max_sclk_vddc); + btc_get_max_clock_from_voltage_dependency_table(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk, + &max_mclk_vddci); + btc_get_max_clock_from_voltage_dependency_table(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk, + &max_mclk_vddc); + + for (i = 0; i < ps->performance_level_count; i++) { + if (max_sclk_vddc) { + if (ps->performance_levels[i].sclk > max_sclk_vddc) + ps->performance_levels[i].sclk = max_sclk_vddc; + } + if (max_mclk_vddci) { + if (ps->performance_levels[i].mclk > max_mclk_vddci) + ps->performance_levels[i].mclk = max_mclk_vddci; + } + if (max_mclk_vddc) { + if (ps->performance_levels[i].mclk > max_mclk_vddc) + ps->performance_levels[i].mclk = max_mclk_vddc; + } + } + /* XXX validate the min clocks required for display */ if (disable_mclk_switching) { diff --git a/drivers/gpu/drm/radeon/uvd_v1_0.c b/drivers/gpu/drm/radeon/uvd_v1_0.c index 7266805d9786..3100fa9cb52f 100644 --- a/drivers/gpu/drm/radeon/uvd_v1_0.c +++ b/drivers/gpu/drm/radeon/uvd_v1_0.c @@ -212,8 +212,8 @@ int uvd_v1_0_start(struct radeon_device *rdev) /* enable VCPU clock */ WREG32(UVD_VCPU_CNTL, 1 << 9); - /* enable UMC */ - WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8)); + /* enable UMC and NC0 */ + WREG32_P(UVD_LMI_CTRL2, 1 << 13, ~((1 << 8) | (1 << 13))); /* boot up the VCPU */ WREG32(UVD_SOFT_RESET, 0); diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c index 8f4743ab5fb2..936093e0271e 100644 --- a/drivers/hv/connection.c +++ b/drivers/hv/connection.c @@ -195,7 +195,7 @@ int vmbus_connect(void) do { ret = vmbus_negotiate_version(msginfo, version); - if (ret) + if (ret == -ETIMEDOUT) goto cleanup; if (vmbus_connection.conn_state == CONNECTED) diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c index 28b03325b872..09988b289622 100644 --- a/drivers/hv/hv_kvp.c +++ b/drivers/hv/hv_kvp.c @@ -32,13 +32,17 @@ /* * Pre win8 version numbers used in ws2008 and ws 2008 r2 (win7) */ +#define WS2008_SRV_MAJOR 1 +#define WS2008_SRV_MINOR 0 +#define WS2008_SRV_VERSION (WS2008_SRV_MAJOR << 16 | WS2008_SRV_MINOR) + #define WIN7_SRV_MAJOR 3 #define WIN7_SRV_MINOR 0 -#define WIN7_SRV_MAJOR_MINOR (WIN7_SRV_MAJOR << 16 | WIN7_SRV_MINOR) +#define WIN7_SRV_VERSION (WIN7_SRV_MAJOR << 16 | WIN7_SRV_MINOR) #define WIN8_SRV_MAJOR 4 #define WIN8_SRV_MINOR 0 -#define WIN8_SRV_MAJOR_MINOR (WIN8_SRV_MAJOR << 16 | WIN8_SRV_MINOR) +#define WIN8_SRV_VERSION (WIN8_SRV_MAJOR << 16 | WIN8_SRV_MINOR) /* * Global state maintained for transaction that is being processed. @@ -587,6 +591,8 @@ void hv_kvp_onchannelcallback(void *context) struct icmsg_hdr *icmsghdrp; struct icmsg_negotiate *negop = NULL; + int util_fw_version; + int kvp_srv_version; if (kvp_transaction.active) { /* @@ -606,17 +612,26 @@ void hv_kvp_onchannelcallback(void *context) if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { /* - * We start with win8 version and if the host cannot - * support that we use the previous version. + * Based on the host, select appropriate + * framework and service versions we will + * negotiate. */ - if (vmbus_prep_negotiate_resp(icmsghdrp, negop, - recv_buffer, UTIL_FW_MAJOR_MINOR, - WIN8_SRV_MAJOR_MINOR)) - goto done; - + switch (vmbus_proto_version) { + case (VERSION_WS2008): + util_fw_version = UTIL_WS2K8_FW_VERSION; + kvp_srv_version = WS2008_SRV_VERSION; + break; + case (VERSION_WIN7): + util_fw_version = UTIL_FW_VERSION; + kvp_srv_version = WIN7_SRV_VERSION; + break; + default: + util_fw_version = UTIL_FW_VERSION; + kvp_srv_version = WIN8_SRV_VERSION; + } vmbus_prep_negotiate_resp(icmsghdrp, negop, - recv_buffer, UTIL_FW_MAJOR_MINOR, - WIN7_SRV_MAJOR_MINOR); + recv_buffer, util_fw_version, + kvp_srv_version); } else { kvp_msg = (struct hv_kvp_msg *)&recv_buffer[ @@ -649,7 +664,6 @@ void hv_kvp_onchannelcallback(void *context) return; } -done: icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION | ICMSGHDRFLAG_RESPONSE; diff --git a/drivers/hv/hv_snapshot.c b/drivers/hv/hv_snapshot.c index e4572f3f2834..0c3546224376 100644 --- a/drivers/hv/hv_snapshot.c +++ b/drivers/hv/hv_snapshot.c @@ -26,7 +26,7 @@ #define VSS_MAJOR 5 #define VSS_MINOR 0 -#define VSS_MAJOR_MINOR (VSS_MAJOR << 16 | VSS_MINOR) +#define VSS_VERSION (VSS_MAJOR << 16 | VSS_MINOR) @@ -190,8 +190,8 @@ void hv_vss_onchannelcallback(void *context) if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { vmbus_prep_negotiate_resp(icmsghdrp, negop, - recv_buffer, UTIL_FW_MAJOR_MINOR, - VSS_MAJOR_MINOR); + recv_buffer, UTIL_FW_VERSION, + VSS_VERSION); } else { vss_msg = (struct hv_vss_msg *)&recv_buffer[ sizeof(struct vmbuspipe_hdr) + diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c index cb82233541b1..273e3ddb3a20 100644 --- a/drivers/hv/hv_util.c +++ b/drivers/hv/hv_util.c @@ -28,17 +28,32 @@ #include <linux/reboot.h> #include <linux/hyperv.h> -#define SHUTDOWN_MAJOR 3 -#define SHUTDOWN_MINOR 0 -#define SHUTDOWN_MAJOR_MINOR (SHUTDOWN_MAJOR << 16 | SHUTDOWN_MINOR) -#define TIMESYNCH_MAJOR 3 -#define TIMESYNCH_MINOR 0 -#define TIMESYNCH_MAJOR_MINOR (TIMESYNCH_MAJOR << 16 | TIMESYNCH_MINOR) +#define SD_MAJOR 3 +#define SD_MINOR 0 +#define SD_VERSION (SD_MAJOR << 16 | SD_MINOR) -#define HEARTBEAT_MAJOR 3 -#define HEARTBEAT_MINOR 0 -#define HEARTBEAT_MAJOR_MINOR (HEARTBEAT_MAJOR << 16 | HEARTBEAT_MINOR) +#define SD_WS2008_MAJOR 1 +#define SD_WS2008_VERSION (SD_WS2008_MAJOR << 16 | SD_MINOR) + +#define TS_MAJOR 3 +#define TS_MINOR 0 +#define TS_VERSION (TS_MAJOR << 16 | TS_MINOR) + +#define TS_WS2008_MAJOR 1 +#define TS_WS2008_VERSION (TS_WS2008_MAJOR << 16 | TS_MINOR) + +#define HB_MAJOR 3 +#define HB_MINOR 0 +#define HB_VERSION (HB_MAJOR << 16 | HB_MINOR) + +#define HB_WS2008_MAJOR 1 +#define HB_WS2008_VERSION (HB_WS2008_MAJOR << 16 | HB_MINOR) + +static int sd_srv_version; +static int ts_srv_version; +static int hb_srv_version; +static int util_fw_version; static void shutdown_onchannelcallback(void *context); static struct hv_util_service util_shutdown = { @@ -99,8 +114,8 @@ static void shutdown_onchannelcallback(void *context) if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { vmbus_prep_negotiate_resp(icmsghdrp, negop, - shut_txf_buf, UTIL_FW_MAJOR_MINOR, - SHUTDOWN_MAJOR_MINOR); + shut_txf_buf, util_fw_version, + sd_srv_version); } else { shutdown_msg = (struct shutdown_msg_data *)&shut_txf_buf[ @@ -216,6 +231,7 @@ static void timesync_onchannelcallback(void *context) struct icmsg_hdr *icmsghdrp; struct ictimesync_data *timedatap; u8 *time_txf_buf = util_timesynch.recv_buffer; + struct icmsg_negotiate *negop = NULL; vmbus_recvpacket(channel, time_txf_buf, PAGE_SIZE, &recvlen, &requestid); @@ -225,9 +241,10 @@ static void timesync_onchannelcallback(void *context) sizeof(struct vmbuspipe_hdr)]; if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { - vmbus_prep_negotiate_resp(icmsghdrp, NULL, time_txf_buf, - UTIL_FW_MAJOR_MINOR, - TIMESYNCH_MAJOR_MINOR); + vmbus_prep_negotiate_resp(icmsghdrp, negop, + time_txf_buf, + util_fw_version, + ts_srv_version); } else { timedatap = (struct ictimesync_data *)&time_txf_buf[ sizeof(struct vmbuspipe_hdr) + @@ -257,6 +274,7 @@ static void heartbeat_onchannelcallback(void *context) struct icmsg_hdr *icmsghdrp; struct heartbeat_msg_data *heartbeat_msg; u8 *hbeat_txf_buf = util_heartbeat.recv_buffer; + struct icmsg_negotiate *negop = NULL; vmbus_recvpacket(channel, hbeat_txf_buf, PAGE_SIZE, &recvlen, &requestid); @@ -266,9 +284,9 @@ static void heartbeat_onchannelcallback(void *context) sizeof(struct vmbuspipe_hdr)]; if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { - vmbus_prep_negotiate_resp(icmsghdrp, NULL, - hbeat_txf_buf, UTIL_FW_MAJOR_MINOR, - HEARTBEAT_MAJOR_MINOR); + vmbus_prep_negotiate_resp(icmsghdrp, negop, + hbeat_txf_buf, util_fw_version, + hb_srv_version); } else { heartbeat_msg = (struct heartbeat_msg_data *)&hbeat_txf_buf[ @@ -321,6 +339,25 @@ static int util_probe(struct hv_device *dev, goto error; hv_set_drvdata(dev, srv); + /* + * Based on the host; initialize the framework and + * service version numbers we will negotiate. + */ + switch (vmbus_proto_version) { + case (VERSION_WS2008): + util_fw_version = UTIL_WS2K8_FW_VERSION; + sd_srv_version = SD_WS2008_VERSION; + ts_srv_version = TS_WS2008_VERSION; + hb_srv_version = HB_WS2008_VERSION; + break; + + default: + util_fw_version = UTIL_FW_VERSION; + sd_srv_version = SD_VERSION; + ts_srv_version = TS_VERSION; + hb_srv_version = HB_VERSION; + } + return 0; error: diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index 62c2e32e25ef..98814d12a604 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c @@ -525,16 +525,25 @@ static int applesmc_init_smcreg_try(void) { struct applesmc_registers *s = &smcreg; bool left_light_sensor, right_light_sensor; + unsigned int count; u8 tmp[1]; int ret; if (s->init_complete) return 0; - ret = read_register_count(&s->key_count); + ret = read_register_count(&count); if (ret) return ret; + if (s->cache && s->key_count != count) { + pr_warn("key count changed from %d to %d\n", + s->key_count, count); + kfree(s->cache); + s->cache = NULL; + } + s->key_count = count; + if (!s->cache) s->cache = kcalloc(s->key_count, sizeof(*s->cache), GFP_KERNEL); if (!s->cache) diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c index dbecf08399f8..5888feef1ac5 100644 --- a/drivers/i2c/busses/i2c-designware-core.c +++ b/drivers/i2c/busses/i2c-designware-core.c @@ -98,6 +98,8 @@ #define DW_IC_ERR_TX_ABRT 0x1 +#define DW_IC_TAR_10BITADDR_MASTER BIT(12) + /* * status codes */ @@ -388,22 +390,34 @@ static int i2c_dw_wait_bus_not_busy(struct dw_i2c_dev *dev) static void i2c_dw_xfer_init(struct dw_i2c_dev *dev) { struct i2c_msg *msgs = dev->msgs; - u32 ic_con; + u32 ic_con, ic_tar = 0; /* Disable the adapter */ __i2c_dw_enable(dev, false); - /* set the slave (target) address */ - dw_writel(dev, msgs[dev->msg_write_idx].addr, DW_IC_TAR); - /* if the slave address is ten bit address, enable 10BITADDR */ ic_con = dw_readl(dev, DW_IC_CON); - if (msgs[dev->msg_write_idx].flags & I2C_M_TEN) + if (msgs[dev->msg_write_idx].flags & I2C_M_TEN) { ic_con |= DW_IC_CON_10BITADDR_MASTER; - else + /* + * If I2C_DYNAMIC_TAR_UPDATE is set, the 10-bit addressing + * mode has to be enabled via bit 12 of IC_TAR register. + * We set it always as I2C_DYNAMIC_TAR_UPDATE can't be + * detected from registers. + */ + ic_tar = DW_IC_TAR_10BITADDR_MASTER; + } else { ic_con &= ~DW_IC_CON_10BITADDR_MASTER; + } + dw_writel(dev, ic_con, DW_IC_CON); + /* + * Set the slave (target) address and enable 10-bit addressing mode + * if applicable. + */ + dw_writel(dev, msgs[dev->msg_write_idx].addr | ic_tar, DW_IC_TAR); + /* Enable the adapter */ __i2c_dw_enable(dev, true); diff --git a/drivers/i2c/busses/i2c-ismt.c b/drivers/i2c/busses/i2c-ismt.c index 8ed79a086f85..1672effbcebb 100644 --- a/drivers/i2c/busses/i2c-ismt.c +++ b/drivers/i2c/busses/i2c-ismt.c @@ -393,6 +393,9 @@ static int ismt_access(struct i2c_adapter *adap, u16 addr, desc = &priv->hw[priv->head]; + /* Initialize the DMA buffer */ + memset(priv->dma_buffer, 0, sizeof(priv->dma_buffer)); + /* Initialize the descriptor */ memset(desc, 0, sizeof(struct ismt_desc)); desc->tgtaddr_rw = ISMT_DESC_ADDR_RW(addr, read_write); diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c index 7f3a47443494..d3e9cc3153a9 100644 --- a/drivers/i2c/busses/i2c-mv64xxx.c +++ b/drivers/i2c/busses/i2c-mv64xxx.c @@ -234,9 +234,9 @@ static int mv64xxx_i2c_offload_msg(struct mv64xxx_i2c_data *drv_data) ctrl_reg |= MV64XXX_I2C_BRIDGE_CONTROL_WR | (msg->len - 1) << MV64XXX_I2C_BRIDGE_CONTROL_TX_SIZE_SHIFT; - writel_relaxed(data_reg_lo, + writel(data_reg_lo, drv_data->reg_base + MV64XXX_I2C_REG_TX_DATA_LO); - writel_relaxed(data_reg_hi, + writel(data_reg_hi, drv_data->reg_base + MV64XXX_I2C_REG_TX_DATA_HI); } else { @@ -697,6 +697,7 @@ static const struct of_device_id mv64xxx_i2c_of_match_table[] = { MODULE_DEVICE_TABLE(of, mv64xxx_i2c_of_match_table); #ifdef CONFIG_OF +#ifdef CONFIG_HAVE_CLK static int mv64xxx_calc_freq(const int tclk, const int n, const int m) { @@ -726,16 +727,12 @@ mv64xxx_find_baud_factors(const u32 req_freq, const u32 tclk, u32 *best_n, return false; return true; } +#endif /* CONFIG_HAVE_CLK */ static int mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data, struct device *dev) { - const struct of_device_id *device; - struct device_node *np = dev->of_node; - u32 bus_freq, tclk; - int rc = 0; - /* CLK is mandatory when using DT to describe the i2c bus. We * need to know tclk in order to calculate bus clock * factors. @@ -744,6 +741,11 @@ mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data, /* Have OF but no CLK */ return -ENODEV; #else + const struct of_device_id *device; + struct device_node *np = dev->of_node; + u32 bus_freq, tclk; + int rc = 0; + if (IS_ERR(drv_data->clk)) { rc = -ENODEV; goto out; diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index 3535f3c0f7b4..3747b9bf67d6 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c @@ -1178,8 +1178,6 @@ static int s3c24xx_i2c_remove(struct platform_device *pdev) i2c_del_adapter(&i2c->adap); - clk_disable_unprepare(i2c->clk); - if (pdev->dev.of_node && IS_ERR(i2c->pctrl)) s3c24xx_i2c_dt_gpio_free(i2c); diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c index 12e32e6b4103..81e3dc260993 100644 --- a/drivers/iio/accel/bma180.c +++ b/drivers/iio/accel/bma180.c @@ -620,7 +620,7 @@ static int bma180_remove(struct i2c_client *client) #ifdef CONFIG_PM_SLEEP static int bma180_suspend(struct device *dev) { - struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); struct bma180_data *data = iio_priv(indio_dev); int ret; @@ -633,7 +633,7 @@ static int bma180_suspend(struct device *dev) static int bma180_resume(struct device *dev) { - struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); struct bma180_data *data = iio_priv(indio_dev); int ret; diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index 84be63bdf038..0f16b553e063 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c @@ -556,7 +556,7 @@ static const struct iio_info at91_adc_info = { static int at91_adc_probe(struct platform_device *pdev) { - unsigned int prsc, mstrclk, ticks, adc_clk, shtim; + unsigned int prsc, mstrclk, ticks, adc_clk, adc_clk_khz, shtim; int ret; struct iio_dev *idev; struct at91_adc_state *st; @@ -649,6 +649,7 @@ static int at91_adc_probe(struct platform_device *pdev) */ mstrclk = clk_get_rate(st->clk); adc_clk = clk_get_rate(st->adc_clk); + adc_clk_khz = adc_clk / 1000; prsc = (mstrclk / (2 * adc_clk)) - 1; if (!st->startup_time) { @@ -662,15 +663,15 @@ static int at91_adc_probe(struct platform_device *pdev) * defined in the electrical characteristics of the board, divided by 8. * The formula thus is : Startup Time = (ticks + 1) * 8 / ADC Clock */ - ticks = round_up((st->startup_time * adc_clk / - 1000000) - 1, 8) / 8; + ticks = round_up((st->startup_time * adc_clk_khz / + 1000) - 1, 8) / 8; /* * a minimal Sample and Hold Time is necessary for the ADC to guarantee * the best converted final value between two channels selection * The formula thus is : Sample and Hold Time = (shtim + 1) / ADCClock */ - shtim = round_up((st->sample_hold_time * adc_clk / - 1000000) - 1, 1); + shtim = round_up((st->sample_hold_time * adc_clk_khz / + 1000) - 1, 1); reg = AT91_ADC_PRESCAL_(prsc) & st->registers->mr_prescal_mask; reg |= AT91_ADC_STARTUP_(ticks) & st->registers->mr_startup_mask; diff --git a/drivers/iio/buffer_cb.c b/drivers/iio/buffer_cb.c index 9d19ba74f22b..415f3c6efd72 100644 --- a/drivers/iio/buffer_cb.c +++ b/drivers/iio/buffer_cb.c @@ -41,6 +41,8 @@ struct iio_cb_buffer *iio_channel_get_all_cb(struct device *dev, goto error_ret; } + iio_buffer_init(&cb_buff->buffer); + cb_buff->private = private; cb_buff->cb = cb; cb_buff->buffer.access = &iio_cb_access; diff --git a/drivers/iio/dac/mcp4725.c b/drivers/iio/dac/mcp4725.c index 1f4a48e6a82c..1397b6e0e414 100644 --- a/drivers/iio/dac/mcp4725.c +++ b/drivers/iio/dac/mcp4725.c @@ -37,21 +37,21 @@ struct mcp4725_data { static int mcp4725_suspend(struct device *dev) { - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct mcp4725_data *data = iio_priv(indio_dev); + struct mcp4725_data *data = iio_priv(i2c_get_clientdata( + to_i2c_client(dev))); u8 outbuf[2]; outbuf[0] = (data->powerdown_mode + 1) << 4; outbuf[1] = 0; data->powerdown = true; - return i2c_master_send(to_i2c_client(dev), outbuf, 2); + return i2c_master_send(data->client, outbuf, 2); } static int mcp4725_resume(struct device *dev) { - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct mcp4725_data *data = iio_priv(indio_dev); + struct mcp4725_data *data = iio_priv(i2c_get_clientdata( + to_i2c_client(dev))); u8 outbuf[2]; /* restore previous DAC value */ @@ -59,7 +59,7 @@ static int mcp4725_resume(struct device *dev) outbuf[1] = data->dac_value & 0xff; data->powerdown = false; - return i2c_master_send(to_i2c_client(dev), outbuf, 2); + return i2c_master_send(data->client, outbuf, 2); } #ifdef CONFIG_PM_SLEEP diff --git a/drivers/iio/iio_core.h b/drivers/iio/iio_core.h index 05c1b74502a3..9b32253b824b 100644 --- a/drivers/iio/iio_core.h +++ b/drivers/iio/iio_core.h @@ -49,11 +49,15 @@ ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf, #define iio_buffer_poll_addr (&iio_buffer_poll) #define iio_buffer_read_first_n_outer_addr (&iio_buffer_read_first_n_outer) +void iio_disable_all_buffers(struct iio_dev *indio_dev); + #else #define iio_buffer_poll_addr NULL #define iio_buffer_read_first_n_outer_addr NULL +static inline void iio_disable_all_buffers(struct iio_dev *indio_dev) {} + #endif int iio_device_register_eventset(struct iio_dev *indio_dev); diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index e73033f3839a..2710f7245c3b 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -460,6 +460,25 @@ static int iio_compute_scan_bytes(struct iio_dev *indio_dev, const long *mask, return bytes; } +void iio_disable_all_buffers(struct iio_dev *indio_dev) +{ + struct iio_buffer *buffer, *_buffer; + + if (list_empty(&indio_dev->buffer_list)) + return; + + if (indio_dev->setup_ops->predisable) + indio_dev->setup_ops->predisable(indio_dev); + + list_for_each_entry_safe(buffer, _buffer, + &indio_dev->buffer_list, buffer_list) + list_del_init(&buffer->buffer_list); + + indio_dev->currentmode = INDIO_DIRECT_MODE; + if (indio_dev->setup_ops->postdisable) + indio_dev->setup_ops->postdisable(indio_dev); +} + int iio_update_buffers(struct iio_dev *indio_dev, struct iio_buffer *insert_buffer, struct iio_buffer *remove_buffer) @@ -528,8 +547,15 @@ int iio_update_buffers(struct iio_dev *indio_dev, * Note can only occur when adding a buffer. */ list_del(&insert_buffer->buffer_list); - indio_dev->active_scan_mask = old_mask; - success = -EINVAL; + if (old_mask) { + indio_dev->active_scan_mask = old_mask; + success = -EINVAL; + } + else { + kfree(compound_mask); + ret = -EINVAL; + goto error_ret; + } } } else { indio_dev->active_scan_mask = compound_mask; diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 97f0297b120f..8e84cd522e49 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -848,8 +848,6 @@ static void iio_device_unregister_sysfs(struct iio_dev *indio_dev) static void iio_dev_release(struct device *device) { struct iio_dev *indio_dev = dev_to_iio_dev(device); - if (indio_dev->chrdev.dev) - cdev_del(&indio_dev->chrdev); if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) iio_device_unregister_trigger_consumer(indio_dev); iio_device_unregister_eventset(indio_dev); @@ -970,6 +968,8 @@ static int iio_chrdev_open(struct inode *inode, struct file *filp) if (test_and_set_bit(IIO_BUSY_BIT_POS, &indio_dev->flags)) return -EBUSY; + iio_device_get(indio_dev); + filp->private_data = indio_dev; return 0; @@ -983,6 +983,8 @@ static int iio_chrdev_release(struct inode *inode, struct file *filp) struct iio_dev *indio_dev = container_of(inode->i_cdev, struct iio_dev, chrdev); clear_bit(IIO_BUSY_BIT_POS, &indio_dev->flags); + iio_device_put(indio_dev); + return 0; } @@ -1052,18 +1054,20 @@ int iio_device_register(struct iio_dev *indio_dev) indio_dev->setup_ops == NULL) indio_dev->setup_ops = &noop_ring_setup_ops; - ret = device_add(&indio_dev->dev); - if (ret < 0) - goto error_unreg_eventset; cdev_init(&indio_dev->chrdev, &iio_buffer_fileops); indio_dev->chrdev.owner = indio_dev->info->driver_module; + indio_dev->chrdev.kobj.parent = &indio_dev->dev.kobj; ret = cdev_add(&indio_dev->chrdev, indio_dev->dev.devt, 1); if (ret < 0) - goto error_del_device; - return 0; + goto error_unreg_eventset; -error_del_device: - device_del(&indio_dev->dev); + ret = device_add(&indio_dev->dev); + if (ret < 0) + goto error_cdev_del; + + return 0; +error_cdev_del: + cdev_del(&indio_dev->chrdev); error_unreg_eventset: iio_device_unregister_eventset(indio_dev); error_free_sysfs: @@ -1078,9 +1082,16 @@ EXPORT_SYMBOL(iio_device_register); void iio_device_unregister(struct iio_dev *indio_dev) { mutex_lock(&indio_dev->info_exist_lock); + + device_del(&indio_dev->dev); + + if (indio_dev->chrdev.dev) + cdev_del(&indio_dev->chrdev); + + iio_disable_all_buffers(indio_dev); + indio_dev->info = NULL; mutex_unlock(&indio_dev->info_exist_lock); - device_del(&indio_dev->dev); } EXPORT_SYMBOL(iio_device_unregister); subsys_initcall(iio_init); diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c index 10aa9ef86cec..6be65ef5faa9 100644 --- a/drivers/iio/industrialio-event.c +++ b/drivers/iio/industrialio-event.c @@ -72,7 +72,8 @@ EXPORT_SYMBOL(iio_push_event); static unsigned int iio_event_poll(struct file *filep, struct poll_table_struct *wait) { - struct iio_event_interface *ev_int = filep->private_data; + struct iio_dev *indio_dev = filep->private_data; + struct iio_event_interface *ev_int = indio_dev->event_interface; unsigned int events = 0; poll_wait(filep, &ev_int->wait, wait); @@ -90,7 +91,8 @@ static ssize_t iio_event_chrdev_read(struct file *filep, size_t count, loff_t *f_ps) { - struct iio_event_interface *ev_int = filep->private_data; + struct iio_dev *indio_dev = filep->private_data; + struct iio_event_interface *ev_int = indio_dev->event_interface; unsigned int copied; int ret; @@ -121,7 +123,8 @@ error_unlock: static int iio_event_chrdev_release(struct inode *inode, struct file *filep) { - struct iio_event_interface *ev_int = filep->private_data; + struct iio_dev *indio_dev = filep->private_data; + struct iio_event_interface *ev_int = indio_dev->event_interface; spin_lock_irq(&ev_int->wait.lock); __clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags); @@ -133,6 +136,8 @@ static int iio_event_chrdev_release(struct inode *inode, struct file *filep) kfifo_reset_out(&ev_int->det_events); spin_unlock_irq(&ev_int->wait.lock); + iio_device_put(indio_dev); + return 0; } @@ -158,12 +163,15 @@ int iio_event_getfd(struct iio_dev *indio_dev) return -EBUSY; } spin_unlock_irq(&ev_int->wait.lock); - fd = anon_inode_getfd("iio:event", - &iio_event_chrdev_fileops, ev_int, O_RDONLY); + iio_device_get(indio_dev); + + fd = anon_inode_getfd("iio:event", &iio_event_chrdev_fileops, + indio_dev, O_RDONLY); if (fd < 0) { spin_lock_irq(&ev_int->wait.lock); __clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags); spin_unlock_irq(&ev_int->wait.lock); + iio_device_put(indio_dev); } return fd; } @@ -276,7 +284,7 @@ static int iio_device_add_event_sysfs(struct iio_dev *indio_dev, goto error_ret; } if (chan->modified) - mask = IIO_MOD_EVENT_CODE(chan->type, 0, chan->channel, + mask = IIO_MOD_EVENT_CODE(chan->type, 0, chan->channel2, i/IIO_EV_DIR_MAX, i%IIO_EV_DIR_MAX); else if (chan->differential) diff --git a/drivers/iio/temperature/tmp006.c b/drivers/iio/temperature/tmp006.c index 64ccde3f1f7a..6d63883da1ab 100644 --- a/drivers/iio/temperature/tmp006.c +++ b/drivers/iio/temperature/tmp006.c @@ -255,12 +255,14 @@ static int tmp006_remove(struct i2c_client *client) #ifdef CONFIG_PM_SLEEP static int tmp006_suspend(struct device *dev) { - return tmp006_powerdown(iio_priv(dev_to_iio_dev(dev))); + struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); + return tmp006_powerdown(iio_priv(indio_dev)); } static int tmp006_resume(struct device *dev) { - struct tmp006_data *data = iio_priv(dev_to_iio_dev(dev)); + struct tmp006_data *data = iio_priv(i2c_get_clientdata( + to_i2c_client(dev))); return i2c_smbus_write_word_swapped(data->client, TMP006_CONFIG, data->config | TMP006_CONFIG_MOD_MASK); } diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index dab4b41f1715..a082fd9e7ebe 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -2294,7 +2294,7 @@ static int cma_alloc_any_port(struct idr *ps, struct rdma_id_private *id_priv) int low, high, remaining; unsigned int rover; - inet_get_local_port_range(&low, &high); + inet_get_local_port_range(&init_net, &low, &high); remaining = (high - low) + 1; rover = net_random() % remaining + low; retry: diff --git a/drivers/isdn/hardware/eicon/um_idi.c b/drivers/isdn/hardware/eicon/um_idi.c index 7cab5c3276c2..e1519718ce67 100644 --- a/drivers/isdn/hardware/eicon/um_idi.c +++ b/drivers/isdn/hardware/eicon/um_idi.c @@ -288,9 +288,9 @@ int divas_um_idi_delete_entity(int adapter_nr, void *entity) cleanup_entity(e); diva_os_free(0, e->os_context); memset(e, 0x00, sizeof(*e)); - diva_os_free(0, e); DBG_LOG(("A(%d) remove E:%08x", adapter_nr, e)); + diva_os_free(0, e); return (0); } diff --git a/drivers/mailbox/mailbox-omap2.c b/drivers/mailbox/mailbox-omap2.c index eba380d7b17f..42d2b893ea67 100644 --- a/drivers/mailbox/mailbox-omap2.c +++ b/drivers/mailbox/mailbox-omap2.c @@ -325,7 +325,6 @@ static int omap2_mbox_remove(struct platform_device *pdev) kfree(privblk); kfree(mboxblk); kfree(list); - platform_set_drvdata(pdev, NULL); return 0; } diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h index b39f6f0b45f2..0f12382aa35d 100644 --- a/drivers/md/bcache/bcache.h +++ b/drivers/md/bcache/bcache.h @@ -498,7 +498,7 @@ struct cached_dev { */ atomic_t has_dirty; - struct ratelimit writeback_rate; + struct bch_ratelimit writeback_rate; struct delayed_work writeback_rate_update; /* @@ -507,10 +507,9 @@ struct cached_dev { */ sector_t last_read; - /* Number of writeback bios in flight */ - atomic_t in_flight; + /* Limit number of writeback bios in flight */ + struct semaphore in_flight; struct closure_with_timer writeback; - struct closure_waitlist writeback_wait; struct keybuf writeback_keys; diff --git a/drivers/md/bcache/bset.c b/drivers/md/bcache/bset.c index 8010eed06a51..22d1ae72c282 100644 --- a/drivers/md/bcache/bset.c +++ b/drivers/md/bcache/bset.c @@ -926,28 +926,45 @@ struct bkey *bch_next_recurse_key(struct btree *b, struct bkey *search) /* Mergesort */ +static void sort_key_next(struct btree_iter *iter, + struct btree_iter_set *i) +{ + i->k = bkey_next(i->k); + + if (i->k == i->end) + *i = iter->data[--iter->used]; +} + static void btree_sort_fixup(struct btree_iter *iter) { while (iter->used > 1) { struct btree_iter_set *top = iter->data, *i = top + 1; - struct bkey *k; if (iter->used > 2 && btree_iter_cmp(i[0], i[1])) i++; - for (k = i->k; - k != i->end && bkey_cmp(top->k, &START_KEY(k)) > 0; - k = bkey_next(k)) - if (top->k > i->k) - __bch_cut_front(top->k, k); - else if (KEY_SIZE(k)) - bch_cut_back(&START_KEY(k), top->k); - - if (top->k < i->k || k == i->k) + if (bkey_cmp(top->k, &START_KEY(i->k)) <= 0) break; - heap_sift(iter, i - top, btree_iter_cmp); + if (!KEY_SIZE(i->k)) { + sort_key_next(iter, i); + heap_sift(iter, i - top, btree_iter_cmp); + continue; + } + + if (top->k > i->k) { + if (bkey_cmp(top->k, i->k) >= 0) + sort_key_next(iter, i); + else + bch_cut_front(top->k, i->k); + + heap_sift(iter, i - top, btree_iter_cmp); + } else { + /* can't happen because of comparison func */ + BUG_ON(!bkey_cmp(&START_KEY(top->k), &START_KEY(i->k))); + bch_cut_back(&START_KEY(i->k), top->k); + } } } diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c index f9764e61978b..f42fc7ed9cd6 100644 --- a/drivers/md/bcache/btree.c +++ b/drivers/md/bcache/btree.c @@ -255,7 +255,7 @@ void bch_btree_node_read(struct btree *b) return; err: - bch_cache_set_error(b->c, "io error reading bucket %lu", + bch_cache_set_error(b->c, "io error reading bucket %zu", PTR_BUCKET_NR(b->c, &b->key, 0)); } @@ -612,7 +612,7 @@ static unsigned long bch_mca_scan(struct shrinker *shrink, return SHRINK_STOP; /* Return -1 if we can't do anything right now */ - if (sc->gfp_mask & __GFP_WAIT) + if (sc->gfp_mask & __GFP_IO) mutex_lock(&c->bucket_lock); else if (!mutex_trylock(&c->bucket_lock)) return -1; diff --git a/drivers/md/bcache/journal.c b/drivers/md/bcache/journal.c index ba95ab84b2be..8435f81e5d85 100644 --- a/drivers/md/bcache/journal.c +++ b/drivers/md/bcache/journal.c @@ -153,7 +153,8 @@ int bch_journal_read(struct cache_set *c, struct list_head *list, bitmap_zero(bitmap, SB_JOURNAL_BUCKETS); pr_debug("%u journal buckets", ca->sb.njournal_buckets); - /* Read journal buckets ordered by golden ratio hash to quickly + /* + * Read journal buckets ordered by golden ratio hash to quickly * find a sequence of buckets with valid journal entries */ for (i = 0; i < ca->sb.njournal_buckets; i++) { @@ -166,18 +167,20 @@ int bch_journal_read(struct cache_set *c, struct list_head *list, goto bsearch; } - /* If that fails, check all the buckets we haven't checked + /* + * If that fails, check all the buckets we haven't checked * already */ pr_debug("falling back to linear search"); - for (l = 0; l < ca->sb.njournal_buckets; l++) { - if (test_bit(l, bitmap)) - continue; - + for (l = find_first_zero_bit(bitmap, ca->sb.njournal_buckets); + l < ca->sb.njournal_buckets; + l = find_next_zero_bit(bitmap, ca->sb.njournal_buckets, l + 1)) if (read_bucket(l)) goto bsearch; - } + + if (list_empty(list)) + continue; bsearch: /* Binary search */ m = r = find_next_bit(bitmap, ca->sb.njournal_buckets, l + 1); @@ -197,10 +200,12 @@ bsearch: r = m; } - /* Read buckets in reverse order until we stop finding more + /* + * Read buckets in reverse order until we stop finding more * journal entries */ - pr_debug("finishing up"); + pr_debug("finishing up: m %u njournal_buckets %u", + m, ca->sb.njournal_buckets); l = m; while (1) { @@ -228,9 +233,10 @@ bsearch: } } - c->journal.seq = list_entry(list->prev, - struct journal_replay, - list)->j.seq; + if (!list_empty(list)) + c->journal.seq = list_entry(list->prev, + struct journal_replay, + list)->j.seq; return 0; #undef read_bucket @@ -428,7 +434,7 @@ static void do_journal_discard(struct cache *ca) return; } - switch (atomic_read(&ja->discard_in_flight) == DISCARD_IN_FLIGHT) { + switch (atomic_read(&ja->discard_in_flight)) { case DISCARD_IN_FLIGHT: return; @@ -689,6 +695,7 @@ void bch_journal_meta(struct cache_set *c, struct closure *cl) if (cl) BUG_ON(!closure_wait(&w->wait, cl)); + closure_flush(&c->journal.io); __journal_try_write(c, true); } } diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c index 786a1a4f74d8..71eb233b9ace 100644 --- a/drivers/md/bcache/request.c +++ b/drivers/md/bcache/request.c @@ -997,14 +997,17 @@ static void request_write(struct cached_dev *dc, struct search *s) } else { bch_writeback_add(dc); - if (s->op.flush_journal) { + if (bio->bi_rw & REQ_FLUSH) { /* Also need to send a flush to the backing device */ - s->op.cache_bio = bio_clone_bioset(bio, GFP_NOIO, - dc->disk.bio_split); + struct bio *flush = bio_alloc_bioset(0, GFP_NOIO, + dc->disk.bio_split); - bio->bi_size = 0; - bio->bi_vcnt = 0; - closure_bio_submit(bio, cl, s->d); + flush->bi_rw = WRITE_FLUSH; + flush->bi_bdev = bio->bi_bdev; + flush->bi_end_io = request_endio; + flush->bi_private = cl; + + closure_bio_submit(flush, cl, s->d); } else { s->op.cache_bio = bio; } diff --git a/drivers/md/bcache/sysfs.c b/drivers/md/bcache/sysfs.c index 4fe6ab2fbe2e..924dcfdae111 100644 --- a/drivers/md/bcache/sysfs.c +++ b/drivers/md/bcache/sysfs.c @@ -223,8 +223,13 @@ STORE(__cached_dev) } if (attr == &sysfs_label) { - /* note: endlines are preserved */ - memcpy(dc->sb.label, buf, SB_LABEL_SIZE); + if (size > SB_LABEL_SIZE) + return -EINVAL; + memcpy(dc->sb.label, buf, size); + if (size < SB_LABEL_SIZE) + dc->sb.label[size] = '\0'; + if (size && dc->sb.label[size - 1] == '\n') + dc->sb.label[size - 1] = '\0'; bch_write_bdev_super(dc, NULL); if (dc->disk.c) { memcpy(dc->disk.c->uuids[dc->disk.id].label, diff --git a/drivers/md/bcache/util.c b/drivers/md/bcache/util.c index 98eb81159a22..420dad545c7d 100644 --- a/drivers/md/bcache/util.c +++ b/drivers/md/bcache/util.c @@ -190,7 +190,16 @@ void bch_time_stats_update(struct time_stats *stats, uint64_t start_time) stats->last = now ?: 1; } -unsigned bch_next_delay(struct ratelimit *d, uint64_t done) +/** + * bch_next_delay() - increment @d by the amount of work done, and return how + * long to delay until the next time to do some work. + * + * @d - the struct bch_ratelimit to update + * @done - the amount of work done, in arbitrary units + * + * Returns the amount of time to delay by, in jiffies + */ +uint64_t bch_next_delay(struct bch_ratelimit *d, uint64_t done) { uint64_t now = local_clock(); diff --git a/drivers/md/bcache/util.h b/drivers/md/bcache/util.h index 1ae2a73ad85f..ea345c6896f4 100644 --- a/drivers/md/bcache/util.h +++ b/drivers/md/bcache/util.h @@ -450,17 +450,23 @@ read_attribute(name ## _last_ ## frequency_units) (ewma) >> factor; \ }) -struct ratelimit { +struct bch_ratelimit { + /* Next time we want to do some work, in nanoseconds */ uint64_t next; + + /* + * Rate at which we want to do work, in units per nanosecond + * The units here correspond to the units passed to bch_next_delay() + */ unsigned rate; }; -static inline void ratelimit_reset(struct ratelimit *d) +static inline void bch_ratelimit_reset(struct bch_ratelimit *d) { d->next = local_clock(); } -unsigned bch_next_delay(struct ratelimit *d, uint64_t done); +uint64_t bch_next_delay(struct bch_ratelimit *d, uint64_t done); #define __DIV_SAFE(n, d, zero) \ ({ \ diff --git a/drivers/md/bcache/writeback.c b/drivers/md/bcache/writeback.c index 22cbff551628..ba3ee48320f2 100644 --- a/drivers/md/bcache/writeback.c +++ b/drivers/md/bcache/writeback.c @@ -94,11 +94,15 @@ static void update_writeback_rate(struct work_struct *work) static unsigned writeback_delay(struct cached_dev *dc, unsigned sectors) { + uint64_t ret; + if (atomic_read(&dc->disk.detaching) || !dc->writeback_percent) return 0; - return bch_next_delay(&dc->writeback_rate, sectors * 10000000ULL); + ret = bch_next_delay(&dc->writeback_rate, sectors * 10000000ULL); + + return min_t(uint64_t, ret, HZ); } /* Background writeback */ @@ -208,7 +212,7 @@ normal_refill: up_write(&dc->writeback_lock); - ratelimit_reset(&dc->writeback_rate); + bch_ratelimit_reset(&dc->writeback_rate); /* Punt to workqueue only so we don't recurse and blow the stack */ continue_at(cl, read_dirty, dirty_wq); @@ -318,9 +322,7 @@ static void write_dirty_finish(struct closure *cl) } bch_keybuf_del(&dc->writeback_keys, w); - atomic_dec_bug(&dc->in_flight); - - closure_wake_up(&dc->writeback_wait); + up(&dc->in_flight); closure_return_with_destructor(cl, dirty_io_destructor); } @@ -349,7 +351,7 @@ static void write_dirty(struct closure *cl) closure_bio_submit(&io->bio, cl, &io->dc->disk); - continue_at(cl, write_dirty_finish, dirty_wq); + continue_at(cl, write_dirty_finish, system_wq); } static void read_dirty_endio(struct bio *bio, int error) @@ -369,7 +371,7 @@ static void read_dirty_submit(struct closure *cl) closure_bio_submit(&io->bio, cl, &io->dc->disk); - continue_at(cl, write_dirty, dirty_wq); + continue_at(cl, write_dirty, system_wq); } static void read_dirty(struct closure *cl) @@ -394,12 +396,8 @@ static void read_dirty(struct closure *cl) if (delay > 0 && (KEY_START(&w->key) != dc->last_read || - jiffies_to_msecs(delay) > 50)) { - w->private = NULL; - - closure_delay(&dc->writeback, delay); - continue_at(cl, read_dirty, dirty_wq); - } + jiffies_to_msecs(delay) > 50)) + delay = schedule_timeout_uninterruptible(delay); dc->last_read = KEY_OFFSET(&w->key); @@ -424,15 +422,10 @@ static void read_dirty(struct closure *cl) trace_bcache_writeback(&w->key); - closure_call(&io->cl, read_dirty_submit, NULL, &dc->disk.cl); + down(&dc->in_flight); + closure_call(&io->cl, read_dirty_submit, NULL, cl); delay = writeback_delay(dc, KEY_SIZE(&w->key)); - - atomic_inc(&dc->in_flight); - - if (!closure_wait_event(&dc->writeback_wait, cl, - atomic_read(&dc->in_flight) < 64)) - continue_at(cl, read_dirty, dirty_wq); } if (0) { @@ -442,7 +435,11 @@ err: bch_keybuf_del(&dc->writeback_keys, w); } - refill_dirty(cl); + /* + * Wait for outstanding writeback IOs to finish (and keybuf slots to be + * freed) before refilling again + */ + continue_at(cl, refill_dirty, dirty_wq); } /* Init */ @@ -484,6 +481,7 @@ void bch_sectors_dirty_init(struct cached_dev *dc) void bch_cached_dev_writeback_init(struct cached_dev *dc) { + sema_init(&dc->in_flight, 64); closure_init_unlocked(&dc->writeback); init_rwsem(&dc->writeback_lock); @@ -513,7 +511,7 @@ void bch_writeback_exit(void) int __init bch_writeback_init(void) { - dirty_wq = create_singlethread_workqueue("bcache_writeback"); + dirty_wq = create_workqueue("bcache_writeback"); if (!dirty_wq) return -ENOMEM; diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c index ea49834377c8..2a20986a2fec 100644 --- a/drivers/md/dm-io.c +++ b/drivers/md/dm-io.c @@ -19,8 +19,6 @@ #define DM_MSG_PREFIX "io" #define DM_IO_MAX_REGIONS BITS_PER_LONG -#define MIN_IOS 16 -#define MIN_BIOS 16 struct dm_io_client { mempool_t *pool; @@ -50,16 +48,17 @@ static struct kmem_cache *_dm_io_cache; struct dm_io_client *dm_io_client_create(void) { struct dm_io_client *client; + unsigned min_ios = dm_get_reserved_bio_based_ios(); client = kmalloc(sizeof(*client), GFP_KERNEL); if (!client) return ERR_PTR(-ENOMEM); - client->pool = mempool_create_slab_pool(MIN_IOS, _dm_io_cache); + client->pool = mempool_create_slab_pool(min_ios, _dm_io_cache); if (!client->pool) goto bad; - client->bios = bioset_create(MIN_BIOS, 0); + client->bios = bioset_create(min_ios, 0); if (!client->bios) goto bad; diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index b759a127f9c3..de570a558764 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c @@ -7,6 +7,7 @@ #include <linux/device-mapper.h> +#include "dm.h" #include "dm-path-selector.h" #include "dm-uevent.h" @@ -116,8 +117,6 @@ struct dm_mpath_io { typedef int (*action_fn) (struct pgpath *pgpath); -#define MIN_IOS 256 /* Mempool size */ - static struct kmem_cache *_mpio_cache; static struct workqueue_struct *kmultipathd, *kmpath_handlerd; @@ -190,6 +189,7 @@ static void free_priority_group(struct priority_group *pg, static struct multipath *alloc_multipath(struct dm_target *ti) { struct multipath *m; + unsigned min_ios = dm_get_reserved_rq_based_ios(); m = kzalloc(sizeof(*m), GFP_KERNEL); if (m) { @@ -202,7 +202,7 @@ static struct multipath *alloc_multipath(struct dm_target *ti) INIT_WORK(&m->trigger_event, trigger_event); init_waitqueue_head(&m->pg_init_wait); mutex_init(&m->work_mutex); - m->mpio_pool = mempool_create_slab_pool(MIN_IOS, _mpio_cache); + m->mpio_pool = mempool_create_slab_pool(min_ios, _mpio_cache); if (!m->mpio_pool) { kfree(m); return NULL; @@ -1268,6 +1268,7 @@ static int noretry_error(int error) case -EREMOTEIO: case -EILSEQ: case -ENODATA: + case -ENOSPC: return 1; } @@ -1298,8 +1299,17 @@ static int do_end_io(struct multipath *m, struct request *clone, if (!error && !clone->errors) return 0; /* I/O complete */ - if (noretry_error(error)) + if (noretry_error(error)) { + if ((clone->cmd_flags & REQ_WRITE_SAME) && + !clone->q->limits.max_write_same_sectors) { + struct queue_limits *limits; + + /* device doesn't really support WRITE SAME, disable it */ + limits = dm_get_queue_limits(dm_table_get_md(m->ti->table)); + limits->max_write_same_sectors = 0; + } return error; + } if (mpio->pgpath) fail_path(mpio->pgpath); diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c index 3ac415675b6c..4caa8e6d59d7 100644 --- a/drivers/md/dm-snap-persistent.c +++ b/drivers/md/dm-snap-persistent.c @@ -256,7 +256,7 @@ static int chunk_io(struct pstore *ps, void *area, chunk_t chunk, int rw, */ INIT_WORK_ONSTACK(&req.work, do_metadata); queue_work(ps->metadata_wq, &req.work); - flush_work(&req.work); + flush_workqueue(ps->metadata_wq); return req.result; } diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index c434e5aab2df..aec57d76db5d 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -725,17 +725,16 @@ static int calc_max_buckets(void) */ static int init_hash_tables(struct dm_snapshot *s) { - sector_t hash_size, cow_dev_size, origin_dev_size, max_buckets; + sector_t hash_size, cow_dev_size, max_buckets; /* * Calculate based on the size of the original volume or * the COW volume... */ cow_dev_size = get_dev_size(s->cow->bdev); - origin_dev_size = get_dev_size(s->origin->bdev); max_buckets = calc_max_buckets(); - hash_size = min(origin_dev_size, cow_dev_size) >> s->store->chunk_shift; + hash_size = cow_dev_size >> s->store->chunk_shift; hash_size = min(hash_size, max_buckets); if (hash_size < 64) diff --git a/drivers/md/dm-stats.c b/drivers/md/dm-stats.c index 8ae31e8d3d64..3d404c1371ed 100644 --- a/drivers/md/dm-stats.c +++ b/drivers/md/dm-stats.c @@ -451,19 +451,26 @@ static void dm_stat_for_entry(struct dm_stat *s, size_t entry, struct dm_stat_percpu *p; /* - * For strict correctness we should use local_irq_disable/enable + * For strict correctness we should use local_irq_save/restore * instead of preempt_disable/enable. * - * This is racy if the driver finishes bios from non-interrupt - * context as well as from interrupt context or from more different - * interrupts. + * preempt_disable/enable is racy if the driver finishes bios + * from non-interrupt context as well as from interrupt context + * or from more different interrupts. * - * However, the race only results in not counting some events, - * so it is acceptable. + * On 64-bit architectures the race only results in not counting some + * events, so it is acceptable. On 32-bit architectures the race could + * cause the counter going off by 2^32, so we need to do proper locking + * there. * * part_stat_lock()/part_stat_unlock() have this race too. */ +#if BITS_PER_LONG == 32 + unsigned long flags; + local_irq_save(flags); +#else preempt_disable(); +#endif p = &s->stat_percpu[smp_processor_id()][entry]; if (!end) { @@ -478,7 +485,11 @@ static void dm_stat_for_entry(struct dm_stat *s, size_t entry, p->ticks[idx] += duration; } +#if BITS_PER_LONG == 32 + local_irq_restore(flags); +#else preempt_enable(); +#endif } static void __dm_stat_bio(struct dm_stat *s, unsigned long bi_rw, diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index ed063427d676..2c0cf511ec23 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c @@ -2095,6 +2095,7 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv) * them down to the data device. The thin device's discard * processing will cause mappings to be removed from the btree. */ + ti->discard_zeroes_data_unsupported = true; if (pf.discard_enabled && pf.discard_passdown) { ti->num_discard_bios = 1; @@ -2104,7 +2105,6 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv) * thin devices' discard limits consistent). */ ti->discards_supported = true; - ti->discard_zeroes_data_unsupported = true; } ti->private = pt; @@ -2689,8 +2689,16 @@ static void pool_io_hints(struct dm_target *ti, struct queue_limits *limits) * They get transferred to the live pool in bind_control_target() * called from pool_preresume(). */ - if (!pt->adjusted_pf.discard_enabled) + if (!pt->adjusted_pf.discard_enabled) { + /* + * Must explicitly disallow stacking discard limits otherwise the + * block layer will stack them if pool's data device has support. + * QUEUE_FLAG_DISCARD wouldn't be set but there is no way for the + * user to see that, so make sure to set all discard limits to 0. + */ + limits->discard_granularity = 0; return; + } disable_passdown_if_not_supported(pt); @@ -2826,10 +2834,10 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv) ti->per_bio_data_size = sizeof(struct dm_thin_endio_hook); /* In case the pool supports discards, pass them on. */ + ti->discard_zeroes_data_unsupported = true; if (tc->pool->pf.discard_enabled) { ti->discards_supported = true; ti->num_discard_bios = 1; - ti->discard_zeroes_data_unsupported = true; /* Discard bios must be split on a block boundary */ ti->split_discard_bios = true; } diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 6a5e9ed2fcc3..b3e26c7d1417 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -211,10 +211,55 @@ struct dm_md_mempools { struct bio_set *bs; }; -#define MIN_IOS 256 +#define RESERVED_BIO_BASED_IOS 16 +#define RESERVED_REQUEST_BASED_IOS 256 +#define RESERVED_MAX_IOS 1024 static struct kmem_cache *_io_cache; static struct kmem_cache *_rq_tio_cache; +/* + * Bio-based DM's mempools' reserved IOs set by the user. + */ +static unsigned reserved_bio_based_ios = RESERVED_BIO_BASED_IOS; + +/* + * Request-based DM's mempools' reserved IOs set by the user. + */ +static unsigned reserved_rq_based_ios = RESERVED_REQUEST_BASED_IOS; + +static unsigned __dm_get_reserved_ios(unsigned *reserved_ios, + unsigned def, unsigned max) +{ + unsigned ios = ACCESS_ONCE(*reserved_ios); + unsigned modified_ios = 0; + + if (!ios) + modified_ios = def; + else if (ios > max) + modified_ios = max; + + if (modified_ios) { + (void)cmpxchg(reserved_ios, ios, modified_ios); + ios = modified_ios; + } + + return ios; +} + +unsigned dm_get_reserved_bio_based_ios(void) +{ + return __dm_get_reserved_ios(&reserved_bio_based_ios, + RESERVED_BIO_BASED_IOS, RESERVED_MAX_IOS); +} +EXPORT_SYMBOL_GPL(dm_get_reserved_bio_based_ios); + +unsigned dm_get_reserved_rq_based_ios(void) +{ + return __dm_get_reserved_ios(&reserved_rq_based_ios, + RESERVED_REQUEST_BASED_IOS, RESERVED_MAX_IOS); +} +EXPORT_SYMBOL_GPL(dm_get_reserved_rq_based_ios); + static int __init local_init(void) { int r = -ENOMEM; @@ -2278,6 +2323,17 @@ struct target_type *dm_get_immutable_target_type(struct mapped_device *md) } /* + * The queue_limits are only valid as long as you have a reference + * count on 'md'. + */ +struct queue_limits *dm_get_queue_limits(struct mapped_device *md) +{ + BUG_ON(!atomic_read(&md->holders)); + return &md->queue->limits; +} +EXPORT_SYMBOL_GPL(dm_get_queue_limits); + +/* * Fully initialize a request-based queue (->elevator, ->request_fn, etc). */ static int dm_init_request_based_queue(struct mapped_device *md) @@ -2862,18 +2918,18 @@ struct dm_md_mempools *dm_alloc_md_mempools(unsigned type, unsigned integrity, u if (type == DM_TYPE_BIO_BASED) { cachep = _io_cache; - pool_size = 16; + pool_size = dm_get_reserved_bio_based_ios(); front_pad = roundup(per_bio_data_size, __alignof__(struct dm_target_io)) + offsetof(struct dm_target_io, clone); } else if (type == DM_TYPE_REQUEST_BASED) { cachep = _rq_tio_cache; - pool_size = MIN_IOS; + pool_size = dm_get_reserved_rq_based_ios(); front_pad = offsetof(struct dm_rq_clone_bio_info, clone); /* per_bio_data_size is not used. See __bind_mempools(). */ WARN_ON(per_bio_data_size != 0); } else goto out; - pools->io_pool = mempool_create_slab_pool(MIN_IOS, cachep); + pools->io_pool = mempool_create_slab_pool(pool_size, cachep); if (!pools->io_pool) goto out; @@ -2924,6 +2980,13 @@ module_exit(dm_exit); module_param(major, uint, 0); MODULE_PARM_DESC(major, "The major number of the device mapper"); + +module_param(reserved_bio_based_ios, uint, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(reserved_bio_based_ios, "Reserved IOs in bio-based mempools"); + +module_param(reserved_rq_based_ios, uint, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(reserved_rq_based_ios, "Reserved IOs in request-based mempools"); + MODULE_DESCRIPTION(DM_NAME " driver"); MODULE_AUTHOR("Joe Thornber <dm-devel@redhat.com>"); MODULE_LICENSE("GPL"); diff --git a/drivers/md/dm.h b/drivers/md/dm.h index 5e604cc7b4aa..1d1ad7b7e527 100644 --- a/drivers/md/dm.h +++ b/drivers/md/dm.h @@ -184,6 +184,9 @@ void dm_free_md_mempools(struct dm_md_mempools *pools); /* * Helpers that are used by DM core */ +unsigned dm_get_reserved_bio_based_ios(void); +unsigned dm_get_reserved_rq_based_ios(void); + static inline bool dm_message_test_buffer_overflow(char *result, unsigned maxlen) { return !maxlen || strlen(result) + 1 >= maxlen; diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index d0fdc134068a..f6ff711aa5bb 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -57,6 +57,7 @@ void mei_amthif_reset_params(struct mei_device *dev) dev->iamthif_ioctl = false; dev->iamthif_state = MEI_IAMTHIF_IDLE; dev->iamthif_timer = 0; + dev->iamthif_stall_timer = 0; } /** diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index 6d0282c08a06..cd2033cd7120 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -297,10 +297,13 @@ int __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length) if (cl->reading_state != MEI_READ_COMPLETE && !waitqueue_active(&cl->rx_wait)) { + mutex_unlock(&dev->device_lock); if (wait_event_interruptible(cl->rx_wait, - (MEI_READ_COMPLETE == cl->reading_state))) { + cl->reading_state == MEI_READ_COMPLETE || + mei_cl_is_transitioning(cl))) { + if (signal_pending(current)) return -EINTR; return -ERESTARTSYS; diff --git a/drivers/misc/mei/client.h b/drivers/misc/mei/client.h index 9eb031e92070..892cc4207fa2 100644 --- a/drivers/misc/mei/client.h +++ b/drivers/misc/mei/client.h @@ -90,6 +90,12 @@ static inline bool mei_cl_is_connected(struct mei_cl *cl) cl->dev->dev_state == MEI_DEV_ENABLED && cl->state == MEI_FILE_CONNECTED); } +static inline bool mei_cl_is_transitioning(struct mei_cl *cl) +{ + return (MEI_FILE_INITIALIZING == cl->state || + MEI_FILE_DISCONNECTED == cl->state || + MEI_FILE_DISCONNECTING == cl->state); +} bool mei_cl_is_other_connecting(struct mei_cl *cl); int mei_cl_disconnect(struct mei_cl *cl); diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index 6127ab64bb39..0a0448326e9d 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c @@ -35,11 +35,15 @@ static void mei_hbm_me_cl_allocate(struct mei_device *dev) struct mei_me_client *clients; int b; + dev->me_clients_num = 0; + dev->me_client_presentation_num = 0; + dev->me_client_index = 0; + /* count how many ME clients we have */ for_each_set_bit(b, dev->me_clients_map, MEI_CLIENTS_MAX) dev->me_clients_num++; - if (dev->me_clients_num <= 0) + if (dev->me_clients_num == 0) return; kfree(dev->me_clients); @@ -221,7 +225,7 @@ static int mei_hbm_prop_req(struct mei_device *dev) struct hbm_props_request *prop_req; const size_t len = sizeof(struct hbm_props_request); unsigned long next_client_index; - u8 client_num; + unsigned long client_num; client_num = dev->me_client_presentation_num; @@ -677,8 +681,6 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) if (dev->dev_state == MEI_DEV_INIT_CLIENTS && dev->hbm_state == MEI_HBM_ENUM_CLIENTS) { dev->init_clients_timer = 0; - dev->me_client_presentation_num = 0; - dev->me_client_index = 0; mei_hbm_me_cl_allocate(dev); dev->hbm_state = MEI_HBM_CLIENT_PROPERTIES; diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index 92c73118b13c..6197018e2f16 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -175,6 +175,9 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled) memset(&dev->wr_ext_msg, 0, sizeof(dev->wr_ext_msg)); } + /* we're already in reset, cancel the init timer */ + dev->init_clients_timer = 0; + dev->me_clients_num = 0; dev->rd_msg_hdr = 0; dev->wd_pending = false; diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 173ff095be0d..cabeddd66c1f 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -249,19 +249,16 @@ static ssize_t mei_read(struct file *file, char __user *ubuf, mutex_unlock(&dev->device_lock); if (wait_event_interruptible(cl->rx_wait, - (MEI_READ_COMPLETE == cl->reading_state || - MEI_FILE_INITIALIZING == cl->state || - MEI_FILE_DISCONNECTED == cl->state || - MEI_FILE_DISCONNECTING == cl->state))) { + MEI_READ_COMPLETE == cl->reading_state || + mei_cl_is_transitioning(cl))) { + if (signal_pending(current)) return -EINTR; return -ERESTARTSYS; } mutex_lock(&dev->device_lock); - if (MEI_FILE_INITIALIZING == cl->state || - MEI_FILE_DISCONNECTED == cl->state || - MEI_FILE_DISCONNECTING == cl->state) { + if (mei_cl_is_transitioning(cl)) { rets = -EBUSY; goto out; } diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 7b918b2fb894..456b322013e2 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -396,9 +396,9 @@ struct mei_device { struct mei_me_client *me_clients; /* Note: memory has to be allocated */ DECLARE_BITMAP(me_clients_map, MEI_CLIENTS_MAX); DECLARE_BITMAP(host_clients_map, MEI_CLIENTS_MAX); - u8 me_clients_num; - u8 me_client_presentation_num; - u8 me_client_index; + unsigned long me_clients_num; + unsigned long me_client_presentation_num; + unsigned long me_client_index; struct mei_cl wd_cl; enum mei_wd_states wd_state; diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index 5db900d917f9..dd03dfdfb0d6 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -1236,7 +1236,6 @@ static int pxa3xx_nand_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_OF static struct of_device_id pxa3xx_nand_dt_ids[] = { { .compatible = "marvell,pxa3xx-nand", @@ -1284,12 +1283,6 @@ static int pxa3xx_nand_probe_dt(struct platform_device *pdev) return 0; } -#else -static inline int pxa3xx_nand_probe_dt(struct platform_device *pdev) -{ - return 0; -} -#endif static int pxa3xx_nand_probe(struct platform_device *pdev) { diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 0d8f427ade93..ea3e64e22e22 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -136,41 +136,6 @@ static inline struct bonding *__get_bond_by_port(struct port *port) } /** - * __get_first_port - get the first port in the bond - * @bond: the bond we're looking at - * - * Return the port of the first slave in @bond, or %NULL if it can't be found. - */ -static inline struct port *__get_first_port(struct bonding *bond) -{ - struct slave *first_slave = bond_first_slave(bond); - - return first_slave ? &(SLAVE_AD_INFO(first_slave).port) : NULL; -} - -/** - * __get_next_port - get the next port in the bond - * @port: the port we're looking at - * - * Return the port of the slave that is next in line of @port's slave in the - * bond, or %NULL if it can't be found. - */ -static inline struct port *__get_next_port(struct port *port) -{ - struct bonding *bond = __get_bond_by_port(port); - struct slave *slave = port->slave, *slave_next; - - // If there's no bond for this port, or this is the last slave - if (bond == NULL) - return NULL; - slave_next = bond_next_slave(bond, slave); - if (!slave_next || bond_is_first_slave(bond, slave_next)) - return NULL; - - return &(SLAVE_AD_INFO(slave_next).port); -} - -/** * __get_first_agg - get the first aggregator in the bond * @bond: the bond we're looking at * @@ -190,28 +155,6 @@ static inline struct aggregator *__get_first_agg(struct port *port) return first_slave ? &(SLAVE_AD_INFO(first_slave).aggregator) : NULL; } -/** - * __get_next_agg - get the next aggregator in the bond - * @aggregator: the aggregator we're looking at - * - * Return the aggregator of the slave that is next in line of @aggregator's - * slave in the bond, or %NULL if it can't be found. - */ -static inline struct aggregator *__get_next_agg(struct aggregator *aggregator) -{ - struct slave *slave = aggregator->slave, *slave_next; - struct bonding *bond = bond_get_bond_by_slave(slave); - - // If there's no bond for this aggregator, or this is the last slave - if (bond == NULL) - return NULL; - slave_next = bond_next_slave(bond, slave); - if (!slave_next || bond_is_first_slave(bond, slave_next)) - return NULL; - - return &(SLAVE_AD_INFO(slave_next).aggregator); -} - /* * __agg_has_partner * @@ -755,16 +698,15 @@ static u32 __get_agg_bandwidth(struct aggregator *aggregator) */ static struct aggregator *__get_active_agg(struct aggregator *aggregator) { - struct aggregator *retval = NULL; + struct bonding *bond = aggregator->slave->bond; + struct list_head *iter; + struct slave *slave; - for (; aggregator; aggregator = __get_next_agg(aggregator)) { - if (aggregator->is_active) { - retval = aggregator; - break; - } - } + bond_for_each_slave(bond, slave, iter) + if (SLAVE_AD_INFO(slave).aggregator.is_active) + return &(SLAVE_AD_INFO(slave).aggregator); - return retval; + return NULL; } /** @@ -1274,12 +1216,17 @@ static void ad_port_selection_logic(struct port *port) { struct aggregator *aggregator, *free_aggregator = NULL, *temp_aggregator; struct port *last_port = NULL, *curr_port; + struct list_head *iter; + struct bonding *bond; + struct slave *slave; int found = 0; // if the port is already Selected, do nothing if (port->sm_vars & AD_PORT_SELECTED) return; + bond = __get_bond_by_port(port); + // if the port is connected to other aggregator, detach it if (port->aggregator) { // detach the port from its former aggregator @@ -1320,8 +1267,8 @@ static void ad_port_selection_logic(struct port *port) } } // search on all aggregators for a suitable aggregator for this port - for (aggregator = __get_first_agg(port); aggregator; - aggregator = __get_next_agg(aggregator)) { + bond_for_each_slave(bond, slave, iter) { + aggregator = &(SLAVE_AD_INFO(slave).aggregator); // keep a free aggregator for later use(if needed) if (!aggregator->lag_ports) { @@ -1515,19 +1462,23 @@ static int agg_device_up(const struct aggregator *agg) static void ad_agg_selection_logic(struct aggregator *agg) { struct aggregator *best, *active, *origin; + struct bonding *bond = agg->slave->bond; + struct list_head *iter; + struct slave *slave; struct port *port; origin = agg; active = __get_active_agg(agg); best = (active && agg_device_up(active)) ? active : NULL; - do { + bond_for_each_slave(bond, slave, iter) { + agg = &(SLAVE_AD_INFO(slave).aggregator); + agg->is_active = 0; if (agg->num_of_ports && agg_device_up(agg)) best = ad_agg_selection_test(best, agg); - - } while ((agg = __get_next_agg(agg))); + } if (best && __get_agg_selection_mode(best->lag_ports) == BOND_AD_STABLE) { @@ -1565,8 +1516,8 @@ static void ad_agg_selection_logic(struct aggregator *agg) best->lag_ports, best->slave, best->slave ? best->slave->dev->name : "NULL"); - for (agg = __get_first_agg(best->lag_ports); agg; - agg = __get_next_agg(agg)) { + bond_for_each_slave(bond, slave, iter) { + agg = &(SLAVE_AD_INFO(slave).aggregator); pr_debug("Agg=%d; P=%d; a k=%d; p k=%d; Ind=%d; Act=%d\n", agg->aggregator_identifier, agg->num_of_ports, @@ -1614,13 +1565,7 @@ static void ad_agg_selection_logic(struct aggregator *agg) } } - if (origin->slave) { - struct bonding *bond; - - bond = bond_get_bond_by_slave(origin->slave); - if (bond) - bond_3ad_set_carrier(bond); - } + bond_3ad_set_carrier(bond); } /** @@ -1969,6 +1914,9 @@ void bond_3ad_unbind_slave(struct slave *slave) struct port *port, *prev_port, *temp_port; struct aggregator *aggregator, *new_aggregator, *temp_aggregator; int select_new_active_agg = 0; + struct bonding *bond = slave->bond; + struct slave *slave_iter; + struct list_head *iter; // find the aggregator related to this slave aggregator = &(SLAVE_AD_INFO(slave).aggregator); @@ -1998,14 +1946,16 @@ void bond_3ad_unbind_slave(struct slave *slave) // reason to search for new aggregator, and that we will find one if ((aggregator->lag_ports != port) || (aggregator->lag_ports->next_port_in_aggregator)) { // find new aggregator for the related port(s) - new_aggregator = __get_first_agg(port); - for (; new_aggregator; new_aggregator = __get_next_agg(new_aggregator)) { + bond_for_each_slave(bond, slave_iter, iter) { + new_aggregator = &(SLAVE_AD_INFO(slave_iter).aggregator); // if the new aggregator is empty, or it is connected to our port only if (!new_aggregator->lag_ports || ((new_aggregator->lag_ports == port) && !new_aggregator->lag_ports->next_port_in_aggregator)) break; } + if (!slave_iter) + new_aggregator = NULL; // if new aggregator found, copy the aggregator's parameters // and connect the related lag_ports to the new aggregator if ((new_aggregator) && ((!new_aggregator->lag_ports) || ((new_aggregator->lag_ports == port) && !new_aggregator->lag_ports->next_port_in_aggregator))) { @@ -2056,15 +2006,17 @@ void bond_3ad_unbind_slave(struct slave *slave) pr_info("%s: Removing an active aggregator\n", slave->bond->dev->name); // select new active aggregator - ad_agg_selection_logic(__get_first_agg(port)); + temp_aggregator = __get_first_agg(port); + if (temp_aggregator) + ad_agg_selection_logic(temp_aggregator); } } } pr_debug("Unbinding port %d\n", port->actor_port_number); // find the aggregator that this port is connected to - temp_aggregator = __get_first_agg(port); - for (; temp_aggregator; temp_aggregator = __get_next_agg(temp_aggregator)) { + bond_for_each_slave(bond, slave_iter, iter) { + temp_aggregator = &(SLAVE_AD_INFO(slave_iter).aggregator); prev_port = NULL; // search the port in the aggregator's related ports for (temp_port = temp_aggregator->lag_ports; temp_port; @@ -2111,19 +2063,24 @@ void bond_3ad_state_machine_handler(struct work_struct *work) { struct bonding *bond = container_of(work, struct bonding, ad_work.work); - struct port *port; struct aggregator *aggregator; + struct list_head *iter; + struct slave *slave; + struct port *port; read_lock(&bond->lock); //check if there are any slaves - if (list_empty(&bond->slave_list)) + if (!bond_has_slaves(bond)) goto re_arm; // check if agg_select_timer timer after initialize is timed out if (BOND_AD_INFO(bond).agg_select_timer && !(--BOND_AD_INFO(bond).agg_select_timer)) { + slave = bond_first_slave(bond); + port = slave ? &(SLAVE_AD_INFO(slave).port) : NULL; + // select the active aggregator for the bond - if ((port = __get_first_port(bond))) { + if (port) { if (!port->slave) { pr_warning("%s: Warning: bond's first port is uninitialized\n", bond->dev->name); @@ -2137,7 +2094,8 @@ void bond_3ad_state_machine_handler(struct work_struct *work) } // for each port run the state machines - for (port = __get_first_port(bond); port; port = __get_next_port(port)) { + bond_for_each_slave(bond, slave, iter) { + port = &(SLAVE_AD_INFO(slave).port); if (!port->slave) { pr_warning("%s: Warning: Found an uninitialized port\n", bond->dev->name); @@ -2382,9 +2340,12 @@ int __bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info) { struct aggregator *aggregator = NULL; + struct list_head *iter; + struct slave *slave; struct port *port; - for (port = __get_first_port(bond); port; port = __get_next_port(port)) { + bond_for_each_slave(bond, slave, iter) { + port = &(SLAVE_AD_INFO(slave).port); if (port->aggregator && port->aggregator->is_active) { aggregator = port->aggregator; break; @@ -2417,14 +2378,15 @@ int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info) int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev) { - struct slave *slave, *start_at; struct bonding *bond = netdev_priv(dev); - int slave_agg_no; - int slaves_in_agg; - int agg_id; - int i; + struct slave *slave, *first_ok_slave; + struct aggregator *agg; struct ad_info ad_info; + struct list_head *iter; + int slaves_in_agg; + int slave_agg_no; int res = 1; + int agg_id; read_lock(&bond->lock); if (__bond_3ad_get_active_agg_info(bond, &ad_info)) { @@ -2437,20 +2399,28 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev) agg_id = ad_info.aggregator_id; if (slaves_in_agg == 0) { - /*the aggregator is empty*/ pr_debug("%s: Error: active aggregator is empty\n", dev->name); goto out; } - slave_agg_no = bond->xmit_hash_policy(skb, slaves_in_agg); + slave_agg_no = bond_xmit_hash(bond, skb, slaves_in_agg); + first_ok_slave = NULL; - bond_for_each_slave(bond, slave) { - struct aggregator *agg = SLAVE_AD_INFO(slave).port.aggregator; + bond_for_each_slave(bond, slave, iter) { + agg = SLAVE_AD_INFO(slave).port.aggregator; + if (!agg || agg->aggregator_identifier != agg_id) + continue; - if (agg && (agg->aggregator_identifier == agg_id)) { + if (slave_agg_no >= 0) { + if (!first_ok_slave && SLAVE_IS_OK(slave)) + first_ok_slave = slave; slave_agg_no--; - if (slave_agg_no < 0) - break; + continue; + } + + if (SLAVE_IS_OK(slave)) { + res = bond_dev_queue_xmit(bond, skb, slave->dev); + goto out; } } @@ -2460,20 +2430,10 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev) goto out; } - start_at = slave; - - bond_for_each_slave_from(bond, slave, i, start_at) { - int slave_agg_id = 0; - struct aggregator *agg = SLAVE_AD_INFO(slave).port.aggregator; - - if (agg) - slave_agg_id = agg->aggregator_identifier; - - if (SLAVE_IS_OK(slave) && agg && (slave_agg_id == agg_id)) { - res = bond_dev_queue_xmit(bond, skb, slave->dev); - break; - } - } + /* we couldn't find any suitable slave after the agg_no, so use the + * first suitable found, if found. */ + if (first_ok_slave) + res = bond_dev_queue_xmit(bond, skb, first_ok_slave->dev); out: read_unlock(&bond->lock); @@ -2515,11 +2475,12 @@ int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond, void bond_3ad_update_lacp_rate(struct bonding *bond) { struct port *port = NULL; + struct list_head *iter; struct slave *slave; int lacp_fast; lacp_fast = bond->params.lacp_fast; - bond_for_each_slave(bond, slave) { + bond_for_each_slave(bond, slave, iter) { port = &(SLAVE_AD_INFO(slave).port); __get_state_machine_lock(port); if (lacp_fast) diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index f428ef574372..e96041816b5b 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c @@ -223,13 +223,14 @@ static long long compute_gap(struct slave *slave) static struct slave *tlb_get_least_loaded_slave(struct bonding *bond) { struct slave *slave, *least_loaded; + struct list_head *iter; long long max_gap; least_loaded = NULL; max_gap = LLONG_MIN; /* Find the slave with the largest gap */ - bond_for_each_slave(bond, slave) { + bond_for_each_slave(bond, slave, iter) { if (SLAVE_IS_OK(slave)) { long long gap = compute_gap(slave); @@ -382,30 +383,31 @@ out: static struct slave *rlb_next_rx_slave(struct bonding *bond) { struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); - struct slave *rx_slave, *slave, *start_at; - int i = 0; - - if (bond_info->next_rx_slave) - start_at = bond_info->next_rx_slave; - else - start_at = bond_first_slave(bond); - - rx_slave = NULL; + struct slave *before = NULL, *rx_slave = NULL, *slave; + struct list_head *iter; + bool found = false; - bond_for_each_slave_from(bond, slave, i, start_at) { - if (SLAVE_IS_OK(slave)) { - if (!rx_slave) { - rx_slave = slave; - } else if (slave->speed > rx_slave->speed) { + bond_for_each_slave(bond, slave, iter) { + if (!SLAVE_IS_OK(slave)) + continue; + if (!found) { + if (!before || before->speed < slave->speed) + before = slave; + } else { + if (!rx_slave || rx_slave->speed < slave->speed) rx_slave = slave; - } } + if (slave == bond_info->rx_slave) + found = true; } + /* we didn't find anything after the current or we have something + * better before and up to the current slave + */ + if (!rx_slave || (before && rx_slave->speed < before->speed)) + rx_slave = before; - if (rx_slave) { - slave = bond_next_slave(bond, rx_slave); - bond_info->next_rx_slave = slave; - } + if (rx_slave) + bond_info->rx_slave = rx_slave; return rx_slave; } @@ -1019,7 +1021,7 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[]) /* loop through vlans and send one packet for each */ rcu_read_lock(); - netdev_for_each_upper_dev_rcu(bond->dev, upper, iter) { + netdev_for_each_all_upper_dev_rcu(bond->dev, upper, iter) { if (upper->priv_flags & IFF_802_1Q_VLAN) alb_send_lp_vid(slave, mac_addr, vlan_dev_vlan_id(upper)); @@ -1172,10 +1174,11 @@ static void alb_change_hw_addr_on_detach(struct bonding *bond, struct slave *sla */ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slave *slave) { - struct slave *tmp_slave1, *free_mac_slave = NULL; struct slave *has_bond_addr = bond->curr_active_slave; + struct slave *tmp_slave1, *free_mac_slave = NULL; + struct list_head *iter; - if (list_empty(&bond->slave_list)) { + if (!bond_has_slaves(bond)) { /* this is the first slave */ return 0; } @@ -1196,7 +1199,7 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav /* The slave's address is equal to the address of the bond. * Search for a spare address in the bond for this slave. */ - bond_for_each_slave(bond, tmp_slave1) { + bond_for_each_slave(bond, tmp_slave1, iter) { if (!bond_slave_has_mac(bond, tmp_slave1->perm_hwaddr)) { /* no slave has tmp_slave1's perm addr * as its curr addr @@ -1246,15 +1249,16 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav */ static int alb_set_mac_address(struct bonding *bond, void *addr) { - char tmp_addr[ETH_ALEN]; - struct slave *slave; + struct slave *slave, *rollback_slave; + struct list_head *iter; struct sockaddr sa; + char tmp_addr[ETH_ALEN]; int res; if (bond->alb_info.rlb_enabled) return 0; - bond_for_each_slave(bond, slave) { + bond_for_each_slave(bond, slave, iter) { /* save net_device's current hw address */ memcpy(tmp_addr, slave->dev->dev_addr, ETH_ALEN); @@ -1274,10 +1278,12 @@ unwind: sa.sa_family = bond->dev->type; /* unwind from head to the slave that failed */ - bond_for_each_slave_continue_reverse(bond, slave) { - memcpy(tmp_addr, slave->dev->dev_addr, ETH_ALEN); - dev_set_mac_address(slave->dev, &sa); - memcpy(slave->dev->dev_addr, tmp_addr, ETH_ALEN); + bond_for_each_slave(bond, rollback_slave, iter) { + if (rollback_slave == slave) + break; + memcpy(tmp_addr, rollback_slave->dev->dev_addr, ETH_ALEN); + dev_set_mac_address(rollback_slave->dev, &sa); + memcpy(rollback_slave->dev->dev_addr, tmp_addr, ETH_ALEN); } return res; @@ -1458,11 +1464,12 @@ void bond_alb_monitor(struct work_struct *work) struct bonding *bond = container_of(work, struct bonding, alb_work.work); struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); + struct list_head *iter; struct slave *slave; read_lock(&bond->lock); - if (list_empty(&bond->slave_list)) { + if (!bond_has_slaves(bond)) { bond_info->tx_rebalance_counter = 0; bond_info->lp_counter = 0; goto re_arm; @@ -1480,7 +1487,7 @@ void bond_alb_monitor(struct work_struct *work) */ read_lock(&bond->curr_slave_lock); - bond_for_each_slave(bond, slave) + bond_for_each_slave(bond, slave, iter) alb_send_learning_packets(slave, slave->dev->dev_addr); read_unlock(&bond->curr_slave_lock); @@ -1493,7 +1500,7 @@ void bond_alb_monitor(struct work_struct *work) read_lock(&bond->curr_slave_lock); - bond_for_each_slave(bond, slave) { + bond_for_each_slave(bond, slave, iter) { tlb_clear_slave(bond, slave, 1); if (slave == bond->curr_active_slave) { SLAVE_TLB_INFO(slave).load = @@ -1599,13 +1606,13 @@ int bond_alb_init_slave(struct bonding *bond, struct slave *slave) */ void bond_alb_deinit_slave(struct bonding *bond, struct slave *slave) { - if (!list_empty(&bond->slave_list)) + if (bond_has_slaves(bond)) alb_change_hw_addr_on_detach(bond, slave); tlb_clear_slave(bond, slave, 0); if (bond->alb_info.rlb_enabled) { - bond->alb_info.next_rx_slave = NULL; + bond->alb_info.rx_slave = NULL; rlb_clear_slave(bond, slave); } } @@ -1669,7 +1676,7 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave swap_slave = bond->curr_active_slave; rcu_assign_pointer(bond->curr_active_slave, new_slave); - if (!new_slave || list_empty(&bond->slave_list)) + if (!new_slave || !bond_has_slaves(bond)) return; /* set the new curr_active_slave to the bonds mac address diff --git a/drivers/net/bonding/bond_alb.h b/drivers/net/bonding/bond_alb.h index c5eff5dafdfe..4226044efd08 100644 --- a/drivers/net/bonding/bond_alb.h +++ b/drivers/net/bonding/bond_alb.h @@ -154,9 +154,7 @@ struct alb_bond_info { u8 rx_ntt; /* flag - need to transmit * to all rx clients */ - struct slave *next_rx_slave;/* next slave to be assigned - * to a new rx client for - */ + struct slave *rx_slave;/* last slave to xmit from */ u8 primary_is_promisc; /* boolean */ u32 rlb_promisc_timeout_counter;/* counts primary * promiscuity time diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 55bbb8b8200c..dfb4f6dd5de0 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -78,6 +78,7 @@ #include <net/netns/generic.h> #include <net/pkt_sched.h> #include <linux/rculist.h> +#include <net/flow_keys.h> #include "bonding.h" #include "bond_3ad.h" #include "bond_alb.h" @@ -159,7 +160,8 @@ MODULE_PARM_DESC(min_links, "Minimum number of available links before turning on module_param(xmit_hash_policy, charp, 0); MODULE_PARM_DESC(xmit_hash_policy, "balance-xor and 802.3ad hashing method; " "0 for layer 2 (default), 1 for layer 3+4, " - "2 for layer 2+3"); + "2 for layer 2+3, 3 for encap layer 2+3, " + "4 for encap layer 3+4"); module_param(arp_interval, int, 0); MODULE_PARM_DESC(arp_interval, "arp interval in milliseconds"); module_param_array(arp_ip_target, charp, NULL, 0); @@ -217,6 +219,8 @@ const struct bond_parm_tbl xmit_hashtype_tbl[] = { { "layer2", BOND_XMIT_POLICY_LAYER2}, { "layer3+4", BOND_XMIT_POLICY_LAYER34}, { "layer2+3", BOND_XMIT_POLICY_LAYER23}, +{ "encap2+3", BOND_XMIT_POLICY_ENCAP23}, +{ "encap3+4", BOND_XMIT_POLICY_ENCAP34}, { NULL, -1}, }; @@ -332,10 +336,11 @@ static int bond_vlan_rx_add_vid(struct net_device *bond_dev, __be16 proto, u16 vid) { struct bonding *bond = netdev_priv(bond_dev); - struct slave *slave; + struct slave *slave, *rollback_slave; + struct list_head *iter; int res; - bond_for_each_slave(bond, slave) { + bond_for_each_slave(bond, slave, iter) { res = vlan_vid_add(slave->dev, proto, vid); if (res) goto unwind; @@ -344,9 +349,13 @@ static int bond_vlan_rx_add_vid(struct net_device *bond_dev, return 0; unwind: - /* unwind from the slave that failed */ - bond_for_each_slave_continue_reverse(bond, slave) - vlan_vid_del(slave->dev, proto, vid); + /* unwind to the slave that failed */ + bond_for_each_slave(bond, rollback_slave, iter) { + if (rollback_slave == slave) + break; + + vlan_vid_del(rollback_slave->dev, proto, vid); + } return res; } @@ -360,9 +369,10 @@ static int bond_vlan_rx_kill_vid(struct net_device *bond_dev, __be16 proto, u16 vid) { struct bonding *bond = netdev_priv(bond_dev); + struct list_head *iter; struct slave *slave; - bond_for_each_slave(bond, slave) + bond_for_each_slave(bond, slave, iter) vlan_vid_del(slave->dev, proto, vid); if (bond_is_lb(bond)) @@ -382,15 +392,16 @@ static int bond_vlan_rx_kill_vid(struct net_device *bond_dev, */ static int bond_set_carrier(struct bonding *bond) { + struct list_head *iter; struct slave *slave; - if (list_empty(&bond->slave_list)) + if (!bond_has_slaves(bond)) goto down; if (bond->params.mode == BOND_MODE_8023AD) return bond_3ad_set_carrier(bond); - bond_for_each_slave(bond, slave) { + bond_for_each_slave(bond, slave, iter) { if (slave->link == BOND_LINK_UP) { if (!netif_carrier_ok(bond->dev)) { netif_carrier_on(bond->dev); @@ -522,7 +533,9 @@ static int bond_check_dev_link(struct bonding *bond, */ static int bond_set_promiscuity(struct bonding *bond, int inc) { + struct list_head *iter; int err = 0; + if (USES_PRIMARY(bond->params.mode)) { /* write lock already acquired */ if (bond->curr_active_slave) { @@ -532,7 +545,7 @@ static int bond_set_promiscuity(struct bonding *bond, int inc) } else { struct slave *slave; - bond_for_each_slave(bond, slave) { + bond_for_each_slave(bond, slave, iter) { err = dev_set_promiscuity(slave->dev, inc); if (err) return err; @@ -546,7 +559,9 @@ static int bond_set_promiscuity(struct bonding *bond, int inc) */ static int bond_set_allmulti(struct bonding *bond, int inc) { + struct list_head *iter; int err = 0; + if (USES_PRIMARY(bond->params.mode)) { /* write lock already acquired */ if (bond->curr_active_slave) { @@ -556,7 +571,7 @@ static int bond_set_allmulti(struct bonding *bond, int inc) } else { struct slave *slave; - bond_for_each_slave(bond, slave) { + bond_for_each_slave(bond, slave, iter) { err = dev_set_allmulti(slave->dev, inc); if (err) return err; @@ -774,43 +789,24 @@ static bool bond_should_change_active(struct bonding *bond) /** * find_best_interface - select the best available slave to be the active one * @bond: our bonding struct - * - * Warning: Caller must hold curr_slave_lock for writing. */ static struct slave *bond_find_best_slave(struct bonding *bond) { - struct slave *new_active, *old_active; - struct slave *bestslave = NULL; + struct slave *slave, *bestslave = NULL; + struct list_head *iter; int mintime = bond->params.updelay; - int i; - - new_active = bond->curr_active_slave; - - if (!new_active) { /* there were no active slaves left */ - new_active = bond_first_slave(bond); - if (!new_active) - return NULL; /* still no slave, return NULL */ - } - if ((bond->primary_slave) && - bond->primary_slave->link == BOND_LINK_UP && - bond_should_change_active(bond)) { - new_active = bond->primary_slave; - } - - /* remember where to stop iterating over the slaves */ - old_active = new_active; - - bond_for_each_slave_from(bond, new_active, i, old_active) { - if (new_active->link == BOND_LINK_UP) { - return new_active; - } else if (new_active->link == BOND_LINK_BACK && - IS_UP(new_active->dev)) { - /* link up, but waiting for stabilization */ - if (new_active->delay < mintime) { - mintime = new_active->delay; - bestslave = new_active; - } + if (bond->primary_slave && bond->primary_slave->link == BOND_LINK_UP && + bond_should_change_active(bond)) + return bond->primary_slave; + + bond_for_each_slave(bond, slave, iter) { + if (slave->link == BOND_LINK_UP) + return slave; + if (slave->link == BOND_LINK_BACK && IS_UP(slave->dev) && + slave->delay < mintime) { + mintime = slave->delay; + bestslave = slave; } } @@ -980,7 +976,6 @@ void bond_select_active_slave(struct bonding *bond) */ static void bond_attach_slave(struct bonding *bond, struct slave *new_slave) { - list_add_tail_rcu(&new_slave->list, &bond->slave_list); bond->slave_cnt++; } @@ -996,7 +991,6 @@ static void bond_attach_slave(struct bonding *bond, struct slave *new_slave) */ static void bond_detach_slave(struct bonding *bond, struct slave *slave) { - list_del_rcu(&slave->list); bond->slave_cnt--; } @@ -1046,9 +1040,10 @@ static void bond_poll_controller(struct net_device *bond_dev) static void bond_netpoll_cleanup(struct net_device *bond_dev) { struct bonding *bond = netdev_priv(bond_dev); + struct list_head *iter; struct slave *slave; - bond_for_each_slave(bond, slave) + bond_for_each_slave(bond, slave, iter) if (IS_UP(slave->dev)) slave_disable_netpoll(slave); } @@ -1056,10 +1051,11 @@ static void bond_netpoll_cleanup(struct net_device *bond_dev) static int bond_netpoll_setup(struct net_device *dev, struct netpoll_info *ni, gfp_t gfp) { struct bonding *bond = netdev_priv(dev); + struct list_head *iter; struct slave *slave; int err = 0; - bond_for_each_slave(bond, slave) { + bond_for_each_slave(bond, slave, iter) { err = slave_enable_netpoll(slave); if (err) { bond_netpoll_cleanup(dev); @@ -1087,10 +1083,11 @@ static netdev_features_t bond_fix_features(struct net_device *dev, netdev_features_t features) { struct bonding *bond = netdev_priv(dev); + struct list_head *iter; netdev_features_t mask; struct slave *slave; - if (list_empty(&bond->slave_list)) { + if (!bond_has_slaves(bond)) { /* Disable adding VLANs to empty bond. But why? --mq */ features |= NETIF_F_VLAN_CHALLENGED; return features; @@ -1100,7 +1097,7 @@ static netdev_features_t bond_fix_features(struct net_device *dev, features &= ~NETIF_F_ONE_FOR_ALL; features |= NETIF_F_ALL_FOR_ALL; - bond_for_each_slave(bond, slave) { + bond_for_each_slave(bond, slave, iter) { features = netdev_increment_features(features, slave->dev->features, mask); @@ -1118,16 +1115,17 @@ static void bond_compute_features(struct bonding *bond) { unsigned int flags, dst_release_flag = IFF_XMIT_DST_RELEASE; netdev_features_t vlan_features = BOND_VLAN_FEATURES; + struct net_device *bond_dev = bond->dev; + struct list_head *iter; + struct slave *slave; unsigned short max_hard_header_len = ETH_HLEN; unsigned int gso_max_size = GSO_MAX_SIZE; - struct net_device *bond_dev = bond->dev; u16 gso_max_segs = GSO_MAX_SEGS; - struct slave *slave; - if (list_empty(&bond->slave_list)) + if (!bond_has_slaves(bond)) goto done; - bond_for_each_slave(bond, slave) { + bond_for_each_slave(bond, slave, iter) { vlan_features = netdev_increment_features(vlan_features, slave->dev->vlan_features, BOND_VLAN_FEATURES); @@ -1233,11 +1231,12 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb) } static int bond_master_upper_dev_link(struct net_device *bond_dev, - struct net_device *slave_dev) + struct net_device *slave_dev, + struct slave *slave) { int err; - err = netdev_master_upper_dev_link(slave_dev, bond_dev); + err = netdev_master_upper_dev_link_private(slave_dev, bond_dev, slave); if (err) return err; slave_dev->flags |= IFF_SLAVE; @@ -1258,7 +1257,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) { struct bonding *bond = netdev_priv(bond_dev); const struct net_device_ops *slave_ops = slave_dev->netdev_ops; - struct slave *new_slave = NULL; + struct slave *new_slave = NULL, *prev_slave; struct sockaddr addr; int link_reporting; int res = 0, i; @@ -1313,7 +1312,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) * bond ether type mutual exclusion - don't allow slaves of dissimilar * ether type (eg ARPHRD_ETHER and ARPHRD_INFINIBAND) share the same bond */ - if (list_empty(&bond->slave_list)) { + if (!bond_has_slaves(bond)) { if (bond_dev->type != slave_dev->type) { pr_debug("%s: change device type from %d to %d\n", bond_dev->name, @@ -1352,7 +1351,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) } if (slave_ops->ndo_set_mac_address == NULL) { - if (list_empty(&bond->slave_list)) { + if (!bond_has_slaves(bond)) { pr_warning("%s: Warning: The first slave device specified does not support setting the MAC address. Setting fail_over_mac to active.", bond_dev->name); bond->params.fail_over_mac = BOND_FOM_ACTIVE; @@ -1368,7 +1367,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) /* If this is the first slave, then we need to set the master's hardware * address to be the same as the slave's. */ - if (list_empty(&bond->slave_list) && + if (!bond_has_slaves(bond) && bond->dev->addr_assign_type == NET_ADDR_RANDOM) bond_set_dev_addr(bond->dev, slave_dev); @@ -1377,7 +1376,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) res = -ENOMEM; goto err_undo_flags; } - INIT_LIST_HEAD(&new_slave->list); /* * Set the new_slave's queue_id to be zero. Queue ID mapping * is set via sysfs or module option if desired. @@ -1413,17 +1411,11 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) } } - res = bond_master_upper_dev_link(bond_dev, slave_dev); - if (res) { - pr_debug("Error %d calling bond_master_upper_dev_link\n", res); - goto err_restore_mac; - } - /* open the slave since the application closed it */ res = dev_open(slave_dev); if (res) { pr_debug("Opening slave %s failed\n", slave_dev->name); - goto err_unset_master; + goto err_restore_mac; } new_slave->bond = bond; @@ -1481,6 +1473,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) write_lock_bh(&bond->lock); + prev_slave = bond_last_slave(bond); bond_attach_slave(bond, new_slave); new_slave->delay = 0; @@ -1568,16 +1561,13 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) */ bond_set_slave_inactive_flags(new_slave); /* if this is the first slave */ - if (bond_first_slave(bond) == new_slave) { + if (!prev_slave) { SLAVE_AD_INFO(new_slave).id = 1; /* Initialize AD with the number of times that the AD timer is called in 1 second * can be called only after the mac address of the bond is set */ bond_3ad_initialize(bond, 1000/AD_TIMER_INTERVAL); } else { - struct slave *prev_slave; - - prev_slave = bond_prev_slave(bond, new_slave); SLAVE_AD_INFO(new_slave).id = SLAVE_AD_INFO(prev_slave).id + 1; } @@ -1626,17 +1616,20 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) read_unlock(&bond->lock); - res = bond_create_slave_symlinks(bond_dev, slave_dev); - if (res) - goto err_detach; - res = netdev_rx_handler_register(slave_dev, bond_handle_frame, new_slave); if (res) { pr_debug("Error %d calling netdev_rx_handler_register\n", res); - goto err_dest_symlinks; + goto err_detach; + } + + res = bond_master_upper_dev_link(bond_dev, slave_dev, new_slave); + if (res) { + pr_debug("Error %d calling bond_master_upper_dev_link\n", res); + goto err_unregister; } + pr_info("%s: enslaving %s as a%s interface with a%s link.\n", bond_dev->name, slave_dev->name, bond_is_active_slave(new_slave) ? "n active" : " backup", @@ -1646,8 +1639,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) return 0; /* Undo stages on error */ -err_dest_symlinks: - bond_destroy_slave_symlinks(bond_dev, slave_dev); +err_unregister: + netdev_rx_handler_unregister(slave_dev); err_detach: if (!USES_PRIMARY(bond->params.mode)) @@ -1675,9 +1668,6 @@ err_close: slave_dev->priv_flags &= ~IFF_BONDING; dev_close(slave_dev); -err_unset_master: - bond_upper_dev_unlink(bond_dev, slave_dev); - err_restore_mac: if (!bond->params.fail_over_mac) { /* XXX TODO - fom follow mode needs to change master's @@ -1698,7 +1688,7 @@ err_free: err_undo_flags: bond_compute_features(bond); /* Enslave of first slave has failed and we need to fix master's mac */ - if (list_empty(&bond->slave_list) && + if (!bond_has_slaves(bond) && ether_addr_equal(bond_dev->dev_addr, slave_dev->dev_addr)) eth_hw_addr_random(bond_dev); @@ -1724,6 +1714,7 @@ static int __bond_release_one(struct net_device *bond_dev, struct bonding *bond = netdev_priv(bond_dev); struct slave *slave, *oldcurrent; struct sockaddr addr; + int old_flags = bond_dev->flags; netdev_features_t old_features = bond_dev->features; /* slave is not a slave or master is not master of this slave */ @@ -1748,6 +1739,8 @@ static int __bond_release_one(struct net_device *bond_dev, } write_unlock_bh(&bond->lock); + + bond_upper_dev_unlink(bond_dev, slave_dev); /* unregister rx_handler early so bond_handle_frame wouldn't be called * for this slave anymore. */ @@ -1776,7 +1769,7 @@ static int __bond_release_one(struct net_device *bond_dev, if (!all && !bond->params.fail_over_mac) { if (ether_addr_equal(bond_dev->dev_addr, slave->perm_hwaddr) && - !list_empty(&bond->slave_list)) + bond_has_slaves(bond)) pr_warn("%s: Warning: the permanent HWaddr of %s - %pM - is still in use by %s. Set the HWaddr of %s to a different address to avoid conflicts.\n", bond_dev->name, slave_dev->name, slave->perm_hwaddr, @@ -1819,7 +1812,7 @@ static int __bond_release_one(struct net_device *bond_dev, write_lock_bh(&bond->lock); } - if (list_empty(&bond->slave_list)) { + if (!bond_has_slaves(bond)) { bond_set_carrier(bond); eth_hw_addr_random(bond_dev); @@ -1835,7 +1828,7 @@ static int __bond_release_one(struct net_device *bond_dev, unblock_netpoll_tx(); synchronize_rcu(); - if (list_empty(&bond->slave_list)) { + if (!bond_has_slaves(bond)) { call_netdevice_notifiers(NETDEV_CHANGEADDR, bond->dev); call_netdevice_notifiers(NETDEV_RELEASE, bond->dev); } @@ -1847,27 +1840,29 @@ static int __bond_release_one(struct net_device *bond_dev, bond_dev->name, slave_dev->name, bond_dev->name); /* must do this from outside any spinlocks */ - bond_destroy_slave_symlinks(bond_dev, slave_dev); - vlan_vids_del_by_dev(slave_dev, bond_dev); /* If the mode USES_PRIMARY, then this cases was handled above by * bond_change_active_slave(..., NULL) */ if (!USES_PRIMARY(bond->params.mode)) { - /* unset promiscuity level from slave */ - if (bond_dev->flags & IFF_PROMISC) + /* unset promiscuity level from slave + * NOTE: The NETDEV_CHANGEADDR call above may change the value + * of the IFF_PROMISC flag in the bond_dev, but we need the + * value of that flag before that change, as that was the value + * when this slave was attached, so we cache at the start of the + * function and use it here. Same goes for ALLMULTI below + */ + if (old_flags & IFF_PROMISC) dev_set_promiscuity(slave_dev, -1); /* unset allmulti level from slave */ - if (bond_dev->flags & IFF_ALLMULTI) + if (old_flags & IFF_ALLMULTI) dev_set_allmulti(slave_dev, -1); bond_hw_addr_flush(bond_dev, slave_dev); } - bond_upper_dev_unlink(bond_dev, slave_dev); - slave_disable_netpoll(slave); /* close slave before restoring its mac address */ @@ -1906,7 +1901,7 @@ static int bond_release_and_destroy(struct net_device *bond_dev, int ret; ret = bond_release(bond_dev, slave_dev); - if (ret == 0 && list_empty(&bond->slave_list)) { + if (ret == 0 && !bond_has_slaves(bond)) { bond_dev->priv_flags |= IFF_DISABLE_NETPOLL; pr_info("%s: destroying bond %s.\n", bond_dev->name, bond_dev->name); @@ -1987,11 +1982,12 @@ static int bond_info_query(struct net_device *bond_dev, struct ifbond *info) static int bond_slave_info_query(struct net_device *bond_dev, struct ifslave *info) { struct bonding *bond = netdev_priv(bond_dev); + struct list_head *iter; int i = 0, res = -ENODEV; struct slave *slave; read_lock(&bond->lock); - bond_for_each_slave(bond, slave) { + bond_for_each_slave(bond, slave, iter) { if (i++ == (int)info->slave_id) { res = 0; strcpy(info->slave_name, slave->dev->name); @@ -2012,12 +2008,13 @@ static int bond_slave_info_query(struct net_device *bond_dev, struct ifslave *in static int bond_miimon_inspect(struct bonding *bond) { int link_state, commit = 0; + struct list_head *iter; struct slave *slave; bool ignore_updelay; ignore_updelay = !bond->curr_active_slave ? true : false; - bond_for_each_slave(bond, slave) { + bond_for_each_slave(bond, slave, iter) { slave->new_link = BOND_LINK_NOCHANGE; link_state = bond_check_dev_link(bond, slave->dev, 0); @@ -2111,9 +2108,10 @@ static int bond_miimon_inspect(struct bonding *bond) static void bond_miimon_commit(struct bonding *bond) { + struct list_head *iter; struct slave *slave; - bond_for_each_slave(bond, slave) { + bond_for_each_slave(bond, slave, iter) { switch (slave->new_link) { case BOND_LINK_NOCHANGE: continue; @@ -2218,7 +2216,7 @@ void bond_mii_monitor(struct work_struct *work) delay = msecs_to_jiffies(bond->params.miimon); - if (list_empty(&bond->slave_list)) + if (!bond_has_slaves(bond)) goto re_arm; should_notify_peers = bond_should_notify_peers(bond); @@ -2267,7 +2265,7 @@ static bool bond_has_this_ip(struct bonding *bond, __be32 ip) return true; rcu_read_lock(); - netdev_for_each_upper_dev_rcu(bond->dev, upper, iter) { + netdev_for_each_all_upper_dev_rcu(bond->dev, upper, iter) { if (ip == bond_confirm_addr(upper, 0, ip)) { ret = true; break; @@ -2342,10 +2340,12 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) * * TODO: QinQ? */ - netdev_for_each_upper_dev_rcu(bond->dev, vlan_upper, vlan_iter) { + netdev_for_each_all_upper_dev_rcu(bond->dev, vlan_upper, + vlan_iter) { if (!is_vlan_dev(vlan_upper)) continue; - netdev_for_each_upper_dev_rcu(vlan_upper, upper, iter) { + netdev_for_each_all_upper_dev_rcu(vlan_upper, upper, + iter) { if (upper == rt->dst.dev) { vlan_id = vlan_dev_vlan_id(vlan_upper); rcu_read_unlock(); @@ -2358,7 +2358,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) * our upper vlans, then just search for any dev that * matches, and in case it's a vlan - save the id */ - netdev_for_each_upper_dev_rcu(bond->dev, upper, iter) { + netdev_for_each_all_upper_dev_rcu(bond->dev, upper, iter) { if (upper == rt->dst.dev) { /* if it's a vlan - get its VID */ if (is_vlan_dev(upper)) @@ -2505,11 +2505,12 @@ void bond_loadbalance_arp_mon(struct work_struct *work) struct bonding *bond = container_of(work, struct bonding, arp_work.work); struct slave *slave, *oldcurrent; + struct list_head *iter; int do_failover = 0; read_lock(&bond->lock); - if (list_empty(&bond->slave_list)) + if (!bond_has_slaves(bond)) goto re_arm; oldcurrent = bond->curr_active_slave; @@ -2521,7 +2522,7 @@ void bond_loadbalance_arp_mon(struct work_struct *work) * TODO: what about up/down delay in arp mode? it wasn't here before * so it can wait */ - bond_for_each_slave(bond, slave) { + bond_for_each_slave(bond, slave, iter) { unsigned long trans_start = dev_trans_start(slave->dev); if (slave->link != BOND_LINK_UP) { @@ -2612,10 +2613,11 @@ re_arm: static int bond_ab_arp_inspect(struct bonding *bond) { unsigned long trans_start, last_rx; + struct list_head *iter; struct slave *slave; int commit = 0; - bond_for_each_slave(bond, slave) { + bond_for_each_slave(bond, slave, iter) { slave->new_link = BOND_LINK_NOCHANGE; last_rx = slave_last_rx(bond, slave); @@ -2682,9 +2684,10 @@ static int bond_ab_arp_inspect(struct bonding *bond) static void bond_ab_arp_commit(struct bonding *bond) { unsigned long trans_start; + struct list_head *iter; struct slave *slave; - bond_for_each_slave(bond, slave) { + bond_for_each_slave(bond, slave, iter) { switch (slave->new_link) { case BOND_LINK_NOCHANGE: continue; @@ -2755,8 +2758,9 @@ do_failover: */ static void bond_ab_arp_probe(struct bonding *bond) { - struct slave *slave, *next_slave; - int i; + struct slave *slave, *before = NULL, *new_slave = NULL; + struct list_head *iter; + bool found = false; read_lock(&bond->curr_slave_lock); @@ -2786,18 +2790,12 @@ static void bond_ab_arp_probe(struct bonding *bond) bond_set_slave_inactive_flags(bond->current_arp_slave); - /* search for next candidate */ - next_slave = bond_next_slave(bond, bond->current_arp_slave); - bond_for_each_slave_from(bond, slave, i, next_slave) { - if (IS_UP(slave->dev)) { - slave->link = BOND_LINK_BACK; - bond_set_slave_active_flags(slave); - bond_arp_send_all(bond, slave); - slave->jiffies = jiffies; - bond->current_arp_slave = slave; - break; - } + bond_for_each_slave(bond, slave, iter) { + if (!found && !before && IS_UP(slave->dev)) + before = slave; + if (found && !new_slave && IS_UP(slave->dev)) + new_slave = slave; /* if the link state is up at this point, we * mark it down - this can happen if we have * simultaneous link failures and @@ -2805,7 +2803,7 @@ static void bond_ab_arp_probe(struct bonding *bond) * one the current slave so it is still marked * up when it is actually down */ - if (slave->link == BOND_LINK_UP) { + if (!IS_UP(slave->dev) && slave->link == BOND_LINK_UP) { slave->link = BOND_LINK_DOWN; if (slave->link_failure_count < UINT_MAX) slave->link_failure_count++; @@ -2815,7 +2813,22 @@ static void bond_ab_arp_probe(struct bonding *bond) pr_info("%s: backup interface %s is now down.\n", bond->dev->name, slave->dev->name); } + if (slave == bond->current_arp_slave) + found = true; } + + if (!new_slave && before) + new_slave = before; + + if (!new_slave) + return; + + new_slave->link = BOND_LINK_BACK; + bond_set_slave_active_flags(new_slave); + bond_arp_send_all(bond, new_slave); + new_slave->jiffies = jiffies; + bond->current_arp_slave = new_slave; + } void bond_activebackup_arp_mon(struct work_struct *work) @@ -2829,7 +2842,7 @@ void bond_activebackup_arp_mon(struct work_struct *work) delta_in_ticks = msecs_to_jiffies(bond->params.arp_interval); - if (list_empty(&bond->slave_list)) + if (!bond_has_slaves(bond)) goto re_arm; should_notify_peers = bond_should_notify_peers(bond); @@ -3026,99 +3039,85 @@ static struct notifier_block bond_netdev_notifier = { /*---------------------------- Hashing Policies -----------------------------*/ -/* - * Hash for the output device based upon layer 2 data - */ -static int bond_xmit_hash_policy_l2(struct sk_buff *skb, int count) +/* L2 hash helper */ +static inline u32 bond_eth_hash(struct sk_buff *skb) { struct ethhdr *data = (struct ethhdr *)skb->data; if (skb_headlen(skb) >= offsetof(struct ethhdr, h_proto)) - return (data->h_dest[5] ^ data->h_source[5]) % count; + return data->h_dest[5] ^ data->h_source[5]; return 0; } -/* - * Hash for the output device based upon layer 2 and layer 3 data. If - * the packet is not IP, fall back on bond_xmit_hash_policy_l2() - */ -static int bond_xmit_hash_policy_l23(struct sk_buff *skb, int count) +/* Extract the appropriate headers based on bond's xmit policy */ +static bool bond_flow_dissect(struct bonding *bond, struct sk_buff *skb, + struct flow_keys *fk) { - const struct ethhdr *data; + const struct ipv6hdr *iph6; const struct iphdr *iph; - const struct ipv6hdr *ipv6h; - u32 v6hash; - const __be32 *s, *d; + int noff, proto = -1; - if (skb->protocol == htons(ETH_P_IP) && - pskb_network_may_pull(skb, sizeof(*iph))) { + if (bond->params.xmit_policy > BOND_XMIT_POLICY_LAYER23) + return skb_flow_dissect(skb, fk); + + fk->ports = 0; + noff = skb_network_offset(skb); + if (skb->protocol == htons(ETH_P_IP)) { + if (!pskb_may_pull(skb, noff + sizeof(*iph))) + return false; iph = ip_hdr(skb); - data = (struct ethhdr *)skb->data; - return ((ntohl(iph->saddr ^ iph->daddr) & 0xffff) ^ - (data->h_dest[5] ^ data->h_source[5])) % count; - } else if (skb->protocol == htons(ETH_P_IPV6) && - pskb_network_may_pull(skb, sizeof(*ipv6h))) { - ipv6h = ipv6_hdr(skb); - data = (struct ethhdr *)skb->data; - s = &ipv6h->saddr.s6_addr32[0]; - d = &ipv6h->daddr.s6_addr32[0]; - v6hash = (s[1] ^ d[1]) ^ (s[2] ^ d[2]) ^ (s[3] ^ d[3]); - v6hash ^= (v6hash >> 24) ^ (v6hash >> 16) ^ (v6hash >> 8); - return (v6hash ^ data->h_dest[5] ^ data->h_source[5]) % count; - } - - return bond_xmit_hash_policy_l2(skb, count); + fk->src = iph->saddr; + fk->dst = iph->daddr; + noff += iph->ihl << 2; + if (!ip_is_fragment(iph)) + proto = iph->protocol; + } else if (skb->protocol == htons(ETH_P_IPV6)) { + if (!pskb_may_pull(skb, noff + sizeof(*iph6))) + return false; + iph6 = ipv6_hdr(skb); + fk->src = (__force __be32)ipv6_addr_hash(&iph6->saddr); + fk->dst = (__force __be32)ipv6_addr_hash(&iph6->daddr); + noff += sizeof(*iph6); + proto = iph6->nexthdr; + } else { + return false; + } + if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER34 && proto >= 0) + fk->ports = skb_flow_get_ports(skb, noff, proto); + + return true; } -/* - * Hash for the output device based upon layer 3 and layer 4 data. If - * the packet is a frag or not TCP or UDP, just use layer 3 data. If it is - * altogether not IP, fall back on bond_xmit_hash_policy_l2() +/** + * bond_xmit_hash - generate a hash value based on the xmit policy + * @bond: bonding device + * @skb: buffer to use for headers + * @count: modulo value + * + * This function will extract the necessary headers from the skb buffer and use + * them to generate a hash based on the xmit_policy set in the bonding device + * which will be reduced modulo count before returning. */ -static int bond_xmit_hash_policy_l34(struct sk_buff *skb, int count) +int bond_xmit_hash(struct bonding *bond, struct sk_buff *skb, int count) { - u32 layer4_xor = 0; - const struct iphdr *iph; - const struct ipv6hdr *ipv6h; - const __be32 *s, *d; - const __be16 *l4 = NULL; - __be16 _l4[2]; - int noff = skb_network_offset(skb); - int poff; - - if (skb->protocol == htons(ETH_P_IP) && - pskb_may_pull(skb, noff + sizeof(*iph))) { - iph = ip_hdr(skb); - poff = proto_ports_offset(iph->protocol); + struct flow_keys flow; + u32 hash; - if (!ip_is_fragment(iph) && poff >= 0) { - l4 = skb_header_pointer(skb, noff + (iph->ihl << 2) + poff, - sizeof(_l4), &_l4); - if (l4) - layer4_xor = ntohs(l4[0] ^ l4[1]); - } - return (layer4_xor ^ - ((ntohl(iph->saddr ^ iph->daddr)) & 0xffff)) % count; - } else if (skb->protocol == htons(ETH_P_IPV6) && - pskb_may_pull(skb, noff + sizeof(*ipv6h))) { - ipv6h = ipv6_hdr(skb); - poff = proto_ports_offset(ipv6h->nexthdr); - if (poff >= 0) { - l4 = skb_header_pointer(skb, noff + sizeof(*ipv6h) + poff, - sizeof(_l4), &_l4); - if (l4) - layer4_xor = ntohs(l4[0] ^ l4[1]); - } - s = &ipv6h->saddr.s6_addr32[0]; - d = &ipv6h->daddr.s6_addr32[0]; - layer4_xor ^= (s[1] ^ d[1]) ^ (s[2] ^ d[2]) ^ (s[3] ^ d[3]); - layer4_xor ^= (layer4_xor >> 24) ^ (layer4_xor >> 16) ^ - (layer4_xor >> 8); - return layer4_xor % count; - } + if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER2 || + !bond_flow_dissect(bond, skb, &flow)) + return bond_eth_hash(skb) % count; - return bond_xmit_hash_policy_l2(skb, count); + if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER23 || + bond->params.xmit_policy == BOND_XMIT_POLICY_ENCAP23) + hash = bond_eth_hash(skb); + else + hash = (__force u32)flow.ports; + hash ^= (__force u32)flow.dst ^ (__force u32)flow.src; + hash ^= (hash >> 16); + hash ^= (hash >> 8); + + return hash % count; } /*-------------------------- Device entry points ----------------------------*/ @@ -3148,13 +3147,14 @@ static void bond_work_cancel_all(struct bonding *bond) static int bond_open(struct net_device *bond_dev) { struct bonding *bond = netdev_priv(bond_dev); + struct list_head *iter; struct slave *slave; /* reset slave->backup and slave->inactive */ read_lock(&bond->lock); - if (!list_empty(&bond->slave_list)) { + if (bond_has_slaves(bond)) { read_lock(&bond->curr_slave_lock); - bond_for_each_slave(bond, slave) { + bond_for_each_slave(bond, slave, iter) { if ((bond->params.mode == BOND_MODE_ACTIVEBACKUP) && (slave != bond->curr_active_slave)) { bond_set_slave_inactive_flags(slave); @@ -3214,12 +3214,13 @@ static struct rtnl_link_stats64 *bond_get_stats(struct net_device *bond_dev, { struct bonding *bond = netdev_priv(bond_dev); struct rtnl_link_stats64 temp; + struct list_head *iter; struct slave *slave; memset(stats, 0, sizeof(*stats)); read_lock_bh(&bond->lock); - bond_for_each_slave(bond, slave) { + bond_for_each_slave(bond, slave, iter) { const struct rtnl_link_stats64 *sstats = dev_get_stats(slave->dev, &temp); @@ -3386,22 +3387,24 @@ static void bond_change_rx_flags(struct net_device *bond_dev, int change) static void bond_set_rx_mode(struct net_device *bond_dev) { struct bonding *bond = netdev_priv(bond_dev); + struct list_head *iter; struct slave *slave; - ASSERT_RTNL(); + rcu_read_lock(); if (USES_PRIMARY(bond->params.mode)) { - slave = rtnl_dereference(bond->curr_active_slave); + slave = rcu_dereference(bond->curr_active_slave); if (slave) { dev_uc_sync(slave->dev, bond_dev); dev_mc_sync(slave->dev, bond_dev); } } else { - bond_for_each_slave(bond, slave) { + bond_for_each_slave_rcu(bond, slave, iter) { dev_uc_sync_multiple(slave->dev, bond_dev); dev_mc_sync_multiple(slave->dev, bond_dev); } } + rcu_read_unlock(); } static int bond_neigh_init(struct neighbour *n) @@ -3464,7 +3467,8 @@ static int bond_neigh_setup(struct net_device *dev, static int bond_change_mtu(struct net_device *bond_dev, int new_mtu) { struct bonding *bond = netdev_priv(bond_dev); - struct slave *slave; + struct slave *slave, *rollback_slave; + struct list_head *iter; int res = 0; pr_debug("bond=%p, name=%s, new_mtu=%d\n", bond, @@ -3485,10 +3489,9 @@ static int bond_change_mtu(struct net_device *bond_dev, int new_mtu) * call to the base driver. */ - bond_for_each_slave(bond, slave) { - pr_debug("s %p s->p %p c_m %p\n", + bond_for_each_slave(bond, slave, iter) { + pr_debug("s %p c_m %p\n", slave, - bond_prev_slave(bond, slave), slave->dev->netdev_ops->ndo_change_mtu); res = dev_set_mtu(slave->dev, new_mtu); @@ -3513,13 +3516,16 @@ static int bond_change_mtu(struct net_device *bond_dev, int new_mtu) unwind: /* unwind from head to the slave that failed */ - bond_for_each_slave_continue_reverse(bond, slave) { + bond_for_each_slave(bond, rollback_slave, iter) { int tmp_res; - tmp_res = dev_set_mtu(slave->dev, bond_dev->mtu); + if (rollback_slave == slave) + break; + + tmp_res = dev_set_mtu(rollback_slave->dev, bond_dev->mtu); if (tmp_res) { pr_debug("unwind err %d dev %s\n", - tmp_res, slave->dev->name); + tmp_res, rollback_slave->dev->name); } } @@ -3536,8 +3542,9 @@ unwind: static int bond_set_mac_address(struct net_device *bond_dev, void *addr) { struct bonding *bond = netdev_priv(bond_dev); + struct slave *slave, *rollback_slave; struct sockaddr *sa = addr, tmp_sa; - struct slave *slave; + struct list_head *iter; int res = 0; if (bond->params.mode == BOND_MODE_ALB) @@ -3571,7 +3578,7 @@ static int bond_set_mac_address(struct net_device *bond_dev, void *addr) * call to the base driver. */ - bond_for_each_slave(bond, slave) { + bond_for_each_slave(bond, slave, iter) { const struct net_device_ops *slave_ops = slave->dev->netdev_ops; pr_debug("slave %p %s\n", slave, slave->dev->name); @@ -3603,13 +3610,16 @@ unwind: tmp_sa.sa_family = bond_dev->type; /* unwind from head to the slave that failed */ - bond_for_each_slave_continue_reverse(bond, slave) { + bond_for_each_slave(bond, rollback_slave, iter) { int tmp_res; - tmp_res = dev_set_mac_address(slave->dev, &tmp_sa); + if (rollback_slave == slave) + break; + + tmp_res = dev_set_mac_address(rollback_slave->dev, &tmp_sa); if (tmp_res) { pr_debug("unwind err %d dev %s\n", - tmp_res, slave->dev->name); + tmp_res, rollback_slave->dev->name); } } @@ -3628,11 +3638,12 @@ unwind: */ void bond_xmit_slave_id(struct bonding *bond, struct sk_buff *skb, int slave_id) { + struct list_head *iter; struct slave *slave; int i = slave_id; /* Here we start from the slave with slave_id */ - bond_for_each_slave_rcu(bond, slave) { + bond_for_each_slave_rcu(bond, slave, iter) { if (--i < 0) { if (slave_can_tx(slave)) { bond_dev_queue_xmit(bond, skb, slave->dev); @@ -3643,7 +3654,7 @@ void bond_xmit_slave_id(struct bonding *bond, struct sk_buff *skb, int slave_id) /* Here we start from the first slave up to slave_id */ i = slave_id; - bond_for_each_slave_rcu(bond, slave) { + bond_for_each_slave_rcu(bond, slave, iter) { if (--i < 0) break; if (slave_can_tx(slave)) { @@ -3700,8 +3711,7 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_d return NETDEV_TX_OK; } -/* - * In bond_xmit_xor() , we determine the output device by using a pre- +/* In bond_xmit_xor() , we determine the output device by using a pre- * determined xmit_hash_policy(), If the selected device is not enabled, * find the next active slave. */ @@ -3709,8 +3719,7 @@ static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev) { struct bonding *bond = netdev_priv(bond_dev); - bond_xmit_slave_id(bond, skb, - bond->xmit_hash_policy(skb, bond->slave_cnt)); + bond_xmit_slave_id(bond, skb, bond_xmit_hash(bond, skb, bond->slave_cnt)); return NETDEV_TX_OK; } @@ -3720,8 +3729,9 @@ static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev) { struct bonding *bond = netdev_priv(bond_dev); struct slave *slave = NULL; + struct list_head *iter; - bond_for_each_slave_rcu(bond, slave) { + bond_for_each_slave_rcu(bond, slave, iter) { if (bond_is_last_slave(bond, slave)) break; if (IS_UP(slave->dev) && slave->link == BOND_LINK_UP) { @@ -3746,22 +3756,6 @@ static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev) /*------------------------- Device initialization ---------------------------*/ -static void bond_set_xmit_hash_policy(struct bonding *bond) -{ - switch (bond->params.xmit_policy) { - case BOND_XMIT_POLICY_LAYER23: - bond->xmit_hash_policy = bond_xmit_hash_policy_l23; - break; - case BOND_XMIT_POLICY_LAYER34: - bond->xmit_hash_policy = bond_xmit_hash_policy_l34; - break; - case BOND_XMIT_POLICY_LAYER2: - default: - bond->xmit_hash_policy = bond_xmit_hash_policy_l2; - break; - } -} - /* * Lookup the slave that corresponds to a qid */ @@ -3770,13 +3764,14 @@ static inline int bond_slave_override(struct bonding *bond, { struct slave *slave = NULL; struct slave *check_slave; + struct list_head *iter; int res = 1; if (!skb->queue_mapping) return 1; /* Find out if any slaves have the same mapping as this skb. */ - bond_for_each_slave_rcu(bond, check_slave) { + bond_for_each_slave_rcu(bond, check_slave, iter) { if (check_slave->queue_id == skb->queue_mapping) { slave = check_slave; break; @@ -3862,7 +3857,7 @@ static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_BUSY; rcu_read_lock(); - if (!list_empty(&bond->slave_list)) + if (bond_has_slaves(bond)) ret = __bond_start_xmit(skb, dev); else kfree_skb(skb); @@ -3871,43 +3866,12 @@ static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev) return ret; } -/* - * set bond mode specific net device operations - */ -void bond_set_mode_ops(struct bonding *bond, int mode) -{ - struct net_device *bond_dev = bond->dev; - - switch (mode) { - case BOND_MODE_ROUNDROBIN: - break; - case BOND_MODE_ACTIVEBACKUP: - break; - case BOND_MODE_XOR: - bond_set_xmit_hash_policy(bond); - break; - case BOND_MODE_BROADCAST: - break; - case BOND_MODE_8023AD: - bond_set_xmit_hash_policy(bond); - break; - case BOND_MODE_ALB: - /* FALLTHRU */ - case BOND_MODE_TLB: - break; - default: - /* Should never happen, mode already checked */ - pr_err("%s: Error: Unknown bonding mode %d\n", - bond_dev->name, mode); - break; - } -} - static int bond_ethtool_get_settings(struct net_device *bond_dev, struct ethtool_cmd *ecmd) { struct bonding *bond = netdev_priv(bond_dev); unsigned long speed = 0; + struct list_head *iter; struct slave *slave; ecmd->duplex = DUPLEX_UNKNOWN; @@ -3919,7 +3883,7 @@ static int bond_ethtool_get_settings(struct net_device *bond_dev, * this is an accurate maximum. */ read_lock(&bond->lock); - bond_for_each_slave(bond, slave) { + bond_for_each_slave(bond, slave, iter) { if (SLAVE_IS_OK(slave)) { if (slave->speed != SPEED_UNKNOWN) speed += slave->speed; @@ -3994,7 +3958,6 @@ static void bond_setup(struct net_device *bond_dev) /* initialize rwlocks */ rwlock_init(&bond->lock); rwlock_init(&bond->curr_slave_lock); - INIT_LIST_HEAD(&bond->slave_list); bond->params = bonding_defaults; /* Initialize pointers */ @@ -4004,7 +3967,6 @@ static void bond_setup(struct net_device *bond_dev) ether_setup(bond_dev); bond_dev->netdev_ops = &bond_netdev_ops; bond_dev->ethtool_ops = &bond_ethtool_ops; - bond_set_mode_ops(bond, bond->params.mode); bond_dev->destructor = bond_destructor; @@ -4050,12 +4012,13 @@ static void bond_setup(struct net_device *bond_dev) static void bond_uninit(struct net_device *bond_dev) { struct bonding *bond = netdev_priv(bond_dev); - struct slave *slave, *tmp_slave; + struct list_head *iter; + struct slave *slave; bond_netpoll_cleanup(bond_dev); /* Release the bonded slaves */ - list_for_each_entry_safe(slave, tmp_slave, &bond->slave_list, list) + bond_for_each_slave(bond, slave, iter) __bond_release_one(bond_dev, slave->dev, true); pr_info("%s: released all slaves\n", bond_dev->name); diff --git a/drivers/net/bonding/bond_procfs.c b/drivers/net/bonding/bond_procfs.c index 20a6ee25bb63..fb868d6c22da 100644 --- a/drivers/net/bonding/bond_procfs.c +++ b/drivers/net/bonding/bond_procfs.c @@ -10,8 +10,9 @@ static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos) __acquires(&bond->lock) { struct bonding *bond = seq->private; - loff_t off = 0; + struct list_head *iter; struct slave *slave; + loff_t off = 0; /* make sure the bond won't be taken away */ rcu_read_lock(); @@ -20,7 +21,7 @@ static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos) if (*pos == 0) return SEQ_START_TOKEN; - bond_for_each_slave(bond, slave) + bond_for_each_slave(bond, slave, iter) if (++off == *pos) return slave; @@ -30,17 +31,25 @@ static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos) static void *bond_info_seq_next(struct seq_file *seq, void *v, loff_t *pos) { struct bonding *bond = seq->private; - struct slave *slave = v; + struct list_head *iter; + struct slave *slave; + bool found = false; ++*pos; if (v == SEQ_START_TOKEN) return bond_first_slave(bond); - if (bond_is_last_slave(bond, slave)) + if (bond_is_last_slave(bond, v)) return NULL; - slave = bond_next_slave(bond, slave); - return slave; + bond_for_each_slave(bond, slave, iter) { + if (found) + return slave; + if (slave == v) + found = true; + } + + return NULL; } static void bond_info_seq_stop(struct seq_file *seq, void *v) diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index c29b836749b6..e9249527e7e7 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -168,41 +168,6 @@ static const struct class_attribute class_attr_bonding_masters = { .namespace = bonding_namespace, }; -int bond_create_slave_symlinks(struct net_device *master, - struct net_device *slave) -{ - char linkname[IFNAMSIZ+7]; - int ret = 0; - - /* first, create a link from the slave back to the master */ - ret = sysfs_create_link(&(slave->dev.kobj), &(master->dev.kobj), - "master"); - if (ret) - return ret; - /* next, create a link from the master to the slave */ - sprintf(linkname, "slave_%s", slave->name); - ret = sysfs_create_link(&(master->dev.kobj), &(slave->dev.kobj), - linkname); - - /* free the master link created earlier in case of error */ - if (ret) - sysfs_remove_link(&(slave->dev.kobj), "master"); - - return ret; - -} - -void bond_destroy_slave_symlinks(struct net_device *master, - struct net_device *slave) -{ - char linkname[IFNAMSIZ+7]; - - sysfs_remove_link(&(slave->dev.kobj), "master"); - sprintf(linkname, "slave_%s", slave->name); - sysfs_remove_link(&(master->dev.kobj), linkname); -} - - /* * Show the slaves in the current bond. */ @@ -210,11 +175,12 @@ static ssize_t bonding_show_slaves(struct device *d, struct device_attribute *attr, char *buf) { struct bonding *bond = to_bond(d); + struct list_head *iter; struct slave *slave; int res = 0; read_lock(&bond->lock); - bond_for_each_slave(bond, slave) { + bond_for_each_slave(bond, slave, iter) { if (res > (PAGE_SIZE - IFNAMSIZ)) { /* not enough space for another interface name */ if ((PAGE_SIZE - res) > 10) @@ -326,7 +292,7 @@ static ssize_t bonding_store_mode(struct device *d, goto out; } - if (!list_empty(&bond->slave_list)) { + if (bond_has_slaves(bond)) { pr_err("unable to update mode of %s because it has slaves.\n", bond->dev->name); ret = -EPERM; @@ -352,7 +318,6 @@ static ssize_t bonding_store_mode(struct device *d, /* don't cache arp_validate between modes */ bond->params.arp_validate = BOND_ARP_VALIDATE_NONE; bond->params.mode = new_value; - bond_set_mode_ops(bond, bond->params.mode); pr_info("%s: setting mode to %s (%d).\n", bond->dev->name, bond_mode_tbl[new_value].modename, new_value); @@ -392,7 +357,6 @@ static ssize_t bonding_store_xmit_hash(struct device *d, ret = -EINVAL; } else { bond->params.xmit_policy = new_value; - bond_set_mode_ops(bond, bond->params.mode); pr_info("%s: setting xmit hash policy to %s (%d).\n", bond->dev->name, xmit_hashtype_tbl[new_value].modename, new_value); @@ -522,7 +486,7 @@ static ssize_t bonding_store_fail_over_mac(struct device *d, if (!rtnl_trylock()) return restart_syscall(); - if (!list_empty(&bond->slave_list)) { + if (bond_has_slaves(bond)) { pr_err("%s: Can't alter fail_over_mac with slaves in bond.\n", bond->dev->name); ret = -EPERM; @@ -656,6 +620,7 @@ static ssize_t bonding_store_arp_targets(struct device *d, const char *buf, size_t count) { struct bonding *bond = to_bond(d); + struct list_head *iter; struct slave *slave; __be32 newtarget, *targets; unsigned long *targets_rx; @@ -688,7 +653,7 @@ static ssize_t bonding_store_arp_targets(struct device *d, &newtarget); /* not to race with bond_arp_rcv */ write_lock_bh(&bond->lock); - bond_for_each_slave(bond, slave) + bond_for_each_slave(bond, slave, iter) slave->target_last_arp_rx[ind] = jiffies; targets[ind] = newtarget; write_unlock_bh(&bond->lock); @@ -714,7 +679,7 @@ static ssize_t bonding_store_arp_targets(struct device *d, &newtarget); write_lock_bh(&bond->lock); - bond_for_each_slave(bond, slave) { + bond_for_each_slave(bond, slave, iter) { targets_rx = slave->target_last_arp_rx; j = ind; for (; (j < BOND_MAX_ARP_TARGETS-1) && targets[j+1]; j++) @@ -1111,6 +1076,7 @@ static ssize_t bonding_store_primary(struct device *d, const char *buf, size_t count) { struct bonding *bond = to_bond(d); + struct list_head *iter; char ifname[IFNAMSIZ]; struct slave *slave; @@ -1138,7 +1104,7 @@ static ssize_t bonding_store_primary(struct device *d, goto out; } - bond_for_each_slave(bond, slave) { + bond_for_each_slave(bond, slave, iter) { if (strncmp(slave->dev->name, ifname, IFNAMSIZ) == 0) { pr_info("%s: Setting %s as primary slave.\n", bond->dev->name, slave->dev->name); @@ -1286,6 +1252,7 @@ static ssize_t bonding_store_active_slave(struct device *d, { struct slave *slave, *old_active, *new_active; struct bonding *bond = to_bond(d); + struct list_head *iter; char ifname[IFNAMSIZ]; if (!rtnl_trylock()) @@ -1313,7 +1280,7 @@ static ssize_t bonding_store_active_slave(struct device *d, goto out; } - bond_for_each_slave(bond, slave) { + bond_for_each_slave(bond, slave, iter) { if (strncmp(slave->dev->name, ifname, IFNAMSIZ) == 0) { old_active = bond->curr_active_slave; new_active = slave; @@ -1493,6 +1460,7 @@ static ssize_t bonding_show_queue_id(struct device *d, char *buf) { struct bonding *bond = to_bond(d); + struct list_head *iter; struct slave *slave; int res = 0; @@ -1500,7 +1468,7 @@ static ssize_t bonding_show_queue_id(struct device *d, return restart_syscall(); read_lock(&bond->lock); - bond_for_each_slave(bond, slave) { + bond_for_each_slave(bond, slave, iter) { if (res > (PAGE_SIZE - IFNAMSIZ - 6)) { /* not enough space for another interface_name:queue_id pair */ if ((PAGE_SIZE - res) > 10) @@ -1529,6 +1497,7 @@ static ssize_t bonding_store_queue_id(struct device *d, { struct slave *slave, *update_slave; struct bonding *bond = to_bond(d); + struct list_head *iter; u16 qid; int ret = count; char *delim; @@ -1565,7 +1534,7 @@ static ssize_t bonding_store_queue_id(struct device *d, /* Search for thes slave and check for duplicate qids */ update_slave = NULL; - bond_for_each_slave(bond, slave) { + bond_for_each_slave(bond, slave, iter) { if (sdev == slave->dev) /* * We don't need to check the matching @@ -1619,6 +1588,7 @@ static ssize_t bonding_store_slaves_active(struct device *d, { struct bonding *bond = to_bond(d); int new_value, ret = count; + struct list_head *iter; struct slave *slave; if (sscanf(buf, "%d", &new_value) != 1) { @@ -1641,7 +1611,7 @@ static ssize_t bonding_store_slaves_active(struct device *d, } read_lock(&bond->lock); - bond_for_each_slave(bond, slave) { + bond_for_each_slave(bond, slave, iter) { if (!bond_is_active_slave(slave)) { if (new_value) slave->inactive = 0; diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 03cf3fd14490..0bd04fbda8e9 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -72,63 +72,37 @@ res; }) /* slave list primitives */ -#define bond_to_slave(ptr) list_entry(ptr, struct slave, list) +#define bond_slave_list(bond) (&(bond)->dev->adj_list.lower) + +#define bond_has_slaves(bond) !list_empty(bond_slave_list(bond)) /* IMPORTANT: bond_first/last_slave can return NULL in case of an empty list */ #define bond_first_slave(bond) \ - list_first_entry_or_null(&(bond)->slave_list, struct slave, list) + (bond_has_slaves(bond) ? \ + netdev_adjacent_get_private(bond_slave_list(bond)->next) : \ + NULL) #define bond_last_slave(bond) \ - (list_empty(&(bond)->slave_list) ? NULL : \ - bond_to_slave((bond)->slave_list.prev)) - -#define bond_is_first_slave(bond, pos) ((pos)->list.prev == &(bond)->slave_list) -#define bond_is_last_slave(bond, pos) ((pos)->list.next == &(bond)->slave_list) - -/* Since bond_first/last_slave can return NULL, these can return NULL too */ -#define bond_next_slave(bond, pos) \ - (bond_is_last_slave(bond, pos) ? bond_first_slave(bond) : \ - bond_to_slave((pos)->list.next)) + (bond_has_slaves(bond) ? \ + netdev_adjacent_get_private(bond_slave_list(bond)->prev) : \ + NULL) -#define bond_prev_slave(bond, pos) \ - (bond_is_first_slave(bond, pos) ? bond_last_slave(bond) : \ - bond_to_slave((pos)->list.prev)) - -/** - * bond_for_each_slave_from - iterate the slaves list from a starting point - * @bond: the bond holding this list. - * @pos: current slave. - * @cnt: counter for max number of moves - * @start: starting point. - * - * Caller must hold bond->lock - */ -#define bond_for_each_slave_from(bond, pos, cnt, start) \ - for (cnt = 0, pos = start; pos && cnt < (bond)->slave_cnt; \ - cnt++, pos = bond_next_slave(bond, pos)) +#define bond_is_first_slave(bond, pos) (pos == bond_first_slave(bond)) +#define bond_is_last_slave(bond, pos) (pos == bond_last_slave(bond)) /** * bond_for_each_slave - iterate over all slaves * @bond: the bond holding this list * @pos: current slave + * @iter: list_head * iterator * * Caller must hold bond->lock */ -#define bond_for_each_slave(bond, pos) \ - list_for_each_entry(pos, &(bond)->slave_list, list) +#define bond_for_each_slave(bond, pos, iter) \ + netdev_for_each_lower_private((bond)->dev, pos, iter) /* Caller must have rcu_read_lock */ -#define bond_for_each_slave_rcu(bond, pos) \ - list_for_each_entry_rcu(pos, &(bond)->slave_list, list) - -/** - * bond_for_each_slave_reverse - iterate in reverse from a given position - * @bond: the bond holding this list - * @pos: slave to continue from - * - * Caller must hold bond->lock - */ -#define bond_for_each_slave_continue_reverse(bond, pos) \ - list_for_each_entry_continue_reverse(pos, &(bond)->slave_list, list) +#define bond_for_each_slave_rcu(bond, pos, iter) \ + netdev_for_each_lower_private_rcu((bond)->dev, pos, iter) #ifdef CONFIG_NET_POLL_CONTROLLER extern atomic_t netpoll_block_tx; @@ -188,7 +162,6 @@ struct bond_parm_tbl { struct slave { struct net_device *dev; /* first - useful for panic debug */ - struct list_head list; struct bonding *bond; /* our master */ int delay; unsigned long jiffies; @@ -228,7 +201,6 @@ struct slave { */ struct bonding { struct net_device *dev; /* first - useful for panic debug */ - struct list_head slave_list; struct slave *curr_active_slave; struct slave *current_arp_slave; struct slave *primary_slave; @@ -245,7 +217,6 @@ struct bonding { char proc_file_name[IFNAMSIZ]; #endif /* CONFIG_PROC_FS */ struct list_head bond_list; - int (*xmit_hash_policy)(struct sk_buff *, int); u16 rr_tx_counter; struct ad_bond_info ad_info; struct alb_bond_info alb_info; @@ -276,13 +247,7 @@ struct bonding { static inline struct slave *bond_get_slave_by_dev(struct bonding *bond, struct net_device *slave_dev) { - struct slave *slave = NULL; - - bond_for_each_slave(bond, slave) - if (slave->dev == slave_dev) - return slave; - - return NULL; + return netdev_lower_dev_get_private(bond->dev, slave_dev); } static inline struct bonding *bond_get_bond_by_slave(struct slave *slave) @@ -432,21 +397,18 @@ static inline bool slave_can_tx(struct slave *slave) struct bond_net; int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond, struct slave *slave); -struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr); int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev); void bond_xmit_slave_id(struct bonding *bond, struct sk_buff *skb, int slave_id); int bond_create(struct net *net, const char *name); int bond_create_sysfs(struct bond_net *net); void bond_destroy_sysfs(struct bond_net *net); void bond_prepare_sysfs_group(struct bonding *bond); -int bond_create_slave_symlinks(struct net_device *master, struct net_device *slave); -void bond_destroy_slave_symlinks(struct net_device *master, struct net_device *slave); int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev); int bond_release(struct net_device *bond_dev, struct net_device *slave_dev); void bond_mii_monitor(struct work_struct *); void bond_loadbalance_arp_mon(struct work_struct *); void bond_activebackup_arp_mon(struct work_struct *); -void bond_set_mode_ops(struct bonding *bond, int mode); +int bond_xmit_hash(struct bonding *bond, struct sk_buff *skb, int count); int bond_parse_parm(const char *mode_arg, const struct bond_parm_tbl *tbl); void bond_select_active_slave(struct bonding *bond); void bond_change_active_slave(struct bonding *bond, struct slave *new_active); @@ -492,9 +454,10 @@ static inline void bond_destroy_proc_dir(struct bond_net *bn) static inline struct slave *bond_slave_has_mac(struct bonding *bond, const u8 *mac) { + struct list_head *iter; struct slave *tmp; - bond_for_each_slave(bond, tmp) + bond_for_each_slave(bond, tmp, iter) if (ether_addr_equal_64bits(mac, tmp->dev->dev_addr)) return tmp; diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index 3b1ff6148702..64f2efaf7638 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c @@ -1347,7 +1347,7 @@ static int at91_can_probe(struct platform_device *pdev) priv->reg_base = addr; priv->devtype_data = *devtype_data; priv->clk = clk; - priv->pdata = pdev->dev.platform_data; + priv->pdata = dev_get_platdata(&pdev->dev); priv->mb0_id = 0x7ff; netif_napi_add(dev, &priv->napi, at91_poll, get_mb_rx_num(priv)); diff --git a/drivers/net/can/bfin_can.c b/drivers/net/can/bfin_can.c index a2700d25ff0e..8a0b515b33ea 100644 --- a/drivers/net/can/bfin_can.c +++ b/drivers/net/can/bfin_can.c @@ -539,7 +539,7 @@ static int bfin_can_probe(struct platform_device *pdev) struct resource *res_mem, *rx_irq, *tx_irq, *err_irq; unsigned short *pdata; - pdata = pdev->dev.platform_data; + pdata = dev_get_platdata(&pdev->dev); if (!pdata) { dev_err(&pdev->dev, "No platform data provided!\n"); err = -EINVAL; diff --git a/drivers/net/can/c_can/c_can_pci.c b/drivers/net/can/c_can/c_can_pci.c index b374be7891a2..bce0be54c2f5 100644 --- a/drivers/net/can/c_can/c_can_pci.c +++ b/drivers/net/can/c_can/c_can_pci.c @@ -160,7 +160,6 @@ static int c_can_pci_probe(struct pci_dev *pdev, return 0; out_free_c_can: - pci_set_drvdata(pdev, NULL); free_c_can_dev(dev); out_iounmap: pci_iounmap(pdev, addr); @@ -181,7 +180,6 @@ static void c_can_pci_remove(struct pci_dev *pdev) unregister_c_can_dev(dev); - pci_set_drvdata(pdev, NULL); free_c_can_dev(dev); pci_iounmap(pdev, priv->base); diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c index 294ced3cc227..d66ac265269c 100644 --- a/drivers/net/can/c_can/c_can_platform.c +++ b/drivers/net/can/c_can/c_can_platform.c @@ -322,7 +322,7 @@ static struct platform_driver c_can_plat_driver = { .driver = { .name = KBUILD_MODNAME, .owner = THIS_MODULE, - .of_match_table = of_match_ptr(c_can_of_table), + .of_match_table = c_can_of_table, }, .probe = c_can_plat_probe, .remove = c_can_plat_remove, diff --git a/drivers/net/can/cc770/cc770_platform.c b/drivers/net/can/cc770/cc770_platform.c index 034bdd816a60..ad76734b3ecc 100644 --- a/drivers/net/can/cc770/cc770_platform.c +++ b/drivers/net/can/cc770/cc770_platform.c @@ -152,7 +152,7 @@ static int cc770_get_platform_data(struct platform_device *pdev, struct cc770_priv *priv) { - struct cc770_platform_data *pdata = pdev->dev.platform_data; + struct cc770_platform_data *pdata = dev_get_platdata(&pdev->dev); priv->can.clock.freq = pdata->osc_freq; if (priv->cpu_interface & CPUIF_DSC) @@ -203,7 +203,7 @@ static int cc770_platform_probe(struct platform_device *pdev) if (pdev->dev.of_node) err = cc770_get_of_node_data(pdev, priv); - else if (pdev->dev.platform_data) + else if (dev_get_platdata(&pdev->dev)) err = cc770_get_platform_data(pdev, priv); else err = -ENODEV; diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 71c677e651d7..df010d64ecbb 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -702,7 +702,6 @@ static int flexcan_chip_start(struct net_device *dev) { struct flexcan_priv *priv = netdev_priv(dev); struct flexcan_regs __iomem *regs = priv->base; - unsigned int i; int err; u32 reg_mcr, reg_ctrl; @@ -772,17 +771,6 @@ static int flexcan_chip_start(struct net_device *dev) netdev_dbg(dev, "%s: writing ctrl=0x%08x", __func__, reg_ctrl); flexcan_write(reg_ctrl, ®s->ctrl); - for (i = 0; i < ARRAY_SIZE(regs->cantxfg); i++) { - flexcan_write(0, ®s->cantxfg[i].can_ctrl); - flexcan_write(0, ®s->cantxfg[i].can_id); - flexcan_write(0, ®s->cantxfg[i].data[0]); - flexcan_write(0, ®s->cantxfg[i].data[1]); - - /* put MB into rx queue */ - flexcan_write(FLEXCAN_MB_CNT_CODE(0x4), - ®s->cantxfg[i].can_ctrl); - } - /* acceptance mask/acceptance code (accept everything) */ flexcan_write(0x0, ®s->rxgmask); flexcan_write(0x0, ®s->rx14mask); @@ -1074,7 +1062,7 @@ static int flexcan_probe(struct platform_device *pdev) priv->dev = dev; priv->clk_ipg = clk_ipg; priv->clk_per = clk_per; - priv->pdata = pdev->dev.platform_data; + priv->pdata = dev_get_platdata(&pdev->dev); priv->devtype_data = devtype_data; priv->reg_xceiver = devm_regulator_get(&pdev->dev, "xceiver"); diff --git a/drivers/net/can/janz-ican3.c b/drivers/net/can/janz-ican3.c index 36bd6fa1c7f3..ab5909a7bae9 100644 --- a/drivers/net/can/janz-ican3.c +++ b/drivers/net/can/janz-ican3.c @@ -1769,7 +1769,7 @@ static int ican3_probe(struct platform_device *pdev) struct device *dev; int ret; - pdata = pdev->dev.platform_data; + pdata = dev_get_platdata(&pdev->dev); if (!pdata) return -ENXIO; diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index fe7dd696957e..08ac401e0214 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c @@ -999,7 +999,7 @@ static int mcp251x_can_probe(struct spi_device *spi) { struct net_device *net; struct mcp251x_priv *priv; - struct mcp251x_platform_data *pdata = spi->dev.platform_data; + struct mcp251x_platform_data *pdata = dev_get_platdata(&spi->dev); int ret = -ENODEV; if (!pdata) diff --git a/drivers/net/can/mscan/mscan.h b/drivers/net/can/mscan/mscan.h index 9c24d60a23b1..e98abb97a050 100644 --- a/drivers/net/can/mscan/mscan.h +++ b/drivers/net/can/mscan/mscan.h @@ -297,8 +297,8 @@ struct mscan_priv { struct napi_struct napi; }; -extern struct net_device *alloc_mscandev(void); -extern int register_mscandev(struct net_device *dev, int mscan_clksrc); -extern void unregister_mscandev(struct net_device *dev); +struct net_device *alloc_mscandev(void); +int register_mscandev(struct net_device *dev, int mscan_clksrc); +void unregister_mscandev(struct net_device *dev); #endif /* __MSCAN_H__ */ diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index 5c314a961970..5f0e9b3bfa7b 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c @@ -964,7 +964,6 @@ static void pch_can_remove(struct pci_dev *pdev) pci_disable_msi(priv->dev); pci_release_regions(pdev); pci_disable_device(pdev); - pci_set_drvdata(pdev, NULL); pch_can_reset(priv); pci_iounmap(pdev, priv->regs); free_candev(priv->ndev); diff --git a/drivers/net/can/sja1000/ems_pci.c b/drivers/net/can/sja1000/ems_pci.c index 3752342a678a..835921388e7b 100644 --- a/drivers/net/can/sja1000/ems_pci.c +++ b/drivers/net/can/sja1000/ems_pci.c @@ -207,7 +207,6 @@ static void ems_pci_del_card(struct pci_dev *pdev) kfree(card); pci_disable_device(pdev); - pci_set_drvdata(pdev, NULL); } static void ems_pci_card_reset(struct ems_pci_card *card) diff --git a/drivers/net/can/sja1000/kvaser_pci.c b/drivers/net/can/sja1000/kvaser_pci.c index 217585b97cd3..087b13bd300e 100644 --- a/drivers/net/can/sja1000/kvaser_pci.c +++ b/drivers/net/can/sja1000/kvaser_pci.c @@ -387,7 +387,6 @@ static void kvaser_pci_remove_one(struct pci_dev *pdev) pci_release_regions(pdev); pci_disable_device(pdev); - pci_set_drvdata(pdev, NULL); } static struct pci_driver kvaser_pci_driver = { diff --git a/drivers/net/can/sja1000/peak_pci.c b/drivers/net/can/sja1000/peak_pci.c index 6b6f0ad75090..065ca49eb45e 100644 --- a/drivers/net/can/sja1000/peak_pci.c +++ b/drivers/net/can/sja1000/peak_pci.c @@ -744,8 +744,6 @@ static void peak_pci_remove(struct pci_dev *pdev) pci_iounmap(pdev, cfg_base); pci_release_regions(pdev); pci_disable_device(pdev); - - pci_set_drvdata(pdev, NULL); } static struct pci_driver peak_pci_driver = { diff --git a/drivers/net/can/sja1000/plx_pci.c b/drivers/net/can/sja1000/plx_pci.c index c52c1e96bf90..f9b4f81cd86a 100644 --- a/drivers/net/can/sja1000/plx_pci.c +++ b/drivers/net/can/sja1000/plx_pci.c @@ -477,7 +477,6 @@ static void plx_pci_del_card(struct pci_dev *pdev) kfree(card); pci_disable_device(pdev); - pci_set_drvdata(pdev, NULL); } /* diff --git a/drivers/net/can/sja1000/sja1000_platform.c b/drivers/net/can/sja1000/sja1000_platform.c index 8e259c541036..29f9b6321187 100644 --- a/drivers/net/can/sja1000/sja1000_platform.c +++ b/drivers/net/can/sja1000/sja1000_platform.c @@ -76,7 +76,7 @@ static int sp_probe(struct platform_device *pdev) struct resource *res_mem, *res_irq; struct sja1000_platform_data *pdata; - pdata = pdev->dev.platform_data; + pdata = dev_get_platdata(&pdev->dev); if (!pdata) { dev_err(&pdev->dev, "No platform data provided!\n"); err = -ENODEV; diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c index 874188ba06f7..25377e547f9b 100644 --- a/drivers/net/can/slcan.c +++ b/drivers/net/can/slcan.c @@ -76,6 +76,10 @@ MODULE_PARM_DESC(maxdev, "Maximum number of slcan interfaces"); /* maximum rx buffer len: extended CAN frame with timestamp */ #define SLC_MTU (sizeof("T1111222281122334455667788EA5F\r")+1) +#define SLC_CMD_LEN 1 +#define SLC_SFF_ID_LEN 3 +#define SLC_EFF_ID_LEN 8 + struct slcan { int magic; @@ -142,47 +146,63 @@ static void slc_bump(struct slcan *sl) { struct sk_buff *skb; struct can_frame cf; - int i, dlc_pos, tmp; - unsigned long ultmp; - char cmd = sl->rbuff[0]; - - if ((cmd != 't') && (cmd != 'T') && (cmd != 'r') && (cmd != 'R')) + int i, tmp; + u32 tmpid; + char *cmd = sl->rbuff; + + cf.can_id = 0; + + switch (*cmd) { + case 'r': + cf.can_id = CAN_RTR_FLAG; + /* fallthrough */ + case 't': + /* store dlc ASCII value and terminate SFF CAN ID string */ + cf.can_dlc = sl->rbuff[SLC_CMD_LEN + SLC_SFF_ID_LEN]; + sl->rbuff[SLC_CMD_LEN + SLC_SFF_ID_LEN] = 0; + /* point to payload data behind the dlc */ + cmd += SLC_CMD_LEN + SLC_SFF_ID_LEN + 1; + break; + case 'R': + cf.can_id = CAN_RTR_FLAG; + /* fallthrough */ + case 'T': + cf.can_id |= CAN_EFF_FLAG; + /* store dlc ASCII value and terminate EFF CAN ID string */ + cf.can_dlc = sl->rbuff[SLC_CMD_LEN + SLC_EFF_ID_LEN]; + sl->rbuff[SLC_CMD_LEN + SLC_EFF_ID_LEN] = 0; + /* point to payload data behind the dlc */ + cmd += SLC_CMD_LEN + SLC_EFF_ID_LEN + 1; + break; + default: return; + } - if (cmd & 0x20) /* tiny chars 'r' 't' => standard frame format */ - dlc_pos = 4; /* dlc position tiiid */ - else - dlc_pos = 9; /* dlc position Tiiiiiiiid */ - - if (!((sl->rbuff[dlc_pos] >= '0') && (sl->rbuff[dlc_pos] < '9'))) + if (kstrtou32(sl->rbuff + SLC_CMD_LEN, 16, &tmpid)) return; - cf.can_dlc = sl->rbuff[dlc_pos] - '0'; /* get can_dlc from ASCII val */ + cf.can_id |= tmpid; - sl->rbuff[dlc_pos] = 0; /* terminate can_id string */ - - if (kstrtoul(sl->rbuff+1, 16, &ultmp)) + /* get can_dlc from sanitized ASCII value */ + if (cf.can_dlc >= '0' && cf.can_dlc < '9') + cf.can_dlc -= '0'; + else return; - cf.can_id = ultmp; - - if (!(cmd & 0x20)) /* NO tiny chars => extended frame format */ - cf.can_id |= CAN_EFF_FLAG; - - if ((cmd | 0x20) == 'r') /* RTR frame */ - cf.can_id |= CAN_RTR_FLAG; - *(u64 *) (&cf.data) = 0; /* clear payload */ - for (i = 0, dlc_pos++; i < cf.can_dlc; i++) { - tmp = hex_to_bin(sl->rbuff[dlc_pos++]); - if (tmp < 0) - return; - cf.data[i] = (tmp << 4); - tmp = hex_to_bin(sl->rbuff[dlc_pos++]); - if (tmp < 0) - return; - cf.data[i] |= tmp; + /* RTR frames may have a dlc > 0 but they never have any data bytes */ + if (!(cf.can_id & CAN_RTR_FLAG)) { + for (i = 0; i < cf.can_dlc; i++) { + tmp = hex_to_bin(*cmd++); + if (tmp < 0) + return; + cf.data[i] = (tmp << 4); + tmp = hex_to_bin(*cmd++); + if (tmp < 0) + return; + cf.data[i] |= tmp; + } } skb = dev_alloc_skb(sizeof(struct can_frame) + @@ -209,7 +229,6 @@ static void slc_bump(struct slcan *sl) /* parse tty input stream */ static void slcan_unesc(struct slcan *sl, unsigned char s) { - if ((s == '\r') || (s == '\a')) { /* CR or BEL ends the pdu */ if (!test_and_clear_bit(SLF_ERROR, &sl->flags) && (sl->rcount > 4)) { @@ -236,27 +255,46 @@ static void slcan_unesc(struct slcan *sl, unsigned char s) /* Encapsulate one can_frame and stuff into a TTY queue. */ static void slc_encaps(struct slcan *sl, struct can_frame *cf) { - int actual, idx, i; - char cmd; + int actual, i; + unsigned char *pos; + unsigned char *endpos; + canid_t id = cf->can_id; + + pos = sl->xbuff; if (cf->can_id & CAN_RTR_FLAG) - cmd = 'R'; /* becomes 'r' in standard frame format */ + *pos = 'R'; /* becomes 'r' in standard frame format (SFF) */ else - cmd = 'T'; /* becomes 't' in standard frame format */ + *pos = 'T'; /* becomes 't' in standard frame format (SSF) */ - if (cf->can_id & CAN_EFF_FLAG) - sprintf(sl->xbuff, "%c%08X%d", cmd, - cf->can_id & CAN_EFF_MASK, cf->can_dlc); - else - sprintf(sl->xbuff, "%c%03X%d", cmd | 0x20, - cf->can_id & CAN_SFF_MASK, cf->can_dlc); + /* determine number of chars for the CAN-identifier */ + if (cf->can_id & CAN_EFF_FLAG) { + id &= CAN_EFF_MASK; + endpos = pos + SLC_EFF_ID_LEN; + } else { + *pos |= 0x20; /* convert R/T to lower case for SFF */ + id &= CAN_SFF_MASK; + endpos = pos + SLC_SFF_ID_LEN; + } - idx = strlen(sl->xbuff); + /* build 3 (SFF) or 8 (EFF) digit CAN identifier */ + pos++; + while (endpos >= pos) { + *endpos-- = hex_asc_upper[id & 0xf]; + id >>= 4; + } + + pos += (cf->can_id & CAN_EFF_FLAG) ? SLC_EFF_ID_LEN : SLC_SFF_ID_LEN; - for (i = 0; i < cf->can_dlc; i++) - sprintf(&sl->xbuff[idx + 2*i], "%02X", cf->data[i]); + *pos++ = cf->can_dlc + '0'; + + /* RTR frames may have a dlc > 0 but they never have any data bytes */ + if (!(cf->can_id & CAN_RTR_FLAG)) { + for (i = 0; i < cf->can_dlc; i++) + pos = hex_byte_pack_upper(pos, cf->data[i]); + } - strcat(sl->xbuff, "\r"); /* add terminating character */ + *pos++ = '\r'; /* Order of next two lines is *very* important. * When we are sending a little amount of data, @@ -267,8 +305,8 @@ static void slc_encaps(struct slcan *sl, struct can_frame *cf) * 14 Oct 1994 Dmitry Gorodchanin. */ set_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags); - actual = sl->tty->ops->write(sl->tty, sl->xbuff, strlen(sl->xbuff)); - sl->xleft = strlen(sl->xbuff) - actual; + actual = sl->tty->ops->write(sl->tty, sl->xbuff, pos - sl->xbuff); + sl->xleft = (pos - sl->xbuff) - actual; sl->xhead = sl->xbuff + actual; sl->dev->stats.tx_bytes += cf->can_dlc; } @@ -286,11 +324,13 @@ static void slcan_write_wakeup(struct tty_struct *tty) if (!sl || sl->magic != SLCAN_MAGIC || !netif_running(sl->dev)) return; + spin_lock(&sl->lock); if (sl->xleft <= 0) { /* Now serial buffer is almost free & we can start * transmission of another packet */ sl->dev->stats.tx_packets++; clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); + spin_unlock(&sl->lock); netif_wake_queue(sl->dev); return; } @@ -298,6 +338,7 @@ static void slcan_write_wakeup(struct tty_struct *tty) actual = tty->ops->write(tty, sl->xhead, sl->xleft); sl->xleft -= actual; sl->xhead += actual; + spin_unlock(&sl->lock); } /* Send a can_frame to a TTY queue. */ diff --git a/drivers/net/can/softing/softing.h b/drivers/net/can/softing/softing.h index afd7d85b6915..35f062282dbd 100644 --- a/drivers/net/can/softing/softing.h +++ b/drivers/net/can/softing/softing.h @@ -71,34 +71,34 @@ struct softing { } id; }; -extern int softing_default_output(struct net_device *netdev); +int softing_default_output(struct net_device *netdev); -extern ktime_t softing_raw2ktime(struct softing *card, u32 raw); +ktime_t softing_raw2ktime(struct softing *card, u32 raw); -extern int softing_chip_poweron(struct softing *card); +int softing_chip_poweron(struct softing *card); -extern int softing_bootloader_command(struct softing *card, int16_t cmd, - const char *msg); +int softing_bootloader_command(struct softing *card, int16_t cmd, + const char *msg); /* Load firmware after reset */ -extern int softing_load_fw(const char *file, struct softing *card, - __iomem uint8_t *virt, unsigned int size, int offset); +int softing_load_fw(const char *file, struct softing *card, + __iomem uint8_t *virt, unsigned int size, int offset); /* Load final application firmware after bootloader */ -extern int softing_load_app_fw(const char *file, struct softing *card); +int softing_load_app_fw(const char *file, struct softing *card); /* * enable or disable irq * only called with fw.lock locked */ -extern int softing_enable_irq(struct softing *card, int enable); +int softing_enable_irq(struct softing *card, int enable); /* start/stop 1 bus on card */ -extern int softing_startstop(struct net_device *netdev, int up); +int softing_startstop(struct net_device *netdev, int up); /* netif_rx() */ -extern int softing_netdev_rx(struct net_device *netdev, - const struct can_frame *msg, ktime_t ktime); +int softing_netdev_rx(struct net_device *netdev, const struct can_frame *msg, + ktime_t ktime); /* SOFTING DPRAM mappings */ #define DPRAM_RX 0x0000 diff --git a/drivers/net/can/softing/softing_main.c b/drivers/net/can/softing/softing_main.c index 65eef1eea2e2..6cd5c01b624d 100644 --- a/drivers/net/can/softing/softing_main.c +++ b/drivers/net/can/softing/softing_main.c @@ -768,7 +768,7 @@ static int softing_pdev_remove(struct platform_device *pdev) static int softing_pdev_probe(struct platform_device *pdev) { - const struct softing_platform_data *pdat = pdev->dev.platform_data; + const struct softing_platform_data *pdat = dev_get_platdata(&pdev->dev); struct softing *card; struct net_device *netdev; struct softing_priv *priv; diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c index 3a349a22d5bc..beb5ef834f0f 100644 --- a/drivers/net/can/ti_hecc.c +++ b/drivers/net/can/ti_hecc.c @@ -894,7 +894,7 @@ static int ti_hecc_probe(struct platform_device *pdev) void __iomem *addr; int err = -ENODEV; - pdata = pdev->dev.platform_data; + pdata = dev_get_platdata(&pdev->dev); if (!pdata) { dev_err(&pdev->dev, "No platform data\n"); goto probe_exit; diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c index a0f647f92bf5..0b7a4c3b01a2 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c +++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c @@ -463,7 +463,7 @@ static int peak_usb_start(struct peak_usb_device *dev) if (i < PCAN_USB_MAX_TX_URBS) { if (i == 0) { netdev_err(netdev, "couldn't setup any tx URB\n"); - return err; + goto err_tx; } netdev_warn(netdev, "tx performance may be slow\n"); @@ -472,7 +472,7 @@ static int peak_usb_start(struct peak_usb_device *dev) if (dev->adapter->dev_start) { err = dev->adapter->dev_start(dev); if (err) - goto failed; + goto err_adapter; } dev->state |= PCAN_USB_STATE_STARTED; @@ -481,19 +481,26 @@ static int peak_usb_start(struct peak_usb_device *dev) if (dev->adapter->dev_set_bus) { err = dev->adapter->dev_set_bus(dev, 1); if (err) - goto failed; + goto err_adapter; } dev->can.state = CAN_STATE_ERROR_ACTIVE; return 0; -failed: +err_adapter: if (err == -ENODEV) netif_device_detach(dev->netdev); netdev_warn(netdev, "couldn't submit control: %d\n", err); + for (i = 0; i < PCAN_USB_MAX_TX_URBS; i++) { + usb_free_urb(dev->tx_contexts[i].urb); + dev->tx_contexts[i].urb = NULL; + } +err_tx: + usb_kill_anchored_urbs(&dev->rx_submitted); + return err; } diff --git a/drivers/net/ethernet/3com/Kconfig b/drivers/net/ethernet/3com/Kconfig index f00c76377b44..65b735d4a6ad 100644 --- a/drivers/net/ethernet/3com/Kconfig +++ b/drivers/net/ethernet/3com/Kconfig @@ -35,7 +35,7 @@ config EL3 config 3C515 tristate "3c515 ISA \"Fast EtherLink\"" - depends on (ISA || EISA) && ISA_DMA_API + depends on ISA && ISA_DMA_API ---help--- If you have a 3Com ISA EtherLink XL "Corkscrew" 3c515 Fast Ethernet network card, say Y and read the Ethernet-HOWTO, available from @@ -70,7 +70,7 @@ config VORTEX select MII ---help--- This option enables driver support for a large number of 10Mbps and - 10/100Mbps EISA, PCI and PCMCIA 3Com network cards: + 10/100Mbps EISA, PCI and Cardbus 3Com network cards: "Vortex" (Fast EtherLink 3c590/3c592/3c595/3c597) EISA and PCI "Boomerang" (EtherLink XL 3c900 or 3c905) PCI diff --git a/drivers/net/ethernet/8390/8390.h b/drivers/net/ethernet/8390/8390.h index ef325ffa1b5a..2923c51bb351 100644 --- a/drivers/net/ethernet/8390/8390.h +++ b/drivers/net/ethernet/8390/8390.h @@ -28,42 +28,42 @@ extern int ei_debug; #endif #ifdef CONFIG_NET_POLL_CONTROLLER -extern void ei_poll(struct net_device *dev); -extern void eip_poll(struct net_device *dev); +void ei_poll(struct net_device *dev); +void eip_poll(struct net_device *dev); #endif /* Without I/O delay - non ISA or later chips */ -extern void NS8390_init(struct net_device *dev, int startp); -extern int ei_open(struct net_device *dev); -extern int ei_close(struct net_device *dev); -extern irqreturn_t ei_interrupt(int irq, void *dev_id); -extern void ei_tx_timeout(struct net_device *dev); -extern netdev_tx_t ei_start_xmit(struct sk_buff *skb, struct net_device *dev); -extern void ei_set_multicast_list(struct net_device *dev); -extern struct net_device_stats *ei_get_stats(struct net_device *dev); +void NS8390_init(struct net_device *dev, int startp); +int ei_open(struct net_device *dev); +int ei_close(struct net_device *dev); +irqreturn_t ei_interrupt(int irq, void *dev_id); +void ei_tx_timeout(struct net_device *dev); +netdev_tx_t ei_start_xmit(struct sk_buff *skb, struct net_device *dev); +void ei_set_multicast_list(struct net_device *dev); +struct net_device_stats *ei_get_stats(struct net_device *dev); extern const struct net_device_ops ei_netdev_ops; -extern struct net_device *__alloc_ei_netdev(int size); +struct net_device *__alloc_ei_netdev(int size); static inline struct net_device *alloc_ei_netdev(void) { return __alloc_ei_netdev(0); } /* With I/O delay form */ -extern void NS8390p_init(struct net_device *dev, int startp); -extern int eip_open(struct net_device *dev); -extern int eip_close(struct net_device *dev); -extern irqreturn_t eip_interrupt(int irq, void *dev_id); -extern void eip_tx_timeout(struct net_device *dev); -extern netdev_tx_t eip_start_xmit(struct sk_buff *skb, struct net_device *dev); -extern void eip_set_multicast_list(struct net_device *dev); -extern struct net_device_stats *eip_get_stats(struct net_device *dev); +void NS8390p_init(struct net_device *dev, int startp); +int eip_open(struct net_device *dev); +int eip_close(struct net_device *dev); +irqreturn_t eip_interrupt(int irq, void *dev_id); +void eip_tx_timeout(struct net_device *dev); +netdev_tx_t eip_start_xmit(struct sk_buff *skb, struct net_device *dev); +void eip_set_multicast_list(struct net_device *dev); +struct net_device_stats *eip_get_stats(struct net_device *dev); extern const struct net_device_ops eip_netdev_ops; -extern struct net_device *__alloc_eip_netdev(int size); +struct net_device *__alloc_eip_netdev(int size); static inline struct net_device *alloc_eip_netdev(void) { return __alloc_eip_netdev(0); diff --git a/drivers/net/ethernet/8390/ax88796.c b/drivers/net/ethernet/8390/ax88796.c index f92f001551da..36fa577970bb 100644 --- a/drivers/net/ethernet/8390/ax88796.c +++ b/drivers/net/ethernet/8390/ax88796.c @@ -702,7 +702,7 @@ static int ax_init_dev(struct net_device *dev) for (i = 0; i < 16; i++) SA_prom[i] = SA_prom[i+i]; - memcpy(dev->dev_addr, SA_prom, 6); + memcpy(dev->dev_addr, SA_prom, ETH_ALEN); } #ifdef CONFIG_AX88796_93CX6 diff --git a/drivers/net/ethernet/adi/bfin_mac.h b/drivers/net/ethernet/adi/bfin_mac.h index 7a07ee07906b..6dec86ac97cd 100644 --- a/drivers/net/ethernet/adi/bfin_mac.h +++ b/drivers/net/ethernet/adi/bfin_mac.h @@ -104,6 +104,6 @@ struct bfin_mac_local { #endif }; -extern int bfin_get_ether_addr(char *addr); +int bfin_get_ether_addr(char *addr); #endif diff --git a/drivers/net/ethernet/amd/7990.h b/drivers/net/ethernet/amd/7990.h index 0a5837b96421..ae33a99bf476 100644 --- a/drivers/net/ethernet/amd/7990.h +++ b/drivers/net/ethernet/amd/7990.h @@ -242,13 +242,13 @@ struct lance_private #define LANCE_ADDR(x) ((int)(x) & ~0xff000000) /* Now the prototypes we export */ -extern int lance_open(struct net_device *dev); -extern int lance_close (struct net_device *dev); -extern int lance_start_xmit (struct sk_buff *skb, struct net_device *dev); -extern void lance_set_multicast (struct net_device *dev); -extern void lance_tx_timeout(struct net_device *dev); +int lance_open(struct net_device *dev); +int lance_close (struct net_device *dev); +int lance_start_xmit (struct sk_buff *skb, struct net_device *dev); +void lance_set_multicast (struct net_device *dev); +void lance_tx_timeout(struct net_device *dev); #ifdef CONFIG_NET_POLL_CONTROLLER -extern void lance_poll(struct net_device *dev); +void lance_poll(struct net_device *dev); #endif #endif /* ndef _7990_H */ diff --git a/drivers/net/ethernet/amd/atarilance.c b/drivers/net/ethernet/amd/atarilance.c index 10ceca523fc0..e07ce5ff2d48 100644 --- a/drivers/net/ethernet/amd/atarilance.c +++ b/drivers/net/ethernet/amd/atarilance.c @@ -586,10 +586,10 @@ static unsigned long __init lance_probe1( struct net_device *dev, switch( lp->cardtype ) { case OLD_RIEBL: /* No ethernet address! (Set some default address) */ - memcpy( dev->dev_addr, OldRieblDefHwaddr, 6 ); + memcpy(dev->dev_addr, OldRieblDefHwaddr, ETH_ALEN); break; case NEW_RIEBL: - lp->memcpy_f( dev->dev_addr, RIEBL_HWADDR_ADDR, 6 ); + lp->memcpy_f(dev->dev_addr, RIEBL_HWADDR_ADDR, ETH_ALEN); break; case PAM_CARD: i = IO->eeprom; diff --git a/drivers/net/ethernet/amd/au1000_eth.c b/drivers/net/ethernet/amd/au1000_eth.c index 91d52b495848..427c148bb643 100644 --- a/drivers/net/ethernet/amd/au1000_eth.c +++ b/drivers/net/ethernet/amd/au1000_eth.c @@ -1138,7 +1138,7 @@ static int au1000_probe(struct platform_device *pdev) aup->phy1_search_mac0 = 1; } else { if (is_valid_ether_addr(pd->mac)) { - memcpy(dev->dev_addr, pd->mac, 6); + memcpy(dev->dev_addr, pd->mac, ETH_ALEN); } else { /* Set a random MAC since no valid provided by platform_data. */ eth_hw_addr_random(dev); diff --git a/drivers/net/ethernet/amd/declance.c b/drivers/net/ethernet/amd/declance.c index 94edc9c6fbbf..cc35f6f4e703 100644 --- a/drivers/net/ethernet/amd/declance.c +++ b/drivers/net/ethernet/amd/declance.c @@ -344,8 +344,8 @@ static void cp_to_buf(const int type, void *to, const void *from, int len) } clen = len & 1; - rtp = tp; - rfp = fp; + rtp = (unsigned char *)tp; + rfp = (const unsigned char *)fp; while (clen--) { *rtp++ = *rfp++; } @@ -372,8 +372,8 @@ static void cp_to_buf(const int type, void *to, const void *from, int len) * do the rest, if any. */ clen = len & 15; - rtp = (unsigned char *) tp; - rfp = (unsigned char *) fp; + rtp = (unsigned char *)tp; + rfp = (const unsigned char *)fp; while (clen--) { *rtp++ = *rfp++; } @@ -403,8 +403,8 @@ static void cp_from_buf(const int type, void *to, const void *from, int len) clen = len & 1; - rtp = tp; - rfp = fp; + rtp = (unsigned char *)tp; + rfp = (const unsigned char *)fp; while (clen--) { *rtp++ = *rfp++; @@ -433,8 +433,8 @@ static void cp_from_buf(const int type, void *to, const void *from, int len) * do the rest, if any. */ clen = len & 15; - rtp = (unsigned char *) tp; - rfp = (unsigned char *) fp; + rtp = (unsigned char *)tp; + rfp = (const unsigned char *)fp; while (clen--) { *rtp++ = *rfp++; } diff --git a/drivers/net/ethernet/amd/lance.c b/drivers/net/ethernet/amd/lance.c index 5c728436b85e..256f590f6bb1 100644 --- a/drivers/net/ethernet/amd/lance.c +++ b/drivers/net/ethernet/amd/lance.c @@ -754,7 +754,7 @@ lance_open(struct net_device *dev) int i; if (dev->irq == 0 || - request_irq(dev->irq, lance_interrupt, 0, lp->name, dev)) { + request_irq(dev->irq, lance_interrupt, 0, dev->name, dev)) { return -EAGAIN; } diff --git a/drivers/net/ethernet/amd/pcnet32.c b/drivers/net/ethernet/amd/pcnet32.c index 2d8e28819779..bd4e6402003a 100644 --- a/drivers/net/ethernet/amd/pcnet32.c +++ b/drivers/net/ethernet/amd/pcnet32.c @@ -1675,7 +1675,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev) pr_cont(" warning: CSR address invalid,\n"); pr_info(" using instead PROM address of"); } - memcpy(dev->dev_addr, promaddr, 6); + memcpy(dev->dev_addr, promaddr, ETH_ALEN); } } diff --git a/drivers/net/ethernet/apple/bmac.c b/drivers/net/ethernet/apple/bmac.c index a597b766f080..daae0e016253 100644 --- a/drivers/net/ethernet/apple/bmac.c +++ b/drivers/net/ethernet/apple/bmac.c @@ -1220,8 +1220,8 @@ static void bmac_reset_and_enable(struct net_device *dev) if (skb != NULL) { data = skb_put(skb, ETHERMINPACKET); memset(data, 0, ETHERMINPACKET); - memcpy(data, dev->dev_addr, 6); - memcpy(data+6, dev->dev_addr, 6); + memcpy(data, dev->dev_addr, ETH_ALEN); + memcpy(data + ETH_ALEN, dev->dev_addr, ETH_ALEN); bmac_transmit_packet(skb, dev); } spin_unlock_irqrestore(&bp->lock, flags); diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c.h b/drivers/net/ethernet/atheros/atl1c/atl1c.h index 0f0556526ba9..7f9369a3b378 100644 --- a/drivers/net/ethernet/atheros/atl1c/atl1c.h +++ b/drivers/net/ethernet/atheros/atl1c/atl1c.h @@ -600,7 +600,7 @@ struct atl1c_adapter { extern char atl1c_driver_name[]; extern char atl1c_driver_version[]; -extern void atl1c_reinit_locked(struct atl1c_adapter *adapter); -extern s32 atl1c_reset_hw(struct atl1c_hw *hw); -extern void atl1c_set_ethtool_ops(struct net_device *netdev); +void atl1c_reinit_locked(struct atl1c_adapter *adapter); +s32 atl1c_reset_hw(struct atl1c_hw *hw); +void atl1c_set_ethtool_ops(struct net_device *netdev); #endif /* _ATL1C_H_ */ diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c index 3ef7092e3f1c..1cda49a28f7f 100644 --- a/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c @@ -153,7 +153,7 @@ static int atl1c_get_permanent_address(struct atl1c_hw *hw) bool atl1c_read_eeprom(struct atl1c_hw *hw, u32 offset, u32 *p_value) { int i; - int ret = false; + bool ret = false; u32 otp_ctrl_data; u32 control; u32 data; diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e.h b/drivers/net/ethernet/atheros/atl1e/atl1e.h index b5fd934585e9..1b0fe2d04a0e 100644 --- a/drivers/net/ethernet/atheros/atl1e/atl1e.h +++ b/drivers/net/ethernet/atheros/atl1e/atl1e.h @@ -499,10 +499,10 @@ struct atl1e_adapter { extern char atl1e_driver_name[]; extern char atl1e_driver_version[]; -extern void atl1e_check_options(struct atl1e_adapter *adapter); -extern int atl1e_up(struct atl1e_adapter *adapter); -extern void atl1e_down(struct atl1e_adapter *adapter); -extern void atl1e_reinit_locked(struct atl1e_adapter *adapter); -extern s32 atl1e_reset_hw(struct atl1e_hw *hw); -extern void atl1e_set_ethtool_ops(struct net_device *netdev); +void atl1e_check_options(struct atl1e_adapter *adapter); +int atl1e_up(struct atl1e_adapter *adapter); +void atl1e_down(struct atl1e_adapter *adapter); +void atl1e_reinit_locked(struct atl1e_adapter *adapter); +s32 atl1e_reset_hw(struct atl1e_hw *hw); +void atl1e_set_ethtool_ops(struct net_device *netdev); #endif /* _ATL1_E_H_ */ diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c index 1966444590f6..7a73f3a9fcb5 100644 --- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c @@ -313,6 +313,34 @@ static void atl1e_set_multi(struct net_device *netdev) } } +static void __atl1e_rx_mode(netdev_features_t features, u32 *mac_ctrl_data) +{ + + if (features & NETIF_F_RXALL) { + /* enable RX of ALL frames */ + *mac_ctrl_data |= MAC_CTRL_DBG; + } else { + /* disable RX of ALL frames */ + *mac_ctrl_data &= ~MAC_CTRL_DBG; + } +} + +static void atl1e_rx_mode(struct net_device *netdev, + netdev_features_t features) +{ + struct atl1e_adapter *adapter = netdev_priv(netdev); + u32 mac_ctrl_data = 0; + + netdev_dbg(adapter->netdev, "%s\n", __func__); + + atl1e_irq_disable(adapter); + mac_ctrl_data = AT_READ_REG(&adapter->hw, REG_MAC_CTRL); + __atl1e_rx_mode(features, &mac_ctrl_data); + AT_WRITE_REG(&adapter->hw, REG_MAC_CTRL, mac_ctrl_data); + atl1e_irq_enable(adapter); +} + + static void __atl1e_vlan_mode(netdev_features_t features, u32 *mac_ctrl_data) { if (features & NETIF_F_HW_VLAN_CTAG_RX) { @@ -394,6 +422,10 @@ static int atl1e_set_features(struct net_device *netdev, if (changed & NETIF_F_HW_VLAN_CTAG_RX) atl1e_vlan_mode(netdev, features); + if (changed & NETIF_F_RXALL) + atl1e_rx_mode(netdev, features); + + return 0; } @@ -1057,7 +1089,8 @@ static void atl1e_setup_mac_ctrl(struct atl1e_adapter *adapter) value |= MAC_CTRL_PROMIS_EN; if (netdev->flags & IFF_ALLMULTI) value |= MAC_CTRL_MC_ALL_EN; - + if (netdev->features & NETIF_F_RXALL) + value |= MAC_CTRL_DBG; AT_WRITE_REG(hw, REG_MAC_CTRL, value); } @@ -1405,7 +1438,8 @@ static void atl1e_clean_rx_irq(struct atl1e_adapter *adapter, u8 que, rx_page_desc[que].rx_nxseq++; /* error packet */ - if (prrs->pkt_flag & RRS_IS_ERR_FRAME) { + if ((prrs->pkt_flag & RRS_IS_ERR_FRAME) && + !(netdev->features & NETIF_F_RXALL)) { if (prrs->err_flag & (RRS_ERR_BAD_CRC | RRS_ERR_DRIBBLE | RRS_ERR_CODE | RRS_ERR_TRUNC)) { @@ -1418,7 +1452,10 @@ static void atl1e_clean_rx_irq(struct atl1e_adapter *adapter, u8 que, } packet_size = ((prrs->word1 >> RRS_PKT_SIZE_SHIFT) & - RRS_PKT_SIZE_MASK) - 4; /* CRC */ + RRS_PKT_SIZE_MASK); + if (likely(!(netdev->features & NETIF_F_RXFCS))) + packet_size -= 4; /* CRC */ + skb = netdev_alloc_skb_ip_align(netdev, packet_size); if (skb == NULL) goto skip_pkt; @@ -2245,7 +2282,8 @@ static int atl1e_init_netdev(struct net_device *netdev, struct pci_dev *pdev) NETIF_F_HW_VLAN_CTAG_RX; netdev->features = netdev->hw_features | NETIF_F_LLTX | NETIF_F_HW_VLAN_CTAG_TX; - + /* not enabled by default */ + netdev->hw_features |= NETIF_F_RXALL | NETIF_F_RXFCS; return 0; } diff --git a/drivers/net/ethernet/atheros/atlx/atl2.h b/drivers/net/ethernet/atheros/atlx/atl2.h index 3ebe19f7242b..2f27d4c4c3ad 100644 --- a/drivers/net/ethernet/atheros/atlx/atl2.h +++ b/drivers/net/ethernet/atheros/atlx/atl2.h @@ -42,7 +42,7 @@ #include "atlx.h" #ifdef ETHTOOL_OPS_COMPAT -extern int ethtool_ioctl(struct ifreq *ifr); +int ethtool_ioctl(struct ifreq *ifr); #endif #define PCI_COMMAND_REGISTER PCI_COMMAND diff --git a/drivers/net/ethernet/broadcom/b44.c b/drivers/net/ethernet/broadcom/b44.c index 9b017d9c58e9..079a597fa20c 100644 --- a/drivers/net/ethernet/broadcom/b44.c +++ b/drivers/net/ethernet/broadcom/b44.c @@ -596,6 +596,7 @@ static void b44_timer(unsigned long __opaque) static void b44_tx(struct b44 *bp) { u32 cur, cons; + unsigned bytes_compl = 0, pkts_compl = 0; cur = br32(bp, B44_DMATX_STAT) & DMATX_STAT_CDMASK; cur /= sizeof(struct dma_desc); @@ -612,9 +613,14 @@ static void b44_tx(struct b44 *bp) skb->len, DMA_TO_DEVICE); rp->skb = NULL; + + bytes_compl += skb->len; + pkts_compl++; + dev_kfree_skb_irq(skb); } + netdev_completed_queue(bp->dev, pkts_compl, bytes_compl); bp->tx_cons = cons; if (netif_queue_stopped(bp->dev) && TX_BUFFS_AVAIL(bp) > B44_TX_WAKEUP_THRESH) @@ -1018,6 +1024,8 @@ static netdev_tx_t b44_start_xmit(struct sk_buff *skb, struct net_device *dev) if (bp->flags & B44_FLAG_REORDER_BUG) br32(bp, B44_DMATX_PTR); + netdev_sent_queue(dev, skb->len); + if (TX_BUFFS_AVAIL(bp) < 1) netif_stop_queue(dev); @@ -1416,6 +1424,8 @@ static void b44_init_hw(struct b44 *bp, int reset_kind) val = br32(bp, B44_ENET_CTRL); bw32(bp, B44_ENET_CTRL, (val | ENET_CTRL_ENABLE)); + + netdev_reset_queue(bp->dev); } static int b44_open(struct net_device *dev) @@ -2101,7 +2111,7 @@ static int b44_get_invariants(struct b44 *bp) * valid PHY address. */ bp->phy_addr &= 0x1F; - memcpy(bp->dev->dev_addr, addr, 6); + memcpy(bp->dev->dev_addr, addr, ETH_ALEN); if (!is_valid_ether_addr(&bp->dev->dev_addr[0])){ pr_err("Invalid MAC address found in EEPROM\n"); diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index 249468f95365..7eca5a174733 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -149,6 +149,8 @@ static netdev_tx_t bgmac_dma_tx_add(struct bgmac *bgmac, dma_desc->ctl0 = cpu_to_le32(ctl0); dma_desc->ctl1 = cpu_to_le32(ctl1); + netdev_sent_queue(net_dev, skb->len); + wmb(); /* Increase ring->end to point empty slot. We tell hardware the first @@ -178,6 +180,7 @@ static void bgmac_dma_tx_free(struct bgmac *bgmac, struct bgmac_dma_ring *ring) struct device *dma_dev = bgmac->core->dma_dev; int empty_slot; bool freed = false; + unsigned bytes_compl = 0, pkts_compl = 0; /* The last slot that hardware didn't consume yet */ empty_slot = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_TX_STATUS); @@ -195,6 +198,9 @@ static void bgmac_dma_tx_free(struct bgmac *bgmac, struct bgmac_dma_ring *ring) slot->skb->len, DMA_TO_DEVICE); slot->dma_addr = 0; + bytes_compl += slot->skb->len; + pkts_compl++; + /* Free memory! :) */ dev_kfree_skb(slot->skb); slot->skb = NULL; @@ -208,6 +214,8 @@ static void bgmac_dma_tx_free(struct bgmac *bgmac, struct bgmac_dma_ring *ring) freed = true; } + netdev_completed_queue(bgmac->net_dev, pkts_compl, bytes_compl); + if (freed && netif_queue_stopped(bgmac->net_dev)) netif_wake_queue(bgmac->net_dev); } @@ -988,6 +996,8 @@ static void bgmac_chip_reset(struct bgmac *bgmac) bgmac_miiconfig(bgmac); bgmac_phy_init(bgmac); + netdev_reset_queue(bgmac->net_dev); + bgmac->int_status = 0; } diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index e838a3f74b69..61118708fe98 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c @@ -5761,8 +5761,8 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode) if (!skb) return -ENOMEM; packet = skb_put(skb, pkt_size); - memcpy(packet, bp->dev->dev_addr, 6); - memset(packet + 6, 0x0, 8); + memcpy(packet, bp->dev->dev_addr, ETH_ALEN); + memset(packet + ETH_ALEN, 0x0, 8); for (i = 14; i < pkt_size; i++) packet[i] = (unsigned char) (i & 0xff); @@ -8514,7 +8514,7 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_drvdata(pdev, dev); - memcpy(dev->dev_addr, bp->mac_addr, 6); + memcpy(dev->dev_addr, bp->mac_addr, ETH_ALEN); dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO_ECN | diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index 97b3d32a98bd..8fe4bcb2407d 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -2231,7 +2231,7 @@ void bnx2x_igu_clear_sb_gen(struct bnx2x *bp, u8 func, u8 idu_sb_id, #define BNX2X_NUM_TESTS_SF 7 #define BNX2X_NUM_TESTS_MF 3 #define BNX2X_NUM_TESTS(bp) (IS_MF(bp) ? BNX2X_NUM_TESTS_MF : \ - BNX2X_NUM_TESTS_SF) + IS_VF(bp) ? 0 : BNX2X_NUM_TESTS_SF) #define BNX2X_PHY_LOOPBACK 0 #define BNX2X_MAC_LOOPBACK 1 @@ -2491,11 +2491,5 @@ enum { #define NUM_MACS 8 -enum bnx2x_pci_bus_speed { - BNX2X_PCI_LINK_SPEED_2500 = 2500, - BNX2X_PCI_LINK_SPEED_5000 = 5000, - BNX2X_PCI_LINK_SPEED_8000 = 8000 -}; - void bnx2x_set_local_cmng(struct bnx2x *bp); #endif /* bnx2x.h */ diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 61726af1de6e..0c64122aeaff 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -2481,8 +2481,7 @@ load_error_cnic2: load_error_cnic1: bnx2x_napi_disable_cnic(bp); /* Update the number of queues without the cnic queues */ - rc = bnx2x_set_real_num_queues(bp, 0); - if (rc) + if (bnx2x_set_real_num_queues(bp, 0)) BNX2X_ERR("Unable to set real_num_queues not including cnic\n"); load_error_cnic0: BNX2X_ERR("CNIC-related load failed\n"); @@ -3256,14 +3255,16 @@ static u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb) if (prot == IPPROTO_TCP) rc |= XMIT_CSUM_TCP; - if (skb_is_gso_v6(skb)) { - rc |= (XMIT_GSO_V6 | XMIT_CSUM_TCP); - if (rc & XMIT_CSUM_ENC) - rc |= XMIT_GSO_ENC_V6; - } else if (skb_is_gso(skb)) { - rc |= (XMIT_GSO_V4 | XMIT_CSUM_TCP); - if (rc & XMIT_CSUM_ENC) - rc |= XMIT_GSO_ENC_V4; + if (skb_is_gso(skb)) { + if (skb_is_gso_v6(skb)) { + rc |= (XMIT_GSO_V6 | XMIT_CSUM_TCP); + if (rc & XMIT_CSUM_ENC) + rc |= XMIT_GSO_ENC_V6; + } else { + rc |= (XMIT_GSO_V4 | XMIT_CSUM_TCP); + if (rc & XMIT_CSUM_ENC) + rc |= XMIT_GSO_ENC_V4; + } } return rc; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index 324de5f05332..8213cc827aae 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c @@ -639,6 +639,9 @@ static int bnx2x_get_regs_len(struct net_device *dev) struct bnx2x *bp = netdev_priv(dev); int regdump_len = 0; + if (IS_VF(bp)) + return 0; + regdump_len = __bnx2x_get_regs_len(bp); regdump_len *= 4; regdump_len += sizeof(struct dump_header); @@ -2900,9 +2903,16 @@ static void bnx2x_self_test(struct net_device *dev, memset(buf, 0, sizeof(u64) * BNX2X_NUM_TESTS(bp)); + if (bnx2x_test_nvram(bp) != 0) { + if (!IS_MF(bp)) + buf[4] = 1; + else + buf[0] = 1; + etest->flags |= ETH_TEST_FL_FAILED; + } + if (!netif_running(dev)) { - DP(BNX2X_MSG_ETHTOOL, - "Can't perform self-test when interface is down\n"); + DP(BNX2X_MSG_ETHTOOL, "Interface is down\n"); return; } @@ -2964,13 +2974,7 @@ static void bnx2x_self_test(struct net_device *dev, /* wait until link state is restored */ bnx2x_wait_for_link(bp, link_up, is_serdes); } - if (bnx2x_test_nvram(bp) != 0) { - if (!IS_MF(bp)) - buf[4] = 1; - else - buf[0] = 1; - etest->flags |= ETH_TEST_FL_FAILED; - } + if (bnx2x_test_intr(bp) != 0) { if (!IS_MF(bp)) buf[5] = 1; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h index 32767f6aa33f..cf1df8b62e2c 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h @@ -172,6 +172,7 @@ struct shared_hw_cfg { /* NVRAM Offset */ #define SHARED_HW_CFG_LED_MAC4 0x000c0000 #define SHARED_HW_CFG_LED_PHY8 0x000d0000 #define SHARED_HW_CFG_LED_EXTPHY1 0x000e0000 + #define SHARED_HW_CFG_LED_EXTPHY2 0x000f0000 #define SHARED_HW_CFG_AN_ENABLE_MASK 0x3f000000 diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index d60a2ea3da19..20dcc02431ca 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -175,6 +175,7 @@ typedef int (*read_sfp_module_eeprom_func_p)(struct bnx2x_phy *phy, #define EDC_MODE_LINEAR 0x0022 #define EDC_MODE_LIMITING 0x0044 #define EDC_MODE_PASSIVE_DAC 0x0055 +#define EDC_MODE_ACTIVE_DAC 0x0066 /* ETS defines*/ #define DCBX_INVALID_COS (0xFF) @@ -3121,7 +3122,7 @@ static void bnx2x_bsc_module_sel(struct link_params *params) } static int bnx2x_bsc_read(struct link_params *params, - struct bnx2x_phy *phy, + struct bnx2x *bp, u8 sl_devid, u16 sl_addr, u8 lc_addr, @@ -3130,7 +3131,6 @@ static int bnx2x_bsc_read(struct link_params *params, { u32 val, i; int rc = 0; - struct bnx2x *bp = params->bp; if (xfer_cnt > 16) { DP(NETIF_MSG_LINK, "invalid xfer_cnt %d. Max is 16 bytes\n", @@ -3684,6 +3684,41 @@ static void bnx2x_warpcore_enable_AN_KR2(struct bnx2x_phy *phy, bnx2x_update_link_attr(params, vars->link_attr_sync); } +static void bnx2x_disable_kr2(struct link_params *params, + struct link_vars *vars, + struct bnx2x_phy *phy) +{ + struct bnx2x *bp = params->bp; + int i; + static struct bnx2x_reg_set reg_set[] = { + /* Step 1 - Program the TX/RX alignment markers */ + {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL5, 0x7690}, + {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL7, 0xe647}, + {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL6, 0xc4f0}, + {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL9, 0x7690}, + {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_RX_CTRL11, 0xe647}, + {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_RX_CTRL10, 0xc4f0}, + {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_USERB0_CTRL, 0x000c}, + {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CTRL1, 0x6000}, + {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CTRL3, 0x0000}, + {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CODE_FIELD, 0x0002}, + {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI1, 0x0000}, + {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI2, 0x0af7}, + {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI3, 0x0af7}, + {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_LD_BAM_CODE, 0x0002}, + {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_LD_UD_CODE, 0x0000} + }; + DP(NETIF_MSG_LINK, "Disabling 20G-KR2\n"); + + for (i = 0; i < ARRAY_SIZE(reg_set); i++) + bnx2x_cl45_write(bp, phy, reg_set[i].devad, reg_set[i].reg, + reg_set[i].val); + vars->link_attr_sync &= ~LINK_ATTR_SYNC_KR2_ENABLE; + bnx2x_update_link_attr(params, vars->link_attr_sync); + + vars->check_kr2_recovery_cnt = CHECK_KR2_RECOVERY_CNT; +} + static void bnx2x_warpcore_set_lpi_passthrough(struct bnx2x_phy *phy, struct link_params *params) { @@ -3715,7 +3750,6 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, struct link_params *params, struct link_vars *vars) { u16 lane, i, cl72_ctrl, an_adv = 0; - u16 ucode_ver; struct bnx2x *bp = params->bp; static struct bnx2x_reg_set reg_set[] = { {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7}, @@ -3806,15 +3840,7 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, /* Advertise pause */ bnx2x_ext_phy_set_pause(params, phy, vars); - /* Set KR Autoneg Work-Around flag for Warpcore version older than D108 - */ - bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_UC_INFO_B1_VERSION, &ucode_ver); - if (ucode_ver < 0xd108) { - DP(NETIF_MSG_LINK, "Enable AN KR work-around. WC ver:0x%x\n", - ucode_ver); - vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY; - } + vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY; bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL5_MISC7, 0x100); @@ -3838,6 +3864,8 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, bnx2x_set_aer_mmd(params, phy); bnx2x_warpcore_enable_AN_KR2(phy, params, vars); + } else { + bnx2x_disable_kr2(params, vars, phy); } /* Enable Autoneg: only on the main lane */ @@ -4347,20 +4375,14 @@ static void bnx2x_warpcore_config_runtime(struct bnx2x_phy *phy, struct bnx2x *bp = params->bp; u32 serdes_net_if; u16 gp_status1 = 0, lnkup = 0, lnkup_kr = 0; - u16 lane = bnx2x_get_warpcore_lane(phy, params); vars->turn_to_run_wc_rt = vars->turn_to_run_wc_rt ? 0 : 1; if (!vars->turn_to_run_wc_rt) return; - /* Return if there is no link partner */ - if (!(bnx2x_warpcore_get_sigdet(phy, params))) { - DP(NETIF_MSG_LINK, "bnx2x_warpcore_get_sigdet false\n"); - return; - } - if (vars->rx_tx_asic_rst) { + u16 lane = bnx2x_get_warpcore_lane(phy, params); serdes_net_if = (REG_RD(bp, params->shmem_base + offsetof(struct shmem_region, dev_info. port_hw_config[params->port].default_cfg)) & @@ -4375,14 +4397,8 @@ static void bnx2x_warpcore_config_runtime(struct bnx2x_phy *phy, /*10G KR*/ lnkup_kr = (gp_status1 >> (12+lane)) & 0x1; - DP(NETIF_MSG_LINK, - "gp_status1 0x%x\n", gp_status1); - if (lnkup_kr || lnkup) { - vars->rx_tx_asic_rst = 0; - DP(NETIF_MSG_LINK, - "link up, rx_tx_asic_rst 0x%x\n", - vars->rx_tx_asic_rst); + vars->rx_tx_asic_rst = 0; } else { /* Reset the lane to see if link comes up.*/ bnx2x_warpcore_reset_lane(bp, phy, 1); @@ -4507,10 +4523,14 @@ static void bnx2x_warpcore_config_init(struct bnx2x_phy *phy, * enabled transmitter to avoid current leakage in case * no module is connected */ - if (bnx2x_is_sfp_module_plugged(phy, params)) - bnx2x_sfp_module_detection(phy, params); - else - bnx2x_sfp_e3_set_transmitter(params, phy, 1); + if ((params->loopback_mode == LOOPBACK_NONE) || + (params->loopback_mode == LOOPBACK_EXT)) { + if (bnx2x_is_sfp_module_plugged(phy, params)) + bnx2x_sfp_module_detection(phy, params); + else + bnx2x_sfp_e3_set_transmitter(params, + phy, 1); + } bnx2x_warpcore_config_sfi(phy, params); break; @@ -5757,6 +5777,11 @@ static int bnx2x_warpcore_read_status(struct bnx2x_phy *phy, rc = bnx2x_get_link_speed_duplex(phy, params, vars, link_up, gp_speed, duplex); + /* In case of KR link down, start up the recovering procedure */ + if ((!link_up) && (phy->media_type == ETH_PHY_KR) && + (!(phy->flags & FLAGS_WC_DUAL_MODE))) + vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY; + DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x link_status 0x%x\n", vars->duplex, vars->flow_ctrl, vars->link_status); return rc; @@ -6345,9 +6370,15 @@ int bnx2x_set_led(struct link_params *params, * intended override. */ break; - } else + } else { + u32 nig_led_mode = ((params->hw_led_mode << + SHARED_HW_CFG_LED_MODE_SHIFT) == + SHARED_HW_CFG_LED_EXTPHY2) ? + (SHARED_HW_CFG_LED_PHY1 >> + SHARED_HW_CFG_LED_MODE_SHIFT) : hw_led_mode; REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, - hw_led_mode); + nig_led_mode); + } REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + port*4, 0); /* Set blinking rate to ~15.9Hz */ @@ -6507,6 +6538,11 @@ static int bnx2x_link_initialize(struct link_params *params, params->phy[INT_PHY].config_init(phy, params, vars); } + /* Re-read this value in case it was changed inside config_init due to + * limitations of optic module + */ + vars->line_speed = params->phy[INT_PHY].req_line_speed; + /* Init external phy*/ if (non_ext_phy) { if (params->phy[INT_PHY].supported & @@ -7886,7 +7922,7 @@ static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy, usleep_range(1000, 2000); bnx2x_warpcore_power_module(params, 1); } - rc = bnx2x_bsc_read(params, phy, dev_addr, addr32, 0, byte_cnt, + rc = bnx2x_bsc_read(params, bp, dev_addr, addr32, 0, byte_cnt, data_array); } while ((rc != 0) && (++cnt < I2C_WA_RETRY_CNT)); @@ -8080,7 +8116,10 @@ static int bnx2x_get_edc_mode(struct bnx2x_phy *phy, if (copper_module_type & SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) { DP(NETIF_MSG_LINK, "Active Copper cable detected\n"); - check_limiting_mode = 1; + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) + *edc_mode = EDC_MODE_ACTIVE_DAC; + else + check_limiting_mode = 1; } else if (copper_module_type & SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) { DP(NETIF_MSG_LINK, @@ -8555,6 +8594,7 @@ static void bnx2x_warpcore_set_limiting_mode(struct link_params *params, mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT; break; case EDC_MODE_PASSIVE_DAC: + case EDC_MODE_ACTIVE_DAC: mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_SFP_DAC; break; default: @@ -9730,32 +9770,41 @@ static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy, MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL, an_1000_val); - /* set 100 speed advertisement */ - if ((phy->req_line_speed == SPEED_AUTO_NEG) && - (phy->speed_cap_mask & - (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL | - PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF))) { - an_10_100_val |= (1<<7); - /* Enable autoneg and restart autoneg for legacy speeds */ - autoneg_val |= (1<<9 | 1<<12); - - if (phy->req_duplex == DUPLEX_FULL) + /* Set 10/100 speed advertisement */ + if (phy->req_line_speed == SPEED_AUTO_NEG) { + if (phy->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL) { + /* Enable autoneg and restart autoneg for legacy speeds + */ + autoneg_val |= (1<<9 | 1<<12); an_10_100_val |= (1<<8); - DP(NETIF_MSG_LINK, "Advertising 100M\n"); - } - /* set 10 speed advertisement */ - if (((phy->req_line_speed == SPEED_AUTO_NEG) && - (phy->speed_cap_mask & - (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL | - PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)) && - (phy->supported & - (SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full)))) { - an_10_100_val |= (1<<5); - autoneg_val |= (1<<9 | 1<<12); - if (phy->req_duplex == DUPLEX_FULL) + DP(NETIF_MSG_LINK, "Advertising 100M-FD\n"); + } + + if (phy->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF) { + /* Enable autoneg and restart autoneg for legacy speeds + */ + autoneg_val |= (1<<9 | 1<<12); + an_10_100_val |= (1<<7); + DP(NETIF_MSG_LINK, "Advertising 100M-HD\n"); + } + + if ((phy->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) && + (phy->supported & SUPPORTED_10baseT_Full)) { an_10_100_val |= (1<<6); - DP(NETIF_MSG_LINK, "Advertising 10M\n"); + autoneg_val |= (1<<9 | 1<<12); + DP(NETIF_MSG_LINK, "Advertising 10M-FD\n"); + } + + if ((phy->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF) && + (phy->supported & SUPPORTED_10baseT_Half)) { + an_10_100_val |= (1<<5); + autoneg_val |= (1<<9 | 1<<12); + DP(NETIF_MSG_LINK, "Advertising 10M-HD\n"); + } } /* Only 10/100 are allowed to work in FORCE mode */ @@ -10609,10 +10658,18 @@ static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy, 0x40); } else { + /* EXTPHY2 LED mode indicate that the 100M/1G/10G LED + * sources are all wired through LED1, rather than only + * 10G in other modes. + */ + val = ((params->hw_led_mode << + SHARED_HW_CFG_LED_MODE_SHIFT) == + SHARED_HW_CFG_LED_EXTPHY2) ? 0x98 : 0x80; + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LED1_MASK, - 0x80); + val); /* Tell LED3 to blink on source */ bnx2x_cl45_read(bp, phy, @@ -13432,43 +13489,6 @@ static void bnx2x_sfp_tx_fault_detection(struct bnx2x_phy *phy, } } } -static void bnx2x_disable_kr2(struct link_params *params, - struct link_vars *vars, - struct bnx2x_phy *phy) -{ - struct bnx2x *bp = params->bp; - int i; - static struct bnx2x_reg_set reg_set[] = { - /* Step 1 - Program the TX/RX alignment markers */ - {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL5, 0x7690}, - {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL7, 0xe647}, - {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL6, 0xc4f0}, - {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL9, 0x7690}, - {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_RX_CTRL11, 0xe647}, - {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_RX_CTRL10, 0xc4f0}, - {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_USERB0_CTRL, 0x000c}, - {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CTRL1, 0x6000}, - {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CTRL3, 0x0000}, - {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CODE_FIELD, 0x0002}, - {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI1, 0x0000}, - {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI2, 0x0af7}, - {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI3, 0x0af7}, - {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_LD_BAM_CODE, 0x0002}, - {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_LD_UD_CODE, 0x0000} - }; - DP(NETIF_MSG_LINK, "Disabling 20G-KR2\n"); - - for (i = 0; i < ARRAY_SIZE(reg_set); i++) - bnx2x_cl45_write(bp, phy, reg_set[i].devad, reg_set[i].reg, - reg_set[i].val); - vars->link_attr_sync &= ~LINK_ATTR_SYNC_KR2_ENABLE; - bnx2x_update_link_attr(params, vars->link_attr_sync); - - vars->check_kr2_recovery_cnt = CHECK_KR2_RECOVERY_CNT; - /* Restart AN on leading lane */ - bnx2x_warpcore_restart_AN_KR(phy, params); -} - static void bnx2x_kr2_recovery(struct link_params *params, struct link_vars *vars, struct bnx2x_phy *phy) @@ -13546,6 +13566,8 @@ static void bnx2x_check_kr2_wa(struct link_params *params, /* Disable KR2 on both lanes */ DP(NETIF_MSG_LINK, "BP=0x%x, NP=0x%x\n", base_page, next_page); bnx2x_disable_kr2(params, vars, phy); + /* Restart AN on leading lane */ + bnx2x_warpcore_restart_AN_KR(phy, params); return; } } diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index a6704b555042..13a569460ef2 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -4703,6 +4703,14 @@ bool bnx2x_chk_parity_attn(struct bnx2x *bp, bool *global, bool print) attn.sig[3] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_4_FUNC_0 + port*4); + /* Since MCP attentions can't be disabled inside the block, we need to + * read AEU registers to see whether they're currently disabled + */ + attn.sig[3] &= ((REG_RD(bp, + !port ? MISC_REG_AEU_ENABLE4_FUNC_0_OUT_0 + : MISC_REG_AEU_ENABLE4_FUNC_1_OUT_0) & + MISC_AEU_ENABLE_MCP_PRTY_BITS) | + ~MISC_AEU_ENABLE_MCP_PRTY_BITS); if (!CHIP_IS_E1x(bp)) attn.sig[4] = REG_RD(bp, @@ -5447,26 +5455,24 @@ static void bnx2x_timer(unsigned long data) if (IS_PF(bp) && !BP_NOMCP(bp)) { int mb_idx = BP_FW_MB_IDX(bp); - u32 drv_pulse; - u32 mcp_pulse; + u16 drv_pulse; + u16 mcp_pulse; ++bp->fw_drv_pulse_wr_seq; bp->fw_drv_pulse_wr_seq &= DRV_PULSE_SEQ_MASK; - /* TBD - add SYSTEM_TIME */ drv_pulse = bp->fw_drv_pulse_wr_seq; bnx2x_drv_pulse(bp); mcp_pulse = (SHMEM_RD(bp, func_mb[mb_idx].mcp_pulse_mb) & MCP_PULSE_SEQ_MASK); /* The delta between driver pulse and mcp response - * should be 1 (before mcp response) or 0 (after mcp response) + * should not get too big. If the MFW is more than 5 pulses + * behind, we should worry about it enough to generate an error + * log. */ - if ((drv_pulse != mcp_pulse) && - (drv_pulse != ((mcp_pulse + 1) & MCP_PULSE_SEQ_MASK))) { - /* someone lost a heartbeat... */ - BNX2X_ERR("drv_pulse (0x%x) != mcp_pulse (0x%x)\n", + if (((drv_pulse - mcp_pulse) & MCP_PULSE_SEQ_MASK) > 5) + BNX2X_ERR("MFW seems hanged: drv_pulse (0x%x) != mcp_pulse (0x%x)\n", drv_pulse, mcp_pulse); - } } if (bp->state == BNX2X_STATE_OPEN) @@ -9873,7 +9879,7 @@ static int bnx2x_prev_path_mark_eeh(struct bnx2x *bp) static bool bnx2x_prev_is_path_marked(struct bnx2x *bp) { struct bnx2x_prev_path_list *tmp_list; - int rc = false; + bool rc = false; if (down_trylock(&bnx2x_prev_sem)) return false; @@ -11740,7 +11746,7 @@ static int bnx2x_open(struct net_device *dev) rc = bnx2x_nic_load(bp, LOAD_OPEN); if (rc) return rc; - return bnx2x_open_epilog(bp); + return 0; } /* called with rtnl_lock */ @@ -12274,28 +12280,6 @@ err_out: return rc; } -static void bnx2x_get_pcie_width_speed(struct bnx2x *bp, int *width, - enum bnx2x_pci_bus_speed *speed) -{ - u32 link_speed, val = 0; - - pci_read_config_dword(bp->pdev, PCICFG_LINK_CONTROL, &val); - *width = (val & PCICFG_LINK_WIDTH) >> PCICFG_LINK_WIDTH_SHIFT; - - link_speed = (val & PCICFG_LINK_SPEED) >> PCICFG_LINK_SPEED_SHIFT; - - switch (link_speed) { - case 3: - *speed = BNX2X_PCI_LINK_SPEED_8000; - break; - case 2: - *speed = BNX2X_PCI_LINK_SPEED_5000; - break; - default: - *speed = BNX2X_PCI_LINK_SPEED_2500; - } -} - static int bnx2x_check_firmware(struct bnx2x *bp) { const struct firmware *firmware = bp->firmware; @@ -12652,8 +12636,8 @@ static int bnx2x_init_one(struct pci_dev *pdev, { struct net_device *dev = NULL; struct bnx2x *bp; - int pcie_width; - enum bnx2x_pci_bus_speed pcie_speed; + enum pcie_link_width pcie_width; + enum pci_bus_speed pcie_speed; int rc, max_non_def_sbs; int rx_count, tx_count, rss_count, doorbell_size; int max_cos_est; @@ -12802,18 +12786,19 @@ static int bnx2x_init_one(struct pci_dev *pdev, dev_addr_add(bp->dev, bp->fip_mac, NETDEV_HW_ADDR_T_SAN); rtnl_unlock(); } - - bnx2x_get_pcie_width_speed(bp, &pcie_width, &pcie_speed); - BNX2X_DEV_INFO("got pcie width %d and speed %d\n", - pcie_width, pcie_speed); - - BNX2X_DEV_INFO("%s (%c%d) PCI-E x%d %s found at mem %lx, IRQ %d, node addr %pM\n", + if (pcie_get_minimum_link(bp->pdev, &pcie_speed, &pcie_width) || + pcie_speed == PCI_SPEED_UNKNOWN || + pcie_width == PCIE_LNK_WIDTH_UNKNOWN) + BNX2X_DEV_INFO("Failed to determine PCI Express Bandwidth\n"); + else + BNX2X_DEV_INFO( + "%s (%c%d) PCI-E x%d %s found at mem %lx, IRQ %d, node addr %pM\n", board_info[ent->driver_data].name, (CHIP_REV(bp) >> 12) + 'A', (CHIP_METAL(bp) >> 4), pcie_width, - pcie_speed == BNX2X_PCI_LINK_SPEED_2500 ? "2.5GHz" : - pcie_speed == BNX2X_PCI_LINK_SPEED_5000 ? "5.0GHz" : - pcie_speed == BNX2X_PCI_LINK_SPEED_8000 ? "8.0GHz" : + pcie_speed == PCIE_SPEED_2_5GT ? "2.5GHz" : + pcie_speed == PCIE_SPEED_5_0GT ? "5.0GHz" : + pcie_speed == PCIE_SPEED_8_0GT ? "8.0GHz" : "Unknown", dev->base_addr, bp->pdev->irq, dev->dev_addr); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c index 2604b6204abe..122703d8127e 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c @@ -1819,7 +1819,7 @@ bnx2x_get_vf_igu_cam_info(struct bnx2x *bp) fid = GET_FIELD((val), IGU_REG_MAPPING_MEMORY_FID); if (fid & IGU_FID_ENCODE_IS_PF) current_pf = fid & IGU_FID_PF_NUM_MASK; - else if (current_pf == BP_ABS_FUNC(bp)) + else if (current_pf == BP_FUNC(bp)) bnx2x_vf_set_igu_info(bp, sb_id, (fid & IGU_FID_VF_NUM_MASK)); DP(BNX2X_MSG_IOV, "%s[%d], igu_sb_id=%d, msix=%d\n", @@ -2802,7 +2802,7 @@ struct set_vf_state_cookie { u8 state; }; -void bnx2x_set_vf_state(void *cookie) +static void bnx2x_set_vf_state(void *cookie) { struct set_vf_state_cookie *p = (struct set_vf_state_cookie *)cookie; @@ -3180,6 +3180,7 @@ int bnx2x_enable_sriov(struct bnx2x *bp) /* set local queue arrays */ vf->vfqs = &bp->vfdb->vfqs[qcount]; qcount += vf_sb_count(vf); + bnx2x_iov_static_resc(bp, vf); } /* prepare msix vectors in VF configuration space */ @@ -3187,6 +3188,8 @@ int bnx2x_enable_sriov(struct bnx2x *bp) bnx2x_pretend_func(bp, HW_VF_HANDLE(bp, vf_idx)); REG_WR(bp, PCICFG_OFFSET + GRC_CONFIG_REG_VF_MSIX_CONTROL, num_vf_queues); + DP(BNX2X_MSG_IOV, "set msix vec num in VF %d cfg space to %d\n", + vf_idx, num_vf_queues); } bnx2x_pretend_func(bp, BP_ABS_FUNC(bp)); @@ -3222,8 +3225,9 @@ void bnx2x_disable_sriov(struct bnx2x *bp) pci_disable_sriov(bp->pdev); } -int bnx2x_vf_ndo_prep(struct bnx2x *bp, int vfidx, struct bnx2x_virtf **vf, - struct pf_vf_bulletin_content **bulletin) +static int bnx2x_vf_ndo_prep(struct bnx2x *bp, int vfidx, + struct bnx2x_virtf **vf, + struct pf_vf_bulletin_content **bulletin) { if (bp->state != BNX2X_STATE_OPEN) { BNX2X_ERR("vf ndo called though PF is down\n"); @@ -3634,29 +3638,6 @@ alloc_mem_err: return -ENOMEM; } -int bnx2x_open_epilog(struct bnx2x *bp) -{ - /* Enable sriov via delayed work. This must be done via delayed work - * because it causes the probe of the vf devices to be run, which invoke - * register_netdevice which must have rtnl lock taken. As we are holding - * the lock right now, that could only work if the probe would not take - * the lock. However, as the probe of the vf may be called from other - * contexts as well (such as passthrough to vm fails) it can't assume - * the lock is being held for it. Using delayed work here allows the - * probe code to simply take the lock (i.e. wait for it to be released - * if it is being held). We only want to do this if the number of VFs - * was set before PF driver was loaded. - */ - if (IS_SRIOV(bp) && BNX2X_NR_VIRTFN(bp)) { - smp_mb__before_clear_bit(); - set_bit(BNX2X_SP_RTNL_ENABLE_SRIOV, &bp->sp_rtnl_state); - smp_mb__after_clear_bit(); - schedule_delayed_work(&bp->sp_rtnl_task, 0); - } - - return 0; -} - void bnx2x_iov_channel_down(struct bnx2x *bp) { int vf_idx; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h index 059f0d460af2..1ff6a9366629 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h @@ -782,7 +782,6 @@ static inline int bnx2x_vf_headroom(struct bnx2x *bp) void bnx2x_pf_set_vfs_vlan(struct bnx2x *bp); int bnx2x_sriov_configure(struct pci_dev *dev, int num_vfs); void bnx2x_iov_channel_down(struct bnx2x *bp); -int bnx2x_open_epilog(struct bnx2x *bp); #else /* CONFIG_BNX2X_SRIOV */ @@ -842,7 +841,6 @@ static inline int bnx2x_vf_pci_alloc(struct bnx2x *bp) {return 0; } static inline void bnx2x_pf_set_vfs_vlan(struct bnx2x *bp) {} static inline int bnx2x_sriov_configure(struct pci_dev *dev, int num_vfs) {return 0; } static inline void bnx2x_iov_channel_down(struct bnx2x *bp) {} -static inline int bnx2x_open_epilog(struct bnx2x *bp) {return 0; } #endif /* CONFIG_BNX2X_SRIOV */ #endif /* bnx2x_sriov.h */ diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c index 6cfb88732452..da16953eb2ec 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c @@ -1765,28 +1765,28 @@ static void bnx2x_vf_mbx_request(struct bnx2x *bp, struct bnx2x_virtf *vf, switch (mbx->first_tlv.tl.type) { case CHANNEL_TLV_ACQUIRE: bnx2x_vf_mbx_acquire(bp, vf, mbx); - break; + return; case CHANNEL_TLV_INIT: bnx2x_vf_mbx_init_vf(bp, vf, mbx); - break; + return; case CHANNEL_TLV_SETUP_Q: bnx2x_vf_mbx_setup_q(bp, vf, mbx); - break; + return; case CHANNEL_TLV_SET_Q_FILTERS: bnx2x_vf_mbx_set_q_filters(bp, vf, mbx); - break; + return; case CHANNEL_TLV_TEARDOWN_Q: bnx2x_vf_mbx_teardown_q(bp, vf, mbx); - break; + return; case CHANNEL_TLV_CLOSE: bnx2x_vf_mbx_close_vf(bp, vf, mbx); - break; + return; case CHANNEL_TLV_RELEASE: bnx2x_vf_mbx_release_vf(bp, vf, mbx); - break; + return; case CHANNEL_TLV_UPDATE_RSS: bnx2x_vf_mbx_update_rss(bp, vf, mbx); - break; + return; } } else { @@ -1802,26 +1802,24 @@ static void bnx2x_vf_mbx_request(struct bnx2x *bp, struct bnx2x_virtf *vf, for (i = 0; i < 20; i++) DP_CONT(BNX2X_MSG_IOV, "%x ", mbx->msg->req.tlv_buf_size.tlv_buffer[i]); + } - /* test whether we can respond to the VF (do we have an address - * for it?) - */ - if (vf->state == VF_ACQUIRED || vf->state == VF_ENABLED) { - /* mbx_resp uses the op_rc of the VF */ - vf->op_rc = PFVF_STATUS_NOT_SUPPORTED; + /* can we respond to VF (do we have an address for it?) */ + if (vf->state == VF_ACQUIRED || vf->state == VF_ENABLED) { + /* mbx_resp uses the op_rc of the VF */ + vf->op_rc = PFVF_STATUS_NOT_SUPPORTED; - /* notify the VF that we do not support this request */ - bnx2x_vf_mbx_resp(bp, vf); - } else { - /* can't send a response since this VF is unknown to us - * just ack the FW to release the mailbox and unlock - * the channel. - */ - storm_memset_vf_mbx_ack(bp, vf->abs_vfid); - mmiowb(); - bnx2x_unlock_vf_pf_channel(bp, vf, - mbx->first_tlv.tl.type); - } + /* notify the VF that we do not support this request */ + bnx2x_vf_mbx_resp(bp, vf); + } else { + /* can't send a response since this VF is unknown to us + * just ack the FW to release the mailbox and unlock + * the channel. + */ + storm_memset_vf_mbx_ack(bp, vf->abs_vfid); + /* Firmware ack should be written before unlocking channel */ + mmiowb(); + bnx2x_unlock_vf_pf_channel(bp, vf, mbx->first_tlv.tl.type); } } diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c index 99394bd49a13..f58a8b80302d 100644 --- a/drivers/net/ethernet/broadcom/cnic.c +++ b/drivers/net/ethernet/broadcom/cnic.c @@ -393,7 +393,7 @@ static int cnic_iscsi_nl_msg_recv(struct cnic_dev *dev, u32 msg_type, csk->vlan_id = path_resp->vlan_id; - memcpy(csk->ha, path_resp->mac_addr, 6); + memcpy(csk->ha, path_resp->mac_addr, ETH_ALEN); if (test_bit(SK_F_IPV6, &csk->flags)) memcpy(&csk->src_ip[0], &path_resp->src.v6_addr, sizeof(struct in6_addr)); @@ -5572,7 +5572,7 @@ static struct cnic_dev *init_bnx2x_cnic(struct net_device *dev) if (cdev->max_fcoe_conn > BNX2X_FCOE_NUM_CONNECTIONS) cdev->max_fcoe_conn = BNX2X_FCOE_NUM_CONNECTIONS; - memcpy(cdev->mac_addr, ethdev->iscsi_mac, 6); + memcpy(cdev->mac_addr, ethdev->iscsi_mac, ETH_ALEN); cp->cnic_ops = &cnic_bnx2x_ops; cp->start_hw = cnic_start_bnx2x_hw; diff --git a/drivers/net/ethernet/broadcom/cnic_if.h b/drivers/net/ethernet/broadcom/cnic_if.h index 0658b43e148c..ebbfe25acaa6 100644 --- a/drivers/net/ethernet/broadcom/cnic_if.h +++ b/drivers/net/ethernet/broadcom/cnic_if.h @@ -353,8 +353,8 @@ struct cnic_ulp_ops { atomic_t ref_count; }; -extern int cnic_register_driver(int ulp_type, struct cnic_ulp_ops *ulp_ops); +int cnic_register_driver(int ulp_type, struct cnic_ulp_ops *ulp_ops); -extern int cnic_unregister_driver(int ulp_type); +int cnic_unregister_driver(int ulp_type); #endif diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 12d961c4ebca..498569e99a1c 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -94,10 +94,10 @@ static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits) #define DRV_MODULE_NAME "tg3" #define TG3_MAJ_NUM 3 -#define TG3_MIN_NUM 133 +#define TG3_MIN_NUM 134 #define DRV_MODULE_VERSION \ __stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM) -#define DRV_MODULE_RELDATE "Jul 29, 2013" +#define DRV_MODULE_RELDATE "Sep 16, 2013" #define RESET_KIND_SHUTDOWN 0 #define RESET_KIND_INIT 1 @@ -337,6 +337,11 @@ static DEFINE_PCI_DEVICE_TABLE(tg3_pci_tbl) = { {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5762)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5725)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5727)}, + {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57764)}, + {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57767)}, + {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57787)}, + {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57782)}, + {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57786)}, {PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX)}, {PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX)}, {PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1000)}, @@ -1326,6 +1331,12 @@ static int tg3_phy_toggle_auxctl_smdsp(struct tg3 *tp, bool enable) return err; } +static int tg3_phy_shdw_write(struct tg3 *tp, int reg, u32 val) +{ + return tg3_writephy(tp, MII_TG3_MISC_SHDW, + reg | val | MII_TG3_MISC_SHDW_WREN); +} + static int tg3_bmcr_reset(struct tg3 *tp) { u32 phy_control; @@ -1364,7 +1375,7 @@ static int tg3_mdio_read(struct mii_bus *bp, int mii_id, int reg) spin_lock_bh(&tp->lock); - if (tg3_readphy(tp, reg, &val)) + if (__tg3_readphy(tp, mii_id, reg, &val)) val = -EIO; spin_unlock_bh(&tp->lock); @@ -1379,7 +1390,7 @@ static int tg3_mdio_write(struct mii_bus *bp, int mii_id, int reg, u16 val) spin_lock_bh(&tp->lock); - if (tg3_writephy(tp, reg, val)) + if (__tg3_writephy(tp, mii_id, reg, val)) ret = -EIO; spin_unlock_bh(&tp->lock); @@ -1397,7 +1408,7 @@ static void tg3_mdio_config_5785(struct tg3 *tp) u32 val; struct phy_device *phydev; - phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]; + phydev = tp->mdio_bus->phy_map[tp->phy_addr]; switch (phydev->drv->phy_id & phydev->drv->phy_id_mask) { case PHY_ID_BCM50610: case PHY_ID_BCM50610M: @@ -1502,6 +1513,13 @@ static int tg3_mdio_init(struct tg3 *tp) TG3_CPMU_PHY_STRAP_IS_SERDES; if (is_serdes) tp->phy_addr += 7; + } else if (tg3_flag(tp, IS_SSB_CORE) && tg3_flag(tp, ROBOSWITCH)) { + int addr; + + addr = ssb_gige_get_phyaddr(tp->pdev); + if (addr < 0) + return addr; + tp->phy_addr = addr; } else tp->phy_addr = TG3_PHY_MII_ADDR; @@ -1522,7 +1540,7 @@ static int tg3_mdio_init(struct tg3 *tp) tp->mdio_bus->read = &tg3_mdio_read; tp->mdio_bus->write = &tg3_mdio_write; tp->mdio_bus->reset = &tg3_mdio_reset; - tp->mdio_bus->phy_mask = ~(1 << TG3_PHY_MII_ADDR); + tp->mdio_bus->phy_mask = ~(1 << tp->phy_addr); tp->mdio_bus->irq = &tp->mdio_irq[0]; for (i = 0; i < PHY_MAX_ADDR; i++) @@ -1543,7 +1561,7 @@ static int tg3_mdio_init(struct tg3 *tp) return i; } - phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]; + phydev = tp->mdio_bus->phy_map[tp->phy_addr]; if (!phydev || !phydev->drv) { dev_warn(&tp->pdev->dev, "No PHY devices\n"); @@ -1953,7 +1971,7 @@ static void tg3_setup_flow_control(struct tg3 *tp, u32 lcladv, u32 rmtadv) u32 old_tx_mode = tp->tx_mode; if (tg3_flag(tp, USE_PHYLIB)) - autoneg = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]->autoneg; + autoneg = tp->mdio_bus->phy_map[tp->phy_addr]->autoneg; else autoneg = tp->link_config.autoneg; @@ -1989,7 +2007,7 @@ static void tg3_adjust_link(struct net_device *dev) u8 oldflowctrl, linkmesg = 0; u32 mac_mode, lcl_adv, rmt_adv; struct tg3 *tp = netdev_priv(dev); - struct phy_device *phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]; + struct phy_device *phydev = tp->mdio_bus->phy_map[tp->phy_addr]; spin_lock_bh(&tp->lock); @@ -2078,7 +2096,7 @@ static int tg3_phy_init(struct tg3 *tp) /* Bring the PHY back to a known state. */ tg3_bmcr_reset(tp); - phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]; + phydev = tp->mdio_bus->phy_map[tp->phy_addr]; /* Attach the MAC to the PHY. */ phydev = phy_connect(tp->dev, dev_name(&phydev->dev), @@ -2105,7 +2123,7 @@ static int tg3_phy_init(struct tg3 *tp) SUPPORTED_Asym_Pause); break; default: - phy_disconnect(tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]); + phy_disconnect(tp->mdio_bus->phy_map[tp->phy_addr]); return -EINVAL; } @@ -2123,7 +2141,7 @@ static void tg3_phy_start(struct tg3 *tp) if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED)) return; - phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]; + phydev = tp->mdio_bus->phy_map[tp->phy_addr]; if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) { tp->phy_flags &= ~TG3_PHYFLG_IS_LOW_POWER; @@ -2143,13 +2161,13 @@ static void tg3_phy_stop(struct tg3 *tp) if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED)) return; - phy_stop(tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]); + phy_stop(tp->mdio_bus->phy_map[tp->phy_addr]); } static void tg3_phy_fini(struct tg3 *tp) { if (tp->phy_flags & TG3_PHYFLG_IS_CONNECTED) { - phy_disconnect(tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]); + phy_disconnect(tp->mdio_bus->phy_map[tp->phy_addr]); tp->phy_flags &= ~TG3_PHYFLG_IS_CONNECTED; } } @@ -2218,25 +2236,21 @@ static void tg3_phy_toggle_apd(struct tg3 *tp, bool enable) return; } - reg = MII_TG3_MISC_SHDW_WREN | - MII_TG3_MISC_SHDW_SCR5_SEL | - MII_TG3_MISC_SHDW_SCR5_LPED | + reg = MII_TG3_MISC_SHDW_SCR5_LPED | MII_TG3_MISC_SHDW_SCR5_DLPTLM | MII_TG3_MISC_SHDW_SCR5_SDTL | MII_TG3_MISC_SHDW_SCR5_C125OE; if (tg3_asic_rev(tp) != ASIC_REV_5784 || !enable) reg |= MII_TG3_MISC_SHDW_SCR5_DLLAPD; - tg3_writephy(tp, MII_TG3_MISC_SHDW, reg); + tg3_phy_shdw_write(tp, MII_TG3_MISC_SHDW_SCR5_SEL, reg); - reg = MII_TG3_MISC_SHDW_WREN | - MII_TG3_MISC_SHDW_APD_SEL | - MII_TG3_MISC_SHDW_APD_WKTM_84MS; + reg = MII_TG3_MISC_SHDW_APD_WKTM_84MS; if (enable) reg |= MII_TG3_MISC_SHDW_APD_ENABLE; - tg3_writephy(tp, MII_TG3_MISC_SHDW, reg); + tg3_phy_shdw_write(tp, MII_TG3_MISC_SHDW_APD_SEL, reg); } static void tg3_phy_toggle_automdix(struct tg3 *tp, bool enable) @@ -4027,7 +4041,7 @@ static int tg3_power_down_prepare(struct tg3 *tp) struct phy_device *phydev; u32 phyid, advertising; - phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]; + phydev = tp->mdio_bus->phy_map[tp->phy_addr]; tp->phy_flags |= TG3_PHYFLG_IS_LOW_POWER; @@ -9196,10 +9210,7 @@ static int tg3_halt(struct tg3 *tp, int kind, bool silent) memset(tp->hw_stats, 0, sizeof(struct tg3_hw_stats)); } - if (err) - return err; - - return 0; + return err; } static int tg3_set_mac_addr(struct net_device *dev, void *p) @@ -11035,7 +11046,18 @@ static int tg3_request_irq(struct tg3 *tp, int irq_num) name = tp->dev->name; else { name = &tnapi->irq_lbl[0]; - snprintf(name, IFNAMSIZ, "%s-%d", tp->dev->name, irq_num); + if (tnapi->tx_buffers && tnapi->rx_rcb) + snprintf(name, IFNAMSIZ, + "%s-txrx-%d", tp->dev->name, irq_num); + else if (tnapi->tx_buffers) + snprintf(name, IFNAMSIZ, + "%s-tx-%d", tp->dev->name, irq_num); + else if (tnapi->rx_rcb) + snprintf(name, IFNAMSIZ, + "%s-rx-%d", tp->dev->name, irq_num); + else + snprintf(name, IFNAMSIZ, + "%s-%d", tp->dev->name, irq_num); name[IFNAMSIZ-1] = 0; } @@ -11907,7 +11929,7 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) struct phy_device *phydev; if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED)) return -EAGAIN; - phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]; + phydev = tp->mdio_bus->phy_map[tp->phy_addr]; return phy_ethtool_gset(phydev, cmd); } @@ -11974,7 +11996,7 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) struct phy_device *phydev; if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED)) return -EAGAIN; - phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]; + phydev = tp->mdio_bus->phy_map[tp->phy_addr]; return phy_ethtool_sset(phydev, cmd); } @@ -12093,12 +12115,10 @@ static int tg3_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) device_set_wakeup_enable(dp, wol->wolopts & WAKE_MAGIC); - spin_lock_bh(&tp->lock); if (device_may_wakeup(dp)) tg3_flag_set(tp, WOL_ENABLE); else tg3_flag_clear(tp, WOL_ENABLE); - spin_unlock_bh(&tp->lock); return 0; } @@ -12131,7 +12151,7 @@ static int tg3_nway_reset(struct net_device *dev) if (tg3_flag(tp, USE_PHYLIB)) { if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED)) return -EAGAIN; - r = phy_start_aneg(tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]); + r = phy_start_aneg(tp->mdio_bus->phy_map[tp->phy_addr]); } else { u32 bmcr; @@ -12247,7 +12267,7 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam u32 newadv; struct phy_device *phydev; - phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]; + phydev = tp->mdio_bus->phy_map[tp->phy_addr]; if (!(phydev->supported & SUPPORTED_Pause) || (!(phydev->supported & SUPPORTED_Asym_Pause) && @@ -13194,8 +13214,8 @@ static int tg3_run_loopback(struct tg3 *tp, u32 pktsz, bool tso_loopback) return -ENOMEM; tx_data = skb_put(skb, tx_len); - memcpy(tx_data, tp->dev->dev_addr, 6); - memset(tx_data + 6, 0x0, 8); + memcpy(tx_data, tp->dev->dev_addr, ETH_ALEN); + memset(tx_data + ETH_ALEN, 0x0, 8); tw32(MAC_RX_MTU_SIZE, tx_len + ETH_FCS_LEN); @@ -13683,7 +13703,7 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) struct phy_device *phydev; if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED)) return -EAGAIN; - phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]; + phydev = tp->mdio_bus->phy_map[tp->phy_addr]; return phy_mii_ioctl(phydev, ifr, cmd); } @@ -14921,6 +14941,12 @@ static void tg3_get_eeprom_hw_cfg(struct tg3 *tp) tg3_chip_rev_id(tp) != CHIPREV_ID_5750_A1) tp->led_ctrl |= (LED_CTRL_MODE_PHY_1 | LED_CTRL_MODE_PHY_2); + + if (tg3_flag(tp, 5717_PLUS) || + tg3_asic_rev(tp) == ASIC_REV_5762) + tp->led_ctrl |= LED_CTRL_BLINK_RATE_OVERRIDE | + LED_CTRL_BLINK_RATE_MASK; + break; case SHASTA_EXT_LED_MAC: @@ -15759,9 +15785,12 @@ static void tg3_detect_asic_rev(struct tg3 *tp, u32 misc_ctrl_reg) tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 || tp->pdev->device == TG3PCI_DEVICE_TIGON3_5719 || tp->pdev->device == TG3PCI_DEVICE_TIGON3_5720 || + tp->pdev->device == TG3PCI_DEVICE_TIGON3_57767 || + tp->pdev->device == TG3PCI_DEVICE_TIGON3_57764 || tp->pdev->device == TG3PCI_DEVICE_TIGON3_5762 || tp->pdev->device == TG3PCI_DEVICE_TIGON3_5725 || - tp->pdev->device == TG3PCI_DEVICE_TIGON3_5727) + tp->pdev->device == TG3PCI_DEVICE_TIGON3_5727 || + tp->pdev->device == TG3PCI_DEVICE_TIGON3_57787) reg = TG3PCI_GEN2_PRODID_ASICREV; else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57781 || tp->pdev->device == TG3PCI_DEVICE_TIGON3_57785 || @@ -16632,8 +16661,8 @@ static int tg3_get_macaddr_sparc(struct tg3 *tp) int len; addr = of_get_property(dp, "local-mac-address", &len); - if (addr && len == 6) { - memcpy(dev->dev_addr, addr, 6); + if (addr && len == ETH_ALEN) { + memcpy(dev->dev_addr, addr, ETH_ALEN); return 0; } return -ENODEV; @@ -16643,7 +16672,7 @@ static int tg3_get_default_macaddr_sparc(struct tg3 *tp) { struct net_device *dev = tp->dev; - memcpy(dev->dev_addr, idprom->id_ethaddr, 6); + memcpy(dev->dev_addr, idprom->id_ethaddr, ETH_ALEN); return 0; } #endif @@ -17052,10 +17081,6 @@ static int tg3_test_dma(struct tg3 *tp) tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl); -#if 0 - /* Unneeded, already done by tg3_get_invariants. */ - tg3_switch_clocks(tp); -#endif if (tg3_asic_rev(tp) != ASIC_REV_5700 && tg3_asic_rev(tp) != ASIC_REV_5701) @@ -17083,20 +17108,6 @@ static int tg3_test_dma(struct tg3 *tp) break; } -#if 0 - /* validate data reached card RAM correctly. */ - for (i = 0; i < TEST_BUFFER_SIZE / sizeof(u32); i++) { - u32 val; - tg3_read_mem(tp, 0x2100 + (i*4), &val); - if (le32_to_cpu(val) != p[i]) { - dev_err(&tp->pdev->dev, - "%s: Buffer corrupted on device! " - "(%d != %d)\n", __func__, val, i); - /* ret = -ENODEV here? */ - } - p[i] = 0; - } -#endif /* Now read it back. */ ret = tg3_do_test_dma(tp, buf, buf_dma, TEST_BUFFER_SIZE, false); if (ret) { @@ -17362,8 +17373,10 @@ static int tg3_init_one(struct pci_dev *pdev, tg3_flag_set(tp, FLUSH_POSTED_WRITES); if (ssb_gige_one_dma_at_once(pdev)) tg3_flag_set(tp, ONE_DMA_AT_ONCE); - if (ssb_gige_have_roboswitch(pdev)) + if (ssb_gige_have_roboswitch(pdev)) { + tg3_flag_set(tp, USE_PHYLIB); tg3_flag_set(tp, ROBOSWITCH); + } if (ssb_gige_is_rgmii(pdev)) tg3_flag_set(tp, RGMII_MODE); } @@ -17409,9 +17422,12 @@ static int tg3_init_one(struct pci_dev *pdev, tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 || tp->pdev->device == TG3PCI_DEVICE_TIGON3_5719 || tp->pdev->device == TG3PCI_DEVICE_TIGON3_5720 || + tp->pdev->device == TG3PCI_DEVICE_TIGON3_57767 || + tp->pdev->device == TG3PCI_DEVICE_TIGON3_57764 || tp->pdev->device == TG3PCI_DEVICE_TIGON3_5762 || tp->pdev->device == TG3PCI_DEVICE_TIGON3_5725 || - tp->pdev->device == TG3PCI_DEVICE_TIGON3_5727) { + tp->pdev->device == TG3PCI_DEVICE_TIGON3_5727 || + tp->pdev->device == TG3PCI_DEVICE_TIGON3_57787) { tg3_flag_set(tp, ENABLE_APE); tp->aperegs = pci_ioremap_bar(pdev, BAR_2); if (!tp->aperegs) { @@ -17628,7 +17644,7 @@ static int tg3_init_one(struct pci_dev *pdev, if (tp->phy_flags & TG3_PHYFLG_IS_CONNECTED) { struct phy_device *phydev; - phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]; + phydev = tp->mdio_bus->phy_map[tp->phy_addr]; netdev_info(dev, "attached PHY driver [%s] (mii_bus:phy_addr=%s)\n", phydev->drv->name, dev_name(&phydev->dev)); diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h index 70257808aa37..5c3835aa1e1b 100644 --- a/drivers/net/ethernet/broadcom/tg3.h +++ b/drivers/net/ethernet/broadcom/tg3.h @@ -68,6 +68,9 @@ #define TG3PCI_DEVICE_TIGON3_5762 0x1687 #define TG3PCI_DEVICE_TIGON3_5725 0x1643 #define TG3PCI_DEVICE_TIGON3_5727 0x16f3 +#define TG3PCI_DEVICE_TIGON3_57764 0x1642 +#define TG3PCI_DEVICE_TIGON3_57767 0x1683 +#define TG3PCI_DEVICE_TIGON3_57787 0x1641 /* 0x04 --> 0x2c unused */ #define TG3PCI_SUBVENDOR_ID_BROADCOM PCI_VENDOR_ID_BROADCOM #define TG3PCI_SUBDEVICE_ID_BROADCOM_95700A6 0x1644 diff --git a/drivers/net/ethernet/brocade/bna/bnad.h b/drivers/net/ethernet/brocade/bna/bnad.h index aefee77523f2..f7e033f8a00e 100644 --- a/drivers/net/ethernet/brocade/bna/bnad.h +++ b/drivers/net/ethernet/brocade/bna/bnad.h @@ -372,38 +372,37 @@ extern u32 bnad_rxqs_per_cq; /* * EXTERN PROTOTYPES */ -extern u32 *cna_get_firmware_buf(struct pci_dev *pdev); +u32 *cna_get_firmware_buf(struct pci_dev *pdev); /* Netdev entry point prototypes */ -extern void bnad_set_rx_mode(struct net_device *netdev); -extern struct net_device_stats *bnad_get_netdev_stats( - struct net_device *netdev); -extern int bnad_mac_addr_set_locked(struct bnad *bnad, u8 *mac_addr); -extern int bnad_enable_default_bcast(struct bnad *bnad); -extern void bnad_restore_vlans(struct bnad *bnad, u32 rx_id); -extern void bnad_set_ethtool_ops(struct net_device *netdev); -extern void bnad_cb_completion(void *arg, enum bfa_status status); +void bnad_set_rx_mode(struct net_device *netdev); +struct net_device_stats *bnad_get_netdev_stats(struct net_device *netdev); +int bnad_mac_addr_set_locked(struct bnad *bnad, u8 *mac_addr); +int bnad_enable_default_bcast(struct bnad *bnad); +void bnad_restore_vlans(struct bnad *bnad, u32 rx_id); +void bnad_set_ethtool_ops(struct net_device *netdev); +void bnad_cb_completion(void *arg, enum bfa_status status); /* Configuration & setup */ -extern void bnad_tx_coalescing_timeo_set(struct bnad *bnad); -extern void bnad_rx_coalescing_timeo_set(struct bnad *bnad); +void bnad_tx_coalescing_timeo_set(struct bnad *bnad); +void bnad_rx_coalescing_timeo_set(struct bnad *bnad); -extern int bnad_setup_rx(struct bnad *bnad, u32 rx_id); -extern int bnad_setup_tx(struct bnad *bnad, u32 tx_id); -extern void bnad_destroy_tx(struct bnad *bnad, u32 tx_id); -extern void bnad_destroy_rx(struct bnad *bnad, u32 rx_id); +int bnad_setup_rx(struct bnad *bnad, u32 rx_id); +int bnad_setup_tx(struct bnad *bnad, u32 tx_id); +void bnad_destroy_tx(struct bnad *bnad, u32 tx_id); +void bnad_destroy_rx(struct bnad *bnad, u32 rx_id); /* Timer start/stop protos */ -extern void bnad_dim_timer_start(struct bnad *bnad); +void bnad_dim_timer_start(struct bnad *bnad); /* Statistics */ -extern void bnad_netdev_qstats_fill(struct bnad *bnad, - struct rtnl_link_stats64 *stats); -extern void bnad_netdev_hwstats_fill(struct bnad *bnad, - struct rtnl_link_stats64 *stats); +void bnad_netdev_qstats_fill(struct bnad *bnad, + struct rtnl_link_stats64 *stats); +void bnad_netdev_hwstats_fill(struct bnad *bnad, + struct rtnl_link_stats64 *stats); /* Debugfs */ -void bnad_debugfs_init(struct bnad *bnad); -void bnad_debugfs_uninit(struct bnad *bnad); +void bnad_debugfs_init(struct bnad *bnad); +void bnad_debugfs_uninit(struct bnad *bnad); /* MACROS */ /* To set & get the stats counters */ diff --git a/drivers/net/ethernet/chelsio/cxgb/common.h b/drivers/net/ethernet/chelsio/cxgb/common.h index 5ccbed1784d2..8abb46b39032 100644 --- a/drivers/net/ethernet/chelsio/cxgb/common.h +++ b/drivers/net/ethernet/chelsio/cxgb/common.h @@ -324,30 +324,30 @@ static inline unsigned int core_ticks_per_usec(const adapter_t *adap) return board_info(adap)->clock_core / 1000000; } -extern int __t1_tpi_read(adapter_t *adapter, u32 addr, u32 *valp); -extern int __t1_tpi_write(adapter_t *adapter, u32 addr, u32 value); -extern int t1_tpi_write(adapter_t *adapter, u32 addr, u32 value); -extern int t1_tpi_read(adapter_t *adapter, u32 addr, u32 *value); - -extern void t1_interrupts_enable(adapter_t *adapter); -extern void t1_interrupts_disable(adapter_t *adapter); -extern void t1_interrupts_clear(adapter_t *adapter); -extern int t1_elmer0_ext_intr_handler(adapter_t *adapter); -extern void t1_elmer0_ext_intr(adapter_t *adapter); -extern int t1_slow_intr_handler(adapter_t *adapter); - -extern int t1_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc); -extern const struct board_info *t1_get_board_info(unsigned int board_id); -extern const struct board_info *t1_get_board_info_from_ids(unsigned int devid, +int __t1_tpi_read(adapter_t *adapter, u32 addr, u32 *valp); +int __t1_tpi_write(adapter_t *adapter, u32 addr, u32 value); +int t1_tpi_write(adapter_t *adapter, u32 addr, u32 value); +int t1_tpi_read(adapter_t *adapter, u32 addr, u32 *value); + +void t1_interrupts_enable(adapter_t *adapter); +void t1_interrupts_disable(adapter_t *adapter); +void t1_interrupts_clear(adapter_t *adapter); +int t1_elmer0_ext_intr_handler(adapter_t *adapter); +void t1_elmer0_ext_intr(adapter_t *adapter); +int t1_slow_intr_handler(adapter_t *adapter); + +int t1_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc); +const struct board_info *t1_get_board_info(unsigned int board_id); +const struct board_info *t1_get_board_info_from_ids(unsigned int devid, unsigned short ssid); -extern int t1_seeprom_read(adapter_t *adapter, u32 addr, __le32 *data); -extern int t1_get_board_rev(adapter_t *adapter, const struct board_info *bi, +int t1_seeprom_read(adapter_t *adapter, u32 addr, __le32 *data); +int t1_get_board_rev(adapter_t *adapter, const struct board_info *bi, struct adapter_params *p); -extern int t1_init_hw_modules(adapter_t *adapter); -extern int t1_init_sw_modules(adapter_t *adapter, const struct board_info *bi); -extern void t1_free_sw_modules(adapter_t *adapter); -extern void t1_fatal_err(adapter_t *adapter); -extern void t1_link_changed(adapter_t *adapter, int port_id); -extern void t1_link_negotiated(adapter_t *adapter, int port_id, int link_stat, +int t1_init_hw_modules(adapter_t *adapter); +int t1_init_sw_modules(adapter_t *adapter, const struct board_info *bi); +void t1_free_sw_modules(adapter_t *adapter); +void t1_fatal_err(adapter_t *adapter); +void t1_link_changed(adapter_t *adapter, int port_id); +void t1_link_negotiated(adapter_t *adapter, int port_id, int link_stat, int speed, int duplex, int pause); #endif /* _CXGB_COMMON_H_ */ diff --git a/drivers/net/ethernet/chelsio/cxgb/pm3393.c b/drivers/net/ethernet/chelsio/cxgb/pm3393.c index 40c7b93ababc..eb33a31b08a0 100644 --- a/drivers/net/ethernet/chelsio/cxgb/pm3393.c +++ b/drivers/net/ethernet/chelsio/cxgb/pm3393.c @@ -499,7 +499,7 @@ static const struct cmac_statistics *pm3393_update_statistics(struct cmac *mac, static int pm3393_macaddress_get(struct cmac *cmac, u8 mac_addr[6]) { - memcpy(mac_addr, cmac->instance->mac_addr, 6); + memcpy(mac_addr, cmac->instance->mac_addr, ETH_ALEN); return 0; } @@ -526,7 +526,7 @@ static int pm3393_macaddress_set(struct cmac *cmac, u8 ma[6]) */ /* Store local copy */ - memcpy(cmac->instance->mac_addr, ma, 6); + memcpy(cmac->instance->mac_addr, ma, ETH_ALEN); lo = ((u32) ma[1] << 8) | (u32) ma[0]; mid = ((u32) ma[3] << 8) | (u32) ma[2]; diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index c73cabdbd4c0..85d0cda5fbfa 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -3983,6 +3983,7 @@ static int cxgb4_inet6addr_handler(struct notifier_block *this, struct net_device *event_dev; int ret = NOTIFY_DONE; struct bonding *bond = netdev_priv(ifa->idev->dev); + struct list_head *iter; struct slave *slave; struct pci_dev *first_pdev = NULL; @@ -3995,7 +3996,7 @@ static int cxgb4_inet6addr_handler(struct notifier_block *this, * in all of them only once. */ read_lock(&bond->lock); - bond_for_each_slave(bond, slave) { + bond_for_each_slave(bond, slave, iter) { if (!first_pdev) { ret = clip_add(slave->dev, ifa, event); /* If clip_add is success then only initialize diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c index df296af20bd5..8475c4cda9e4 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c @@ -1396,8 +1396,9 @@ static inline void copy_frags(struct sk_buff *skb, * Builds an sk_buff from the given packet gather list. Returns the * sk_buff or %NULL if sk_buff allocation failed. */ -struct sk_buff *t4vf_pktgl_to_skb(const struct pkt_gl *gl, - unsigned int skb_len, unsigned int pull_len) +static struct sk_buff *t4vf_pktgl_to_skb(const struct pkt_gl *gl, + unsigned int skb_len, + unsigned int pull_len) { struct sk_buff *skb; @@ -1443,7 +1444,7 @@ out: * Releases the pages of a packet gather list. We do not own the last * page on the list and do not free it. */ -void t4vf_pktgl_free(const struct pkt_gl *gl) +static void t4vf_pktgl_free(const struct pkt_gl *gl) { int frag; @@ -1640,7 +1641,7 @@ static inline void rspq_next(struct sge_rspq *rspq) * on this queue. If the system is under memory shortage use a fairly * long delay to help recovery. */ -int process_responses(struct sge_rspq *rspq, int budget) +static int process_responses(struct sge_rspq *rspq, int budget) { struct sge_eth_rxq *rxq = container_of(rspq, struct sge_eth_rxq, rspq); int budget_left = budget; @@ -1893,7 +1894,7 @@ static unsigned int process_intrq(struct adapter *adapter) * The MSI interrupt handler handles data events from SGE response queues as * well as error and other async events as they all use the same MSI vector. */ -irqreturn_t t4vf_intr_msi(int irq, void *cookie) +static irqreturn_t t4vf_intr_msi(int irq, void *cookie) { struct adapter *adapter = cookie; diff --git a/drivers/net/ethernet/davicom/dm9000.c b/drivers/net/ethernet/davicom/dm9000.c index 5f5896e522d2..be8efeea51f2 100644 --- a/drivers/net/ethernet/davicom/dm9000.c +++ b/drivers/net/ethernet/davicom/dm9000.c @@ -1603,7 +1603,7 @@ dm9000_probe(struct platform_device *pdev) if (!is_valid_ether_addr(ndev->dev_addr) && pdata != NULL) { mac_src = "platform data"; - memcpy(ndev->dev_addr, pdata->dev_addr, 6); + memcpy(ndev->dev_addr, pdata->dev_addr, ETH_ALEN); } if (!is_valid_ether_addr(ndev->dev_addr)) { diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h index ace5050dba38..add6d7a953c6 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h @@ -88,7 +88,8 @@ static inline char *nic_name(struct pci_dev *pdev) #define BE_MIN_MTU 256 #define BE_NUM_VLANS_SUPPORTED 64 -#define BE_MAX_EQD 96u +#define BE_UMC_NUM_VLANS_SUPPORTED 15 +#define BE_MAX_EQD 128u #define BE_MAX_TX_FRAG_COUNT 30 #define EVNT_Q_LEN 1024 @@ -200,6 +201,17 @@ struct be_eq_obj { struct be_adapter *adapter; } ____cacheline_aligned_in_smp; +struct be_aic_obj { /* Adaptive interrupt coalescing (AIC) info */ + bool enable; + u32 min_eqd; /* in usecs */ + u32 max_eqd; /* in usecs */ + u32 prev_eqd; /* in usecs */ + u32 et_eqd; /* configured val when aic is off */ + ulong jiffies; + u64 rx_pkts_prev; /* Used to calculate RX pps */ + u64 tx_reqs_prev; /* Used to calculate TX pps */ +}; + struct be_mcc_obj { struct be_queue_info q; struct be_queue_info cq; @@ -214,6 +226,7 @@ struct be_tx_stats { u64 tx_compl; ulong tx_jiffies; u32 tx_stops; + u32 tx_drv_drops; /* pkts dropped by driver */ struct u64_stats_sync sync; struct u64_stats_sync sync_compl; }; @@ -238,15 +251,12 @@ struct be_rx_page_info { struct be_rx_stats { u64 rx_bytes; u64 rx_pkts; - u64 rx_pkts_prev; - ulong rx_jiffies; u32 rx_drops_no_skbs; /* skb allocation errors */ u32 rx_drops_no_frags; /* HW has no fetched frags */ u32 rx_post_fail; /* page post alloc failures */ u32 rx_compl; u32 rx_mcast_pkts; u32 rx_compl_err; /* completions with err set */ - u32 rx_pps; /* pkts per second */ struct u64_stats_sync sync; }; @@ -333,6 +343,7 @@ enum vf_state { #define BE_FLAGS_LINK_STATUS_INIT 1 #define BE_FLAGS_WORKER_SCHEDULED (1 << 3) +#define BE_FLAGS_VLAN_PROMISC (1 << 4) #define BE_FLAGS_NAPI_ENABLED (1 << 9) #define BE_UC_PMAC_COUNT 30 #define BE_VF_UC_PMAC_COUNT 2 @@ -403,6 +414,7 @@ struct be_adapter { u32 big_page_size; /* Compounded page size shared by rx wrbs */ struct be_drv_stats drv_stats; + struct be_aic_obj aic_obj[MAX_EVT_QS]; u16 vlans_added; u8 vlan_tag[VLAN_N_VID]; u8 vlan_prio_bmap; /* Available Priority BitMap */ @@ -470,8 +482,8 @@ struct be_adapter { #define be_physfn(adapter) (!adapter->virtfn) #define sriov_enabled(adapter) (adapter->num_vfs > 0) -#define sriov_want(adapter) (be_max_vfs(adapter) && num_vfs && \ - be_physfn(adapter)) +#define sriov_want(adapter) (be_physfn(adapter) && \ + (num_vfs || pci_num_vf(adapter->pdev))) #define for_all_vfs(adapter, vf_cfg, i) \ for (i = 0, vf_cfg = &adapter->vf_cfg[i]; i < adapter->num_vfs; \ i++, vf_cfg++) @@ -694,27 +706,27 @@ static inline int qnq_async_evt_rcvd(struct be_adapter *adapter) return adapter->flags & BE_FLAGS_QNQ_ASYNC_EVT_RCVD; } -extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, - u16 num_popped); -extern void be_link_status_update(struct be_adapter *adapter, u8 link_status); -extern void be_parse_stats(struct be_adapter *adapter); -extern int be_load_fw(struct be_adapter *adapter, u8 *func); -extern bool be_is_wol_supported(struct be_adapter *adapter); -extern bool be_pause_supported(struct be_adapter *adapter); -extern u32 be_get_fw_log_level(struct be_adapter *adapter); +void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, + u16 num_popped); +void be_link_status_update(struct be_adapter *adapter, u8 link_status); +void be_parse_stats(struct be_adapter *adapter); +int be_load_fw(struct be_adapter *adapter, u8 *func); +bool be_is_wol_supported(struct be_adapter *adapter); +bool be_pause_supported(struct be_adapter *adapter); +u32 be_get_fw_log_level(struct be_adapter *adapter); int be_update_queues(struct be_adapter *adapter); int be_poll(struct napi_struct *napi, int budget); /* * internal function to initialize-cleanup roce device. */ -extern void be_roce_dev_add(struct be_adapter *); -extern void be_roce_dev_remove(struct be_adapter *); +void be_roce_dev_add(struct be_adapter *); +void be_roce_dev_remove(struct be_adapter *); /* * internal function to open-close roce device during ifup-ifdown. */ -extern void be_roce_dev_open(struct be_adapter *); -extern void be_roce_dev_close(struct be_adapter *); +void be_roce_dev_open(struct be_adapter *); +void be_roce_dev_close(struct be_adapter *); #endif /* BE_H */ diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index 1ab5dab11eff..787bce8c5246 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -180,6 +180,9 @@ static int be_mcc_compl_process(struct be_adapter *adapter, dev_err(&adapter->pdev->dev, "opcode %d-%d failed:status %d-%d\n", opcode, subsystem, compl_status, extd_status); + + if (extd_status == MCC_ADDL_STS_INSUFFICIENT_RESOURCES) + return extd_status; } } done: @@ -1195,7 +1198,6 @@ int be_cmd_txq_create(struct be_adapter *adapter, struct be_tx_obj *txo) if (lancer_chip(adapter)) { req->hdr.version = 1; - req->if_id = cpu_to_le16(adapter->if_handle); } else if (BEx_chip(adapter)) { if (adapter->function_caps & BE_FUNCTION_CAPS_SUPER_NIC) req->hdr.version = 2; @@ -1203,6 +1205,8 @@ int be_cmd_txq_create(struct be_adapter *adapter, struct be_tx_obj *txo) req->hdr.version = 2; } + if (req->hdr.version > 0) + req->if_id = cpu_to_le16(adapter->if_handle); req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size); req->ulp_num = BE_ULP1_NUM; req->type = BE_ETH_TX_RING_TYPE_STANDARD; @@ -1715,11 +1719,12 @@ err: /* set the EQ delay interval of an EQ to specified value * Uses async mcc */ -int be_cmd_modify_eqd(struct be_adapter *adapter, u32 eq_id, u32 eqd) +int be_cmd_modify_eqd(struct be_adapter *adapter, struct be_set_eqd *set_eqd, + int num) { struct be_mcc_wrb *wrb; struct be_cmd_req_modify_eq_delay *req; - int status = 0; + int status = 0, i; spin_lock_bh(&adapter->mcc_lock); @@ -1733,13 +1738,15 @@ int be_cmd_modify_eqd(struct be_adapter *adapter, u32 eq_id, u32 eqd) be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, OPCODE_COMMON_MODIFY_EQ_DELAY, sizeof(*req), wrb, NULL); - req->num_eq = cpu_to_le32(1); - req->delay[0].eq_id = cpu_to_le32(eq_id); - req->delay[0].phase = 0; - req->delay[0].delay_multiplier = cpu_to_le32(eqd); + req->num_eq = cpu_to_le32(num); + for (i = 0; i < num; i++) { + req->set_eqd[i].eq_id = cpu_to_le32(set_eqd[i].eq_id); + req->set_eqd[i].phase = 0; + req->set_eqd[i].delay_multiplier = + cpu_to_le32(set_eqd[i].delay_multiplier); + } be_mcc_notify(adapter); - err: spin_unlock_bh(&adapter->mcc_lock); return status; @@ -1812,6 +1819,12 @@ int be_cmd_rx_filter(struct be_adapter *adapter, u32 flags, u32 value) } else if (flags & IFF_ALLMULTI) { req->if_flags_mask = req->if_flags = cpu_to_le32(BE_IF_FLAGS_MCAST_PROMISCUOUS); + } else if (flags & BE_FLAGS_VLAN_PROMISC) { + req->if_flags_mask = cpu_to_le32(BE_IF_FLAGS_VLAN_PROMISCUOUS); + + if (value == ON) + req->if_flags = + cpu_to_le32(BE_IF_FLAGS_VLAN_PROMISCUOUS); } else { struct netdev_hw_addr *ha; int i = 0; @@ -3510,7 +3523,7 @@ int be_cmd_enable_vf(struct be_adapter *adapter, u8 domain) struct be_cmd_enable_disable_vf *req; int status; - if (!lancer_chip(adapter)) + if (BEx_chip(adapter)) return 0; spin_lock_bh(&adapter->mcc_lock); diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h index d026226db88c..337ef1f96f0b 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.h +++ b/drivers/net/ethernet/emulex/benet/be_cmds.h @@ -60,6 +60,8 @@ enum { MCC_STATUS_NOT_SUPPORTED = 66 }; +#define MCC_ADDL_STS_INSUFFICIENT_RESOURCES 0x16 + #define CQE_STATUS_COMPL_MASK 0xFFFF #define CQE_STATUS_COMPL_SHIFT 0 /* bits 0 - 15 */ #define CQE_STATUS_EXTD_MASK 0xFFFF @@ -1055,14 +1057,16 @@ struct be_cmd_resp_get_flow_control { } __packed; /******************** Modify EQ Delay *******************/ +struct be_set_eqd { + u32 eq_id; + u32 phase; + u32 delay_multiplier; +}; + struct be_cmd_req_modify_eq_delay { struct be_cmd_req_hdr hdr; u32 num_eq; - struct { - u32 eq_id; - u32 phase; - u32 delay_multiplier; - } delay[8]; + struct be_set_eqd set_eqd[MAX_EVT_QS]; } __packed; struct be_cmd_resp_modify_eq_delay { @@ -1791,7 +1795,7 @@ struct be_nic_res_desc { u8 acpi_params; u8 wol_param; u16 rsvd7; - u32 rsvd8[3]; + u32 rsvd8[7]; } __packed; struct be_cmd_req_get_func_config { @@ -1863,137 +1867,120 @@ struct be_cmd_resp_get_iface_list { struct be_if_desc if_desc; }; -extern int be_pci_fnum_get(struct be_adapter *adapter); -extern int be_fw_wait_ready(struct be_adapter *adapter); -extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, - bool permanent, u32 if_handle, u32 pmac_id); -extern int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr, - u32 if_id, u32 *pmac_id, u32 domain); -extern int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, - int pmac_id, u32 domain); -extern int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, - u32 en_flags, u32 *if_handle, u32 domain); -extern int be_cmd_if_destroy(struct be_adapter *adapter, int if_handle, - u32 domain); -extern int be_cmd_eq_create(struct be_adapter *adapter, struct be_eq_obj *eqo); -extern int be_cmd_cq_create(struct be_adapter *adapter, - struct be_queue_info *cq, struct be_queue_info *eq, - bool no_delay, int num_cqe_dma_coalesce); -extern int be_cmd_mccq_create(struct be_adapter *adapter, - struct be_queue_info *mccq, - struct be_queue_info *cq); -extern int be_cmd_txq_create(struct be_adapter *adapter, - struct be_tx_obj *txo); -extern int be_cmd_rxq_create(struct be_adapter *adapter, - struct be_queue_info *rxq, u16 cq_id, - u16 frag_size, u32 if_id, u32 rss, u8 *rss_id); -extern int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q, - int type); -extern int be_cmd_rxq_destroy(struct be_adapter *adapter, - struct be_queue_info *q); -extern int be_cmd_link_status_query(struct be_adapter *adapter, u16 *link_speed, - u8 *link_status, u32 dom); -extern int be_cmd_reset(struct be_adapter *adapter); -extern int be_cmd_get_stats(struct be_adapter *adapter, - struct be_dma_mem *nonemb_cmd); -extern int lancer_cmd_get_pport_stats(struct be_adapter *adapter, - struct be_dma_mem *nonemb_cmd); -extern int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver, - char *fw_on_flash); - -extern int be_cmd_modify_eqd(struct be_adapter *adapter, u32 eq_id, u32 eqd); -extern int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id, - u16 *vtag_array, u32 num, bool untagged, - bool promiscuous); -extern int be_cmd_rx_filter(struct be_adapter *adapter, u32 flags, u32 status); -extern int be_cmd_set_flow_control(struct be_adapter *adapter, - u32 tx_fc, u32 rx_fc); -extern int be_cmd_get_flow_control(struct be_adapter *adapter, - u32 *tx_fc, u32 *rx_fc); -extern int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num, +int be_pci_fnum_get(struct be_adapter *adapter); +int be_fw_wait_ready(struct be_adapter *adapter); +int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, + bool permanent, u32 if_handle, u32 pmac_id); +int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr, u32 if_id, + u32 *pmac_id, u32 domain); +int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, int pmac_id, + u32 domain); +int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags, + u32 *if_handle, u32 domain); +int be_cmd_if_destroy(struct be_adapter *adapter, int if_handle, u32 domain); +int be_cmd_eq_create(struct be_adapter *adapter, struct be_eq_obj *eqo); +int be_cmd_cq_create(struct be_adapter *adapter, struct be_queue_info *cq, + struct be_queue_info *eq, bool no_delay, + int num_cqe_dma_coalesce); +int be_cmd_mccq_create(struct be_adapter *adapter, struct be_queue_info *mccq, + struct be_queue_info *cq); +int be_cmd_txq_create(struct be_adapter *adapter, struct be_tx_obj *txo); +int be_cmd_rxq_create(struct be_adapter *adapter, struct be_queue_info *rxq, + u16 cq_id, u16 frag_size, u32 if_id, u32 rss, u8 *rss_id); +int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q, + int type); +int be_cmd_rxq_destroy(struct be_adapter *adapter, struct be_queue_info *q); +int be_cmd_link_status_query(struct be_adapter *adapter, u16 *link_speed, + u8 *link_status, u32 dom); +int be_cmd_reset(struct be_adapter *adapter); +int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd); +int lancer_cmd_get_pport_stats(struct be_adapter *adapter, + struct be_dma_mem *nonemb_cmd); +int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver, + char *fw_on_flash); +int be_cmd_modify_eqd(struct be_adapter *adapter, struct be_set_eqd *, int num); +int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id, u16 *vtag_array, + u32 num, bool untagged, bool promiscuous); +int be_cmd_rx_filter(struct be_adapter *adapter, u32 flags, u32 status); +int be_cmd_set_flow_control(struct be_adapter *adapter, u32 tx_fc, u32 rx_fc); +int be_cmd_get_flow_control(struct be_adapter *adapter, u32 *tx_fc, u32 *rx_fc); +int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num, u32 *function_mode, u32 *function_caps, u16 *asic_rev); -extern int be_cmd_reset_function(struct be_adapter *adapter); -extern int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable, - u32 rss_hash_opts, u16 table_size); -extern int be_process_mcc(struct be_adapter *adapter); -extern int be_cmd_set_beacon_state(struct be_adapter *adapter, - u8 port_num, u8 beacon, u8 status, u8 state); -extern int be_cmd_get_beacon_state(struct be_adapter *adapter, - u8 port_num, u32 *state); -extern int be_cmd_write_flashrom(struct be_adapter *adapter, - struct be_dma_mem *cmd, u32 flash_oper, - u32 flash_opcode, u32 buf_size); -extern int lancer_cmd_write_object(struct be_adapter *adapter, - struct be_dma_mem *cmd, - u32 data_size, u32 data_offset, - const char *obj_name, - u32 *data_written, u8 *change_status, - u8 *addn_status); +int be_cmd_reset_function(struct be_adapter *adapter); +int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable, + u32 rss_hash_opts, u16 table_size); +int be_process_mcc(struct be_adapter *adapter); +int be_cmd_set_beacon_state(struct be_adapter *adapter, u8 port_num, u8 beacon, + u8 status, u8 state); +int be_cmd_get_beacon_state(struct be_adapter *adapter, u8 port_num, + u32 *state); +int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd, + u32 flash_oper, u32 flash_opcode, u32 buf_size); +int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd, + u32 data_size, u32 data_offset, + const char *obj_name, u32 *data_written, + u8 *change_status, u8 *addn_status); int lancer_cmd_read_object(struct be_adapter *adapter, struct be_dma_mem *cmd, - u32 data_size, u32 data_offset, const char *obj_name, - u32 *data_read, u32 *eof, u8 *addn_status); + u32 data_size, u32 data_offset, const char *obj_name, + u32 *data_read, u32 *eof, u8 *addn_status); int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc, - int offset); -extern int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac, - struct be_dma_mem *nonemb_cmd); -extern int be_cmd_fw_init(struct be_adapter *adapter); -extern int be_cmd_fw_clean(struct be_adapter *adapter); -extern void be_async_mcc_enable(struct be_adapter *adapter); -extern void be_async_mcc_disable(struct be_adapter *adapter); -extern int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num, - u32 loopback_type, u32 pkt_size, - u32 num_pkts, u64 pattern); -extern int be_cmd_ddr_dma_test(struct be_adapter *adapter, u64 pattern, - u32 byte_cnt, struct be_dma_mem *cmd); -extern int be_cmd_get_seeprom_data(struct be_adapter *adapter, - struct be_dma_mem *nonemb_cmd); -extern int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num, - u8 loopback_type, u8 enable); -extern int be_cmd_get_phy_info(struct be_adapter *adapter); -extern int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain); -extern void be_detect_error(struct be_adapter *adapter); -extern int be_cmd_get_die_temperature(struct be_adapter *adapter); -extern int be_cmd_get_cntl_attributes(struct be_adapter *adapter); -extern int be_cmd_req_native_mode(struct be_adapter *adapter); -extern int be_cmd_get_reg_len(struct be_adapter *adapter, u32 *log_size); -extern void be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf); -extern int be_cmd_get_fn_privileges(struct be_adapter *adapter, - u32 *privilege, u32 domain); -extern int be_cmd_set_fn_privileges(struct be_adapter *adapter, - u32 privileges, u32 vf_num); -extern int be_cmd_get_mac_from_list(struct be_adapter *adapter, u8 *mac, - bool *pmac_id_active, u32 *pmac_id, - u8 domain); -extern int be_cmd_get_active_mac(struct be_adapter *adapter, u32 pmac_id, - u8 *mac); -extern int be_cmd_get_perm_mac(struct be_adapter *adapter, u8 *mac); -extern int be_cmd_set_mac_list(struct be_adapter *adapter, u8 *mac_array, - u8 mac_count, u32 domain); -extern int be_cmd_set_mac(struct be_adapter *adapter, u8 *mac, int if_id, - u32 dom); -extern int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid, - u32 domain, u16 intf_id, u16 hsw_mode); -extern int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid, - u32 domain, u16 intf_id, u8 *mode); -extern int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter); -extern int be_cmd_get_ext_fat_capabilites(struct be_adapter *adapter, - struct be_dma_mem *cmd); -extern int be_cmd_set_ext_fat_capabilites(struct be_adapter *adapter, - struct be_dma_mem *cmd, - struct be_fat_conf_params *cfgs); -extern int lancer_wait_ready(struct be_adapter *adapter); -extern int lancer_physdev_ctrl(struct be_adapter *adapter, u32 mask); -extern int lancer_initiate_dump(struct be_adapter *adapter); -extern bool dump_present(struct be_adapter *adapter); -extern int lancer_test_and_set_rdy_state(struct be_adapter *adapter); -extern int be_cmd_query_port_name(struct be_adapter *adapter, u8 *port_name); + int offset); +int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac, + struct be_dma_mem *nonemb_cmd); +int be_cmd_fw_init(struct be_adapter *adapter); +int be_cmd_fw_clean(struct be_adapter *adapter); +void be_async_mcc_enable(struct be_adapter *adapter); +void be_async_mcc_disable(struct be_adapter *adapter); +int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num, + u32 loopback_type, u32 pkt_size, u32 num_pkts, + u64 pattern); +int be_cmd_ddr_dma_test(struct be_adapter *adapter, u64 pattern, u32 byte_cnt, + struct be_dma_mem *cmd); +int be_cmd_get_seeprom_data(struct be_adapter *adapter, + struct be_dma_mem *nonemb_cmd); +int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num, + u8 loopback_type, u8 enable); +int be_cmd_get_phy_info(struct be_adapter *adapter); +int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain); +void be_detect_error(struct be_adapter *adapter); +int be_cmd_get_die_temperature(struct be_adapter *adapter); +int be_cmd_get_cntl_attributes(struct be_adapter *adapter); +int be_cmd_req_native_mode(struct be_adapter *adapter); +int be_cmd_get_reg_len(struct be_adapter *adapter, u32 *log_size); +void be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf); +int be_cmd_get_fn_privileges(struct be_adapter *adapter, u32 *privilege, + u32 domain); +int be_cmd_set_fn_privileges(struct be_adapter *adapter, u32 privileges, + u32 vf_num); +int be_cmd_get_mac_from_list(struct be_adapter *adapter, u8 *mac, + bool *pmac_id_active, u32 *pmac_id, u8 domain); +int be_cmd_get_active_mac(struct be_adapter *adapter, u32 pmac_id, u8 *mac); +int be_cmd_get_perm_mac(struct be_adapter *adapter, u8 *mac); +int be_cmd_set_mac_list(struct be_adapter *adapter, u8 *mac_array, u8 mac_count, + u32 domain); +int be_cmd_set_mac(struct be_adapter *adapter, u8 *mac, int if_id, u32 dom); +int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid, u32 domain, + u16 intf_id, u16 hsw_mode); +int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid, u32 domain, + u16 intf_id, u8 *mode); +int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter); +int be_cmd_get_ext_fat_capabilites(struct be_adapter *adapter, + struct be_dma_mem *cmd); +int be_cmd_set_ext_fat_capabilites(struct be_adapter *adapter, + struct be_dma_mem *cmd, + struct be_fat_conf_params *cfgs); +int lancer_wait_ready(struct be_adapter *adapter); +int lancer_physdev_ctrl(struct be_adapter *adapter, u32 mask); +int lancer_initiate_dump(struct be_adapter *adapter); +bool dump_present(struct be_adapter *adapter); +int lancer_test_and_set_rdy_state(struct be_adapter *adapter); +int be_cmd_query_port_name(struct be_adapter *adapter, u8 *port_name); int be_cmd_get_func_config(struct be_adapter *adapter, struct be_resources *res); int be_cmd_get_profile_config(struct be_adapter *adapter, struct be_resources *res, u8 domain); -extern int be_cmd_set_profile_config(struct be_adapter *adapter, u32 bps, - u8 domain); -extern int be_cmd_get_if_id(struct be_adapter *adapter, - struct be_vf_cfg *vf_cfg, int vf_num); -extern int be_cmd_enable_vf(struct be_adapter *adapter, u8 domain); -extern int be_cmd_intr_set(struct be_adapter *adapter, bool intr_enable); +int be_cmd_set_profile_config(struct be_adapter *adapter, u32 bps, u8 domain); +int be_cmd_get_if_id(struct be_adapter *adapter, struct be_vf_cfg *vf_cfg, + int vf_num); +int be_cmd_enable_vf(struct be_adapter *adapter, u8 domain); +int be_cmd_intr_set(struct be_adapter *adapter, bool intr_enable); diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c index b440a1fac77b..3dcf817e756d 100644 --- a/drivers/net/ethernet/emulex/benet/be_ethtool.c +++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c @@ -155,7 +155,9 @@ static const struct be_ethtool_stat et_tx_stats[] = { /* Number of times the TX queue was stopped due to lack * of spaces in the TXQ. */ - {DRVSTAT_TX_INFO(tx_stops)} + {DRVSTAT_TX_INFO(tx_stops)}, + /* Pkts dropped in the driver's transmit path */ + {DRVSTAT_TX_INFO(tx_drv_drops)} }; #define ETHTOOL_TXSTATS_NUM (ARRAY_SIZE(et_tx_stats)) @@ -290,19 +292,19 @@ static int be_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *et) { struct be_adapter *adapter = netdev_priv(netdev); - struct be_eq_obj *eqo = &adapter->eq_obj[0]; + struct be_aic_obj *aic = &adapter->aic_obj[0]; - et->rx_coalesce_usecs = eqo->cur_eqd; - et->rx_coalesce_usecs_high = eqo->max_eqd; - et->rx_coalesce_usecs_low = eqo->min_eqd; + et->rx_coalesce_usecs = aic->prev_eqd; + et->rx_coalesce_usecs_high = aic->max_eqd; + et->rx_coalesce_usecs_low = aic->min_eqd; - et->tx_coalesce_usecs = eqo->cur_eqd; - et->tx_coalesce_usecs_high = eqo->max_eqd; - et->tx_coalesce_usecs_low = eqo->min_eqd; + et->tx_coalesce_usecs = aic->prev_eqd; + et->tx_coalesce_usecs_high = aic->max_eqd; + et->tx_coalesce_usecs_low = aic->min_eqd; - et->use_adaptive_rx_coalesce = eqo->enable_aic; - et->use_adaptive_tx_coalesce = eqo->enable_aic; + et->use_adaptive_rx_coalesce = aic->enable; + et->use_adaptive_tx_coalesce = aic->enable; return 0; } @@ -314,14 +316,17 @@ static int be_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *et) { struct be_adapter *adapter = netdev_priv(netdev); + struct be_aic_obj *aic = &adapter->aic_obj[0]; struct be_eq_obj *eqo; int i; for_all_evt_queues(adapter, eqo, i) { - eqo->enable_aic = et->use_adaptive_rx_coalesce; - eqo->max_eqd = min(et->rx_coalesce_usecs_high, BE_MAX_EQD); - eqo->min_eqd = min(et->rx_coalesce_usecs_low, eqo->max_eqd); - eqo->eqd = et->rx_coalesce_usecs; + aic->enable = et->use_adaptive_rx_coalesce; + aic->max_eqd = min(et->rx_coalesce_usecs_high, BE_MAX_EQD); + aic->min_eqd = min(et->rx_coalesce_usecs_low, aic->max_eqd); + aic->et_eqd = min(et->rx_coalesce_usecs, aic->max_eqd); + aic->et_eqd = max(aic->et_eqd, aic->min_eqd); + aic++; } return 0; diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 100b528b9bd0..9daee2e8db04 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -855,11 +855,11 @@ static struct sk_buff *be_xmit_workarounds(struct be_adapter *adapter, unsigned int eth_hdr_len; struct iphdr *ip; - /* Lancer ASIC has a bug wherein packets that are 32 bytes or less + /* Lancer, SH-R ASICs have a bug wherein Packets that are 32 bytes or less * may cause a transmit stall on that port. So the work-around is to - * pad such packets to a 36-byte length. + * pad short packets (<= 32 bytes) to a 36-byte length. */ - if (unlikely(lancer_chip(adapter) && skb->len <= 32)) { + if (unlikely(!BEx_chip(adapter) && skb->len <= 32)) { if (skb_padto(skb, 36)) goto tx_drop; skb->len = 36; @@ -935,8 +935,10 @@ static netdev_tx_t be_xmit(struct sk_buff *skb, struct net_device *netdev) u32 start = txq->head; skb = be_xmit_workarounds(adapter, skb, &skip_hw_vlan); - if (!skb) + if (!skb) { + tx_stats(txo)->tx_drv_drops++; return NETDEV_TX_OK; + } wrb_cnt = wrb_cnt_for_skb(adapter, skb, &dummy_wrb); @@ -965,6 +967,7 @@ static netdev_tx_t be_xmit(struct sk_buff *skb, struct net_device *netdev) be_tx_stats_update(txo, wrb_cnt, copied, gso_segs, stopped); } else { txq->head = start; + tx_stats(txo)->tx_drv_drops++; dev_kfree_skb_any(skb); } return NETDEV_TX_OK; @@ -1013,18 +1016,40 @@ static int be_vid_config(struct be_adapter *adapter) status = be_cmd_vlan_config(adapter, adapter->if_handle, vids, num, 1, 0); - /* Set to VLAN promisc mode as setting VLAN filter failed */ if (status) { - dev_info(&adapter->pdev->dev, "Exhausted VLAN HW filters.\n"); - dev_info(&adapter->pdev->dev, "Disabling HW VLAN filtering.\n"); - goto set_vlan_promisc; + /* Set to VLAN promisc mode as setting VLAN filter failed */ + if (status == MCC_ADDL_STS_INSUFFICIENT_RESOURCES) + goto set_vlan_promisc; + dev_err(&adapter->pdev->dev, + "Setting HW VLAN filtering failed.\n"); + } else { + if (adapter->flags & BE_FLAGS_VLAN_PROMISC) { + /* hw VLAN filtering re-enabled. */ + status = be_cmd_rx_filter(adapter, + BE_FLAGS_VLAN_PROMISC, OFF); + if (!status) { + dev_info(&adapter->pdev->dev, + "Disabling VLAN Promiscuous mode.\n"); + adapter->flags &= ~BE_FLAGS_VLAN_PROMISC; + dev_info(&adapter->pdev->dev, + "Re-Enabling HW VLAN filtering\n"); + } + } } return status; set_vlan_promisc: - status = be_cmd_vlan_config(adapter, adapter->if_handle, - NULL, 0, 1, 1); + dev_warn(&adapter->pdev->dev, "Exhausted VLAN HW filters.\n"); + + status = be_cmd_rx_filter(adapter, BE_FLAGS_VLAN_PROMISC, ON); + if (!status) { + dev_info(&adapter->pdev->dev, "Enable VLAN Promiscuous mode\n"); + dev_info(&adapter->pdev->dev, "Disabling HW VLAN filtering\n"); + adapter->flags |= BE_FLAGS_VLAN_PROMISC; + } else + dev_err(&adapter->pdev->dev, + "Failed to enable VLAN Promiscuous mode.\n"); return status; } @@ -1033,10 +1058,6 @@ static int be_vlan_add_vid(struct net_device *netdev, __be16 proto, u16 vid) struct be_adapter *adapter = netdev_priv(netdev); int status = 0; - if (!lancer_chip(adapter) && !be_physfn(adapter)) { - status = -EINVAL; - goto ret; - } /* Packets with VID 0 are always received by Lancer by default */ if (lancer_chip(adapter) && vid == 0) @@ -1059,11 +1080,6 @@ static int be_vlan_rem_vid(struct net_device *netdev, __be16 proto, u16 vid) struct be_adapter *adapter = netdev_priv(netdev); int status = 0; - if (!lancer_chip(adapter) && !be_physfn(adapter)) { - status = -EINVAL; - goto ret; - } - /* Packets with VID 0 are always received by Lancer by default */ if (lancer_chip(adapter) && vid == 0) goto ret; @@ -1188,8 +1204,8 @@ static int be_get_vf_config(struct net_device *netdev, int vf, vi->vf = vf; vi->tx_rate = vf_cfg->tx_rate; - vi->vlan = vf_cfg->vlan_tag; - vi->qos = 0; + vi->vlan = vf_cfg->vlan_tag & VLAN_VID_MASK; + vi->qos = vf_cfg->vlan_tag >> VLAN_PRIO_SHIFT; memcpy(&vi->mac, vf_cfg->mac_addr, ETH_ALEN); return 0; @@ -1199,28 +1215,29 @@ static int be_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos) { struct be_adapter *adapter = netdev_priv(netdev); + struct be_vf_cfg *vf_cfg = &adapter->vf_cfg[vf]; int status = 0; if (!sriov_enabled(adapter)) return -EPERM; - if (vf >= adapter->num_vfs || vlan > 4095) + if (vf >= adapter->num_vfs || vlan > 4095 || qos > 7) return -EINVAL; - if (vlan) { - if (adapter->vf_cfg[vf].vlan_tag != vlan) { + if (vlan || qos) { + vlan |= qos << VLAN_PRIO_SHIFT; + if (vf_cfg->vlan_tag != vlan) { /* If this is new value, program it. Else skip. */ - adapter->vf_cfg[vf].vlan_tag = vlan; - - status = be_cmd_set_hsw_config(adapter, vlan, - vf + 1, adapter->vf_cfg[vf].if_handle, 0); + vf_cfg->vlan_tag = vlan; + status = be_cmd_set_hsw_config(adapter, vlan, vf + 1, + vf_cfg->if_handle, 0); } } else { /* Reset Transparent Vlan Tagging. */ - adapter->vf_cfg[vf].vlan_tag = 0; - vlan = adapter->vf_cfg[vf].def_vid; + vf_cfg->vlan_tag = 0; + vlan = vf_cfg->def_vid; status = be_cmd_set_hsw_config(adapter, vlan, vf + 1, - adapter->vf_cfg[vf].if_handle, 0); + vf_cfg->if_handle, 0); } @@ -1261,53 +1278,79 @@ static int be_set_vf_tx_rate(struct net_device *netdev, return status; } -static void be_eqd_update(struct be_adapter *adapter, struct be_eq_obj *eqo) +static void be_aic_update(struct be_aic_obj *aic, u64 rx_pkts, u64 tx_pkts, + ulong now) { - struct be_rx_stats *stats = rx_stats(&adapter->rx_obj[eqo->idx]); - ulong now = jiffies; - ulong delta = now - stats->rx_jiffies; - u64 pkts; - unsigned int start, eqd; + aic->rx_pkts_prev = rx_pkts; + aic->tx_reqs_prev = tx_pkts; + aic->jiffies = now; +} - if (!eqo->enable_aic) { - eqd = eqo->eqd; - goto modify_eqd; - } +static void be_eqd_update(struct be_adapter *adapter) +{ + struct be_set_eqd set_eqd[MAX_EVT_QS]; + int eqd, i, num = 0, start; + struct be_aic_obj *aic; + struct be_eq_obj *eqo; + struct be_rx_obj *rxo; + struct be_tx_obj *txo; + u64 rx_pkts, tx_pkts; + ulong now; + u32 pps, delta; - if (eqo->idx >= adapter->num_rx_qs) - return; + for_all_evt_queues(adapter, eqo, i) { + aic = &adapter->aic_obj[eqo->idx]; + if (!aic->enable) { + if (aic->jiffies) + aic->jiffies = 0; + eqd = aic->et_eqd; + goto modify_eqd; + } - stats = rx_stats(&adapter->rx_obj[eqo->idx]); + rxo = &adapter->rx_obj[eqo->idx]; + do { + start = u64_stats_fetch_begin_bh(&rxo->stats.sync); + rx_pkts = rxo->stats.rx_pkts; + } while (u64_stats_fetch_retry_bh(&rxo->stats.sync, start)); - /* Wrapped around */ - if (time_before(now, stats->rx_jiffies)) { - stats->rx_jiffies = now; - return; - } + txo = &adapter->tx_obj[eqo->idx]; + do { + start = u64_stats_fetch_begin_bh(&txo->stats.sync); + tx_pkts = txo->stats.tx_reqs; + } while (u64_stats_fetch_retry_bh(&txo->stats.sync, start)); - /* Update once a second */ - if (delta < HZ) - return; - do { - start = u64_stats_fetch_begin_bh(&stats->sync); - pkts = stats->rx_pkts; - } while (u64_stats_fetch_retry_bh(&stats->sync, start)); - - stats->rx_pps = (unsigned long)(pkts - stats->rx_pkts_prev) / (delta / HZ); - stats->rx_pkts_prev = pkts; - stats->rx_jiffies = now; - eqd = (stats->rx_pps / 110000) << 3; - eqd = min(eqd, eqo->max_eqd); - eqd = max(eqd, eqo->min_eqd); - if (eqd < 10) - eqd = 0; + /* Skip, if wrapped around or first calculation */ + now = jiffies; + if (!aic->jiffies || time_before(now, aic->jiffies) || + rx_pkts < aic->rx_pkts_prev || + tx_pkts < aic->tx_reqs_prev) { + be_aic_update(aic, rx_pkts, tx_pkts, now); + continue; + } + + delta = jiffies_to_msecs(now - aic->jiffies); + pps = (((u32)(rx_pkts - aic->rx_pkts_prev) * 1000) / delta) + + (((u32)(tx_pkts - aic->tx_reqs_prev) * 1000) / delta); + eqd = (pps / 15000) << 2; + if (eqd < 8) + eqd = 0; + eqd = min_t(u32, eqd, aic->max_eqd); + eqd = max_t(u32, eqd, aic->min_eqd); + + be_aic_update(aic, rx_pkts, tx_pkts, now); modify_eqd: - if (eqd != eqo->cur_eqd) { - be_cmd_modify_eqd(adapter, eqo->q.id, eqd); - eqo->cur_eqd = eqd; + if (eqd != aic->prev_eqd) { + set_eqd[num].delay_multiplier = (eqd * 65)/100; + set_eqd[num].eq_id = eqo->q.id; + aic->prev_eqd = eqd; + num++; + } } + + if (num) + be_cmd_modify_eqd(adapter, set_eqd, num); } static void be_rx_stats_update(struct be_rx_obj *rxo, @@ -1924,6 +1967,7 @@ static int be_evt_queues_create(struct be_adapter *adapter) { struct be_queue_info *eq; struct be_eq_obj *eqo; + struct be_aic_obj *aic; int i, rc; adapter->num_evt_qs = min_t(u16, num_irqs(adapter), @@ -1932,11 +1976,12 @@ static int be_evt_queues_create(struct be_adapter *adapter) for_all_evt_queues(adapter, eqo, i) { netif_napi_add(adapter->netdev, &eqo->napi, be_poll, BE_NAPI_WEIGHT); + aic = &adapter->aic_obj[i]; eqo->adapter = adapter; eqo->tx_budget = BE_TX_BUDGET; eqo->idx = i; - eqo->max_eqd = BE_MAX_EQD; - eqo->enable_aic = true; + aic->max_eqd = BE_MAX_EQD; + aic->enable = true; eq = &eqo->q; rc = be_queue_alloc(adapter, eq, EVNT_Q_LEN, @@ -2923,7 +2968,8 @@ static int be_vf_setup(struct be_adapter *adapter) goto err; vf_cfg->def_vid = def_vlan; - be_cmd_enable_vf(adapter, vf + 1); + if (!old_vfs) + be_cmd_enable_vf(adapter, vf + 1); } if (!old_vfs) { @@ -2948,12 +2994,12 @@ static void BEx_get_resources(struct be_adapter *adapter, struct pci_dev *pdev = adapter->pdev; bool use_sriov = false; - if (BE3_chip(adapter) && be_physfn(adapter)) { + if (BE3_chip(adapter) && sriov_want(adapter)) { int max_vfs; max_vfs = pci_sriov_get_totalvfs(pdev); res->max_vfs = max_vfs > 0 ? min(MAX_VFS, max_vfs) : 0; - use_sriov = res->max_vfs && num_vfs; + use_sriov = res->max_vfs; } if (be_physfn(adapter)) @@ -2963,12 +3009,15 @@ static void BEx_get_resources(struct be_adapter *adapter, if (adapter->function_mode & FLEX10_MODE) res->max_vlans = BE_NUM_VLANS_SUPPORTED/8; + else if (adapter->function_mode & UMC_ENABLED) + res->max_vlans = BE_UMC_NUM_VLANS_SUPPORTED; else res->max_vlans = BE_NUM_VLANS_SUPPORTED; res->max_mcast_mac = BE_MAX_MC; + /* For BE3 1Gb ports, F/W does not properly support multiple TXQs */ if (BE2_chip(adapter) || use_sriov || be_is_mc(adapter) || - !be_physfn(adapter)) + !be_physfn(adapter) || (adapter->port_num > 1)) res->max_tx_qs = 1; else res->max_tx_qs = BE3_MAX_TX_QS; @@ -3010,14 +3059,6 @@ static int be_get_resources(struct be_adapter *adapter) adapter->res = res; } - /* For BE3 only check if FW suggests a different max-txqs value */ - if (BE3_chip(adapter)) { - status = be_cmd_get_profile_config(adapter, &res, 0); - if (!status && res.max_tx_qs) - adapter->res.max_tx_qs = - min(adapter->res.max_tx_qs, res.max_tx_qs); - } - /* For Lancer, SH etc read per-function resource limits from FW. * GET_FUNC_CONFIG returns per function guaranteed limits. * GET_PROFILE_CONFIG returns PCI-E related limits PF-pool limits @@ -3242,7 +3283,7 @@ static int be_setup(struct be_adapter *adapter) be_cmd_set_flow_control(adapter, adapter->tx_fc, adapter->rx_fc); - if (be_physfn(adapter) && num_vfs) { + if (sriov_want(adapter)) { if (be_max_vfs(adapter)) be_vf_setup(adapter); else @@ -4246,7 +4287,6 @@ static void be_worker(struct work_struct *work) struct be_adapter *adapter = container_of(work, struct be_adapter, work.work); struct be_rx_obj *rxo; - struct be_eq_obj *eqo; int i; /* when interrupts are not yet enabled, just reap any pending @@ -4277,8 +4317,7 @@ static void be_worker(struct work_struct *work) } } - for_all_evt_queues(adapter, eqo, i) - be_eqd_update(adapter, eqo); + be_eqd_update(adapter); reschedule: adapter->work_counter++; diff --git a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c index 6b60582ce8cf..56f2f608a9f4 100644 --- a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c +++ b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c @@ -1083,7 +1083,7 @@ static int fs_enet_probe(struct platform_device *ofdev) mac_addr = of_get_mac_address(ofdev->dev.of_node); if (mac_addr) - memcpy(ndev->dev_addr, mac_addr, 6); + memcpy(ndev->dev_addr, mac_addr, ETH_ALEN); ret = fep->ops->allocate_bd(ndev); if (ret) diff --git a/drivers/net/ethernet/freescale/gianfar.h b/drivers/net/ethernet/freescale/gianfar.h index 04112b98ff5d..114c58f9d8d2 100644 --- a/drivers/net/ethernet/freescale/gianfar.h +++ b/drivers/net/ethernet/freescale/gianfar.h @@ -1177,21 +1177,21 @@ static inline void gfar_read_filer(struct gfar_private *priv, *fpr = gfar_read(®s->rqfpr); } -extern void lock_rx_qs(struct gfar_private *priv); -extern void lock_tx_qs(struct gfar_private *priv); -extern void unlock_rx_qs(struct gfar_private *priv); -extern void unlock_tx_qs(struct gfar_private *priv); -extern irqreturn_t gfar_receive(int irq, void *dev_id); -extern int startup_gfar(struct net_device *dev); -extern void stop_gfar(struct net_device *dev); -extern void gfar_halt(struct net_device *dev); -extern void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev, - int enable, u32 regnum, u32 read); -extern void gfar_configure_coalescing_all(struct gfar_private *priv); +void lock_rx_qs(struct gfar_private *priv); +void lock_tx_qs(struct gfar_private *priv); +void unlock_rx_qs(struct gfar_private *priv); +void unlock_tx_qs(struct gfar_private *priv); +irqreturn_t gfar_receive(int irq, void *dev_id); +int startup_gfar(struct net_device *dev); +void stop_gfar(struct net_device *dev); +void gfar_halt(struct net_device *dev); +void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev, int enable, + u32 regnum, u32 read); +void gfar_configure_coalescing_all(struct gfar_private *priv); void gfar_init_sysfs(struct net_device *dev); int gfar_set_features(struct net_device *dev, netdev_features_t features); -extern void gfar_check_rx_parser_mode(struct gfar_private *priv); -extern void gfar_vlan_mode(struct net_device *dev, netdev_features_t features); +void gfar_check_rx_parser_mode(struct gfar_private *priv); +void gfar_vlan_mode(struct net_device *dev, netdev_features_t features); extern const struct ethtool_ops gfar_ethtool_ops; diff --git a/drivers/net/ethernet/freescale/gianfar_ptp.c b/drivers/net/ethernet/freescale/gianfar_ptp.c index 098f133908ae..e006a09ba899 100644 --- a/drivers/net/ethernet/freescale/gianfar_ptp.c +++ b/drivers/net/ethernet/freescale/gianfar_ptp.c @@ -452,7 +452,9 @@ static int gianfar_ptp_probe(struct platform_device *dev) err = -ENODEV; etsects->caps = ptp_gianfar_caps; - etsects->cksel = DEFAULT_CKSEL; + + if (get_of_u32(node, "fsl,cksel", &etsects->cksel)) + etsects->cksel = DEFAULT_CKSEL; if (get_of_u32(node, "fsl,tclk-period", &etsects->tclk_period) || get_of_u32(node, "fsl,tmr-prsc", &etsects->tmr_prsc) || diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c index 5930c39672db..d58a3dfc95c2 100644 --- a/drivers/net/ethernet/freescale/ucc_geth.c +++ b/drivers/net/ethernet/freescale/ucc_geth.c @@ -3899,7 +3899,7 @@ static int ucc_geth_probe(struct platform_device* ofdev) mac_addr = of_get_mac_address(np); if (mac_addr) - memcpy(dev->dev_addr, mac_addr, 6); + memcpy(dev->dev_addr, mac_addr, ETH_ALEN); ugeth->ug_info = ug_info; ugeth->dev = device; diff --git a/drivers/net/ethernet/hp/hp100.c b/drivers/net/ethernet/hp/hp100.c index 91227d03274e..37860096f744 100644 --- a/drivers/net/ethernet/hp/hp100.c +++ b/drivers/net/ethernet/hp/hp100.c @@ -1098,7 +1098,7 @@ static int hp100_open(struct net_device *dev) if (request_irq(dev->irq, hp100_interrupt, lp->bus == HP100_BUS_PCI || lp->bus == HP100_BUS_EISA ? IRQF_SHARED : 0, - "hp100", dev)) { + dev->name, dev)) { printk("hp100: %s: unable to get IRQ %d\n", dev->name, dev->irq); return -EAGAIN; } diff --git a/drivers/net/ethernet/i825xx/82596.c b/drivers/net/ethernet/i825xx/82596.c index e38816145395..a15877affc9b 100644 --- a/drivers/net/ethernet/i825xx/82596.c +++ b/drivers/net/ethernet/i825xx/82596.c @@ -711,7 +711,7 @@ static int init_i596_mem(struct net_device *dev) i596_add_cmd(dev, &lp->cf_cmd.cmd); DEB(DEB_INIT,printk(KERN_DEBUG "%s: queuing CmdSASetup\n", dev->name)); - memcpy(lp->sa_cmd.eth_addr, dev->dev_addr, 6); + memcpy(lp->sa_cmd.eth_addr, dev->dev_addr, ETH_ALEN); lp->sa_cmd.cmd.command = CmdSASetup; i596_add_cmd(dev, &lp->sa_cmd.cmd); @@ -1155,7 +1155,7 @@ struct net_device * __init i82596_probe(int unit) err = -ENODEV; goto out; } - memcpy(eth_addr, (void *) 0xfffc1f2c, 6); /* YUCK! Get addr from NOVRAM */ + memcpy(eth_addr, (void *) 0xfffc1f2c, ETH_ALEN); /* YUCK! Get addr from NOVRAM */ dev->base_addr = MVME_I596_BASE; dev->irq = (unsigned) MVME16x_IRQ_I596; goto found; diff --git a/drivers/net/ethernet/i825xx/lib82596.c b/drivers/net/ethernet/i825xx/lib82596.c index d653bac4cfc4..861fa15e1e81 100644 --- a/drivers/net/ethernet/i825xx/lib82596.c +++ b/drivers/net/ethernet/i825xx/lib82596.c @@ -607,7 +607,7 @@ static int init_i596_mem(struct net_device *dev) i596_add_cmd(dev, &dma->cf_cmd.cmd); DEB(DEB_INIT, printk(KERN_DEBUG "%s: queuing CmdSASetup\n", dev->name)); - memcpy(dma->sa_cmd.eth_addr, dev->dev_addr, 6); + memcpy(dma->sa_cmd.eth_addr, dev->dev_addr, ETH_ALEN); dma->sa_cmd.cmd.command = SWAP16(CmdSASetup); DMA_WBACK(dev, &(dma->sa_cmd), sizeof(struct sa_cmd)); i596_add_cmd(dev, &dma->sa_cmd.cmd); @@ -1396,13 +1396,13 @@ static void set_multicast_list(struct net_device *dev) netdev_for_each_mc_addr(ha, dev) { if (!cnt--) break; - memcpy(cp, ha->addr, 6); + memcpy(cp, ha->addr, ETH_ALEN); if (i596_debug > 1) DEB(DEB_MULTI, printk(KERN_DEBUG "%s: Adding address %pM\n", dev->name, cp)); - cp += 6; + cp += ETH_ALEN; } DMA_WBACK_INV(dev, &dma->mc_cmd, sizeof(struct mc_cmd)); i596_add_cmd(dev, &cmd->cmd); diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c index 6b5c7222342c..ef21a2e10180 100644 --- a/drivers/net/ethernet/ibm/emac/core.c +++ b/drivers/net/ethernet/ibm/emac/core.c @@ -2676,7 +2676,7 @@ static int emac_init_config(struct emac_instance *dev) np->full_name); return -ENXIO; } - memcpy(dev->ndev->dev_addr, p, 6); + memcpy(dev->ndev->dev_addr, p, ETH_ALEN); /* IAHT and GAHT filter parameterization */ if (emac_has_feature(dev, EMAC_FTR_EMAC4SYNC)) { diff --git a/drivers/net/ethernet/ibm/emac/debug.h b/drivers/net/ethernet/ibm/emac/debug.h index 59a92d5870b5..9c45efe4c8fe 100644 --- a/drivers/net/ethernet/ibm/emac/debug.h +++ b/drivers/net/ethernet/ibm/emac/debug.h @@ -29,13 +29,13 @@ struct emac_instance; struct mal_instance; -extern void emac_dbg_register(struct emac_instance *dev); -extern void emac_dbg_unregister(struct emac_instance *dev); -extern void mal_dbg_register(struct mal_instance *mal); -extern void mal_dbg_unregister(struct mal_instance *mal); -extern int emac_init_debug(void) __init; -extern void emac_fini_debug(void) __exit; -extern void emac_dbg_dump_all(void); +void emac_dbg_register(struct emac_instance *dev); +void emac_dbg_unregister(struct emac_instance *dev); +void mal_dbg_register(struct mal_instance *mal); +void mal_dbg_unregister(struct mal_instance *mal); +int emac_init_debug(void) __init; +void emac_fini_debug(void) __exit; +void emac_dbg_dump_all(void); # define DBG_LEVEL 1 diff --git a/drivers/net/ethernet/ibm/emac/rgmii.h b/drivers/net/ethernet/ibm/emac/rgmii.h index 668bceeff4a2..d4f1374d1900 100644 --- a/drivers/net/ethernet/ibm/emac/rgmii.h +++ b/drivers/net/ethernet/ibm/emac/rgmii.h @@ -56,15 +56,15 @@ struct rgmii_instance { #ifdef CONFIG_IBM_EMAC_RGMII -extern int rgmii_init(void); -extern void rgmii_exit(void); -extern int rgmii_attach(struct platform_device *ofdev, int input, int mode); -extern void rgmii_detach(struct platform_device *ofdev, int input); -extern void rgmii_get_mdio(struct platform_device *ofdev, int input); -extern void rgmii_put_mdio(struct platform_device *ofdev, int input); -extern void rgmii_set_speed(struct platform_device *ofdev, int input, int speed); -extern int rgmii_get_regs_len(struct platform_device *ofdev); -extern void *rgmii_dump_regs(struct platform_device *ofdev, void *buf); +int rgmii_init(void); +void rgmii_exit(void); +int rgmii_attach(struct platform_device *ofdev, int input, int mode); +void rgmii_detach(struct platform_device *ofdev, int input); +void rgmii_get_mdio(struct platform_device *ofdev, int input); +void rgmii_put_mdio(struct platform_device *ofdev, int input); +void rgmii_set_speed(struct platform_device *ofdev, int input, int speed); +int rgmii_get_regs_len(struct platform_device *ofdev); +void *rgmii_dump_regs(struct platform_device *ofdev, void *buf); #else diff --git a/drivers/net/ethernet/ibm/emac/tah.h b/drivers/net/ethernet/ibm/emac/tah.h index 350b7096a041..4d5f336f07b3 100644 --- a/drivers/net/ethernet/ibm/emac/tah.h +++ b/drivers/net/ethernet/ibm/emac/tah.h @@ -72,13 +72,13 @@ struct tah_instance { #ifdef CONFIG_IBM_EMAC_TAH -extern int tah_init(void); -extern void tah_exit(void); -extern int tah_attach(struct platform_device *ofdev, int channel); -extern void tah_detach(struct platform_device *ofdev, int channel); -extern void tah_reset(struct platform_device *ofdev); -extern int tah_get_regs_len(struct platform_device *ofdev); -extern void *tah_dump_regs(struct platform_device *ofdev, void *buf); +int tah_init(void); +void tah_exit(void); +int tah_attach(struct platform_device *ofdev, int channel); +void tah_detach(struct platform_device *ofdev, int channel); +void tah_reset(struct platform_device *ofdev); +int tah_get_regs_len(struct platform_device *ofdev); +void *tah_dump_regs(struct platform_device *ofdev, void *buf); #else diff --git a/drivers/net/ethernet/ibm/emac/zmii.h b/drivers/net/ethernet/ibm/emac/zmii.h index 455bfb085493..0959c55b1459 100644 --- a/drivers/net/ethernet/ibm/emac/zmii.h +++ b/drivers/net/ethernet/ibm/emac/zmii.h @@ -53,15 +53,15 @@ struct zmii_instance { #ifdef CONFIG_IBM_EMAC_ZMII -extern int zmii_init(void); -extern void zmii_exit(void); -extern int zmii_attach(struct platform_device *ofdev, int input, int *mode); -extern void zmii_detach(struct platform_device *ofdev, int input); -extern void zmii_get_mdio(struct platform_device *ofdev, int input); -extern void zmii_put_mdio(struct platform_device *ofdev, int input); -extern void zmii_set_speed(struct platform_device *ofdev, int input, int speed); -extern int zmii_get_regs_len(struct platform_device *ocpdev); -extern void *zmii_dump_regs(struct platform_device *ofdev, void *buf); +int zmii_init(void); +void zmii_exit(void); +int zmii_attach(struct platform_device *ofdev, int input, int *mode); +void zmii_detach(struct platform_device *ofdev, int input); +void zmii_get_mdio(struct platform_device *ofdev, int input); +void zmii_put_mdio(struct platform_device *ofdev, int input); +void zmii_set_speed(struct platform_device *ofdev, int input, int speed); +int zmii_get_regs_len(struct platform_device *ocpdev); +void *zmii_dump_regs(struct platform_device *ofdev, void *buf); #else # define zmii_init() 0 diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c index 5d41aee69d16..952d795230a4 100644 --- a/drivers/net/ethernet/ibm/ibmveth.c +++ b/drivers/net/ethernet/ibm/ibmveth.c @@ -1185,7 +1185,7 @@ static void ibmveth_set_multicast_list(struct net_device *netdev) netdev_for_each_mc_addr(ha, netdev) { /* add the multicast address to the filter table */ unsigned long mcast_addr = 0; - memcpy(((char *)&mcast_addr)+2, ha->addr, 6); + memcpy(((char *)&mcast_addr)+2, ha->addr, ETH_ALEN); lpar_rc = h_multicast_ctrl(adapter->vdev->unit_address, IbmVethMcastAddFilter, mcast_addr); @@ -1370,7 +1370,7 @@ static int ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id) netif_napi_add(netdev, &adapter->napi, ibmveth_poll, 16); adapter->mac_addr = 0; - memcpy(&adapter->mac_addr, mac_addr_p, 6); + memcpy(&adapter->mac_addr, mac_addr_p, ETH_ALEN); netdev->irq = dev->irq; netdev->netdev_ops = &ibmveth_netdev_ops; diff --git a/drivers/net/ethernet/intel/e1000/e1000.h b/drivers/net/ethernet/intel/e1000/e1000.h index 26d9cd59ec75..58c147271a36 100644 --- a/drivers/net/ethernet/intel/e1000/e1000.h +++ b/drivers/net/ethernet/intel/e1000/e1000.h @@ -325,7 +325,7 @@ enum e1000_state_t { #undef pr_fmt #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -extern struct net_device *e1000_get_hw_dev(struct e1000_hw *hw); +struct net_device *e1000_get_hw_dev(struct e1000_hw *hw); #define e_dbg(format, arg...) \ netdev_dbg(e1000_get_hw_dev(hw), format, ## arg) #define e_err(msglvl, format, arg...) \ @@ -346,20 +346,20 @@ extern struct net_device *e1000_get_hw_dev(struct e1000_hw *hw); extern char e1000_driver_name[]; extern const char e1000_driver_version[]; -extern int e1000_up(struct e1000_adapter *adapter); -extern void e1000_down(struct e1000_adapter *adapter); -extern void e1000_reinit_locked(struct e1000_adapter *adapter); -extern void e1000_reset(struct e1000_adapter *adapter); -extern int e1000_set_spd_dplx(struct e1000_adapter *adapter, u32 spd, u8 dplx); -extern int e1000_setup_all_rx_resources(struct e1000_adapter *adapter); -extern int e1000_setup_all_tx_resources(struct e1000_adapter *adapter); -extern void e1000_free_all_rx_resources(struct e1000_adapter *adapter); -extern void e1000_free_all_tx_resources(struct e1000_adapter *adapter); -extern void e1000_update_stats(struct e1000_adapter *adapter); -extern bool e1000_has_link(struct e1000_adapter *adapter); -extern void e1000_power_up_phy(struct e1000_adapter *); -extern void e1000_set_ethtool_ops(struct net_device *netdev); -extern void e1000_check_options(struct e1000_adapter *adapter); -extern char *e1000_get_hw_dev_name(struct e1000_hw *hw); +int e1000_up(struct e1000_adapter *adapter); +void e1000_down(struct e1000_adapter *adapter); +void e1000_reinit_locked(struct e1000_adapter *adapter); +void e1000_reset(struct e1000_adapter *adapter); +int e1000_set_spd_dplx(struct e1000_adapter *adapter, u32 spd, u8 dplx); +int e1000_setup_all_rx_resources(struct e1000_adapter *adapter); +int e1000_setup_all_tx_resources(struct e1000_adapter *adapter); +void e1000_free_all_rx_resources(struct e1000_adapter *adapter); +void e1000_free_all_tx_resources(struct e1000_adapter *adapter); +void e1000_update_stats(struct e1000_adapter *adapter); +bool e1000_has_link(struct e1000_adapter *adapter); +void e1000_power_up_phy(struct e1000_adapter *); +void e1000_set_ethtool_ops(struct net_device *netdev); +void e1000_check_options(struct e1000_adapter *adapter); +char *e1000_get_hw_dev_name(struct e1000_hw *hw); #endif /* _E1000_H_ */ diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h index ad0edd11015d..0150f7fc893d 100644 --- a/drivers/net/ethernet/intel/e1000e/e1000.h +++ b/drivers/net/ethernet/intel/e1000e/e1000.h @@ -472,26 +472,25 @@ enum latency_range { extern char e1000e_driver_name[]; extern const char e1000e_driver_version[]; -extern void e1000e_check_options(struct e1000_adapter *adapter); -extern void e1000e_set_ethtool_ops(struct net_device *netdev); - -extern int e1000e_up(struct e1000_adapter *adapter); -extern void e1000e_down(struct e1000_adapter *adapter); -extern void e1000e_reinit_locked(struct e1000_adapter *adapter); -extern void e1000e_reset(struct e1000_adapter *adapter); -extern void e1000e_power_up_phy(struct e1000_adapter *adapter); -extern int e1000e_setup_rx_resources(struct e1000_ring *ring); -extern int e1000e_setup_tx_resources(struct e1000_ring *ring); -extern void e1000e_free_rx_resources(struct e1000_ring *ring); -extern void e1000e_free_tx_resources(struct e1000_ring *ring); -extern struct rtnl_link_stats64 *e1000e_get_stats64(struct net_device *netdev, - struct rtnl_link_stats64 - *stats); -extern void e1000e_set_interrupt_capability(struct e1000_adapter *adapter); -extern void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter); -extern void e1000e_get_hw_control(struct e1000_adapter *adapter); -extern void e1000e_release_hw_control(struct e1000_adapter *adapter); -extern void e1000e_write_itr(struct e1000_adapter *adapter, u32 itr); +void e1000e_check_options(struct e1000_adapter *adapter); +void e1000e_set_ethtool_ops(struct net_device *netdev); + +int e1000e_up(struct e1000_adapter *adapter); +void e1000e_down(struct e1000_adapter *adapter); +void e1000e_reinit_locked(struct e1000_adapter *adapter); +void e1000e_reset(struct e1000_adapter *adapter); +void e1000e_power_up_phy(struct e1000_adapter *adapter); +int e1000e_setup_rx_resources(struct e1000_ring *ring); +int e1000e_setup_tx_resources(struct e1000_ring *ring); +void e1000e_free_rx_resources(struct e1000_ring *ring); +void e1000e_free_tx_resources(struct e1000_ring *ring); +struct rtnl_link_stats64 *e1000e_get_stats64(struct net_device *netdev, + struct rtnl_link_stats64 *stats); +void e1000e_set_interrupt_capability(struct e1000_adapter *adapter); +void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter); +void e1000e_get_hw_control(struct e1000_adapter *adapter); +void e1000e_release_hw_control(struct e1000_adapter *adapter); +void e1000e_write_itr(struct e1000_adapter *adapter, u32 itr); extern unsigned int copybreak; @@ -508,8 +507,8 @@ extern const struct e1000_info e1000_pch2_info; extern const struct e1000_info e1000_pch_lpt_info; extern const struct e1000_info e1000_es2_info; -extern void e1000e_ptp_init(struct e1000_adapter *adapter); -extern void e1000e_ptp_remove(struct e1000_adapter *adapter); +void e1000e_ptp_init(struct e1000_adapter *adapter); +void e1000e_ptp_remove(struct e1000_adapter *adapter); static inline s32 e1000_phy_hw_reset(struct e1000_hw *hw) { @@ -536,7 +535,7 @@ static inline s32 e1e_wphy_locked(struct e1000_hw *hw, u32 offset, u16 data) return hw->phy.ops.write_reg_locked(hw, offset, data); } -extern void e1000e_reload_nvm_generic(struct e1000_hw *hw); +void e1000e_reload_nvm_generic(struct e1000_hw *hw); static inline s32 e1000e_read_mac_addr(struct e1000_hw *hw) { diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq.c b/drivers/net/ethernet/intel/i40e/i40e_adminq.c index 0c524fa9f811..cfef7fc32cdd 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_adminq.c +++ b/drivers/net/ethernet/intel/i40e/i40e_adminq.c @@ -701,8 +701,7 @@ i40e_status i40e_asq_send_command(struct i40e_hw *hw, details = I40E_ADMINQ_DETAILS(hw->aq.asq, hw->aq.asq.next_to_use); if (cmd_details) { - memcpy(details, cmd_details, - sizeof(struct i40e_asq_cmd_details)); + *details = *cmd_details; /* If the cmd_details are defined copy the cookie. The * cpu_to_le32 is not needed here because the data is ignored @@ -760,7 +759,7 @@ i40e_status i40e_asq_send_command(struct i40e_hw *hw, desc_on_ring = I40E_ADMINQ_DESC(hw->aq.asq, hw->aq.asq.next_to_use); /* if the desc is available copy the temp desc to the right place */ - memcpy(desc_on_ring, desc, sizeof(struct i40e_aq_desc)); + *desc_on_ring = *desc; /* if buff is not NULL assume indirect command */ if (buff != NULL) { @@ -807,7 +806,7 @@ i40e_status i40e_asq_send_command(struct i40e_hw *hw, /* if ready, copy the desc back to temp */ if (i40e_asq_done(hw)) { - memcpy(desc, desc_on_ring, sizeof(struct i40e_aq_desc)); + *desc = *desc_on_ring; if (buff != NULL) memcpy(buff, dma_buff->va, buff_size); retval = le16_to_cpu(desc->retval); diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c index c21df7bc3b1d..1e4ea134975a 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_common.c +++ b/drivers/net/ethernet/intel/i40e/i40e_common.c @@ -507,7 +507,7 @@ i40e_status i40e_aq_get_link_info(struct i40e_hw *hw, /* save link status information */ if (link) - memcpy(link, hw_link_info, sizeof(struct i40e_link_status)); + *link = *hw_link_info; /* flag cleared so helper functions don't call AQ again */ hw->phy.get_link_info = false; diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 601d482694ea..221aa4795017 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -101,10 +101,10 @@ int i40e_allocate_dma_mem_d(struct i40e_hw *hw, struct i40e_dma_mem *mem, mem->size = ALIGN(size, alignment); mem->va = dma_zalloc_coherent(&pf->pdev->dev, mem->size, &mem->pa, GFP_KERNEL); - if (mem->va) - return 0; + if (!mem->va) + return -ENOMEM; - return -ENOMEM; + return 0; } /** @@ -136,10 +136,10 @@ int i40e_allocate_virt_mem_d(struct i40e_hw *hw, struct i40e_virt_mem *mem, mem->size = size; mem->va = kzalloc(size, GFP_KERNEL); - if (mem->va) - return 0; + if (!mem->va) + return -ENOMEM; - return -ENOMEM; + return 0; } /** @@ -174,8 +174,7 @@ static int i40e_get_lump(struct i40e_pf *pf, struct i40e_lump_tracking *pile, u16 needed, u16 id) { int ret = -ENOMEM; - int i = 0; - int j = 0; + int i, j; if (!pile || needed == 0 || id >= I40E_PILE_VALID_BIT) { dev_info(&pf->pdev->dev, @@ -186,7 +185,7 @@ static int i40e_get_lump(struct i40e_pf *pf, struct i40e_lump_tracking *pile, /* start the linear search with an imperfect hint */ i = pile->search_hint; - while (i < pile->num_entries && ret < 0) { + while (i < pile->num_entries) { /* skip already allocated entries */ if (pile->list[i] & I40E_PILE_VALID_BIT) { i++; @@ -205,6 +204,7 @@ static int i40e_get_lump(struct i40e_pf *pf, struct i40e_lump_tracking *pile, pile->list[i+j] = id | I40E_PILE_VALID_BIT; ret = i; pile->search_hint = i + j; + break; } else { /* not enough, so skip over it and continue looking */ i += j; @@ -1388,7 +1388,7 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi) bool add_happened = false; int filter_list_len = 0; u32 changed_flags = 0; - i40e_status ret = 0; + i40e_status aq_ret = 0; struct i40e_pf *pf; int num_add = 0; int num_del = 0; @@ -1449,28 +1449,28 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi) /* flush a full buffer */ if (num_del == filter_list_len) { - ret = i40e_aq_remove_macvlan(&pf->hw, + aq_ret = i40e_aq_remove_macvlan(&pf->hw, vsi->seid, del_list, num_del, NULL); num_del = 0; memset(del_list, 0, sizeof(*del_list)); - if (ret) + if (aq_ret) dev_info(&pf->pdev->dev, "ignoring delete macvlan error, err %d, aq_err %d while flushing a full buffer\n", - ret, + aq_ret, pf->hw.aq.asq_last_status); } } if (num_del) { - ret = i40e_aq_remove_macvlan(&pf->hw, vsi->seid, + aq_ret = i40e_aq_remove_macvlan(&pf->hw, vsi->seid, del_list, num_del, NULL); num_del = 0; - if (ret) + if (aq_ret) dev_info(&pf->pdev->dev, "ignoring delete macvlan error, err %d, aq_err %d\n", - ret, pf->hw.aq.asq_last_status); + aq_ret, pf->hw.aq.asq_last_status); } kfree(del_list); @@ -1515,32 +1515,30 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi) /* flush a full buffer */ if (num_add == filter_list_len) { - ret = i40e_aq_add_macvlan(&pf->hw, - vsi->seid, - add_list, - num_add, - NULL); + aq_ret = i40e_aq_add_macvlan(&pf->hw, vsi->seid, + add_list, num_add, + NULL); num_add = 0; - if (ret) + if (aq_ret) break; memset(add_list, 0, sizeof(*add_list)); } } if (num_add) { - ret = i40e_aq_add_macvlan(&pf->hw, vsi->seid, - add_list, num_add, NULL); + aq_ret = i40e_aq_add_macvlan(&pf->hw, vsi->seid, + add_list, num_add, NULL); num_add = 0; } kfree(add_list); add_list = NULL; - if (add_happened && (!ret)) { + if (add_happened && (!aq_ret)) { /* do nothing */; - } else if (add_happened && (ret)) { + } else if (add_happened && (aq_ret)) { dev_info(&pf->pdev->dev, "add filter failed, err %d, aq_err %d\n", - ret, pf->hw.aq.asq_last_status); + aq_ret, pf->hw.aq.asq_last_status); if ((pf->hw.aq.asq_last_status == I40E_AQ_RC_ENOSPC) && !test_bit(__I40E_FILTER_OVERFLOW_PROMISC, &vsi->state)) { @@ -1556,28 +1554,27 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi) if (changed_flags & IFF_ALLMULTI) { bool cur_multipromisc; cur_multipromisc = !!(vsi->current_netdev_flags & IFF_ALLMULTI); - ret = i40e_aq_set_vsi_multicast_promiscuous(&vsi->back->hw, - vsi->seid, - cur_multipromisc, - NULL); - if (ret) + aq_ret = i40e_aq_set_vsi_multicast_promiscuous(&vsi->back->hw, + vsi->seid, + cur_multipromisc, + NULL); + if (aq_ret) dev_info(&pf->pdev->dev, "set multi promisc failed, err %d, aq_err %d\n", - ret, pf->hw.aq.asq_last_status); + aq_ret, pf->hw.aq.asq_last_status); } if ((changed_flags & IFF_PROMISC) || promisc_forced_on) { bool cur_promisc; cur_promisc = (!!(vsi->current_netdev_flags & IFF_PROMISC) || test_bit(__I40E_FILTER_OVERFLOW_PROMISC, &vsi->state)); - ret = i40e_aq_set_vsi_unicast_promiscuous(&vsi->back->hw, - vsi->seid, - cur_promisc, - NULL); - if (ret) + aq_ret = i40e_aq_set_vsi_unicast_promiscuous(&vsi->back->hw, + vsi->seid, + cur_promisc, NULL); + if (aq_ret) dev_info(&pf->pdev->dev, "set uni promisc failed, err %d, aq_err %d\n", - ret, pf->hw.aq.asq_last_status); + aq_ret, pf->hw.aq.asq_last_status); } clear_bit(__I40E_CONFIG_BUSY, &vsi->state); @@ -1790,6 +1787,8 @@ int i40e_vsi_add_vlan(struct i40e_vsi *vsi, s16 vid) * i40e_vsi_kill_vlan - Remove vsi membership for given vlan * @vsi: the vsi being configured * @vid: vlan id to be removed (0 = untagged only , -1 = any) + * + * Return: 0 on success or negative otherwise **/ int i40e_vsi_kill_vlan(struct i40e_vsi *vsi, s16 vid) { @@ -1863,37 +1862,39 @@ int i40e_vsi_kill_vlan(struct i40e_vsi *vsi, s16 vid) * i40e_vlan_rx_add_vid - Add a vlan id filter to HW offload * @netdev: network interface to be adjusted * @vid: vlan id to be added + * + * net_device_ops implementation for adding vlan ids **/ static int i40e_vlan_rx_add_vid(struct net_device *netdev, __always_unused __be16 proto, u16 vid) { struct i40e_netdev_priv *np = netdev_priv(netdev); struct i40e_vsi *vsi = np->vsi; - int ret; + int ret = 0; if (vid > 4095) - return 0; + return -EINVAL; + + netdev_info(netdev, "adding %pM vid=%d\n", netdev->dev_addr, vid); - netdev_info(vsi->netdev, "adding %pM vid=%d\n", - netdev->dev_addr, vid); /* If the network stack called us with vid = 0, we should * indicate to i40e_vsi_add_vlan() that we want to receive * any traffic (i.e. with any vlan tag, or untagged) */ ret = i40e_vsi_add_vlan(vsi, vid ? vid : I40E_VLAN_ANY); - if (!ret) { - if (vid < VLAN_N_VID) - set_bit(vid, vsi->active_vlans); - } + if (!ret && (vid < VLAN_N_VID)) + set_bit(vid, vsi->active_vlans); - return 0; + return ret; } /** * i40e_vlan_rx_kill_vid - Remove a vlan id filter from HW offload * @netdev: network interface to be adjusted * @vid: vlan id to be removed + * + * net_device_ops implementation for adding vlan ids **/ static int i40e_vlan_rx_kill_vid(struct net_device *netdev, __always_unused __be16 proto, u16 vid) @@ -1901,15 +1902,16 @@ static int i40e_vlan_rx_kill_vid(struct net_device *netdev, struct i40e_netdev_priv *np = netdev_priv(netdev); struct i40e_vsi *vsi = np->vsi; - netdev_info(vsi->netdev, "removing %pM vid=%d\n", - netdev->dev_addr, vid); + netdev_info(netdev, "removing %pM vid=%d\n", netdev->dev_addr, vid); + /* return code is ignored as there is nothing a user * can do about failure to remove and a log message was - * already printed from another function + * already printed from the other function */ i40e_vsi_kill_vlan(vsi, vid); clear_bit(vid, vsi->active_vlans); + return 0; } @@ -1936,10 +1938,10 @@ static void i40e_restore_vlan(struct i40e_vsi *vsi) * @vsi: the vsi being adjusted * @vid: the vlan id to set as a PVID **/ -i40e_status i40e_vsi_add_pvid(struct i40e_vsi *vsi, u16 vid) +int i40e_vsi_add_pvid(struct i40e_vsi *vsi, u16 vid) { struct i40e_vsi_context ctxt; - i40e_status ret; + i40e_status aq_ret; vsi->info.valid_sections = cpu_to_le16(I40E_AQ_VSI_PROP_VLAN_VALID); vsi->info.pvid = cpu_to_le16(vid); @@ -1948,14 +1950,15 @@ i40e_status i40e_vsi_add_pvid(struct i40e_vsi *vsi, u16 vid) ctxt.seid = vsi->seid; memcpy(&ctxt.info, &vsi->info, sizeof(vsi->info)); - ret = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL); - if (ret) { + aq_ret = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL); + if (aq_ret) { dev_info(&vsi->back->pdev->dev, "%s: update vsi failed, aq_err=%d\n", __func__, vsi->back->hw.aq.asq_last_status); + return -ENOENT; } - return ret; + return 0; } /** @@ -3326,7 +3329,8 @@ static void i40e_pf_unquiesce_all_vsi(struct i40e_pf *pf) **/ static u8 i40e_dcb_get_num_tc(struct i40e_dcbx_config *dcbcfg) { - int num_tc = 0, i; + u8 num_tc = 0; + int i; /* Scan the ETS Config Priority Table to find * traffic class enabled for a given priority @@ -3341,9 +3345,7 @@ static u8 i40e_dcb_get_num_tc(struct i40e_dcbx_config *dcbcfg) /* Traffic class index starts from zero so * increment to return the actual count */ - num_tc++; - - return num_tc; + return num_tc + 1; } /** @@ -3451,28 +3453,27 @@ static int i40e_vsi_get_bw_info(struct i40e_vsi *vsi) struct i40e_aqc_query_vsi_bw_config_resp bw_config = {0}; struct i40e_pf *pf = vsi->back; struct i40e_hw *hw = &pf->hw; + i40e_status aq_ret; u32 tc_bw_max; - int ret; int i; /* Get the VSI level BW configuration */ - ret = i40e_aq_query_vsi_bw_config(hw, vsi->seid, &bw_config, NULL); - if (ret) { + aq_ret = i40e_aq_query_vsi_bw_config(hw, vsi->seid, &bw_config, NULL); + if (aq_ret) { dev_info(&pf->pdev->dev, "couldn't get pf vsi bw config, err %d, aq_err %d\n", - ret, pf->hw.aq.asq_last_status); - return ret; + aq_ret, pf->hw.aq.asq_last_status); + return -EINVAL; } /* Get the VSI level BW configuration per TC */ - ret = i40e_aq_query_vsi_ets_sla_config(hw, vsi->seid, - &bw_ets_config, - NULL); - if (ret) { + aq_ret = i40e_aq_query_vsi_ets_sla_config(hw, vsi->seid, &bw_ets_config, + NULL); + if (aq_ret) { dev_info(&pf->pdev->dev, "couldn't get pf vsi ets bw config, err %d, aq_err %d\n", - ret, pf->hw.aq.asq_last_status); - return ret; + aq_ret, pf->hw.aq.asq_last_status); + return -EINVAL; } if (bw_config.tc_valid_bits != bw_ets_config.tc_valid_bits) { @@ -3494,7 +3495,8 @@ static int i40e_vsi_get_bw_info(struct i40e_vsi *vsi) /* 3 bits out of 4 for each TC */ vsi->bw_ets_max_quanta[i] = (u8)((tc_bw_max >> (i*4)) & 0x7); } - return ret; + + return 0; } /** @@ -3505,30 +3507,30 @@ static int i40e_vsi_get_bw_info(struct i40e_vsi *vsi) * * Returns 0 on success, negative value on failure **/ -static int i40e_vsi_configure_bw_alloc(struct i40e_vsi *vsi, - u8 enabled_tc, +static int i40e_vsi_configure_bw_alloc(struct i40e_vsi *vsi, u8 enabled_tc, u8 *bw_share) { struct i40e_aqc_configure_vsi_tc_bw_data bw_data; - int i, ret = 0; + i40e_status aq_ret; + int i; bw_data.tc_valid_bits = enabled_tc; for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) bw_data.tc_bw_credits[i] = bw_share[i]; - ret = i40e_aq_config_vsi_tc_bw(&vsi->back->hw, vsi->seid, - &bw_data, NULL); - if (ret) { + aq_ret = i40e_aq_config_vsi_tc_bw(&vsi->back->hw, vsi->seid, &bw_data, + NULL); + if (aq_ret) { dev_info(&vsi->back->pdev->dev, "%s: AQ command Config VSI BW allocation per TC failed = %d\n", __func__, vsi->back->hw.aq.asq_last_status); - return ret; + return -EINVAL; } for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) vsi->info.qs_handle[i] = bw_data.qs_handles[i]; - return ret; + return 0; } /** diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.h b/drivers/net/ethernet/intel/igb/e1000_82575.h index 74a1506b4235..8c2437722aad 100644 --- a/drivers/net/ethernet/intel/igb/e1000_82575.h +++ b/drivers/net/ethernet/intel/igb/e1000_82575.h @@ -28,14 +28,14 @@ #ifndef _E1000_82575_H_ #define _E1000_82575_H_ -extern void igb_shutdown_serdes_link_82575(struct e1000_hw *hw); -extern void igb_power_up_serdes_link_82575(struct e1000_hw *hw); -extern void igb_power_down_phy_copper_82575(struct e1000_hw *hw); -extern void igb_rx_fifo_flush_82575(struct e1000_hw *hw); -extern s32 igb_read_i2c_byte(struct e1000_hw *hw, u8 byte_offset, - u8 dev_addr, u8 *data); -extern s32 igb_write_i2c_byte(struct e1000_hw *hw, u8 byte_offset, - u8 dev_addr, u8 data); +void igb_shutdown_serdes_link_82575(struct e1000_hw *hw); +void igb_power_up_serdes_link_82575(struct e1000_hw *hw); +void igb_power_down_phy_copper_82575(struct e1000_hw *hw); +void igb_rx_fifo_flush_82575(struct e1000_hw *hw); +s32 igb_read_i2c_byte(struct e1000_hw *hw, u8 byte_offset, u8 dev_addr, + u8 *data); +s32 igb_write_i2c_byte(struct e1000_hw *hw, u8 byte_offset, u8 dev_addr, + u8 data); #define ID_LED_DEFAULT_82575_SERDES ((ID_LED_DEF1_DEF2 << 12) | \ (ID_LED_DEF1_DEF2 << 8) | \ diff --git a/drivers/net/ethernet/intel/igb/e1000_hw.h b/drivers/net/ethernet/intel/igb/e1000_hw.h index 37a9c06a6c68..2e166b22d52b 100644 --- a/drivers/net/ethernet/intel/igb/e1000_hw.h +++ b/drivers/net/ethernet/intel/igb/e1000_hw.h @@ -562,11 +562,11 @@ struct e1000_hw { u8 revision_id; }; -extern struct net_device *igb_get_hw_dev(struct e1000_hw *hw); +struct net_device *igb_get_hw_dev(struct e1000_hw *hw); #define hw_dbg(format, arg...) \ netdev_dbg(igb_get_hw_dev(hw), format, ##arg) /* These functions must be implemented by drivers */ -s32 igb_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value); -s32 igb_write_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value); +s32 igb_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value); +s32 igb_write_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value); #endif /* _E1000_HW_H_ */ diff --git a/drivers/net/ethernet/intel/igb/e1000_i210.h b/drivers/net/ethernet/intel/igb/e1000_i210.h index dde3c4b7ea99..2d913716573a 100644 --- a/drivers/net/ethernet/intel/igb/e1000_i210.h +++ b/drivers/net/ethernet/intel/igb/e1000_i210.h @@ -28,26 +28,24 @@ #ifndef _E1000_I210_H_ #define _E1000_I210_H_ -extern s32 igb_update_flash_i210(struct e1000_hw *hw); -extern s32 igb_update_nvm_checksum_i210(struct e1000_hw *hw); -extern s32 igb_validate_nvm_checksum_i210(struct e1000_hw *hw); -extern s32 igb_write_nvm_srwr_i210(struct e1000_hw *hw, u16 offset, - u16 words, u16 *data); -extern s32 igb_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset, - u16 words, u16 *data); -extern s32 igb_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask); -extern void igb_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask); -extern s32 igb_acquire_nvm_i210(struct e1000_hw *hw); -extern void igb_release_nvm_i210(struct e1000_hw *hw); -extern s32 igb_valid_led_default_i210(struct e1000_hw *hw, u16 *data); -extern s32 igb_read_invm_version(struct e1000_hw *hw, - struct e1000_fw_version *invm_ver); -extern s32 igb_read_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, - u16 *data); -extern s32 igb_write_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, - u16 data); -extern s32 igb_init_nvm_params_i210(struct e1000_hw *hw); -extern bool igb_get_flash_presence_i210(struct e1000_hw *hw); +s32 igb_update_flash_i210(struct e1000_hw *hw); +s32 igb_update_nvm_checksum_i210(struct e1000_hw *hw); +s32 igb_validate_nvm_checksum_i210(struct e1000_hw *hw); +s32 igb_write_nvm_srwr_i210(struct e1000_hw *hw, u16 offset, u16 words, + u16 *data); +s32 igb_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset, u16 words, + u16 *data); +s32 igb_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask); +void igb_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask); +s32 igb_acquire_nvm_i210(struct e1000_hw *hw); +void igb_release_nvm_i210(struct e1000_hw *hw); +s32 igb_valid_led_default_i210(struct e1000_hw *hw, u16 *data); +s32 igb_read_invm_version(struct e1000_hw *hw, + struct e1000_fw_version *invm_ver); +s32 igb_read_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 *data); +s32 igb_write_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 data); +s32 igb_init_nvm_params_i210(struct e1000_hw *hw); +bool igb_get_flash_presence_i210(struct e1000_hw *hw); #define E1000_STM_OPCODE 0xDB00 #define E1000_EEPROM_FLASH_SIZE_WORD 0x11 diff --git a/drivers/net/ethernet/intel/igb/e1000_mac.h b/drivers/net/ethernet/intel/igb/e1000_mac.h index 5e13e83cc608..e4cbe8ef67b3 100644 --- a/drivers/net/ethernet/intel/igb/e1000_mac.h +++ b/drivers/net/ethernet/intel/igb/e1000_mac.h @@ -86,6 +86,6 @@ enum e1000_mng_mode { #define E1000_MNG_DHCP_COOKIE_STATUS_VLAN 0x2 -extern void e1000_init_function_pointers_82575(struct e1000_hw *hw); +void e1000_init_function_pointers_82575(struct e1000_hw *hw); #endif diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h index 6807b098edae..5e9ed89403aa 100644 --- a/drivers/net/ethernet/intel/igb/igb.h +++ b/drivers/net/ethernet/intel/igb/igb.h @@ -483,40 +483,38 @@ enum igb_boards { extern char igb_driver_name[]; extern char igb_driver_version[]; -extern int igb_up(struct igb_adapter *); -extern void igb_down(struct igb_adapter *); -extern void igb_reinit_locked(struct igb_adapter *); -extern void igb_reset(struct igb_adapter *); -extern void igb_write_rss_indir_tbl(struct igb_adapter *); -extern int igb_set_spd_dplx(struct igb_adapter *, u32, u8); -extern int igb_setup_tx_resources(struct igb_ring *); -extern int igb_setup_rx_resources(struct igb_ring *); -extern void igb_free_tx_resources(struct igb_ring *); -extern void igb_free_rx_resources(struct igb_ring *); -extern void igb_configure_tx_ring(struct igb_adapter *, struct igb_ring *); -extern void igb_configure_rx_ring(struct igb_adapter *, struct igb_ring *); -extern void igb_setup_tctl(struct igb_adapter *); -extern void igb_setup_rctl(struct igb_adapter *); -extern netdev_tx_t igb_xmit_frame_ring(struct sk_buff *, struct igb_ring *); -extern void igb_unmap_and_free_tx_resource(struct igb_ring *, - struct igb_tx_buffer *); -extern void igb_alloc_rx_buffers(struct igb_ring *, u16); -extern void igb_update_stats(struct igb_adapter *, struct rtnl_link_stats64 *); -extern bool igb_has_link(struct igb_adapter *adapter); -extern void igb_set_ethtool_ops(struct net_device *); -extern void igb_power_up_link(struct igb_adapter *); -extern void igb_set_fw_version(struct igb_adapter *); -extern void igb_ptp_init(struct igb_adapter *adapter); -extern void igb_ptp_stop(struct igb_adapter *adapter); -extern void igb_ptp_reset(struct igb_adapter *adapter); -extern void igb_ptp_tx_work(struct work_struct *work); -extern void igb_ptp_rx_hang(struct igb_adapter *adapter); -extern void igb_ptp_tx_hwtstamp(struct igb_adapter *adapter); -extern void igb_ptp_rx_rgtstamp(struct igb_q_vector *q_vector, - struct sk_buff *skb); -extern void igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, - unsigned char *va, - struct sk_buff *skb); +int igb_up(struct igb_adapter *); +void igb_down(struct igb_adapter *); +void igb_reinit_locked(struct igb_adapter *); +void igb_reset(struct igb_adapter *); +int igb_reinit_queues(struct igb_adapter *); +void igb_write_rss_indir_tbl(struct igb_adapter *); +int igb_set_spd_dplx(struct igb_adapter *, u32, u8); +int igb_setup_tx_resources(struct igb_ring *); +int igb_setup_rx_resources(struct igb_ring *); +void igb_free_tx_resources(struct igb_ring *); +void igb_free_rx_resources(struct igb_ring *); +void igb_configure_tx_ring(struct igb_adapter *, struct igb_ring *); +void igb_configure_rx_ring(struct igb_adapter *, struct igb_ring *); +void igb_setup_tctl(struct igb_adapter *); +void igb_setup_rctl(struct igb_adapter *); +netdev_tx_t igb_xmit_frame_ring(struct sk_buff *, struct igb_ring *); +void igb_unmap_and_free_tx_resource(struct igb_ring *, struct igb_tx_buffer *); +void igb_alloc_rx_buffers(struct igb_ring *, u16); +void igb_update_stats(struct igb_adapter *, struct rtnl_link_stats64 *); +bool igb_has_link(struct igb_adapter *adapter); +void igb_set_ethtool_ops(struct net_device *); +void igb_power_up_link(struct igb_adapter *); +void igb_set_fw_version(struct igb_adapter *); +void igb_ptp_init(struct igb_adapter *adapter); +void igb_ptp_stop(struct igb_adapter *adapter); +void igb_ptp_reset(struct igb_adapter *adapter); +void igb_ptp_tx_work(struct work_struct *work); +void igb_ptp_rx_hang(struct igb_adapter *adapter); +void igb_ptp_tx_hwtstamp(struct igb_adapter *adapter); +void igb_ptp_rx_rgtstamp(struct igb_q_vector *q_vector, struct sk_buff *skb); +void igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, unsigned char *va, + struct sk_buff *skb); static inline void igb_ptp_rx_hwtstamp(struct igb_ring *rx_ring, union e1000_adv_rx_desc *rx_desc, struct sk_buff *skb) @@ -531,11 +529,11 @@ static inline void igb_ptp_rx_hwtstamp(struct igb_ring *rx_ring, rx_ring->last_rx_timestamp = jiffies; } -extern int igb_ptp_hwtstamp_ioctl(struct net_device *netdev, - struct ifreq *ifr, int cmd); +int igb_ptp_hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr, + int cmd); #ifdef CONFIG_IGB_HWMON -extern void igb_sysfs_exit(struct igb_adapter *adapter); -extern int igb_sysfs_init(struct igb_adapter *adapter); +void igb_sysfs_exit(struct igb_adapter *adapter); +int igb_sysfs_init(struct igb_adapter *adapter); #endif static inline s32 igb_reset_phy(struct e1000_hw *hw) { diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c index 48cbc833b051..ebdac0273501 100644 --- a/drivers/net/ethernet/intel/igb/igb_ethtool.c +++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c @@ -1607,6 +1607,9 @@ static int igb_integrated_phy_loopback(struct igb_adapter *adapter) igb_write_phy_reg(hw, I347AT4_PAGE_SELECT, 0); igb_write_phy_reg(hw, PHY_CONTROL, 0x4140); } + } else if (hw->phy.type == e1000_phy_82580) { + /* enable MII loopback */ + igb_write_phy_reg(hw, I82580_PHY_LBK_CTRL, 0x8041); } /* add small delay to avoid loopback test failure */ @@ -1656,7 +1659,8 @@ static int igb_setup_loopback_test(struct igb_adapter *adapter) if ((hw->device_id == E1000_DEV_ID_DH89XXCC_SGMII) || (hw->device_id == E1000_DEV_ID_DH89XXCC_SERDES) || (hw->device_id == E1000_DEV_ID_DH89XXCC_BACKPLANE) || - (hw->device_id == E1000_DEV_ID_DH89XXCC_SFP)) { + (hw->device_id == E1000_DEV_ID_DH89XXCC_SFP) || + (hw->device_id == E1000_DEV_ID_I354_SGMII)) { /* Enable DH89xxCC MPHY for near end loopback */ reg = rd32(E1000_MPHY_ADDR_CTL); @@ -1722,7 +1726,8 @@ static void igb_loopback_cleanup(struct igb_adapter *adapter) if ((hw->device_id == E1000_DEV_ID_DH89XXCC_SGMII) || (hw->device_id == E1000_DEV_ID_DH89XXCC_SERDES) || (hw->device_id == E1000_DEV_ID_DH89XXCC_BACKPLANE) || - (hw->device_id == E1000_DEV_ID_DH89XXCC_SFP)) { + (hw->device_id == E1000_DEV_ID_DH89XXCC_SFP) || + (hw->device_id == E1000_DEV_ID_I354_SGMII)) { u32 reg; /* Disable near end loopback on DH89xxCC */ @@ -2872,6 +2877,88 @@ static int igb_set_rxfh_indir(struct net_device *netdev, const u32 *indir) return 0; } +static unsigned int igb_max_channels(struct igb_adapter *adapter) +{ + struct e1000_hw *hw = &adapter->hw; + unsigned int max_combined = 0; + + switch (hw->mac.type) { + case e1000_i211: + max_combined = IGB_MAX_RX_QUEUES_I211; + break; + case e1000_82575: + case e1000_i210: + max_combined = IGB_MAX_RX_QUEUES_82575; + break; + case e1000_i350: + if (!!adapter->vfs_allocated_count) { + max_combined = 1; + break; + } + /* fall through */ + case e1000_82576: + if (!!adapter->vfs_allocated_count) { + max_combined = 2; + break; + } + /* fall through */ + case e1000_82580: + case e1000_i354: + default: + max_combined = IGB_MAX_RX_QUEUES; + break; + } + + return max_combined; +} + +static void igb_get_channels(struct net_device *netdev, + struct ethtool_channels *ch) +{ + struct igb_adapter *adapter = netdev_priv(netdev); + + /* Report maximum channels */ + ch->max_combined = igb_max_channels(adapter); + + /* Report info for other vector */ + if (adapter->msix_entries) { + ch->max_other = NON_Q_VECTORS; + ch->other_count = NON_Q_VECTORS; + } + + ch->combined_count = adapter->rss_queues; +} + +static int igb_set_channels(struct net_device *netdev, + struct ethtool_channels *ch) +{ + struct igb_adapter *adapter = netdev_priv(netdev); + unsigned int count = ch->combined_count; + + /* Verify they are not requesting separate vectors */ + if (!count || ch->rx_count || ch->tx_count) + return -EINVAL; + + /* Verify other_count is valid and has not been changed */ + if (ch->other_count != NON_Q_VECTORS) + return -EINVAL; + + /* Verify the number of channels doesn't exceed hw limits */ + if (count > igb_max_channels(adapter)) + return -EINVAL; + + if (count != adapter->rss_queues) { + adapter->rss_queues = count; + + /* Hardware has to reinitialize queues and interrupts to + * match the new configuration. + */ + return igb_reinit_queues(adapter); + } + + return 0; +} + static const struct ethtool_ops igb_ethtool_ops = { .get_settings = igb_get_settings, .set_settings = igb_set_settings, @@ -2908,6 +2995,8 @@ static const struct ethtool_ops igb_ethtool_ops = { .get_rxfh_indir_size = igb_get_rxfh_indir_size, .get_rxfh_indir = igb_get_rxfh_indir, .set_rxfh_indir = igb_set_rxfh_indir, + .get_channels = igb_get_channels, + .set_channels = igb_set_channels, .begin = igb_ethtool_begin, .complete = igb_ethtool_complete, }; diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 8cf44f2a8ccd..a505d3bad09a 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -5708,7 +5708,7 @@ static void igb_vf_reset_msg(struct igb_adapter *adapter, u32 vf) /* reply to reset with ack and vf mac address */ msgbuf[0] = E1000_VF_RESET | E1000_VT_MSGTYPE_ACK; - memcpy(addr, vf_mac, 6); + memcpy(addr, vf_mac, ETH_ALEN); igb_write_mbx(hw, msgbuf, 3, vf); } @@ -7838,4 +7838,26 @@ s32 igb_write_i2c_byte(struct e1000_hw *hw, u8 byte_offset, return E1000_SUCCESS; } + +int igb_reinit_queues(struct igb_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + struct pci_dev *pdev = adapter->pdev; + int err = 0; + + if (netif_running(netdev)) + igb_close(netdev); + + igb_clear_interrupt_scheme(adapter); + + if (igb_init_interrupt_scheme(adapter, true)) { + dev_err(&pdev->dev, "Unable to allocate memory for queues\n"); + return -ENOMEM; + } + + if (netif_running(netdev)) + err = igb_open(netdev); + + return err; +} /* igb_main.c */ diff --git a/drivers/net/ethernet/intel/igbvf/igbvf.h b/drivers/net/ethernet/intel/igbvf/igbvf.h index a1463e3d14c0..7d6a25c8f889 100644 --- a/drivers/net/ethernet/intel/igbvf/igbvf.h +++ b/drivers/net/ethernet/intel/igbvf/igbvf.h @@ -312,17 +312,17 @@ enum igbvf_state_t { extern char igbvf_driver_name[]; extern const char igbvf_driver_version[]; -extern void igbvf_check_options(struct igbvf_adapter *); -extern void igbvf_set_ethtool_ops(struct net_device *); - -extern int igbvf_up(struct igbvf_adapter *); -extern void igbvf_down(struct igbvf_adapter *); -extern void igbvf_reinit_locked(struct igbvf_adapter *); -extern int igbvf_setup_rx_resources(struct igbvf_adapter *, struct igbvf_ring *); -extern int igbvf_setup_tx_resources(struct igbvf_adapter *, struct igbvf_ring *); -extern void igbvf_free_rx_resources(struct igbvf_ring *); -extern void igbvf_free_tx_resources(struct igbvf_ring *); -extern void igbvf_update_stats(struct igbvf_adapter *); +void igbvf_check_options(struct igbvf_adapter *); +void igbvf_set_ethtool_ops(struct net_device *); + +int igbvf_up(struct igbvf_adapter *); +void igbvf_down(struct igbvf_adapter *); +void igbvf_reinit_locked(struct igbvf_adapter *); +int igbvf_setup_rx_resources(struct igbvf_adapter *, struct igbvf_ring *); +int igbvf_setup_tx_resources(struct igbvf_adapter *, struct igbvf_ring *); +void igbvf_free_rx_resources(struct igbvf_ring *); +void igbvf_free_tx_resources(struct igbvf_ring *); +void igbvf_update_stats(struct igbvf_adapter *); extern unsigned int copybreak; diff --git a/drivers/net/ethernet/intel/igbvf/vf.c b/drivers/net/ethernet/intel/igbvf/vf.c index eea0e10ce12f..955ad8c2c534 100644 --- a/drivers/net/ethernet/intel/igbvf/vf.c +++ b/drivers/net/ethernet/intel/igbvf/vf.c @@ -154,7 +154,7 @@ static s32 e1000_reset_hw_vf(struct e1000_hw *hw) ret_val = mbx->ops.read_posted(hw, msgbuf, 3); if (!ret_val) { if (msgbuf[0] == (E1000_VF_RESET | E1000_VT_MSGTYPE_ACK)) - memcpy(hw->mac.perm_addr, addr, 6); + memcpy(hw->mac.perm_addr, addr, ETH_ALEN); else ret_val = -E1000_ERR_MAC_INIT; } @@ -314,7 +314,7 @@ static void e1000_rar_set_vf(struct e1000_hw *hw, u8 * addr, u32 index) memset(msgbuf, 0, 12); msgbuf[0] = E1000_VF_SET_MAC_ADDR; - memcpy(msg_addr, addr, 6); + memcpy(msg_addr, addr, ETH_ALEN); ret_val = mbx->ops.write_posted(hw, msgbuf, 3); if (!ret_val) diff --git a/drivers/net/ethernet/intel/ixgb/ixgb.h b/drivers/net/ethernet/intel/ixgb/ixgb.h index 4d2ae97ff1b3..2224cc2edf13 100644 --- a/drivers/net/ethernet/intel/ixgb/ixgb.h +++ b/drivers/net/ethernet/intel/ixgb/ixgb.h @@ -187,21 +187,21 @@ enum ixgb_state_t { }; /* Exported from other modules */ -extern void ixgb_check_options(struct ixgb_adapter *adapter); -extern void ixgb_set_ethtool_ops(struct net_device *netdev); +void ixgb_check_options(struct ixgb_adapter *adapter); +void ixgb_set_ethtool_ops(struct net_device *netdev); extern char ixgb_driver_name[]; extern const char ixgb_driver_version[]; -extern void ixgb_set_speed_duplex(struct net_device *netdev); +void ixgb_set_speed_duplex(struct net_device *netdev); -extern int ixgb_up(struct ixgb_adapter *adapter); -extern void ixgb_down(struct ixgb_adapter *adapter, bool kill_watchdog); -extern void ixgb_reset(struct ixgb_adapter *adapter); -extern int ixgb_setup_rx_resources(struct ixgb_adapter *adapter); -extern int ixgb_setup_tx_resources(struct ixgb_adapter *adapter); -extern void ixgb_free_rx_resources(struct ixgb_adapter *adapter); -extern void ixgb_free_tx_resources(struct ixgb_adapter *adapter); -extern void ixgb_update_stats(struct ixgb_adapter *adapter); +int ixgb_up(struct ixgb_adapter *adapter); +void ixgb_down(struct ixgb_adapter *adapter, bool kill_watchdog); +void ixgb_reset(struct ixgb_adapter *adapter); +int ixgb_setup_rx_resources(struct ixgb_adapter *adapter); +int ixgb_setup_tx_resources(struct ixgb_adapter *adapter); +void ixgb_free_rx_resources(struct ixgb_adapter *adapter); +void ixgb_free_tx_resources(struct ixgb_adapter *adapter); +void ixgb_update_stats(struct ixgb_adapter *adapter); #endif /* _IXGB_H_ */ diff --git a/drivers/net/ethernet/intel/ixgb/ixgb_hw.h b/drivers/net/ethernet/intel/ixgb/ixgb_hw.h index 2a99a35c33aa..0bd5d72e1af5 100644 --- a/drivers/net/ethernet/intel/ixgb/ixgb_hw.h +++ b/drivers/net/ethernet/intel/ixgb/ixgb_hw.h @@ -759,27 +759,20 @@ struct ixgb_hw_stats { }; /* Function Prototypes */ -extern bool ixgb_adapter_stop(struct ixgb_hw *hw); -extern bool ixgb_init_hw(struct ixgb_hw *hw); -extern bool ixgb_adapter_start(struct ixgb_hw *hw); -extern void ixgb_check_for_link(struct ixgb_hw *hw); -extern bool ixgb_check_for_bad_link(struct ixgb_hw *hw); - -extern void ixgb_rar_set(struct ixgb_hw *hw, - u8 *addr, - u32 index); +bool ixgb_adapter_stop(struct ixgb_hw *hw); +bool ixgb_init_hw(struct ixgb_hw *hw); +bool ixgb_adapter_start(struct ixgb_hw *hw); +void ixgb_check_for_link(struct ixgb_hw *hw); +bool ixgb_check_for_bad_link(struct ixgb_hw *hw); +void ixgb_rar_set(struct ixgb_hw *hw, u8 *addr, u32 index); /* Filters (multicast, vlan, receive) */ -extern void ixgb_mc_addr_list_update(struct ixgb_hw *hw, - u8 *mc_addr_list, - u32 mc_addr_count, - u32 pad); +void ixgb_mc_addr_list_update(struct ixgb_hw *hw, u8 *mc_addr_list, + u32 mc_addr_count, u32 pad); /* Vfta functions */ -extern void ixgb_write_vfta(struct ixgb_hw *hw, - u32 offset, - u32 value); +void ixgb_write_vfta(struct ixgb_hw *hw, u32 offset, u32 value); /* Access functions to eeprom data */ void ixgb_get_ee_mac_addr(struct ixgb_hw *hw, u8 *mac_addr); diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h index 0ac6b11c6e4e..dc1588ee264a 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h @@ -55,7 +55,7 @@ #include <net/busy_poll.h> #ifdef CONFIG_NET_RX_BUSY_POLL -#define LL_EXTENDED_STATS +#define BP_EXTENDED_STATS #endif /* common prefix used by pr_<> macros */ #undef pr_fmt @@ -187,11 +187,11 @@ struct ixgbe_rx_buffer { struct ixgbe_queue_stats { u64 packets; u64 bytes; -#ifdef LL_EXTENDED_STATS +#ifdef BP_EXTENDED_STATS u64 yields; u64 misses; u64 cleaned; -#endif /* LL_EXTENDED_STATS */ +#endif /* BP_EXTENDED_STATS */ }; struct ixgbe_tx_queue_stats { @@ -399,7 +399,7 @@ static inline bool ixgbe_qv_lock_napi(struct ixgbe_q_vector *q_vector) WARN_ON(q_vector->state & IXGBE_QV_STATE_NAPI); q_vector->state |= IXGBE_QV_STATE_NAPI_YIELD; rc = false; -#ifdef LL_EXTENDED_STATS +#ifdef BP_EXTENDED_STATS q_vector->tx.ring->stats.yields++; #endif } else @@ -432,7 +432,7 @@ static inline bool ixgbe_qv_lock_poll(struct ixgbe_q_vector *q_vector) if ((q_vector->state & IXGBE_QV_LOCKED)) { q_vector->state |= IXGBE_QV_STATE_POLL_YIELD; rc = false; -#ifdef LL_EXTENDED_STATS +#ifdef BP_EXTENDED_STATS q_vector->rx.ring->stats.yields++; #endif } else @@ -457,7 +457,7 @@ static inline bool ixgbe_qv_unlock_poll(struct ixgbe_q_vector *q_vector) } /* true if a socket is polling, even if it did not get the lock */ -static inline bool ixgbe_qv_ll_polling(struct ixgbe_q_vector *q_vector) +static inline bool ixgbe_qv_busy_polling(struct ixgbe_q_vector *q_vector) { WARN_ON(!(q_vector->state & IXGBE_QV_LOCKED)); return q_vector->state & IXGBE_QV_USER_PEND; @@ -487,7 +487,7 @@ static inline bool ixgbe_qv_unlock_poll(struct ixgbe_q_vector *q_vector) return false; } -static inline bool ixgbe_qv_ll_polling(struct ixgbe_q_vector *q_vector) +static inline bool ixgbe_qv_busy_polling(struct ixgbe_q_vector *q_vector) { return false; } @@ -786,93 +786,89 @@ extern const char ixgbe_driver_version[]; extern char ixgbe_default_device_descr[]; #endif /* IXGBE_FCOE */ -extern void ixgbe_up(struct ixgbe_adapter *adapter); -extern void ixgbe_down(struct ixgbe_adapter *adapter); -extern void ixgbe_reinit_locked(struct ixgbe_adapter *adapter); -extern void ixgbe_reset(struct ixgbe_adapter *adapter); -extern void ixgbe_set_ethtool_ops(struct net_device *netdev); -extern int ixgbe_setup_rx_resources(struct ixgbe_ring *); -extern int ixgbe_setup_tx_resources(struct ixgbe_ring *); -extern void ixgbe_free_rx_resources(struct ixgbe_ring *); -extern void ixgbe_free_tx_resources(struct ixgbe_ring *); -extern void ixgbe_configure_rx_ring(struct ixgbe_adapter *,struct ixgbe_ring *); -extern void ixgbe_configure_tx_ring(struct ixgbe_adapter *,struct ixgbe_ring *); -extern void ixgbe_disable_rx_queue(struct ixgbe_adapter *adapter, - struct ixgbe_ring *); -extern void ixgbe_update_stats(struct ixgbe_adapter *adapter); -extern int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter); -extern int ixgbe_wol_supported(struct ixgbe_adapter *adapter, u16 device_id, +void ixgbe_up(struct ixgbe_adapter *adapter); +void ixgbe_down(struct ixgbe_adapter *adapter); +void ixgbe_reinit_locked(struct ixgbe_adapter *adapter); +void ixgbe_reset(struct ixgbe_adapter *adapter); +void ixgbe_set_ethtool_ops(struct net_device *netdev); +int ixgbe_setup_rx_resources(struct ixgbe_ring *); +int ixgbe_setup_tx_resources(struct ixgbe_ring *); +void ixgbe_free_rx_resources(struct ixgbe_ring *); +void ixgbe_free_tx_resources(struct ixgbe_ring *); +void ixgbe_configure_rx_ring(struct ixgbe_adapter *, struct ixgbe_ring *); +void ixgbe_configure_tx_ring(struct ixgbe_adapter *, struct ixgbe_ring *); +void ixgbe_disable_rx_queue(struct ixgbe_adapter *adapter, struct ixgbe_ring *); +void ixgbe_update_stats(struct ixgbe_adapter *adapter); +int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter); +int ixgbe_wol_supported(struct ixgbe_adapter *adapter, u16 device_id, u16 subdevice_id); -extern void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter); -extern netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *, - struct ixgbe_adapter *, - struct ixgbe_ring *); -extern void ixgbe_unmap_and_free_tx_resource(struct ixgbe_ring *, - struct ixgbe_tx_buffer *); -extern void ixgbe_alloc_rx_buffers(struct ixgbe_ring *, u16); -extern void ixgbe_write_eitr(struct ixgbe_q_vector *); -extern int ixgbe_poll(struct napi_struct *napi, int budget); -extern int ethtool_ioctl(struct ifreq *ifr); -extern s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw); -extern s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 fdirctrl); -extern s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 fdirctrl); -extern s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw, - union ixgbe_atr_hash_dword input, - union ixgbe_atr_hash_dword common, - u8 queue); -extern s32 ixgbe_fdir_set_input_mask_82599(struct ixgbe_hw *hw, - union ixgbe_atr_input *input_mask); -extern s32 ixgbe_fdir_write_perfect_filter_82599(struct ixgbe_hw *hw, - union ixgbe_atr_input *input, - u16 soft_id, u8 queue); -extern s32 ixgbe_fdir_erase_perfect_filter_82599(struct ixgbe_hw *hw, - union ixgbe_atr_input *input, - u16 soft_id); -extern void ixgbe_atr_compute_perfect_hash_82599(union ixgbe_atr_input *input, - union ixgbe_atr_input *mask); -extern bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw); -extern void ixgbe_set_rx_mode(struct net_device *netdev); +void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter); +netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *, struct ixgbe_adapter *, + struct ixgbe_ring *); +void ixgbe_unmap_and_free_tx_resource(struct ixgbe_ring *, + struct ixgbe_tx_buffer *); +void ixgbe_alloc_rx_buffers(struct ixgbe_ring *, u16); +void ixgbe_write_eitr(struct ixgbe_q_vector *); +int ixgbe_poll(struct napi_struct *napi, int budget); +int ethtool_ioctl(struct ifreq *ifr); +s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw); +s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 fdirctrl); +s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 fdirctrl); +s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw, + union ixgbe_atr_hash_dword input, + union ixgbe_atr_hash_dword common, + u8 queue); +s32 ixgbe_fdir_set_input_mask_82599(struct ixgbe_hw *hw, + union ixgbe_atr_input *input_mask); +s32 ixgbe_fdir_write_perfect_filter_82599(struct ixgbe_hw *hw, + union ixgbe_atr_input *input, + u16 soft_id, u8 queue); +s32 ixgbe_fdir_erase_perfect_filter_82599(struct ixgbe_hw *hw, + union ixgbe_atr_input *input, + u16 soft_id); +void ixgbe_atr_compute_perfect_hash_82599(union ixgbe_atr_input *input, + union ixgbe_atr_input *mask); +bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw); +void ixgbe_set_rx_mode(struct net_device *netdev); #ifdef CONFIG_IXGBE_DCB -extern void ixgbe_set_rx_drop_en(struct ixgbe_adapter *adapter); +void ixgbe_set_rx_drop_en(struct ixgbe_adapter *adapter); #endif -extern int ixgbe_setup_tc(struct net_device *dev, u8 tc); -extern void ixgbe_tx_ctxtdesc(struct ixgbe_ring *, u32, u32, u32, u32); -extern void ixgbe_do_reset(struct net_device *netdev); +int ixgbe_setup_tc(struct net_device *dev, u8 tc); +void ixgbe_tx_ctxtdesc(struct ixgbe_ring *, u32, u32, u32, u32); +void ixgbe_do_reset(struct net_device *netdev); #ifdef CONFIG_IXGBE_HWMON -extern void ixgbe_sysfs_exit(struct ixgbe_adapter *adapter); -extern int ixgbe_sysfs_init(struct ixgbe_adapter *adapter); +void ixgbe_sysfs_exit(struct ixgbe_adapter *adapter); +int ixgbe_sysfs_init(struct ixgbe_adapter *adapter); #endif /* CONFIG_IXGBE_HWMON */ #ifdef IXGBE_FCOE -extern void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter); -extern int ixgbe_fso(struct ixgbe_ring *tx_ring, - struct ixgbe_tx_buffer *first, - u8 *hdr_len); -extern int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, - union ixgbe_adv_rx_desc *rx_desc, - struct sk_buff *skb); -extern int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid, - struct scatterlist *sgl, unsigned int sgc); -extern int ixgbe_fcoe_ddp_target(struct net_device *netdev, u16 xid, - struct scatterlist *sgl, unsigned int sgc); -extern int ixgbe_fcoe_ddp_put(struct net_device *netdev, u16 xid); -extern int ixgbe_setup_fcoe_ddp_resources(struct ixgbe_adapter *adapter); -extern void ixgbe_free_fcoe_ddp_resources(struct ixgbe_adapter *adapter); -extern int ixgbe_fcoe_enable(struct net_device *netdev); -extern int ixgbe_fcoe_disable(struct net_device *netdev); +void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter); +int ixgbe_fso(struct ixgbe_ring *tx_ring, struct ixgbe_tx_buffer *first, + u8 *hdr_len); +int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, + union ixgbe_adv_rx_desc *rx_desc, struct sk_buff *skb); +int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid, + struct scatterlist *sgl, unsigned int sgc); +int ixgbe_fcoe_ddp_target(struct net_device *netdev, u16 xid, + struct scatterlist *sgl, unsigned int sgc); +int ixgbe_fcoe_ddp_put(struct net_device *netdev, u16 xid); +int ixgbe_setup_fcoe_ddp_resources(struct ixgbe_adapter *adapter); +void ixgbe_free_fcoe_ddp_resources(struct ixgbe_adapter *adapter); +int ixgbe_fcoe_enable(struct net_device *netdev); +int ixgbe_fcoe_disable(struct net_device *netdev); #ifdef CONFIG_IXGBE_DCB -extern u8 ixgbe_fcoe_getapp(struct ixgbe_adapter *adapter); -extern u8 ixgbe_fcoe_setapp(struct ixgbe_adapter *adapter, u8 up); +u8 ixgbe_fcoe_getapp(struct ixgbe_adapter *adapter); +u8 ixgbe_fcoe_setapp(struct ixgbe_adapter *adapter, u8 up); #endif /* CONFIG_IXGBE_DCB */ -extern int ixgbe_fcoe_get_wwn(struct net_device *netdev, u64 *wwn, int type); -extern int ixgbe_fcoe_get_hbainfo(struct net_device *netdev, - struct netdev_fcoe_hbainfo *info); -extern u8 ixgbe_fcoe_get_tc(struct ixgbe_adapter *adapter); +int ixgbe_fcoe_get_wwn(struct net_device *netdev, u64 *wwn, int type); +int ixgbe_fcoe_get_hbainfo(struct net_device *netdev, + struct netdev_fcoe_hbainfo *info); +u8 ixgbe_fcoe_get_tc(struct ixgbe_adapter *adapter); #endif /* IXGBE_FCOE */ #ifdef CONFIG_DEBUG_FS -extern void ixgbe_dbg_adapter_init(struct ixgbe_adapter *adapter); -extern void ixgbe_dbg_adapter_exit(struct ixgbe_adapter *adapter); -extern void ixgbe_dbg_init(void); -extern void ixgbe_dbg_exit(void); +void ixgbe_dbg_adapter_init(struct ixgbe_adapter *adapter); +void ixgbe_dbg_adapter_exit(struct ixgbe_adapter *adapter); +void ixgbe_dbg_init(void); +void ixgbe_dbg_exit(void); #else static inline void ixgbe_dbg_adapter_init(struct ixgbe_adapter *adapter) {} static inline void ixgbe_dbg_adapter_exit(struct ixgbe_adapter *adapter) {} @@ -884,12 +880,12 @@ static inline struct netdev_queue *txring_txq(const struct ixgbe_ring *ring) return netdev_get_tx_queue(ring->netdev, ring->queue_index); } -extern void ixgbe_ptp_init(struct ixgbe_adapter *adapter); -extern void ixgbe_ptp_stop(struct ixgbe_adapter *adapter); -extern void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter); -extern void ixgbe_ptp_rx_hang(struct ixgbe_adapter *adapter); -extern void __ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector, - struct sk_buff *skb); +void ixgbe_ptp_init(struct ixgbe_adapter *adapter); +void ixgbe_ptp_stop(struct ixgbe_adapter *adapter); +void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter); +void ixgbe_ptp_rx_hang(struct ixgbe_adapter *adapter); +void __ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector, + struct sk_buff *skb); static inline void ixgbe_ptp_rx_hwtstamp(struct ixgbe_ring *rx_ring, union ixgbe_adv_rx_desc *rx_desc, struct sk_buff *skb) @@ -906,11 +902,11 @@ static inline void ixgbe_ptp_rx_hwtstamp(struct ixgbe_ring *rx_ring, rx_ring->last_rx_timestamp = jiffies; } -extern int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter, - struct ifreq *ifr, int cmd); -extern void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter); -extern void ixgbe_ptp_reset(struct ixgbe_adapter *adapter); -extern void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter, u32 eicr); +int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter, struct ifreq *ifr, + int cmd); +void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter); +void ixgbe_ptp_reset(struct ixgbe_adapter *adapter); +void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter, u32 eicr); #ifdef CONFIG_PCI_IOV void ixgbe_sriov_reinit(struct ixgbe_adapter *adapter); #endif diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c index e8649abf97c0..90aac31b3551 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c @@ -442,7 +442,7 @@ static void ixgbe_set_msglevel(struct net_device *netdev, u32 data) static int ixgbe_get_regs_len(struct net_device *netdev) { -#define IXGBE_REGS_LEN 1129 +#define IXGBE_REGS_LEN 1139 return IXGBE_REGS_LEN * sizeof(u32); } @@ -602,22 +602,53 @@ static void ixgbe_get_regs(struct net_device *netdev, regs_buff[828] = IXGBE_READ_REG(hw, IXGBE_FHFT(0)); /* DCB */ - regs_buff[829] = IXGBE_READ_REG(hw, IXGBE_RMCS); - regs_buff[830] = IXGBE_READ_REG(hw, IXGBE_DPMCS); - regs_buff[831] = IXGBE_READ_REG(hw, IXGBE_PDPMCS); - regs_buff[832] = IXGBE_READ_REG(hw, IXGBE_RUPPBMR); - for (i = 0; i < 8; i++) - regs_buff[833 + i] = IXGBE_READ_REG(hw, IXGBE_RT2CR(i)); - for (i = 0; i < 8; i++) - regs_buff[841 + i] = IXGBE_READ_REG(hw, IXGBE_RT2SR(i)); - for (i = 0; i < 8; i++) - regs_buff[849 + i] = IXGBE_READ_REG(hw, IXGBE_TDTQ2TCCR(i)); - for (i = 0; i < 8; i++) - regs_buff[857 + i] = IXGBE_READ_REG(hw, IXGBE_TDTQ2TCSR(i)); + regs_buff[829] = IXGBE_READ_REG(hw, IXGBE_RMCS); /* same as FCCFG */ + regs_buff[831] = IXGBE_READ_REG(hw, IXGBE_PDPMCS); /* same as RTTPCS */ + + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + regs_buff[830] = IXGBE_READ_REG(hw, IXGBE_DPMCS); + regs_buff[832] = IXGBE_READ_REG(hw, IXGBE_RUPPBMR); + for (i = 0; i < 8; i++) + regs_buff[833 + i] = + IXGBE_READ_REG(hw, IXGBE_RT2CR(i)); + for (i = 0; i < 8; i++) + regs_buff[841 + i] = + IXGBE_READ_REG(hw, IXGBE_RT2SR(i)); + for (i = 0; i < 8; i++) + regs_buff[849 + i] = + IXGBE_READ_REG(hw, IXGBE_TDTQ2TCCR(i)); + for (i = 0; i < 8; i++) + regs_buff[857 + i] = + IXGBE_READ_REG(hw, IXGBE_TDTQ2TCSR(i)); + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + regs_buff[830] = IXGBE_READ_REG(hw, IXGBE_RTTDCS); + regs_buff[832] = IXGBE_READ_REG(hw, IXGBE_RTRPCS); + for (i = 0; i < 8; i++) + regs_buff[833 + i] = + IXGBE_READ_REG(hw, IXGBE_RTRPT4C(i)); + for (i = 0; i < 8; i++) + regs_buff[841 + i] = + IXGBE_READ_REG(hw, IXGBE_RTRPT4S(i)); + for (i = 0; i < 8; i++) + regs_buff[849 + i] = + IXGBE_READ_REG(hw, IXGBE_RTTDT2C(i)); + for (i = 0; i < 8; i++) + regs_buff[857 + i] = + IXGBE_READ_REG(hw, IXGBE_RTTDT2S(i)); + break; + default: + break; + } + for (i = 0; i < 8; i++) - regs_buff[865 + i] = IXGBE_READ_REG(hw, IXGBE_TDPT2TCCR(i)); + regs_buff[865 + i] = + IXGBE_READ_REG(hw, IXGBE_TDPT2TCCR(i)); /* same as RTTPT2C */ for (i = 0; i < 8; i++) - regs_buff[873 + i] = IXGBE_READ_REG(hw, IXGBE_TDPT2TCSR(i)); + regs_buff[873 + i] = + IXGBE_READ_REG(hw, IXGBE_TDPT2TCSR(i)); /* same as RTTPT2S */ /* Statistics */ regs_buff[881] = IXGBE_GET_STAT(adapter, crcerrs); @@ -757,6 +788,20 @@ static void ixgbe_get_regs(struct net_device *netdev, /* 82599 X540 specific registers */ regs_buff[1128] = IXGBE_READ_REG(hw, IXGBE_MFLCN); + + /* 82599 X540 specific DCB registers */ + regs_buff[1129] = IXGBE_READ_REG(hw, IXGBE_RTRUP2TC); + regs_buff[1130] = IXGBE_READ_REG(hw, IXGBE_RTTUP2TC); + for (i = 0; i < 4; i++) + regs_buff[1131 + i] = IXGBE_READ_REG(hw, IXGBE_TXLLQ(i)); + regs_buff[1135] = IXGBE_READ_REG(hw, IXGBE_RTTBCNRM); + /* same as RTTQCNRM */ + regs_buff[1136] = IXGBE_READ_REG(hw, IXGBE_RTTBCNRD); + /* same as RTTQCNRR */ + + /* X540 specific DCB registers */ + regs_buff[1137] = IXGBE_READ_REG(hw, IXGBE_RTTQCNCR); + regs_buff[1138] = IXGBE_READ_REG(hw, IXGBE_RTTQCNTG); } static int ixgbe_get_eeprom_len(struct net_device *netdev) @@ -1072,7 +1117,7 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev, data[i] = 0; data[i+1] = 0; i += 2; -#ifdef LL_EXTENDED_STATS +#ifdef BP_EXTENDED_STATS data[i] = 0; data[i+1] = 0; data[i+2] = 0; @@ -1087,7 +1132,7 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev, data[i+1] = ring->stats.bytes; } while (u64_stats_fetch_retry_bh(&ring->syncp, start)); i += 2; -#ifdef LL_EXTENDED_STATS +#ifdef BP_EXTENDED_STATS data[i] = ring->stats.yields; data[i+1] = ring->stats.misses; data[i+2] = ring->stats.cleaned; @@ -1100,7 +1145,7 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev, data[i] = 0; data[i+1] = 0; i += 2; -#ifdef LL_EXTENDED_STATS +#ifdef BP_EXTENDED_STATS data[i] = 0; data[i+1] = 0; data[i+2] = 0; @@ -1115,7 +1160,7 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev, data[i+1] = ring->stats.bytes; } while (u64_stats_fetch_retry_bh(&ring->syncp, start)); i += 2; -#ifdef LL_EXTENDED_STATS +#ifdef BP_EXTENDED_STATS data[i] = ring->stats.yields; data[i+1] = ring->stats.misses; data[i+2] = ring->stats.cleaned; @@ -1157,28 +1202,28 @@ static void ixgbe_get_strings(struct net_device *netdev, u32 stringset, p += ETH_GSTRING_LEN; sprintf(p, "tx_queue_%u_bytes", i); p += ETH_GSTRING_LEN; -#ifdef LL_EXTENDED_STATS - sprintf(p, "tx_queue_%u_ll_napi_yield", i); +#ifdef BP_EXTENDED_STATS + sprintf(p, "tx_queue_%u_bp_napi_yield", i); p += ETH_GSTRING_LEN; - sprintf(p, "tx_queue_%u_ll_misses", i); + sprintf(p, "tx_queue_%u_bp_misses", i); p += ETH_GSTRING_LEN; - sprintf(p, "tx_queue_%u_ll_cleaned", i); + sprintf(p, "tx_queue_%u_bp_cleaned", i); p += ETH_GSTRING_LEN; -#endif /* LL_EXTENDED_STATS */ +#endif /* BP_EXTENDED_STATS */ } for (i = 0; i < IXGBE_NUM_RX_QUEUES; i++) { sprintf(p, "rx_queue_%u_packets", i); p += ETH_GSTRING_LEN; sprintf(p, "rx_queue_%u_bytes", i); p += ETH_GSTRING_LEN; -#ifdef LL_EXTENDED_STATS - sprintf(p, "rx_queue_%u_ll_poll_yield", i); +#ifdef BP_EXTENDED_STATS + sprintf(p, "rx_queue_%u_bp_poll_yield", i); p += ETH_GSTRING_LEN; - sprintf(p, "rx_queue_%u_ll_misses", i); + sprintf(p, "rx_queue_%u_bp_misses", i); p += ETH_GSTRING_LEN; - sprintf(p, "rx_queue_%u_ll_cleaned", i); + sprintf(p, "rx_queue_%u_bp_cleaned", i); p += ETH_GSTRING_LEN; -#endif /* LL_EXTENDED_STATS */ +#endif /* BP_EXTENDED_STATS */ } for (i = 0; i < IXGBE_MAX_PACKET_BUFFERS; i++) { sprintf(p, "tx_pb_%u_pxon", i); diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 0ade0cd5ef53..43b777aad288 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -1585,7 +1585,7 @@ static void ixgbe_rx_skb(struct ixgbe_q_vector *q_vector, { struct ixgbe_adapter *adapter = q_vector->adapter; - if (ixgbe_qv_ll_polling(q_vector)) + if (ixgbe_qv_busy_polling(q_vector)) netif_receive_skb(skb); else if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) napi_gro_receive(&q_vector->napi, skb); @@ -2097,7 +2097,7 @@ static int ixgbe_low_latency_recv(struct napi_struct *napi) ixgbe_for_each_ring(ring, q_vector->rx) { found = ixgbe_clean_rx_irq(q_vector, ring, 4); -#ifdef LL_EXTENDED_STATS +#ifdef BP_EXTENDED_STATS if (found) ring->stats.cleaned += found; else diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h index 24af12e3719e..aae900a256da 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h @@ -57,28 +57,28 @@ #define IXGBE_SFF_QSFP_DEVICE_TECH 0x93 /* Bitmasks */ -#define IXGBE_SFF_DA_PASSIVE_CABLE 0x4 -#define IXGBE_SFF_DA_ACTIVE_CABLE 0x8 -#define IXGBE_SFF_DA_SPEC_ACTIVE_LIMITING 0x4 -#define IXGBE_SFF_1GBASESX_CAPABLE 0x1 -#define IXGBE_SFF_1GBASELX_CAPABLE 0x2 -#define IXGBE_SFF_1GBASET_CAPABLE 0x8 -#define IXGBE_SFF_10GBASESR_CAPABLE 0x10 -#define IXGBE_SFF_10GBASELR_CAPABLE 0x20 -#define IXGBE_SFF_SOFT_RS_SELECT_MASK 0x8 -#define IXGBE_SFF_SOFT_RS_SELECT_10G 0x8 -#define IXGBE_SFF_SOFT_RS_SELECT_1G 0x0 -#define IXGBE_SFF_ADDRESSING_MODE 0x4 -#define IXGBE_SFF_QSFP_DA_ACTIVE_CABLE 0x1 -#define IXGBE_SFF_QSFP_DA_PASSIVE_CABLE 0x8 +#define IXGBE_SFF_DA_PASSIVE_CABLE 0x4 +#define IXGBE_SFF_DA_ACTIVE_CABLE 0x8 +#define IXGBE_SFF_DA_SPEC_ACTIVE_LIMITING 0x4 +#define IXGBE_SFF_1GBASESX_CAPABLE 0x1 +#define IXGBE_SFF_1GBASELX_CAPABLE 0x2 +#define IXGBE_SFF_1GBASET_CAPABLE 0x8 +#define IXGBE_SFF_10GBASESR_CAPABLE 0x10 +#define IXGBE_SFF_10GBASELR_CAPABLE 0x20 +#define IXGBE_SFF_SOFT_RS_SELECT_MASK 0x8 +#define IXGBE_SFF_SOFT_RS_SELECT_10G 0x8 +#define IXGBE_SFF_SOFT_RS_SELECT_1G 0x0 +#define IXGBE_SFF_ADDRESSING_MODE 0x4 +#define IXGBE_SFF_QSFP_DA_ACTIVE_CABLE 0x1 +#define IXGBE_SFF_QSFP_DA_PASSIVE_CABLE 0x8 #define IXGBE_SFF_QSFP_CONNECTOR_NOT_SEPARABLE 0x23 #define IXGBE_SFF_QSFP_TRANSMITER_850NM_VCSEL 0x0 -#define IXGBE_I2C_EEPROM_READ_MASK 0x100 -#define IXGBE_I2C_EEPROM_STATUS_MASK 0x3 -#define IXGBE_I2C_EEPROM_STATUS_NO_OPERATION 0x0 -#define IXGBE_I2C_EEPROM_STATUS_PASS 0x1 -#define IXGBE_I2C_EEPROM_STATUS_FAIL 0x2 -#define IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS 0x3 +#define IXGBE_I2C_EEPROM_READ_MASK 0x100 +#define IXGBE_I2C_EEPROM_STATUS_MASK 0x3 +#define IXGBE_I2C_EEPROM_STATUS_NO_OPERATION 0x0 +#define IXGBE_I2C_EEPROM_STATUS_PASS 0x1 +#define IXGBE_I2C_EEPROM_STATUS_FAIL 0x2 +#define IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS 0x3 /* Flow control defines */ #define IXGBE_TAF_SYM_PAUSE 0x400 diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c index 276d7b135332..1fe7cb0142e1 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c @@ -558,7 +558,7 @@ static int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter, struct ixgbe_hw *hw = &adapter->hw; int rar_entry = hw->mac.num_rar_entries - (vf + 1); - memcpy(adapter->vfinfo[vf].vf_mac_addresses, mac_addr, 6); + memcpy(adapter->vfinfo[vf].vf_mac_addresses, mac_addr, ETH_ALEN); hw->mac.ops.set_rar(hw, rar_entry, mac_addr, vf, IXGBE_RAH_AV); return 0; @@ -621,16 +621,13 @@ static int ixgbe_set_vf_macvlan(struct ixgbe_adapter *adapter, int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask) { - unsigned char vf_mac_addr[6]; struct ixgbe_adapter *adapter = pci_get_drvdata(pdev); unsigned int vfn = (event_mask & 0x3f); bool enable = ((event_mask & 0x10000000U) != 0); - if (enable) { - eth_zero_addr(vf_mac_addr); - memcpy(adapter->vfinfo[vfn].vf_mac_addresses, vf_mac_addr, 6); - } + if (enable) + eth_zero_addr(adapter->vfinfo[vfn].vf_mac_addresses); return 0; } diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h index 10775cb9b6d8..7c19e969576f 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h @@ -561,6 +561,10 @@ struct ixgbe_thermal_sensor_data { #define IXGBE_RTTDQSEL 0x04904 #define IXGBE_RTTDT1C 0x04908 #define IXGBE_RTTDT1S 0x0490C +#define IXGBE_RTTQCNCR 0x08B00 +#define IXGBE_RTTQCNTG 0x04A90 +#define IXGBE_RTTBCNRD 0x0498C +#define IXGBE_RTTQCNRR 0x0498C #define IXGBE_RTTDTECC 0x04990 #define IXGBE_RTTDTECC_NO_BCN 0x00000100 #define IXGBE_RTTBCNRC 0x04984 @@ -570,6 +574,7 @@ struct ixgbe_thermal_sensor_data { #define IXGBE_RTTBCNRC_RF_INT_MASK \ (IXGBE_RTTBCNRC_RF_DEC_MASK << IXGBE_RTTBCNRC_RF_INT_SHIFT) #define IXGBE_RTTBCNRM 0x04980 +#define IXGBE_RTTQCNRM 0x04980 /* FCoE DMA Context Registers */ #define IXGBE_FCPTRL 0x02410 /* FC User Desc. PTR Low */ diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c index 389324f5929a..24b80a6cfca4 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c @@ -32,12 +32,12 @@ #include "ixgbe.h" #include "ixgbe_phy.h" -#define IXGBE_X540_MAX_TX_QUEUES 128 -#define IXGBE_X540_MAX_RX_QUEUES 128 -#define IXGBE_X540_RAR_ENTRIES 128 -#define IXGBE_X540_MC_TBL_SIZE 128 -#define IXGBE_X540_VFT_TBL_SIZE 128 -#define IXGBE_X540_RX_PB_SIZE 384 +#define IXGBE_X540_MAX_TX_QUEUES 128 +#define IXGBE_X540_MAX_RX_QUEUES 128 +#define IXGBE_X540_RAR_ENTRIES 128 +#define IXGBE_X540_MC_TBL_SIZE 128 +#define IXGBE_X540_VFT_TBL_SIZE 128 +#define IXGBE_X540_RX_PB_SIZE 384 static s32 ixgbe_update_flash_X540(struct ixgbe_hw *hw); static s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw); diff --git a/drivers/net/ethernet/intel/ixgbevf/ethtool.c b/drivers/net/ethernet/intel/ixgbevf/ethtool.c index c9d0c12d6f04..84329b0d567a 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ethtool.c +++ b/drivers/net/ethernet/intel/ixgbevf/ethtool.c @@ -140,58 +140,10 @@ static void ixgbevf_set_msglevel(struct net_device *netdev, u32 data) #define IXGBE_GET_STAT(_A_, _R_) (_A_->stats._R_) -static char *ixgbevf_reg_names[] = { - "IXGBE_VFCTRL", - "IXGBE_VFSTATUS", - "IXGBE_VFLINKS", - "IXGBE_VFRXMEMWRAP", - "IXGBE_VFFRTIMER", - "IXGBE_VTEICR", - "IXGBE_VTEICS", - "IXGBE_VTEIMS", - "IXGBE_VTEIMC", - "IXGBE_VTEIAC", - "IXGBE_VTEIAM", - "IXGBE_VTEITR", - "IXGBE_VTIVAR", - "IXGBE_VTIVAR_MISC", - "IXGBE_VFRDBAL0", - "IXGBE_VFRDBAL1", - "IXGBE_VFRDBAH0", - "IXGBE_VFRDBAH1", - "IXGBE_VFRDLEN0", - "IXGBE_VFRDLEN1", - "IXGBE_VFRDH0", - "IXGBE_VFRDH1", - "IXGBE_VFRDT0", - "IXGBE_VFRDT1", - "IXGBE_VFRXDCTL0", - "IXGBE_VFRXDCTL1", - "IXGBE_VFSRRCTL0", - "IXGBE_VFSRRCTL1", - "IXGBE_VFPSRTYPE", - "IXGBE_VFTDBAL0", - "IXGBE_VFTDBAL1", - "IXGBE_VFTDBAH0", - "IXGBE_VFTDBAH1", - "IXGBE_VFTDLEN0", - "IXGBE_VFTDLEN1", - "IXGBE_VFTDH0", - "IXGBE_VFTDH1", - "IXGBE_VFTDT0", - "IXGBE_VFTDT1", - "IXGBE_VFTXDCTL0", - "IXGBE_VFTXDCTL1", - "IXGBE_VFTDWBAL0", - "IXGBE_VFTDWBAL1", - "IXGBE_VFTDWBAH0", - "IXGBE_VFTDWBAH1" -}; - - static int ixgbevf_get_regs_len(struct net_device *netdev) { - return (ARRAY_SIZE(ixgbevf_reg_names)) * sizeof(u32); +#define IXGBE_REGS_LEN 45 + return IXGBE_REGS_LEN * sizeof(u32); } static void ixgbevf_get_regs(struct net_device *netdev, @@ -264,9 +216,6 @@ static void ixgbevf_get_regs(struct net_device *netdev, regs_buff[41 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDWBAL(i)); for (i = 0; i < 2; i++) regs_buff[43 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDWBAH(i)); - - for (i = 0; i < ARRAY_SIZE(ixgbevf_reg_names); i++) - hw_dbg(hw, "%s\t%8.8x\n", ixgbevf_reg_names[i], regs_buff[i]); } static void ixgbevf_get_drvinfo(struct net_device *netdev, diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h index fff0d9867529..64a2b912e73c 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h @@ -281,27 +281,23 @@ extern const struct ixgbe_mbx_operations ixgbevf_mbx_ops; extern const char ixgbevf_driver_name[]; extern const char ixgbevf_driver_version[]; -extern void ixgbevf_up(struct ixgbevf_adapter *adapter); -extern void ixgbevf_down(struct ixgbevf_adapter *adapter); -extern void ixgbevf_reinit_locked(struct ixgbevf_adapter *adapter); -extern void ixgbevf_reset(struct ixgbevf_adapter *adapter); -extern void ixgbevf_set_ethtool_ops(struct net_device *netdev); -extern int ixgbevf_setup_rx_resources(struct ixgbevf_adapter *, - struct ixgbevf_ring *); -extern int ixgbevf_setup_tx_resources(struct ixgbevf_adapter *, - struct ixgbevf_ring *); -extern void ixgbevf_free_rx_resources(struct ixgbevf_adapter *, - struct ixgbevf_ring *); -extern void ixgbevf_free_tx_resources(struct ixgbevf_adapter *, - struct ixgbevf_ring *); -extern void ixgbevf_update_stats(struct ixgbevf_adapter *adapter); -extern int ethtool_ioctl(struct ifreq *ifr); - -extern void ixgbe_napi_add_all(struct ixgbevf_adapter *adapter); -extern void ixgbe_napi_del_all(struct ixgbevf_adapter *adapter); +void ixgbevf_up(struct ixgbevf_adapter *adapter); +void ixgbevf_down(struct ixgbevf_adapter *adapter); +void ixgbevf_reinit_locked(struct ixgbevf_adapter *adapter); +void ixgbevf_reset(struct ixgbevf_adapter *adapter); +void ixgbevf_set_ethtool_ops(struct net_device *netdev); +int ixgbevf_setup_rx_resources(struct ixgbevf_adapter *, struct ixgbevf_ring *); +int ixgbevf_setup_tx_resources(struct ixgbevf_adapter *, struct ixgbevf_ring *); +void ixgbevf_free_rx_resources(struct ixgbevf_adapter *, struct ixgbevf_ring *); +void ixgbevf_free_tx_resources(struct ixgbevf_adapter *, struct ixgbevf_ring *); +void ixgbevf_update_stats(struct ixgbevf_adapter *adapter); +int ethtool_ioctl(struct ifreq *ifr); + +void ixgbe_napi_add_all(struct ixgbevf_adapter *adapter); +void ixgbe_napi_del_all(struct ixgbevf_adapter *adapter); #ifdef DEBUG -extern char *ixgbevf_get_hw_dev_name(struct ixgbe_hw *hw); +char *ixgbevf_get_hw_dev_name(struct ixgbe_hw *hw); #define hw_dbg(hw, format, arg...) \ printk(KERN_DEBUG "%s: " format, ixgbevf_get_hw_dev_name(hw), ##arg) #else diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index 59a62bbfb371..ce27d62f9c8e 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -756,37 +756,12 @@ static void ixgbevf_set_itr(struct ixgbevf_q_vector *q_vector) static irqreturn_t ixgbevf_msix_other(int irq, void *data) { struct ixgbevf_adapter *adapter = data; - struct pci_dev *pdev = adapter->pdev; struct ixgbe_hw *hw = &adapter->hw; - u32 msg; - bool got_ack = false; hw->mac.get_link_status = 1; - if (!hw->mbx.ops.check_for_ack(hw)) - got_ack = true; - - if (!hw->mbx.ops.check_for_msg(hw)) { - hw->mbx.ops.read(hw, &msg, 1); - - if ((msg & IXGBE_MBVFICR_VFREQ_MASK) == IXGBE_PF_CONTROL_MSG) { - mod_timer(&adapter->watchdog_timer, - round_jiffies(jiffies + 1)); - adapter->link_up = false; - } - if (msg & IXGBE_VT_MSGTYPE_NACK) - dev_info(&pdev->dev, - "Last Request of type %2.2x to PF Nacked\n", - msg & 0xFF); - hw->mbx.v2p_mailbox |= IXGBE_VFMAILBOX_PFSTS; - } - - /* checking for the ack clears the PFACK bit. Place - * it back in the v2p_mailbox cache so that anyone - * polling for an ack will not miss it - */ - if (got_ack) - hw->mbx.v2p_mailbox |= IXGBE_VFMAILBOX_PFACK; + if (!test_bit(__IXGBEVF_DOWN, &adapter->state)) + mod_timer(&adapter->watchdog_timer, jiffies); IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, adapter->eims_other); @@ -1327,27 +1302,51 @@ static void ixgbevf_configure(struct ixgbevf_adapter *adapter) } } -#define IXGBE_MAX_RX_DESC_POLL 10 -static inline void ixgbevf_rx_desc_queue_enable(struct ixgbevf_adapter *adapter, - int rxr) +#define IXGBEVF_MAX_RX_DESC_POLL 10 +static void ixgbevf_rx_desc_queue_enable(struct ixgbevf_adapter *adapter, + int rxr) { struct ixgbe_hw *hw = &adapter->hw; + int wait_loop = IXGBEVF_MAX_RX_DESC_POLL; + u32 rxdctl; int j = adapter->rx_ring[rxr].reg_idx; - int k; - for (k = 0; k < IXGBE_MAX_RX_DESC_POLL; k++) { - if (IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(j)) & IXGBE_RXDCTL_ENABLE) - break; - else - msleep(1); - } - if (k >= IXGBE_MAX_RX_DESC_POLL) { - hw_dbg(hw, "RXDCTL.ENABLE on Rx queue %d " - "not set within the polling period\n", rxr); - } + do { + usleep_range(1000, 2000); + rxdctl = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(j)); + } while (--wait_loop && !(rxdctl & IXGBE_RXDCTL_ENABLE)); + + if (!wait_loop) + hw_dbg(hw, "RXDCTL.ENABLE queue %d not set while polling\n", + rxr); + + ixgbevf_release_rx_desc(&adapter->hw, &adapter->rx_ring[rxr], + (adapter->rx_ring[rxr].count - 1)); +} + +static void ixgbevf_disable_rx_queue(struct ixgbevf_adapter *adapter, + struct ixgbevf_ring *ring) +{ + struct ixgbe_hw *hw = &adapter->hw; + int wait_loop = IXGBEVF_MAX_RX_DESC_POLL; + u32 rxdctl; + u8 reg_idx = ring->reg_idx; - ixgbevf_release_rx_desc(hw, &adapter->rx_ring[rxr], - adapter->rx_ring[rxr].count - 1); + rxdctl = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(reg_idx)); + rxdctl &= ~IXGBE_RXDCTL_ENABLE; + + /* write value back with RXDCTL.ENABLE bit cleared */ + IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(reg_idx), rxdctl); + + /* the hardware may take up to 100us to really disable the rx queue */ + do { + udelay(10); + rxdctl = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(reg_idx)); + } while (--wait_loop && (rxdctl & IXGBE_RXDCTL_ENABLE)); + + if (!wait_loop) + hw_dbg(hw, "RXDCTL.ENABLE queue %d not cleared while polling\n", + reg_idx); } static void ixgbevf_save_reset_stats(struct ixgbevf_adapter *adapter) @@ -1545,8 +1544,6 @@ void ixgbevf_up(struct ixgbevf_adapter *adapter) { struct ixgbe_hw *hw = &adapter->hw; - ixgbevf_negotiate_api(adapter); - ixgbevf_reset_queues(adapter); ixgbevf_configure(adapter); @@ -1679,7 +1676,10 @@ void ixgbevf_down(struct ixgbevf_adapter *adapter) /* signal that we are down to the interrupt handler */ set_bit(__IXGBEVF_DOWN, &adapter->state); - /* disable receives */ + + /* disable all enabled rx queues */ + for (i = 0; i < adapter->num_rx_queues; i++) + ixgbevf_disable_rx_queue(adapter, &adapter->rx_ring[i]); netif_tx_disable(netdev); @@ -1733,10 +1733,12 @@ void ixgbevf_reset(struct ixgbevf_adapter *adapter) struct ixgbe_hw *hw = &adapter->hw; struct net_device *netdev = adapter->netdev; - if (hw->mac.ops.reset_hw(hw)) + if (hw->mac.ops.reset_hw(hw)) { hw_dbg(hw, "PF still resetting\n"); - else + } else { hw->mac.ops.init_hw(hw); + ixgbevf_negotiate_api(adapter); + } if (is_valid_ether_addr(adapter->hw.mac.addr)) { memcpy(netdev->dev_addr, adapter->hw.mac.addr, @@ -2072,6 +2074,9 @@ static int ixgbevf_sw_init(struct ixgbevf_adapter *adapter) hw->mac.max_tx_queues = 2; hw->mac.max_rx_queues = 2; + /* lock to protect mailbox accesses */ + spin_lock_init(&adapter->mbx_lock); + err = hw->mac.ops.reset_hw(hw); if (err) { dev_info(&pdev->dev, @@ -2082,6 +2087,7 @@ static int ixgbevf_sw_init(struct ixgbevf_adapter *adapter) pr_err("init_shared_code failed: %d\n", err); goto out; } + ixgbevf_negotiate_api(adapter); err = hw->mac.ops.get_mac_addr(hw, hw->mac.addr); if (err) dev_info(&pdev->dev, "Error reading MAC address\n"); @@ -2097,9 +2103,6 @@ static int ixgbevf_sw_init(struct ixgbevf_adapter *adapter) memcpy(hw->mac.addr, netdev->dev_addr, netdev->addr_len); } - /* lock to protect mailbox accesses */ - spin_lock_init(&adapter->mbx_lock); - /* Enable dynamic interrupt throttling rates */ adapter->rx_itr_setting = 1; adapter->tx_itr_setting = 1; @@ -2620,8 +2623,6 @@ static int ixgbevf_open(struct net_device *netdev) } } - ixgbevf_negotiate_api(adapter); - /* setup queue reg_idx and Rx queue count */ err = ixgbevf_setup_queues(adapter); if (err) @@ -3216,6 +3217,8 @@ static int ixgbevf_resume(struct pci_dev *pdev) } pci_set_master(pdev); + ixgbevf_reset(adapter); + rtnl_lock(); err = ixgbevf_init_interrupt_scheme(adapter); rtnl_unlock(); @@ -3224,8 +3227,6 @@ static int ixgbevf_resume(struct pci_dev *pdev) return err; } - ixgbevf_reset(adapter); - if (netif_running(netdev)) { err = ixgbevf_open(netdev); if (err) diff --git a/drivers/net/ethernet/intel/ixgbevf/vf.c b/drivers/net/ethernet/intel/ixgbevf/vf.c index 387b52635bc0..4d44d64ae387 100644 --- a/drivers/net/ethernet/intel/ixgbevf/vf.c +++ b/drivers/net/ethernet/intel/ixgbevf/vf.c @@ -242,7 +242,7 @@ static s32 ixgbevf_set_uc_addr_vf(struct ixgbe_hw *hw, u32 index, u8 *addr) msgbuf[0] |= index << IXGBE_VT_MSGINFO_SHIFT; msgbuf[0] |= IXGBE_VF_SET_MACVLAN; if (addr) - memcpy(msg_addr, addr, 6); + memcpy(msg_addr, addr, ETH_ALEN); ret_val = mbx->ops.write_posted(hw, msgbuf, 3); if (!ret_val) @@ -275,7 +275,7 @@ static s32 ixgbevf_set_rar_vf(struct ixgbe_hw *hw, u32 index, u8 *addr, memset(msgbuf, 0, sizeof(msgbuf)); msgbuf[0] = IXGBE_VF_SET_MAC_ADDR; - memcpy(msg_addr, addr, 6); + memcpy(msg_addr, addr, ETH_ALEN); ret_val = mbx->ops.write_posted(hw, msgbuf, 3); if (!ret_val) diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c index 23de82a9da82..b56d2a29cd0e 100644 --- a/drivers/net/ethernet/jme.c +++ b/drivers/net/ethernet/jme.c @@ -309,7 +309,7 @@ static void jme_load_macaddr(struct net_device *netdev) { struct jme_adapter *jme = netdev_priv(netdev); - unsigned char macaddr[6]; + unsigned char macaddr[ETH_ALEN]; u32 val; spin_lock_bh(&jme->macaddr_lock); @@ -321,7 +321,7 @@ jme_load_macaddr(struct net_device *netdev) val = jread32(jme, JME_RXUMA_HI); macaddr[4] = (val >> 0) & 0xFF; macaddr[5] = (val >> 8) & 0xFF; - memcpy(netdev->dev_addr, macaddr, 6); + memcpy(netdev->dev_addr, macaddr, ETH_ALEN); spin_unlock_bh(&jme->macaddr_lock); } diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c index a36fa80968eb..4a5e3b0f712e 100644 --- a/drivers/net/ethernet/korina.c +++ b/drivers/net/ethernet/korina.c @@ -1110,7 +1110,7 @@ static int korina_probe(struct platform_device *pdev) lp = netdev_priv(dev); bif->dev = dev; - memcpy(dev->dev_addr, bif->mac, 6); + memcpy(dev->dev_addr, bif->mac, ETH_ALEN); lp->rx_irq = platform_get_irq_byname(pdev, "korina_rx"); lp->tx_irq = platform_get_irq_byname(pdev, "korina_tx"); diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c index 7fb5677451f9..99f16cbf2fd8 100644 --- a/drivers/net/ethernet/marvell/mv643xx_eth.c +++ b/drivers/net/ethernet/marvell/mv643xx_eth.c @@ -2514,7 +2514,7 @@ static int mv643xx_eth_shared_of_add_port(struct platform_device *pdev, mac_addr = of_get_mac_address(pnp); if (mac_addr) - memcpy(ppd.mac_addr, mac_addr, 6); + memcpy(ppd.mac_addr, mac_addr, ETH_ALEN); mv643xx_eth_property(pnp, "tx-queue-size", ppd.tx_queue_size); mv643xx_eth_property(pnp, "tx-sram-addr", ppd.tx_sram_addr); @@ -2696,7 +2696,7 @@ static void set_params(struct mv643xx_eth_private *mp, struct net_device *dev = mp->dev; if (is_valid_ether_addr(pd->mac_addr)) - memcpy(dev->dev_addr, pd->mac_addr, 6); + memcpy(dev->dev_addr, pd->mac_addr, ETH_ALEN); else uc_addr_get(mp, dev->dev_addr); diff --git a/drivers/net/ethernet/marvell/skge.c b/drivers/net/ethernet/marvell/skge.c index 1a9c4f6269ea..ecc7f7b696b8 100644 --- a/drivers/net/ethernet/marvell/skge.c +++ b/drivers/net/ethernet/marvell/skge.c @@ -3086,13 +3086,16 @@ static struct sk_buff *skge_rx_get(struct net_device *dev, PCI_DMA_FROMDEVICE); skge_rx_reuse(e, skge->rx_buf_size); } else { + struct skge_element ee; struct sk_buff *nskb; nskb = netdev_alloc_skb_ip_align(dev, skge->rx_buf_size); if (!nskb) goto resubmit; - skb = e->skb; + ee = *e; + + skb = ee.skb; prefetch(skb->data); if (skge_rx_setup(skge, e, nskb, skge->rx_buf_size) < 0) { @@ -3101,8 +3104,8 @@ static struct sk_buff *skge_rx_get(struct net_device *dev, } pci_unmap_single(skge->hw->pdev, - dma_unmap_addr(e, mapaddr), - dma_unmap_len(e, maplen), + dma_unmap_addr(&ee, mapaddr), + dma_unmap_len(&ee, maplen), PCI_DMA_FROMDEVICE); } diff --git a/drivers/net/ethernet/micrel/ks8851_mll.c b/drivers/net/ethernet/micrel/ks8851_mll.c index 075f4e21d33d..c83d16dc7cd5 100644 --- a/drivers/net/ethernet/micrel/ks8851_mll.c +++ b/drivers/net/ethernet/micrel/ks8851_mll.c @@ -1248,7 +1248,7 @@ static void ks_set_mac(struct ks_net *ks, u8 *data) w = ((u & 0xFF) << 8) | ((u >> 8) & 0xFF); ks_wrreg16(ks, KS_MARL, w); - memcpy(ks->mac_addr, data, 6); + memcpy(ks->mac_addr, data, ETH_ALEN); if (ks->enabled) ks_start_rx(ks); @@ -1651,7 +1651,7 @@ static int ks8851_probe(struct platform_device *pdev) } netdev_info(netdev, "Mac address is: %pM\n", ks->mac_addr); - memcpy(netdev->dev_addr, ks->mac_addr, 6); + memcpy(netdev->dev_addr, ks->mac_addr, ETH_ALEN); ks_set_mac(ks, netdev->dev_addr); diff --git a/drivers/net/ethernet/moxa/moxart_ether.c b/drivers/net/ethernet/moxa/moxart_ether.c index 83c2091c9c23..bd1a2d2bc2ae 100644 --- a/drivers/net/ethernet/moxa/moxart_ether.c +++ b/drivers/net/ethernet/moxa/moxart_ether.c @@ -543,7 +543,7 @@ static const struct of_device_id moxart_mac_match[] = { { } }; -struct __initdata platform_driver moxart_mac_driver = { +static struct platform_driver moxart_mac_driver = { .probe = moxart_mac_probe, .remove = moxart_remove, .driver = { diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c index 149355b52ad0..1975550c3634 100644 --- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c +++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c @@ -934,7 +934,7 @@ static inline void myri10ge_ss_init_lock(struct myri10ge_slice_state *ss) static inline bool myri10ge_ss_lock_napi(struct myri10ge_slice_state *ss) { - int rc = true; + bool rc = true; spin_lock(&ss->lock); if ((ss->state & SLICE_LOCKED)) { WARN_ON((ss->state & SLICE_STATE_NAPI)); @@ -957,7 +957,7 @@ static inline void myri10ge_ss_unlock_napi(struct myri10ge_slice_state *ss) static inline bool myri10ge_ss_lock_poll(struct myri10ge_slice_state *ss) { - int rc = true; + bool rc = true; spin_lock_bh(&ss->lock); if ((ss->state & SLICE_LOCKED)) { ss->state |= SLICE_STATE_POLL_YIELD; @@ -3164,7 +3164,7 @@ static void myri10ge_set_multicast_list(struct net_device *dev) /* Walk the multicast list, and add each address */ netdev_for_each_mc_addr(ha, dev) { - memcpy(data, &ha->addr, 6); + memcpy(data, &ha->addr, ETH_ALEN); cmd.data0 = ntohl(data[0]); cmd.data1 = ntohl(data[1]); err = myri10ge_send_cmd(mgp, MXGEFW_JOIN_MULTICAST_GROUP, @@ -3207,7 +3207,7 @@ static int myri10ge_set_mac_address(struct net_device *dev, void *addr) } /* change the dev structure */ - memcpy(dev->dev_addr, sa->sa_data, 6); + memcpy(dev->dev_addr, sa->sa_data, ETH_ALEN); return 0; } diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h index 6797b1075874..2a9003071d51 100644 --- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h +++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h @@ -653,38 +653,38 @@ struct pch_gbe_adapter { extern const char pch_driver_version[]; /* pch_gbe_main.c */ -extern int pch_gbe_up(struct pch_gbe_adapter *adapter); -extern void pch_gbe_down(struct pch_gbe_adapter *adapter); -extern void pch_gbe_reinit_locked(struct pch_gbe_adapter *adapter); -extern void pch_gbe_reset(struct pch_gbe_adapter *adapter); -extern int pch_gbe_setup_tx_resources(struct pch_gbe_adapter *adapter, - struct pch_gbe_tx_ring *txdr); -extern int pch_gbe_setup_rx_resources(struct pch_gbe_adapter *adapter, - struct pch_gbe_rx_ring *rxdr); -extern void pch_gbe_free_tx_resources(struct pch_gbe_adapter *adapter, - struct pch_gbe_tx_ring *tx_ring); -extern void pch_gbe_free_rx_resources(struct pch_gbe_adapter *adapter, - struct pch_gbe_rx_ring *rx_ring); -extern void pch_gbe_update_stats(struct pch_gbe_adapter *adapter); -extern u32 pch_ch_control_read(struct pci_dev *pdev); -extern void pch_ch_control_write(struct pci_dev *pdev, u32 val); -extern u32 pch_ch_event_read(struct pci_dev *pdev); -extern void pch_ch_event_write(struct pci_dev *pdev, u32 val); -extern u32 pch_src_uuid_lo_read(struct pci_dev *pdev); -extern u32 pch_src_uuid_hi_read(struct pci_dev *pdev); -extern u64 pch_rx_snap_read(struct pci_dev *pdev); -extern u64 pch_tx_snap_read(struct pci_dev *pdev); -extern int pch_set_station_address(u8 *addr, struct pci_dev *pdev); +int pch_gbe_up(struct pch_gbe_adapter *adapter); +void pch_gbe_down(struct pch_gbe_adapter *adapter); +void pch_gbe_reinit_locked(struct pch_gbe_adapter *adapter); +void pch_gbe_reset(struct pch_gbe_adapter *adapter); +int pch_gbe_setup_tx_resources(struct pch_gbe_adapter *adapter, + struct pch_gbe_tx_ring *txdr); +int pch_gbe_setup_rx_resources(struct pch_gbe_adapter *adapter, + struct pch_gbe_rx_ring *rxdr); +void pch_gbe_free_tx_resources(struct pch_gbe_adapter *adapter, + struct pch_gbe_tx_ring *tx_ring); +void pch_gbe_free_rx_resources(struct pch_gbe_adapter *adapter, + struct pch_gbe_rx_ring *rx_ring); +void pch_gbe_update_stats(struct pch_gbe_adapter *adapter); +u32 pch_ch_control_read(struct pci_dev *pdev); +void pch_ch_control_write(struct pci_dev *pdev, u32 val); +u32 pch_ch_event_read(struct pci_dev *pdev); +void pch_ch_event_write(struct pci_dev *pdev, u32 val); +u32 pch_src_uuid_lo_read(struct pci_dev *pdev); +u32 pch_src_uuid_hi_read(struct pci_dev *pdev); +u64 pch_rx_snap_read(struct pci_dev *pdev); +u64 pch_tx_snap_read(struct pci_dev *pdev); +int pch_set_station_address(u8 *addr, struct pci_dev *pdev); /* pch_gbe_param.c */ -extern void pch_gbe_check_options(struct pch_gbe_adapter *adapter); +void pch_gbe_check_options(struct pch_gbe_adapter *adapter); /* pch_gbe_ethtool.c */ -extern void pch_gbe_set_ethtool_ops(struct net_device *netdev); +void pch_gbe_set_ethtool_ops(struct net_device *netdev); /* pch_gbe_mac.c */ -extern s32 pch_gbe_mac_force_mac_fc(struct pch_gbe_hw *hw); -extern s32 pch_gbe_mac_read_mac_addr(struct pch_gbe_hw *hw); -extern u16 pch_gbe_mac_ctrl_miim(struct pch_gbe_hw *hw, - u32 addr, u32 dir, u32 reg, u16 data); +s32 pch_gbe_mac_force_mac_fc(struct pch_gbe_hw *hw); +s32 pch_gbe_mac_read_mac_addr(struct pch_gbe_hw *hw); +u16 pch_gbe_mac_ctrl_miim(struct pch_gbe_hw *hw, u32 addr, u32 dir, u32 reg, + u16 data); #endif /* _PCH_GBE_H_ */ diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic.h b/drivers/net/ethernet/qlogic/netxen/netxen_nic.h index 32675e16021e..9adcdbb49476 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic.h +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic.h @@ -53,8 +53,8 @@ #define _NETXEN_NIC_LINUX_MAJOR 4 #define _NETXEN_NIC_LINUX_MINOR 0 -#define _NETXEN_NIC_LINUX_SUBVERSION 81 -#define NETXEN_NIC_LINUX_VERSIONID "4.0.81" +#define _NETXEN_NIC_LINUX_SUBVERSION 82 +#define NETXEN_NIC_LINUX_VERSIONID "4.0.82" #define NETXEN_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c)) #define _major(v) (((v) >> 24) & 0xff) @@ -1883,9 +1883,8 @@ static inline u32 netxen_tx_avail(struct nx_host_tx_ring *tx_ring) int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 *mac); int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, u64 *mac); -extern void netxen_change_ringparam(struct netxen_adapter *adapter); -extern int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, - int *valp); +void netxen_change_ringparam(struct netxen_adapter *adapter); +int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp); extern const struct ethtool_ops netxen_nic_ethtool_ops; diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h index 32c790659f9c..0c64c82b9acf 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h @@ -958,6 +958,7 @@ enum { #define NETXEN_PEG_HALT_STATUS2 (NETXEN_CAM_RAM(0xac)) #define NX_CRB_DEV_REF_COUNT (NETXEN_CAM_RAM(0x138)) #define NX_CRB_DEV_STATE (NETXEN_CAM_RAM(0x140)) +#define NETXEN_ULA_KEY (NETXEN_CAM_RAM(0x178)) /* MiniDIMM related macros */ #define NETXEN_DIMM_CAPABILITY (NETXEN_CAM_RAM(0x258)) diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c index 8375cbde9969..67efe754367d 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c @@ -648,7 +648,7 @@ nx_p3_sre_macaddr_change(struct netxen_adapter *adapter, u8 *addr, unsigned op) mac_req = (nx_mac_req_t *)&req.words[0]; mac_req->op = op; - memcpy(mac_req->mac_addr, addr, 6); + memcpy(mac_req->mac_addr, addr, ETH_ALEN); return netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); } diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c index cbd75f97ffb3..5ec21c50373c 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c @@ -1415,6 +1415,32 @@ netxen_setup_netdev(struct netxen_adapter *adapter, return 0; } +#define NETXEN_ULA_ADAPTER_KEY (0xdaddad01) +#define NETXEN_NON_ULA_ADAPTER_KEY (0xdaddad00) + +static void netxen_read_ula_info(struct netxen_adapter *adapter) +{ + u32 temp; + + /* Print ULA info only once for an adapter */ + if (adapter->portnum != 0) + return; + + temp = NXRD32(adapter, NETXEN_ULA_KEY); + switch (temp) { + case NETXEN_ULA_ADAPTER_KEY: + dev_info(&adapter->pdev->dev, "ULA adapter"); + break; + case NETXEN_NON_ULA_ADAPTER_KEY: + dev_info(&adapter->pdev->dev, "non ULA adapter"); + break; + default: + break; + } + + return; +} + #ifdef CONFIG_PCIEAER static void netxen_mask_aer_correctable(struct netxen_adapter *adapter) { @@ -1561,6 +1587,8 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_out_disable_msi; } + netxen_read_ula_info(adapter); + err = netxen_setup_netdev(adapter, netdev); if (err) goto err_out_disable_msi; diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c index 4d7ad0074d1c..ebe4c86e5230 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c @@ -1794,3 +1794,11 @@ const struct ethtool_ops qlcnic_sriov_vf_ethtool_ops = { .set_msglevel = qlcnic_set_msglevel, .get_msglevel = qlcnic_get_msglevel, }; + +const struct ethtool_ops qlcnic_ethtool_failed_ops = { + .get_settings = qlcnic_get_settings, + .get_drvinfo = qlcnic_get_drvinfo, + .set_msglevel = qlcnic_set_msglevel, + .get_msglevel = qlcnic_get_msglevel, + .set_dump = qlcnic_set_dump, +}; diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c index f8adc7b01f1f..73e72eb83bdf 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c @@ -445,7 +445,7 @@ int qlcnic_82xx_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr, mac_req = (struct qlcnic_mac_req *)&req.words[0]; mac_req->op = op; - memcpy(mac_req->mac_addr, addr, 6); + memcpy(mac_req->mac_addr, addr, ETH_ALEN); vlan_req = (struct qlcnic_vlan_req *)&req.words[1]; vlan_req->vlan_id = cpu_to_le16(vlan_id); diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index c4c5023e1fdf..21d00a0449a1 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -431,6 +431,9 @@ static void qlcnic_82xx_cancel_idc_work(struct qlcnic_adapter *adapter) while (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) usleep_range(10000, 11000); + if (!adapter->fw_work.work.func) + return; + cancel_delayed_work_sync(&adapter->fw_work); } @@ -2275,8 +2278,9 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) adapter->portnum = adapter->ahw->pci_func; err = qlcnic_start_firmware(adapter); if (err) { - dev_err(&pdev->dev, "Loading fw failed.Please Reboot\n"); - goto err_out_free_hw; + dev_err(&pdev->dev, "Loading fw failed.Please Reboot\n" + "\t\tIf reboot doesn't help, try flashing the card\n"); + goto err_out_maintenance_mode; } qlcnic_get_multiq_capability(adapter); @@ -2408,6 +2412,22 @@ err_out_disable_pdev: pci_set_drvdata(pdev, NULL); pci_disable_device(pdev); return err; + +err_out_maintenance_mode: + netdev->netdev_ops = &qlcnic_netdev_failed_ops; + SET_ETHTOOL_OPS(netdev, &qlcnic_ethtool_failed_ops); + err = register_netdev(netdev); + + if (err) { + dev_err(&pdev->dev, "Failed to register net device\n"); + qlcnic_clr_all_drv_state(adapter, 0); + goto err_out_free_hw; + } + + pci_set_drvdata(pdev, adapter); + qlcnic_add_sysfs(adapter); + + return 0; } static void qlcnic_remove(struct pci_dev *pdev) @@ -2518,8 +2538,16 @@ static int qlcnic_resume(struct pci_dev *pdev) static int qlcnic_open(struct net_device *netdev) { struct qlcnic_adapter *adapter = netdev_priv(netdev); + u32 state; int err; + state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE); + if (state == QLCNIC_DEV_FAILED || state == QLCNIC_DEV_BADBAD) { + netdev_err(netdev, "%s: Device is in FAILED state\n", __func__); + + return -EIO; + } + netif_carrier_off(netdev); err = qlcnic_attach(adapter); @@ -3228,6 +3256,13 @@ void qlcnic_82xx_dev_request_reset(struct qlcnic_adapter *adapter, u32 key) return; state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE); + if (state == QLCNIC_DEV_FAILED || state == QLCNIC_DEV_BADBAD) { + netdev_err(adapter->netdev, "%s: Device is in FAILED state\n", + __func__); + qlcnic_api_unlock(adapter); + + return; + } if (state == QLCNIC_DEV_READY) { QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_STATE, diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c index 330d9a8774ad..686f460b1502 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c @@ -397,6 +397,7 @@ static int qlcnic_pci_sriov_disable(struct qlcnic_adapter *adapter) { struct net_device *netdev = adapter->netdev; + rtnl_lock(); if (netif_running(netdev)) __qlcnic_down(adapter, netdev); @@ -407,12 +408,15 @@ static int qlcnic_pci_sriov_disable(struct qlcnic_adapter *adapter) /* After disabling SRIOV re-init the driver in default mode configure opmode based on op_mode of function */ - if (qlcnic_83xx_configure_opmode(adapter)) + if (qlcnic_83xx_configure_opmode(adapter)) { + rtnl_unlock(); return -EIO; + } if (netif_running(netdev)) __qlcnic_up(adapter, netdev); + rtnl_unlock(); return 0; } @@ -533,6 +537,7 @@ static int qlcnic_pci_sriov_enable(struct qlcnic_adapter *adapter, int num_vfs) return -EIO; } + rtnl_lock(); if (netif_running(netdev)) __qlcnic_down(adapter, netdev); @@ -555,6 +560,7 @@ static int qlcnic_pci_sriov_enable(struct qlcnic_adapter *adapter, int num_vfs) __qlcnic_up(adapter, netdev); error: + rtnl_unlock(); return err; } diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c index c6165d05cc13..019f4377307f 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c @@ -1272,6 +1272,7 @@ void qlcnic_remove_sysfs_entries(struct qlcnic_adapter *adapter) void qlcnic_create_diag_entries(struct qlcnic_adapter *adapter) { struct device *dev = &adapter->pdev->dev; + u32 state; if (device_create_bin_file(dev, &bin_attr_port_stats)) dev_info(dev, "failed to create port stats sysfs entry"); @@ -1285,8 +1286,13 @@ void qlcnic_create_diag_entries(struct qlcnic_adapter *adapter) if (device_create_bin_file(dev, &bin_attr_mem)) dev_info(dev, "failed to create mem sysfs entry\n"); + state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE); + if (state == QLCNIC_DEV_FAILED || state == QLCNIC_DEV_BADBAD) + return; + if (device_create_bin_file(dev, &bin_attr_pci_config)) dev_info(dev, "failed to create pci config sysfs entry"); + if (device_create_file(dev, &dev_attr_beacon)) dev_info(dev, "failed to create beacon sysfs entry"); @@ -1307,6 +1313,7 @@ void qlcnic_create_diag_entries(struct qlcnic_adapter *adapter) void qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter) { struct device *dev = &adapter->pdev->dev; + u32 state; device_remove_bin_file(dev, &bin_attr_port_stats); @@ -1315,6 +1322,11 @@ void qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter) device_remove_file(dev, &dev_attr_diag_mode); device_remove_bin_file(dev, &bin_attr_crb); device_remove_bin_file(dev, &bin_attr_mem); + + state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE); + if (state == QLCNIC_DEV_FAILED || state == QLCNIC_DEV_BADBAD) + return; + device_remove_bin_file(dev, &bin_attr_pci_config); device_remove_file(dev, &dev_attr_beacon); if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) diff --git a/drivers/net/ethernet/qlogic/qlge/qlge.h b/drivers/net/ethernet/qlogic/qlge/qlge.h index 899433778466..0c9c4e895595 100644 --- a/drivers/net/ethernet/qlogic/qlge/qlge.h +++ b/drivers/net/ethernet/qlogic/qlge/qlge.h @@ -18,7 +18,7 @@ */ #define DRV_NAME "qlge" #define DRV_STRING "QLogic 10 Gigabit PCI-E Ethernet Driver " -#define DRV_VERSION "v1.00.00.32" +#define DRV_VERSION "1.00.00.33" #define WQ_ADDR_ALIGN 0x3 /* 4 byte alignment */ @@ -2206,14 +2206,14 @@ extern char qlge_driver_name[]; extern const char qlge_driver_version[]; extern const struct ethtool_ops qlge_ethtool_ops; -extern int ql_sem_spinlock(struct ql_adapter *qdev, u32 sem_mask); -extern void ql_sem_unlock(struct ql_adapter *qdev, u32 sem_mask); -extern int ql_read_xgmac_reg(struct ql_adapter *qdev, u32 reg, u32 *data); -extern int ql_get_mac_addr_reg(struct ql_adapter *qdev, u32 type, u16 index, - u32 *value); -extern int ql_get_routing_reg(struct ql_adapter *qdev, u32 index, u32 *value); -extern int ql_write_cfg(struct ql_adapter *qdev, void *ptr, int size, u32 bit, - u16 q_id); +int ql_sem_spinlock(struct ql_adapter *qdev, u32 sem_mask); +void ql_sem_unlock(struct ql_adapter *qdev, u32 sem_mask); +int ql_read_xgmac_reg(struct ql_adapter *qdev, u32 reg, u32 *data); +int ql_get_mac_addr_reg(struct ql_adapter *qdev, u32 type, u16 index, + u32 *value); +int ql_get_routing_reg(struct ql_adapter *qdev, u32 index, u32 *value); +int ql_write_cfg(struct ql_adapter *qdev, void *ptr, int size, u32 bit, + u16 q_id); void ql_queue_fw_error(struct ql_adapter *qdev); void ql_mpi_work(struct work_struct *work); void ql_mpi_reset_work(struct work_struct *work); @@ -2233,10 +2233,9 @@ int ql_unpause_mpi_risc(struct ql_adapter *qdev); int ql_pause_mpi_risc(struct ql_adapter *qdev); int ql_hard_reset_mpi_risc(struct ql_adapter *qdev); int ql_soft_reset_mpi_risc(struct ql_adapter *qdev); -int ql_dump_risc_ram_area(struct ql_adapter *qdev, void *buf, - u32 ram_addr, int word_count); -int ql_core_dump(struct ql_adapter *qdev, - struct ql_mpi_coredump *mpi_coredump); +int ql_dump_risc_ram_area(struct ql_adapter *qdev, void *buf, u32 ram_addr, + int word_count); +int ql_core_dump(struct ql_adapter *qdev, struct ql_mpi_coredump *mpi_coredump); int ql_mb_about_fw(struct ql_adapter *qdev); int ql_mb_wol_set_magic(struct ql_adapter *qdev, u32 enable_wol); int ql_mb_wol_mode(struct ql_adapter *qdev, u32 wol); @@ -2249,8 +2248,7 @@ int ql_mb_get_port_cfg(struct ql_adapter *qdev); int ql_mb_set_port_cfg(struct ql_adapter *qdev); int ql_wait_fifo_empty(struct ql_adapter *qdev); void ql_get_dump(struct ql_adapter *qdev, void *buff); -void ql_gen_reg_dump(struct ql_adapter *qdev, - struct ql_reg_dump *mpi_coredump); +void ql_gen_reg_dump(struct ql_adapter *qdev, struct ql_reg_dump *mpi_coredump); netdev_tx_t ql_lb_send(struct sk_buff *skb, struct net_device *ndev); void ql_check_lb_frame(struct ql_adapter *, struct sk_buff *); int ql_own_firmware(struct ql_adapter *qdev); @@ -2264,9 +2262,9 @@ int ql_clean_lb_rx_ring(struct rx_ring *rx_ring, int budget); /* #define QL_OB_DUMP */ #ifdef QL_REG_DUMP -extern void ql_dump_xgmac_control_regs(struct ql_adapter *qdev); -extern void ql_dump_routing_entries(struct ql_adapter *qdev); -extern void ql_dump_regs(struct ql_adapter *qdev); +void ql_dump_xgmac_control_regs(struct ql_adapter *qdev); +void ql_dump_routing_entries(struct ql_adapter *qdev); +void ql_dump_regs(struct ql_adapter *qdev); #define QL_DUMP_REGS(qdev) ql_dump_regs(qdev) #define QL_DUMP_ROUTE(qdev) ql_dump_routing_entries(qdev) #define QL_DUMP_XGMAC_CONTROL_REGS(qdev) ql_dump_xgmac_control_regs(qdev) @@ -2277,26 +2275,26 @@ extern void ql_dump_regs(struct ql_adapter *qdev); #endif #ifdef QL_STAT_DUMP -extern void ql_dump_stat(struct ql_adapter *qdev); +void ql_dump_stat(struct ql_adapter *qdev); #define QL_DUMP_STAT(qdev) ql_dump_stat(qdev) #else #define QL_DUMP_STAT(qdev) #endif #ifdef QL_DEV_DUMP -extern void ql_dump_qdev(struct ql_adapter *qdev); +void ql_dump_qdev(struct ql_adapter *qdev); #define QL_DUMP_QDEV(qdev) ql_dump_qdev(qdev) #else #define QL_DUMP_QDEV(qdev) #endif #ifdef QL_CB_DUMP -extern void ql_dump_wqicb(struct wqicb *wqicb); -extern void ql_dump_tx_ring(struct tx_ring *tx_ring); -extern void ql_dump_ricb(struct ricb *ricb); -extern void ql_dump_cqicb(struct cqicb *cqicb); -extern void ql_dump_rx_ring(struct rx_ring *rx_ring); -extern void ql_dump_hw_cb(struct ql_adapter *qdev, int size, u32 bit, u16 q_id); +void ql_dump_wqicb(struct wqicb *wqicb); +void ql_dump_tx_ring(struct tx_ring *tx_ring); +void ql_dump_ricb(struct ricb *ricb); +void ql_dump_cqicb(struct cqicb *cqicb); +void ql_dump_rx_ring(struct rx_ring *rx_ring); +void ql_dump_hw_cb(struct ql_adapter *qdev, int size, u32 bit, u16 q_id); #define QL_DUMP_RICB(ricb) ql_dump_ricb(ricb) #define QL_DUMP_WQICB(wqicb) ql_dump_wqicb(wqicb) #define QL_DUMP_TX_RING(tx_ring) ql_dump_tx_ring(tx_ring) @@ -2314,9 +2312,9 @@ extern void ql_dump_hw_cb(struct ql_adapter *qdev, int size, u32 bit, u16 q_id); #endif #ifdef QL_OB_DUMP -extern void ql_dump_tx_desc(struct tx_buf_desc *tbd); -extern void ql_dump_ob_mac_iocb(struct ob_mac_iocb_req *ob_mac_iocb); -extern void ql_dump_ob_mac_rsp(struct ob_mac_iocb_rsp *ob_mac_rsp); +void ql_dump_tx_desc(struct tx_buf_desc *tbd); +void ql_dump_ob_mac_iocb(struct ob_mac_iocb_req *ob_mac_iocb); +void ql_dump_ob_mac_rsp(struct ob_mac_iocb_rsp *ob_mac_rsp); #define QL_DUMP_OB_MAC_IOCB(ob_mac_iocb) ql_dump_ob_mac_iocb(ob_mac_iocb) #define QL_DUMP_OB_MAC_RSP(ob_mac_rsp) ql_dump_ob_mac_rsp(ob_mac_rsp) #else @@ -2325,14 +2323,14 @@ extern void ql_dump_ob_mac_rsp(struct ob_mac_iocb_rsp *ob_mac_rsp); #endif #ifdef QL_IB_DUMP -extern void ql_dump_ib_mac_rsp(struct ib_mac_iocb_rsp *ib_mac_rsp); +void ql_dump_ib_mac_rsp(struct ib_mac_iocb_rsp *ib_mac_rsp); #define QL_DUMP_IB_MAC_RSP(ib_mac_rsp) ql_dump_ib_mac_rsp(ib_mac_rsp) #else #define QL_DUMP_IB_MAC_RSP(ib_mac_rsp) #endif #ifdef QL_ALL_DUMP -extern void ql_dump_all(struct ql_adapter *qdev); +void ql_dump_all(struct ql_adapter *qdev); #define QL_DUMP_ALL(qdev) ql_dump_all(qdev) #else #define QL_DUMP_ALL(qdev) diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c b/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c index 10093f0c4c0f..6bc5db703920 100644 --- a/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c +++ b/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c @@ -740,8 +740,8 @@ int ql_core_dump(struct ql_adapter *qdev, struct ql_mpi_coredump *mpi_coredump) int i; if (!mpi_coredump) { - netif_err(qdev, drv, qdev->ndev, "No memory available\n"); - return -ENOMEM; + netif_err(qdev, drv, qdev->ndev, "No memory allocated\n"); + return -EINVAL; } /* Try to get the spinlock, but dont worry if diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/drivers/net/ethernet/qlogic/qlge/qlge_main.c index 2553cf4503b9..64f94098bc02 100644 --- a/drivers/net/ethernet/qlogic/qlge/qlge_main.c +++ b/drivers/net/ethernet/qlogic/qlge/qlge_main.c @@ -96,8 +96,10 @@ static DEFINE_PCI_DEVICE_TABLE(qlge_pci_tbl) = { MODULE_DEVICE_TABLE(pci, qlge_pci_tbl); -static int ql_wol(struct ql_adapter *qdev); -static void qlge_set_multicast_list(struct net_device *ndev); +static int ql_wol(struct ql_adapter *); +static void qlge_set_multicast_list(struct net_device *); +static int ql_adapter_down(struct ql_adapter *); +static int ql_adapter_up(struct ql_adapter *); /* This hardware semaphore causes exclusive access to * resources shared between the NIC driver, MPI firmware, @@ -1464,6 +1466,29 @@ static void ql_categorize_rx_err(struct ql_adapter *qdev, u8 rx_err, } } +/** + * ql_update_mac_hdr_len - helper routine to update the mac header length + * based on vlan tags if present + */ +static void ql_update_mac_hdr_len(struct ql_adapter *qdev, + struct ib_mac_iocb_rsp *ib_mac_rsp, + void *page, size_t *len) +{ + u16 *tags; + + if (qdev->ndev->features & NETIF_F_HW_VLAN_CTAG_RX) + return; + if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_V) { + tags = (u16 *)page; + /* Look for stacked vlan tags in ethertype field */ + if (tags[6] == ETH_P_8021Q && + tags[8] == ETH_P_8021Q) + *len += 2 * VLAN_HLEN; + else + *len += VLAN_HLEN; + } +} + /* Process an inbound completion from an rx ring. */ static void ql_process_mac_rx_gro_page(struct ql_adapter *qdev, struct rx_ring *rx_ring, @@ -1523,6 +1548,7 @@ static void ql_process_mac_rx_page(struct ql_adapter *qdev, void *addr; struct bq_desc *lbq_desc = ql_get_curr_lchunk(qdev, rx_ring); struct napi_struct *napi = &rx_ring->napi; + size_t hlen = ETH_HLEN; skb = netdev_alloc_skb(ndev, length); if (!skb) { @@ -1540,25 +1566,28 @@ static void ql_process_mac_rx_page(struct ql_adapter *qdev, goto err_out; } + /* Update the MAC header length*/ + ql_update_mac_hdr_len(qdev, ib_mac_rsp, addr, &hlen); + /* The max framesize filter on this chip is set higher than * MTU since FCoE uses 2k frames. */ - if (skb->len > ndev->mtu + ETH_HLEN) { + if (skb->len > ndev->mtu + hlen) { netif_err(qdev, drv, qdev->ndev, "Segment too small, dropping.\n"); rx_ring->rx_dropped++; goto err_out; } - memcpy(skb_put(skb, ETH_HLEN), addr, ETH_HLEN); + memcpy(skb_put(skb, hlen), addr, hlen); netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev, "%d bytes of headers and data in large. Chain page to new skb and pull tail.\n", length); skb_fill_page_desc(skb, 0, lbq_desc->p.pg_chunk.page, - lbq_desc->p.pg_chunk.offset+ETH_HLEN, - length-ETH_HLEN); - skb->len += length-ETH_HLEN; - skb->data_len += length-ETH_HLEN; - skb->truesize += length-ETH_HLEN; + lbq_desc->p.pg_chunk.offset + hlen, + length - hlen); + skb->len += length - hlen; + skb->data_len += length - hlen; + skb->truesize += length - hlen; rx_ring->rx_packets++; rx_ring->rx_bytes += skb->len; @@ -1576,7 +1605,7 @@ static void ql_process_mac_rx_page(struct ql_adapter *qdev, (ib_mac_rsp->flags3 & IB_MAC_IOCB_RSP_V4)) { /* Unfragmented ipv4 UDP frame. */ struct iphdr *iph = - (struct iphdr *) ((u8 *)addr + ETH_HLEN); + (struct iphdr *)((u8 *)addr + hlen); if (!(iph->frag_off & htons(IP_MF|IP_OFFSET))) { skb->ip_summed = CHECKSUM_UNNECESSARY; @@ -1726,7 +1755,8 @@ static struct sk_buff *ql_build_rx_skb(struct ql_adapter *qdev, struct bq_desc *sbq_desc; struct sk_buff *skb = NULL; u32 length = le32_to_cpu(ib_mac_rsp->data_len); - u32 hdr_len = le32_to_cpu(ib_mac_rsp->hdr_len); + u32 hdr_len = le32_to_cpu(ib_mac_rsp->hdr_len); + size_t hlen = ETH_HLEN; /* * Handle the header buffer if present. @@ -1853,9 +1883,10 @@ static struct sk_buff *ql_build_rx_skb(struct ql_adapter *qdev, skb->data_len += length; skb->truesize += length; length -= length; - __pskb_pull_tail(skb, - (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_V) ? - VLAN_ETH_HLEN : ETH_HLEN); + ql_update_mac_hdr_len(qdev, ib_mac_rsp, + lbq_desc->p.pg_chunk.va, + &hlen); + __pskb_pull_tail(skb, hlen); } } else { /* @@ -1910,8 +1941,9 @@ static struct sk_buff *ql_build_rx_skb(struct ql_adapter *qdev, length -= size; i++; } - __pskb_pull_tail(skb, (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_V) ? - VLAN_ETH_HLEN : ETH_HLEN); + ql_update_mac_hdr_len(qdev, ib_mac_rsp, lbq_desc->p.pg_chunk.va, + &hlen); + __pskb_pull_tail(skb, hlen); } return skb; } @@ -2003,7 +2035,7 @@ static void ql_process_mac_split_rx_intr(struct ql_adapter *qdev, rx_ring->rx_packets++; rx_ring->rx_bytes += skb->len; skb_record_rx_queue(skb, rx_ring->cq_id); - if ((ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_V) && (vlan_id != 0)) + if (vlan_id != 0xffff) __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan_id); if (skb->ip_summed == CHECKSUM_UNNECESSARY) napi_gro_receive(&rx_ring->napi, skb); @@ -2017,7 +2049,8 @@ static unsigned long ql_process_mac_rx_intr(struct ql_adapter *qdev, struct ib_mac_iocb_rsp *ib_mac_rsp) { u32 length = le32_to_cpu(ib_mac_rsp->data_len); - u16 vlan_id = (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_V) ? + u16 vlan_id = ((ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_V) && + (qdev->ndev->features & NETIF_F_HW_VLAN_CTAG_RX)) ? ((le16_to_cpu(ib_mac_rsp->vlan_id) & IB_MAC_IOCB_RSP_VLAN_MASK)) : 0xffff; @@ -2310,9 +2343,39 @@ static void qlge_vlan_mode(struct net_device *ndev, netdev_features_t features) } } +/** + * qlge_update_hw_vlan_features - helper routine to reinitialize the adapter + * based on the features to enable/disable hardware vlan accel + */ +static int qlge_update_hw_vlan_features(struct net_device *ndev, + netdev_features_t features) +{ + struct ql_adapter *qdev = netdev_priv(ndev); + int status = 0; + + status = ql_adapter_down(qdev); + if (status) { + netif_err(qdev, link, qdev->ndev, + "Failed to bring down the adapter\n"); + return status; + } + + /* update the features with resent change */ + ndev->features = features; + + status = ql_adapter_up(qdev); + if (status) { + netif_err(qdev, link, qdev->ndev, + "Failed to bring up the adapter\n"); + return status; + } + return status; +} + static netdev_features_t qlge_fix_features(struct net_device *ndev, netdev_features_t features) { + int err; /* * Since there is no support for separate rx/tx vlan accel * enable/disable make sure tx flag is always in same state as rx. @@ -2322,6 +2385,11 @@ static netdev_features_t qlge_fix_features(struct net_device *ndev, else features &= ~NETIF_F_HW_VLAN_CTAG_TX; + /* Update the behavior of vlan accel in the adapter */ + err = qlge_update_hw_vlan_features(ndev, features); + if (err) + return err; + return features; } @@ -3704,8 +3772,12 @@ static int ql_adapter_initialize(struct ql_adapter *qdev) ql_write32(qdev, SYS, mask | value); /* Set the default queue, and VLAN behavior. */ - value = NIC_RCV_CFG_DFQ | NIC_RCV_CFG_RV; - mask = NIC_RCV_CFG_DFQ_MASK | (NIC_RCV_CFG_RV << 16); + value = NIC_RCV_CFG_DFQ; + mask = NIC_RCV_CFG_DFQ_MASK; + if (qdev->ndev->features & NETIF_F_HW_VLAN_CTAG_RX) { + value |= NIC_RCV_CFG_RV; + mask |= (NIC_RCV_CFG_RV << 16); + } ql_write32(qdev, NIC_RCV_CFG, (mask | value)); /* Set the MPI interrupt to enabled. */ @@ -4692,11 +4764,15 @@ static int qlge_probe(struct pci_dev *pdev, qdev = netdev_priv(ndev); SET_NETDEV_DEV(ndev, &pdev->dev); - ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | - NETIF_F_TSO | NETIF_F_TSO_ECN | - NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_RXCSUM; - ndev->features = ndev->hw_features | - NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_FILTER; + ndev->hw_features = NETIF_F_SG | + NETIF_F_IP_CSUM | + NETIF_F_TSO | + NETIF_F_TSO_ECN | + NETIF_F_HW_VLAN_CTAG_TX | + NETIF_F_HW_VLAN_CTAG_RX | + NETIF_F_HW_VLAN_CTAG_FILTER | + NETIF_F_RXCSUM; + ndev->features = ndev->hw_features; ndev->vlan_features = ndev->hw_features; if (test_bit(QL_DMA64, &qdev->flags)) diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_mpi.c b/drivers/net/ethernet/qlogic/qlge/qlge_mpi.c index ff2bf8a4e247..7ad146080c36 100644 --- a/drivers/net/ethernet/qlogic/qlge/qlge_mpi.c +++ b/drivers/net/ethernet/qlogic/qlge/qlge_mpi.c @@ -1274,7 +1274,7 @@ void ql_mpi_reset_work(struct work_struct *work) return; } - if (!ql_core_dump(qdev, qdev->mpi_coredump)) { + if (qdev->mpi_coredump && !ql_core_dump(qdev, qdev->mpi_coredump)) { netif_err(qdev, drv, qdev->ndev, "Core is dumped!\n"); qdev->core_is_dumped = 1; queue_delayed_work(qdev->workqueue, diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 5cd831ebfa83..c8df52bac162 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -868,7 +868,7 @@ static void update_mac_address(struct net_device *ndev) static void read_mac_address(struct net_device *ndev, unsigned char *mac) { if (mac[0] || mac[1] || mac[2] || mac[3] || mac[4] || mac[5]) { - memcpy(ndev->dev_addr, mac, 6); + memcpy(ndev->dev_addr, mac, ETH_ALEN); } else { ndev->dev_addr[0] = (sh_eth_read(ndev, MAHR) >> 24); ndev->dev_addr[1] = (sh_eth_read(ndev, MAHR) >> 16) & 0xFF; diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c index 9f18ae984f9e..844ee7539d33 100644 --- a/drivers/net/ethernet/sfc/ef10.c +++ b/drivers/net/ethernet/sfc/ef10.c @@ -285,6 +285,181 @@ static int efx_ef10_free_vis(struct efx_nic *efx) return rc; } +#ifdef EFX_USE_PIO + +static void efx_ef10_free_piobufs(struct efx_nic *efx) +{ + struct efx_ef10_nic_data *nic_data = efx->nic_data; + MCDI_DECLARE_BUF(inbuf, MC_CMD_FREE_PIOBUF_IN_LEN); + unsigned int i; + int rc; + + BUILD_BUG_ON(MC_CMD_FREE_PIOBUF_OUT_LEN != 0); + + for (i = 0; i < nic_data->n_piobufs; i++) { + MCDI_SET_DWORD(inbuf, FREE_PIOBUF_IN_PIOBUF_HANDLE, + nic_data->piobuf_handle[i]); + rc = efx_mcdi_rpc(efx, MC_CMD_FREE_PIOBUF, inbuf, sizeof(inbuf), + NULL, 0, NULL); + WARN_ON(rc); + } + + nic_data->n_piobufs = 0; +} + +static int efx_ef10_alloc_piobufs(struct efx_nic *efx, unsigned int n) +{ + struct efx_ef10_nic_data *nic_data = efx->nic_data; + MCDI_DECLARE_BUF(outbuf, MC_CMD_ALLOC_PIOBUF_OUT_LEN); + unsigned int i; + size_t outlen; + int rc = 0; + + BUILD_BUG_ON(MC_CMD_ALLOC_PIOBUF_IN_LEN != 0); + + for (i = 0; i < n; i++) { + rc = efx_mcdi_rpc(efx, MC_CMD_ALLOC_PIOBUF, NULL, 0, + outbuf, sizeof(outbuf), &outlen); + if (rc) + break; + if (outlen < MC_CMD_ALLOC_PIOBUF_OUT_LEN) { + rc = -EIO; + break; + } + nic_data->piobuf_handle[i] = + MCDI_DWORD(outbuf, ALLOC_PIOBUF_OUT_PIOBUF_HANDLE); + netif_dbg(efx, probe, efx->net_dev, + "allocated PIO buffer %u handle %x\n", i, + nic_data->piobuf_handle[i]); + } + + nic_data->n_piobufs = i; + if (rc) + efx_ef10_free_piobufs(efx); + return rc; +} + +static int efx_ef10_link_piobufs(struct efx_nic *efx) +{ + struct efx_ef10_nic_data *nic_data = efx->nic_data; + MCDI_DECLARE_BUF(inbuf, + max(MC_CMD_LINK_PIOBUF_IN_LEN, + MC_CMD_UNLINK_PIOBUF_IN_LEN)); + struct efx_channel *channel; + struct efx_tx_queue *tx_queue; + unsigned int offset, index; + int rc; + + BUILD_BUG_ON(MC_CMD_LINK_PIOBUF_OUT_LEN != 0); + BUILD_BUG_ON(MC_CMD_UNLINK_PIOBUF_OUT_LEN != 0); + + /* Link a buffer to each VI in the write-combining mapping */ + for (index = 0; index < nic_data->n_piobufs; ++index) { + MCDI_SET_DWORD(inbuf, LINK_PIOBUF_IN_PIOBUF_HANDLE, + nic_data->piobuf_handle[index]); + MCDI_SET_DWORD(inbuf, LINK_PIOBUF_IN_TXQ_INSTANCE, + nic_data->pio_write_vi_base + index); + rc = efx_mcdi_rpc(efx, MC_CMD_LINK_PIOBUF, + inbuf, MC_CMD_LINK_PIOBUF_IN_LEN, + NULL, 0, NULL); + if (rc) { + netif_err(efx, drv, efx->net_dev, + "failed to link VI %u to PIO buffer %u (%d)\n", + nic_data->pio_write_vi_base + index, index, + rc); + goto fail; + } + netif_dbg(efx, probe, efx->net_dev, + "linked VI %u to PIO buffer %u\n", + nic_data->pio_write_vi_base + index, index); + } + + /* Link a buffer to each TX queue */ + efx_for_each_channel(channel, efx) { + efx_for_each_channel_tx_queue(tx_queue, channel) { + /* We assign the PIO buffers to queues in + * reverse order to allow for the following + * special case. + */ + offset = ((efx->tx_channel_offset + efx->n_tx_channels - + tx_queue->channel->channel - 1) * + efx_piobuf_size); + index = offset / ER_DZ_TX_PIOBUF_SIZE; + offset = offset % ER_DZ_TX_PIOBUF_SIZE; + + /* When the host page size is 4K, the first + * host page in the WC mapping may be within + * the same VI page as the last TX queue. We + * can only link one buffer to each VI. + */ + if (tx_queue->queue == nic_data->pio_write_vi_base) { + BUG_ON(index != 0); + rc = 0; + } else { + MCDI_SET_DWORD(inbuf, + LINK_PIOBUF_IN_PIOBUF_HANDLE, + nic_data->piobuf_handle[index]); + MCDI_SET_DWORD(inbuf, + LINK_PIOBUF_IN_TXQ_INSTANCE, + tx_queue->queue); + rc = efx_mcdi_rpc(efx, MC_CMD_LINK_PIOBUF, + inbuf, MC_CMD_LINK_PIOBUF_IN_LEN, + NULL, 0, NULL); + } + + if (rc) { + /* This is non-fatal; the TX path just + * won't use PIO for this queue + */ + netif_err(efx, drv, efx->net_dev, + "failed to link VI %u to PIO buffer %u (%d)\n", + tx_queue->queue, index, rc); + tx_queue->piobuf = NULL; + } else { + tx_queue->piobuf = + nic_data->pio_write_base + + index * EFX_VI_PAGE_SIZE + offset; + tx_queue->piobuf_offset = offset; + netif_dbg(efx, probe, efx->net_dev, + "linked VI %u to PIO buffer %u offset %x addr %p\n", + tx_queue->queue, index, + tx_queue->piobuf_offset, + tx_queue->piobuf); + } + } + } + + return 0; + +fail: + while (index--) { + MCDI_SET_DWORD(inbuf, UNLINK_PIOBUF_IN_TXQ_INSTANCE, + nic_data->pio_write_vi_base + index); + efx_mcdi_rpc(efx, MC_CMD_UNLINK_PIOBUF, + inbuf, MC_CMD_UNLINK_PIOBUF_IN_LEN, + NULL, 0, NULL); + } + return rc; +} + +#else /* !EFX_USE_PIO */ + +static int efx_ef10_alloc_piobufs(struct efx_nic *efx, unsigned int n) +{ + return n == 0 ? 0 : -ENOBUFS; +} + +static int efx_ef10_link_piobufs(struct efx_nic *efx) +{ + return 0; +} + +static void efx_ef10_free_piobufs(struct efx_nic *efx) +{ +} + +#endif /* EFX_USE_PIO */ + static void efx_ef10_remove(struct efx_nic *efx) { struct efx_ef10_nic_data *nic_data = efx->nic_data; @@ -295,9 +470,15 @@ static void efx_ef10_remove(struct efx_nic *efx) /* This needs to be after efx_ptp_remove_channel() with no filters */ efx_ef10_rx_free_indir_table(efx); + if (nic_data->wc_membase) + iounmap(nic_data->wc_membase); + rc = efx_ef10_free_vis(efx); WARN_ON(rc != 0); + if (!nic_data->must_restore_piobufs) + efx_ef10_free_piobufs(efx); + efx_mcdi_fini(efx); efx_nic_free_buffer(efx, &nic_data->mcdi_buf); kfree(nic_data); @@ -330,12 +511,126 @@ static int efx_ef10_alloc_vis(struct efx_nic *efx, return 0; } +/* Note that the failure path of this function does not free + * resources, as this will be done by efx_ef10_remove(). + */ static int efx_ef10_dimension_resources(struct efx_nic *efx) { - unsigned int n_vis = - max(efx->n_channels, efx->n_tx_channels * EFX_TXQ_TYPES); + struct efx_ef10_nic_data *nic_data = efx->nic_data; + unsigned int uc_mem_map_size, wc_mem_map_size; + unsigned int min_vis, pio_write_vi_base, max_vis; + void __iomem *membase; + int rc; + + min_vis = max(efx->n_channels, efx->n_tx_channels * EFX_TXQ_TYPES); + +#ifdef EFX_USE_PIO + /* Try to allocate PIO buffers if wanted and if the full + * number of PIO buffers would be sufficient to allocate one + * copy-buffer per TX channel. Failure is non-fatal, as there + * are only a small number of PIO buffers shared between all + * functions of the controller. + */ + if (efx_piobuf_size != 0 && + ER_DZ_TX_PIOBUF_SIZE / efx_piobuf_size * EF10_TX_PIOBUF_COUNT >= + efx->n_tx_channels) { + unsigned int n_piobufs = + DIV_ROUND_UP(efx->n_tx_channels, + ER_DZ_TX_PIOBUF_SIZE / efx_piobuf_size); + + rc = efx_ef10_alloc_piobufs(efx, n_piobufs); + if (rc) + netif_err(efx, probe, efx->net_dev, + "failed to allocate PIO buffers (%d)\n", rc); + else + netif_dbg(efx, probe, efx->net_dev, + "allocated %u PIO buffers\n", n_piobufs); + } +#else + nic_data->n_piobufs = 0; +#endif - return efx_ef10_alloc_vis(efx, n_vis, n_vis); + /* PIO buffers should be mapped with write-combining enabled, + * and we want to make single UC and WC mappings rather than + * several of each (in fact that's the only option if host + * page size is >4K). So we may allocate some extra VIs just + * for writing PIO buffers through. + */ + uc_mem_map_size = PAGE_ALIGN((min_vis - 1) * EFX_VI_PAGE_SIZE + + ER_DZ_TX_PIOBUF); + if (nic_data->n_piobufs) { + pio_write_vi_base = uc_mem_map_size / EFX_VI_PAGE_SIZE; + wc_mem_map_size = (PAGE_ALIGN((pio_write_vi_base + + nic_data->n_piobufs) * + EFX_VI_PAGE_SIZE) - + uc_mem_map_size); + max_vis = pio_write_vi_base + nic_data->n_piobufs; + } else { + pio_write_vi_base = 0; + wc_mem_map_size = 0; + max_vis = min_vis; + } + + /* In case the last attached driver failed to free VIs, do it now */ + rc = efx_ef10_free_vis(efx); + if (rc != 0) + return rc; + + rc = efx_ef10_alloc_vis(efx, min_vis, max_vis); + if (rc != 0) + return rc; + + /* If we didn't get enough VIs to map all the PIO buffers, free the + * PIO buffers + */ + if (nic_data->n_piobufs && + nic_data->n_allocated_vis < + pio_write_vi_base + nic_data->n_piobufs) { + netif_dbg(efx, probe, efx->net_dev, + "%u VIs are not sufficient to map %u PIO buffers\n", + nic_data->n_allocated_vis, nic_data->n_piobufs); + efx_ef10_free_piobufs(efx); + } + + /* Shrink the original UC mapping of the memory BAR */ + membase = ioremap_nocache(efx->membase_phys, uc_mem_map_size); + if (!membase) { + netif_err(efx, probe, efx->net_dev, + "could not shrink memory BAR to %x\n", + uc_mem_map_size); + return -ENOMEM; + } + iounmap(efx->membase); + efx->membase = membase; + + /* Set up the WC mapping if needed */ + if (wc_mem_map_size) { + nic_data->wc_membase = ioremap_wc(efx->membase_phys + + uc_mem_map_size, + wc_mem_map_size); + if (!nic_data->wc_membase) { + netif_err(efx, probe, efx->net_dev, + "could not allocate WC mapping of size %x\n", + wc_mem_map_size); + return -ENOMEM; + } + nic_data->pio_write_vi_base = pio_write_vi_base; + nic_data->pio_write_base = + nic_data->wc_membase + + (pio_write_vi_base * EFX_VI_PAGE_SIZE + ER_DZ_TX_PIOBUF - + uc_mem_map_size); + + rc = efx_ef10_link_piobufs(efx); + if (rc) + efx_ef10_free_piobufs(efx); + } + + netif_dbg(efx, probe, efx->net_dev, + "memory BAR at %pa (virtual %p+%x UC, %p+%x WC)\n", + &efx->membase_phys, efx->membase, uc_mem_map_size, + nic_data->wc_membase, wc_mem_map_size); + + return 0; } static int efx_ef10_init_nic(struct efx_nic *efx) @@ -359,6 +654,21 @@ static int efx_ef10_init_nic(struct efx_nic *efx) nic_data->must_realloc_vis = false; } + if (nic_data->must_restore_piobufs && nic_data->n_piobufs) { + rc = efx_ef10_alloc_piobufs(efx, nic_data->n_piobufs); + if (rc == 0) { + rc = efx_ef10_link_piobufs(efx); + if (rc) + efx_ef10_free_piobufs(efx); + } + + /* Log an error on failure, but this is non-fatal */ + if (rc) + netif_err(efx, drv, efx->net_dev, + "failed to restore PIO buffers (%d)\n", rc); + nic_data->must_restore_piobufs = false; + } + efx_ef10_rx_push_indir_table(efx); return 0; } @@ -716,6 +1026,7 @@ static int efx_ef10_mcdi_poll_reboot(struct efx_nic *efx) /* All our allocations have been reset */ nic_data->must_realloc_vis = true; nic_data->must_restore_filters = true; + nic_data->must_restore_piobufs = true; nic_data->rx_rss_context = EFX_EF10_RSS_CONTEXT_INVALID; /* The datapath firmware might have been changed */ @@ -2137,7 +2448,7 @@ out_unlock: return rc; } -void efx_ef10_filter_update_rx_scatter(struct efx_nic *efx) +static void efx_ef10_filter_update_rx_scatter(struct efx_nic *efx) { /* no need to do anything here on EF10 */ } diff --git a/drivers/net/ethernet/sfc/ef10_regs.h b/drivers/net/ethernet/sfc/ef10_regs.h index b3f4e3755fd9..207ac9a1e3de 100644 --- a/drivers/net/ethernet/sfc/ef10_regs.h +++ b/drivers/net/ethernet/sfc/ef10_regs.h @@ -315,6 +315,7 @@ #define ESF_DZ_TX_PIO_TYPE_WIDTH 1 #define ESF_DZ_TX_PIO_OPT_LBN 60 #define ESF_DZ_TX_PIO_OPT_WIDTH 3 +#define ESE_DZ_TX_OPTION_DESC_PIO 1 #define ESF_DZ_TX_PIO_CONT_LBN 59 #define ESF_DZ_TX_PIO_CONT_WIDTH 1 #define ESF_DZ_TX_PIO_BYTE_CNT_LBN 32 diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h index 34d00f5771fe..b8235ee5d7d7 100644 --- a/drivers/net/ethernet/sfc/efx.h +++ b/drivers/net/ethernet/sfc/efx.h @@ -18,37 +18,36 @@ #define EFX_MEM_BAR 2 /* TX */ -extern int efx_probe_tx_queue(struct efx_tx_queue *tx_queue); -extern void efx_remove_tx_queue(struct efx_tx_queue *tx_queue); -extern void efx_init_tx_queue(struct efx_tx_queue *tx_queue); -extern void efx_init_tx_queue_core_txq(struct efx_tx_queue *tx_queue); -extern void efx_fini_tx_queue(struct efx_tx_queue *tx_queue); -extern netdev_tx_t -efx_hard_start_xmit(struct sk_buff *skb, struct net_device *net_dev); -extern netdev_tx_t -efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb); -extern void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index); -extern int efx_setup_tc(struct net_device *net_dev, u8 num_tc); -extern unsigned int efx_tx_max_skb_descs(struct efx_nic *efx); +int efx_probe_tx_queue(struct efx_tx_queue *tx_queue); +void efx_remove_tx_queue(struct efx_tx_queue *tx_queue); +void efx_init_tx_queue(struct efx_tx_queue *tx_queue); +void efx_init_tx_queue_core_txq(struct efx_tx_queue *tx_queue); +void efx_fini_tx_queue(struct efx_tx_queue *tx_queue); +netdev_tx_t efx_hard_start_xmit(struct sk_buff *skb, + struct net_device *net_dev); +netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb); +void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index); +int efx_setup_tc(struct net_device *net_dev, u8 num_tc); +unsigned int efx_tx_max_skb_descs(struct efx_nic *efx); +extern unsigned int efx_piobuf_size; /* RX */ -extern void efx_rx_config_page_split(struct efx_nic *efx); -extern int efx_probe_rx_queue(struct efx_rx_queue *rx_queue); -extern void efx_remove_rx_queue(struct efx_rx_queue *rx_queue); -extern void efx_init_rx_queue(struct efx_rx_queue *rx_queue); -extern void efx_fini_rx_queue(struct efx_rx_queue *rx_queue); -extern void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue); -extern void efx_rx_slow_fill(unsigned long context); -extern void __efx_rx_packet(struct efx_channel *channel); -extern void efx_rx_packet(struct efx_rx_queue *rx_queue, - unsigned int index, unsigned int n_frags, - unsigned int len, u16 flags); +void efx_rx_config_page_split(struct efx_nic *efx); +int efx_probe_rx_queue(struct efx_rx_queue *rx_queue); +void efx_remove_rx_queue(struct efx_rx_queue *rx_queue); +void efx_init_rx_queue(struct efx_rx_queue *rx_queue); +void efx_fini_rx_queue(struct efx_rx_queue *rx_queue); +void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue); +void efx_rx_slow_fill(unsigned long context); +void __efx_rx_packet(struct efx_channel *channel); +void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, + unsigned int n_frags, unsigned int len, u16 flags); static inline void efx_rx_flush_packet(struct efx_channel *channel) { if (channel->rx_pkt_n_frags) __efx_rx_packet(channel); } -extern void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue); +void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue); #define EFX_MAX_DMAQ_SIZE 4096UL #define EFX_DEFAULT_DMAQ_SIZE 1024UL @@ -162,9 +161,9 @@ static inline s32 efx_filter_get_rx_ids(struct efx_nic *efx, return efx->type->filter_get_rx_ids(efx, priority, buf, size); } #ifdef CONFIG_RFS_ACCEL -extern int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb, - u16 rxq_index, u32 flow_id); -extern bool __efx_filter_rfs_expire(struct efx_nic *efx, unsigned quota); +int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb, + u16 rxq_index, u32 flow_id); +bool __efx_filter_rfs_expire(struct efx_nic *efx, unsigned quota); static inline void efx_filter_rfs_expire(struct efx_channel *channel) { if (channel->rfs_filters_added >= 60 && @@ -176,50 +175,48 @@ static inline void efx_filter_rfs_expire(struct efx_channel *channel) static inline void efx_filter_rfs_expire(struct efx_channel *channel) {} #define efx_filter_rfs_enabled() 0 #endif -extern bool efx_filter_is_mc_recipient(const struct efx_filter_spec *spec); +bool efx_filter_is_mc_recipient(const struct efx_filter_spec *spec); /* Channels */ -extern int efx_channel_dummy_op_int(struct efx_channel *channel); -extern void efx_channel_dummy_op_void(struct efx_channel *channel); -extern int -efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries); +int efx_channel_dummy_op_int(struct efx_channel *channel); +void efx_channel_dummy_op_void(struct efx_channel *channel); +int efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries); /* Ports */ -extern int efx_reconfigure_port(struct efx_nic *efx); -extern int __efx_reconfigure_port(struct efx_nic *efx); +int efx_reconfigure_port(struct efx_nic *efx); +int __efx_reconfigure_port(struct efx_nic *efx); /* Ethtool support */ extern const struct ethtool_ops efx_ethtool_ops; /* Reset handling */ -extern int efx_reset(struct efx_nic *efx, enum reset_type method); -extern void efx_reset_down(struct efx_nic *efx, enum reset_type method); -extern int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok); -extern int efx_try_recovery(struct efx_nic *efx); +int efx_reset(struct efx_nic *efx, enum reset_type method); +void efx_reset_down(struct efx_nic *efx, enum reset_type method); +int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok); +int efx_try_recovery(struct efx_nic *efx); /* Global */ -extern void efx_schedule_reset(struct efx_nic *efx, enum reset_type type); -extern int efx_init_irq_moderation(struct efx_nic *efx, unsigned int tx_usecs, - unsigned int rx_usecs, bool rx_adaptive, - bool rx_may_override_tx); -extern void efx_get_irq_moderation(struct efx_nic *efx, unsigned int *tx_usecs, - unsigned int *rx_usecs, bool *rx_adaptive); +void efx_schedule_reset(struct efx_nic *efx, enum reset_type type); +int efx_init_irq_moderation(struct efx_nic *efx, unsigned int tx_usecs, + unsigned int rx_usecs, bool rx_adaptive, + bool rx_may_override_tx); +void efx_get_irq_moderation(struct efx_nic *efx, unsigned int *tx_usecs, + unsigned int *rx_usecs, bool *rx_adaptive); /* Dummy PHY ops for PHY drivers */ -extern int efx_port_dummy_op_int(struct efx_nic *efx); -extern void efx_port_dummy_op_void(struct efx_nic *efx); - +int efx_port_dummy_op_int(struct efx_nic *efx); +void efx_port_dummy_op_void(struct efx_nic *efx); /* MTD */ #ifdef CONFIG_SFC_MTD -extern int efx_mtd_add(struct efx_nic *efx, struct efx_mtd_partition *parts, - size_t n_parts, size_t sizeof_part); +int efx_mtd_add(struct efx_nic *efx, struct efx_mtd_partition *parts, + size_t n_parts, size_t sizeof_part); static inline int efx_mtd_probe(struct efx_nic *efx) { return efx->type->mtd_probe(efx); } -extern void efx_mtd_rename(struct efx_nic *efx); -extern void efx_mtd_remove(struct efx_nic *efx); +void efx_mtd_rename(struct efx_nic *efx); +void efx_mtd_remove(struct efx_nic *efx); #else static inline int efx_mtd_probe(struct efx_nic *efx) { return 0; } static inline void efx_mtd_rename(struct efx_nic *efx) {} @@ -241,9 +238,9 @@ static inline void efx_schedule_channel_irq(struct efx_channel *channel) efx_schedule_channel(channel); } -extern void efx_link_status_changed(struct efx_nic *efx); -extern void efx_link_set_advertising(struct efx_nic *efx, u32); -extern void efx_link_set_wanted_fc(struct efx_nic *efx, u8); +void efx_link_status_changed(struct efx_nic *efx); +void efx_link_set_advertising(struct efx_nic *efx, u32); +void efx_link_set_wanted_fc(struct efx_nic *efx, u8); static inline void efx_device_detach_sync(struct efx_nic *efx) { diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c index 5b471cf5c323..1f529fa2edb1 100644 --- a/drivers/net/ethernet/sfc/ethtool.c +++ b/drivers/net/ethernet/sfc/ethtool.c @@ -70,6 +70,7 @@ static const struct efx_sw_stat_desc efx_sw_stat_desc[] = { EFX_ETHTOOL_UINT_TXQ_STAT(tso_long_headers), EFX_ETHTOOL_UINT_TXQ_STAT(tso_packets), EFX_ETHTOOL_UINT_TXQ_STAT(pushes), + EFX_ETHTOOL_UINT_TXQ_STAT(pio_packets), EFX_ETHTOOL_ATOMIC_NIC_ERROR_STAT(rx_reset), EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_tobe_disc), EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_ip_hdr_chksum_err), @@ -1035,8 +1036,8 @@ static int efx_ethtool_set_rxfh_indir(struct net_device *net_dev, return 0; } -int efx_ethtool_get_ts_info(struct net_device *net_dev, - struct ethtool_ts_info *ts_info) +static int efx_ethtool_get_ts_info(struct net_device *net_dev, + struct ethtool_ts_info *ts_info) { struct efx_nic *efx = netdev_priv(net_dev); diff --git a/drivers/net/ethernet/sfc/io.h b/drivers/net/ethernet/sfc/io.h index 96ce507d8602..4d3f119b67b3 100644 --- a/drivers/net/ethernet/sfc/io.h +++ b/drivers/net/ethernet/sfc/io.h @@ -66,6 +66,11 @@ #define EFX_USE_QWORD_IO 1 #endif +/* PIO is a win only if write-combining is possible */ +#ifdef ARCH_HAS_IOREMAP_WC +#define EFX_USE_PIO 1 +#endif + #ifdef EFX_USE_QWORD_IO static inline void _efx_writeq(struct efx_nic *efx, __le64 value, unsigned int reg) diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c index 128d7cdf9eb2..c082562dbf4e 100644 --- a/drivers/net/ethernet/sfc/mcdi.c +++ b/drivers/net/ethernet/sfc/mcdi.c @@ -27,10 +27,10 @@ /* A reboot/assertion causes the MCDI status word to be set after the * command word is set or a REBOOT event is sent. If we notice a reboot - * via these mechanisms then wait 20ms for the status word to be set. + * via these mechanisms then wait 250ms for the status word to be set. */ #define MCDI_STATUS_DELAY_US 100 -#define MCDI_STATUS_DELAY_COUNT 200 +#define MCDI_STATUS_DELAY_COUNT 2500 #define MCDI_STATUS_SLEEP_MS \ (MCDI_STATUS_DELAY_US * MCDI_STATUS_DELAY_COUNT / 1000) @@ -800,9 +800,6 @@ static void efx_mcdi_ev_death(struct efx_nic *efx, int rc) } else { int count; - /* Nobody was waiting for an MCDI request, so trigger a reset */ - efx_schedule_reset(efx, RESET_TYPE_MC_FAILURE); - /* Consume the status word since efx_mcdi_rpc_finish() won't */ for (count = 0; count < MCDI_STATUS_DELAY_COUNT; ++count) { if (efx_mcdi_poll_reboot(efx)) @@ -810,6 +807,9 @@ static void efx_mcdi_ev_death(struct efx_nic *efx, int rc) udelay(MCDI_STATUS_DELAY_US); } mcdi->new_epoch = true; + + /* Nobody was waiting for an MCDI request, so trigger a reset */ + efx_schedule_reset(efx, RESET_TYPE_MC_FAILURE); } spin_unlock(&mcdi->iface_lock); diff --git a/drivers/net/ethernet/sfc/mcdi.h b/drivers/net/ethernet/sfc/mcdi.h index c34d0d4e10ee..656a3277c2b2 100644 --- a/drivers/net/ethernet/sfc/mcdi.h +++ b/drivers/net/ethernet/sfc/mcdi.h @@ -108,38 +108,35 @@ static inline struct efx_mcdi_mon *efx_mcdi_mon(struct efx_nic *efx) } #endif -extern int efx_mcdi_init(struct efx_nic *efx); -extern void efx_mcdi_fini(struct efx_nic *efx); +int efx_mcdi_init(struct efx_nic *efx); +void efx_mcdi_fini(struct efx_nic *efx); -extern int efx_mcdi_rpc(struct efx_nic *efx, unsigned cmd, - const efx_dword_t *inbuf, size_t inlen, +int efx_mcdi_rpc(struct efx_nic *efx, unsigned cmd, const efx_dword_t *inbuf, + size_t inlen, efx_dword_t *outbuf, size_t outlen, + size_t *outlen_actual); + +int efx_mcdi_rpc_start(struct efx_nic *efx, unsigned cmd, + const efx_dword_t *inbuf, size_t inlen); +int efx_mcdi_rpc_finish(struct efx_nic *efx, unsigned cmd, size_t inlen, efx_dword_t *outbuf, size_t outlen, size_t *outlen_actual); -extern int efx_mcdi_rpc_start(struct efx_nic *efx, unsigned cmd, - const efx_dword_t *inbuf, size_t inlen); -extern int efx_mcdi_rpc_finish(struct efx_nic *efx, unsigned cmd, size_t inlen, - efx_dword_t *outbuf, size_t outlen, - size_t *outlen_actual); - typedef void efx_mcdi_async_completer(struct efx_nic *efx, unsigned long cookie, int rc, efx_dword_t *outbuf, size_t outlen_actual); -extern int efx_mcdi_rpc_async(struct efx_nic *efx, unsigned int cmd, - const efx_dword_t *inbuf, size_t inlen, - size_t outlen, - efx_mcdi_async_completer *complete, - unsigned long cookie); +int efx_mcdi_rpc_async(struct efx_nic *efx, unsigned int cmd, + const efx_dword_t *inbuf, size_t inlen, size_t outlen, + efx_mcdi_async_completer *complete, + unsigned long cookie); -extern int efx_mcdi_poll_reboot(struct efx_nic *efx); -extern void efx_mcdi_mode_poll(struct efx_nic *efx); -extern void efx_mcdi_mode_event(struct efx_nic *efx); -extern void efx_mcdi_flush_async(struct efx_nic *efx); +int efx_mcdi_poll_reboot(struct efx_nic *efx); +void efx_mcdi_mode_poll(struct efx_nic *efx); +void efx_mcdi_mode_event(struct efx_nic *efx); +void efx_mcdi_flush_async(struct efx_nic *efx); -extern void efx_mcdi_process_event(struct efx_channel *channel, - efx_qword_t *event); -extern void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev); +void efx_mcdi_process_event(struct efx_channel *channel, efx_qword_t *event); +void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev); /* We expect that 16- and 32-bit fields in MCDI requests and responses * are appropriately aligned, but 64-bit fields are only @@ -275,55 +272,54 @@ extern void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev); #define MCDI_EVENT_FIELD(_ev, _field) \ EFX_QWORD_FIELD(_ev, MCDI_EVENT_ ## _field) -extern void efx_mcdi_print_fwver(struct efx_nic *efx, char *buf, size_t len); -extern int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address, - u16 *fw_subtype_list, u32 *capabilities); -extern int efx_mcdi_log_ctrl(struct efx_nic *efx, bool evq, bool uart, - u32 dest_evq); -extern int efx_mcdi_nvram_types(struct efx_nic *efx, u32 *nvram_types_out); -extern int efx_mcdi_nvram_info(struct efx_nic *efx, unsigned int type, - size_t *size_out, size_t *erase_size_out, - bool *protected_out); -extern int efx_mcdi_nvram_test_all(struct efx_nic *efx); -extern int efx_mcdi_handle_assertion(struct efx_nic *efx); -extern void efx_mcdi_set_id_led(struct efx_nic *efx, enum efx_led_mode mode); -extern int efx_mcdi_wol_filter_set_magic(struct efx_nic *efx, - const u8 *mac, int *id_out); -extern int efx_mcdi_wol_filter_get_magic(struct efx_nic *efx, int *id_out); -extern int efx_mcdi_wol_filter_remove(struct efx_nic *efx, int id); -extern int efx_mcdi_wol_filter_reset(struct efx_nic *efx); -extern int efx_mcdi_flush_rxqs(struct efx_nic *efx); -extern int efx_mcdi_port_probe(struct efx_nic *efx); -extern void efx_mcdi_port_remove(struct efx_nic *efx); -extern int efx_mcdi_port_reconfigure(struct efx_nic *efx); -extern int efx_mcdi_port_get_number(struct efx_nic *efx); -extern u32 efx_mcdi_phy_get_caps(struct efx_nic *efx); -extern void efx_mcdi_process_link_change(struct efx_nic *efx, efx_qword_t *ev); -extern int efx_mcdi_set_mac(struct efx_nic *efx); +void efx_mcdi_print_fwver(struct efx_nic *efx, char *buf, size_t len); +int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address, + u16 *fw_subtype_list, u32 *capabilities); +int efx_mcdi_log_ctrl(struct efx_nic *efx, bool evq, bool uart, u32 dest_evq); +int efx_mcdi_nvram_types(struct efx_nic *efx, u32 *nvram_types_out); +int efx_mcdi_nvram_info(struct efx_nic *efx, unsigned int type, + size_t *size_out, size_t *erase_size_out, + bool *protected_out); +int efx_mcdi_nvram_test_all(struct efx_nic *efx); +int efx_mcdi_handle_assertion(struct efx_nic *efx); +void efx_mcdi_set_id_led(struct efx_nic *efx, enum efx_led_mode mode); +int efx_mcdi_wol_filter_set_magic(struct efx_nic *efx, const u8 *mac, + int *id_out); +int efx_mcdi_wol_filter_get_magic(struct efx_nic *efx, int *id_out); +int efx_mcdi_wol_filter_remove(struct efx_nic *efx, int id); +int efx_mcdi_wol_filter_reset(struct efx_nic *efx); +int efx_mcdi_flush_rxqs(struct efx_nic *efx); +int efx_mcdi_port_probe(struct efx_nic *efx); +void efx_mcdi_port_remove(struct efx_nic *efx); +int efx_mcdi_port_reconfigure(struct efx_nic *efx); +int efx_mcdi_port_get_number(struct efx_nic *efx); +u32 efx_mcdi_phy_get_caps(struct efx_nic *efx); +void efx_mcdi_process_link_change(struct efx_nic *efx, efx_qword_t *ev); +int efx_mcdi_set_mac(struct efx_nic *efx); #define EFX_MC_STATS_GENERATION_INVALID ((__force __le64)(-1)) -extern void efx_mcdi_mac_start_stats(struct efx_nic *efx); -extern void efx_mcdi_mac_stop_stats(struct efx_nic *efx); -extern bool efx_mcdi_mac_check_fault(struct efx_nic *efx); -extern enum reset_type efx_mcdi_map_reset_reason(enum reset_type reason); -extern int efx_mcdi_reset(struct efx_nic *efx, enum reset_type method); -extern int efx_mcdi_set_workaround(struct efx_nic *efx, u32 type, bool enabled); +void efx_mcdi_mac_start_stats(struct efx_nic *efx); +void efx_mcdi_mac_stop_stats(struct efx_nic *efx); +bool efx_mcdi_mac_check_fault(struct efx_nic *efx); +enum reset_type efx_mcdi_map_reset_reason(enum reset_type reason); +int efx_mcdi_reset(struct efx_nic *efx, enum reset_type method); +int efx_mcdi_set_workaround(struct efx_nic *efx, u32 type, bool enabled); #ifdef CONFIG_SFC_MCDI_MON -extern int efx_mcdi_mon_probe(struct efx_nic *efx); -extern void efx_mcdi_mon_remove(struct efx_nic *efx); +int efx_mcdi_mon_probe(struct efx_nic *efx); +void efx_mcdi_mon_remove(struct efx_nic *efx); #else static inline int efx_mcdi_mon_probe(struct efx_nic *efx) { return 0; } static inline void efx_mcdi_mon_remove(struct efx_nic *efx) {} #endif #ifdef CONFIG_SFC_MTD -extern int efx_mcdi_mtd_read(struct mtd_info *mtd, loff_t start, - size_t len, size_t *retlen, u8 *buffer); -extern int efx_mcdi_mtd_erase(struct mtd_info *mtd, loff_t start, size_t len); -extern int efx_mcdi_mtd_write(struct mtd_info *mtd, loff_t start, - size_t len, size_t *retlen, const u8 *buffer); -extern int efx_mcdi_mtd_sync(struct mtd_info *mtd); -extern void efx_mcdi_mtd_rename(struct efx_mtd_partition *part); +int efx_mcdi_mtd_read(struct mtd_info *mtd, loff_t start, size_t len, + size_t *retlen, u8 *buffer); +int efx_mcdi_mtd_erase(struct mtd_info *mtd, loff_t start, size_t len); +int efx_mcdi_mtd_write(struct mtd_info *mtd, loff_t start, size_t len, + size_t *retlen, const u8 *buffer); +int efx_mcdi_mtd_sync(struct mtd_info *mtd); +void efx_mcdi_mtd_rename(struct efx_mtd_partition *part); #endif #endif /* EFX_MCDI_H */ diff --git a/drivers/net/ethernet/sfc/mdio_10g.h b/drivers/net/ethernet/sfc/mdio_10g.h index 16824fecc5ee..4a2dc4c281b7 100644 --- a/drivers/net/ethernet/sfc/mdio_10g.h +++ b/drivers/net/ethernet/sfc/mdio_10g.h @@ -20,7 +20,7 @@ static inline unsigned efx_mdio_id_rev(u32 id) { return id & 0xf; } static inline unsigned efx_mdio_id_model(u32 id) { return (id >> 4) & 0x3f; } -extern unsigned efx_mdio_id_oui(u32 id); +unsigned efx_mdio_id_oui(u32 id); static inline int efx_mdio_read(struct efx_nic *efx, int devad, int addr) { @@ -56,7 +56,7 @@ static inline bool efx_mdio_phyxgxs_lane_sync(struct efx_nic *efx) return sync; } -extern const char *efx_mdio_mmd_name(int mmd); +const char *efx_mdio_mmd_name(int mmd); /* * Reset a specific MMD and wait for reset to clear. @@ -64,30 +64,29 @@ extern const char *efx_mdio_mmd_name(int mmd); * * This function will sleep */ -extern int efx_mdio_reset_mmd(struct efx_nic *efx, int mmd, - int spins, int spintime); +int efx_mdio_reset_mmd(struct efx_nic *efx, int mmd, int spins, int spintime); /* As efx_mdio_check_mmd but for multiple MMDs */ int efx_mdio_check_mmds(struct efx_nic *efx, unsigned int mmd_mask); /* Check the link status of specified mmds in bit mask */ -extern bool efx_mdio_links_ok(struct efx_nic *efx, unsigned int mmd_mask); +bool efx_mdio_links_ok(struct efx_nic *efx, unsigned int mmd_mask); /* Generic transmit disable support though PMAPMD */ -extern void efx_mdio_transmit_disable(struct efx_nic *efx); +void efx_mdio_transmit_disable(struct efx_nic *efx); /* Generic part of reconfigure: set/clear loopback bits */ -extern void efx_mdio_phy_reconfigure(struct efx_nic *efx); +void efx_mdio_phy_reconfigure(struct efx_nic *efx); /* Set the power state of the specified MMDs */ -extern void efx_mdio_set_mmds_lpower(struct efx_nic *efx, - int low_power, unsigned int mmd_mask); +void efx_mdio_set_mmds_lpower(struct efx_nic *efx, int low_power, + unsigned int mmd_mask); /* Set (some of) the PHY settings over MDIO */ -extern int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd); +int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd); /* Push advertising flags and restart autonegotiation */ -extern void efx_mdio_an_reconfigure(struct efx_nic *efx); +void efx_mdio_an_reconfigure(struct efx_nic *efx); /* Get pause parameters from AN if available (otherwise return * requested pause parameters) @@ -95,8 +94,7 @@ extern void efx_mdio_an_reconfigure(struct efx_nic *efx); u8 efx_mdio_get_pause(struct efx_nic *efx); /* Wait for specified MMDs to exit reset within a timeout */ -extern int efx_mdio_wait_reset_mmds(struct efx_nic *efx, - unsigned int mmd_mask); +int efx_mdio_wait_reset_mmds(struct efx_nic *efx, unsigned int mmd_mask); /* Set or clear flag, debouncing */ static inline void @@ -107,6 +105,6 @@ efx_mdio_set_flag(struct efx_nic *efx, int devad, int addr, } /* Liveness self-test for MDIO PHYs */ -extern int efx_mdio_test_alive(struct efx_nic *efx); +int efx_mdio_test_alive(struct efx_nic *efx); #endif /* EFX_MDIO_10G_H */ diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index b172ed133055..aac22a1e85b8 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -182,6 +182,9 @@ struct efx_tx_buffer { * @tsoh_page: Array of pages of TSO header buffers * @txd: The hardware descriptor ring * @ptr_mask: The size of the ring minus 1. + * @piobuf: PIO buffer region for this TX queue (shared with its partner). + * Size of the region is efx_piobuf_size. + * @piobuf_offset: Buffer offset to be specified in PIO descriptors * @initialised: Has hardware queue been initialised? * @read_count: Current read pointer. * This is the number of buffers that have been removed from both rings. @@ -209,6 +212,7 @@ struct efx_tx_buffer { * blocks * @tso_packets: Number of packets via the TSO xmit path * @pushes: Number of times the TX push feature has been used + * @pio_packets: Number of times the TX PIO feature has been used * @empty_read_count: If the completion path has seen the queue as empty * and the transmission path has not yet checked this, the value of * @read_count bitwise-added to %EFX_EMPTY_COUNT_VALID; otherwise 0. @@ -223,6 +227,8 @@ struct efx_tx_queue { struct efx_buffer *tsoh_page; struct efx_special_buffer txd; unsigned int ptr_mask; + void __iomem *piobuf; + unsigned int piobuf_offset; bool initialised; /* Members used mainly on the completion path */ @@ -238,6 +244,7 @@ struct efx_tx_queue { unsigned int tso_long_headers; unsigned int tso_packets; unsigned int pushes; + unsigned int pio_packets; /* Members shared between paths and sometimes updated */ unsigned int empty_read_count ____cacheline_aligned_in_smp; diff --git a/drivers/net/ethernet/sfc/nic.c b/drivers/net/ethernet/sfc/nic.c index e7dbd2dd202e..c75009b8c0d9 100644 --- a/drivers/net/ethernet/sfc/nic.c +++ b/drivers/net/ethernet/sfc/nic.c @@ -19,6 +19,7 @@ #include "bitfield.h" #include "efx.h" #include "nic.h" +#include "ef10_regs.h" #include "farch_regs.h" #include "io.h" #include "workarounds.h" @@ -166,26 +167,30 @@ void efx_nic_fini_interrupt(struct efx_nic *efx) /* Register dump */ -#define REGISTER_REVISION_A 1 -#define REGISTER_REVISION_B 2 -#define REGISTER_REVISION_C 3 -#define REGISTER_REVISION_Z 3 /* latest revision */ +#define REGISTER_REVISION_FA 1 +#define REGISTER_REVISION_FB 2 +#define REGISTER_REVISION_FC 3 +#define REGISTER_REVISION_FZ 3 /* last Falcon arch revision */ +#define REGISTER_REVISION_ED 4 +#define REGISTER_REVISION_EZ 4 /* latest EF10 revision */ struct efx_nic_reg { u32 offset:24; - u32 min_revision:2, max_revision:2; + u32 min_revision:3, max_revision:3; }; -#define REGISTER(name, min_rev, max_rev) { \ - FR_ ## min_rev ## max_rev ## _ ## name, \ - REGISTER_REVISION_ ## min_rev, REGISTER_REVISION_ ## max_rev \ +#define REGISTER(name, arch, min_rev, max_rev) { \ + arch ## R_ ## min_rev ## max_rev ## _ ## name, \ + REGISTER_REVISION_ ## arch ## min_rev, \ + REGISTER_REVISION_ ## arch ## max_rev \ } -#define REGISTER_AA(name) REGISTER(name, A, A) -#define REGISTER_AB(name) REGISTER(name, A, B) -#define REGISTER_AZ(name) REGISTER(name, A, Z) -#define REGISTER_BB(name) REGISTER(name, B, B) -#define REGISTER_BZ(name) REGISTER(name, B, Z) -#define REGISTER_CZ(name) REGISTER(name, C, Z) +#define REGISTER_AA(name) REGISTER(name, F, A, A) +#define REGISTER_AB(name) REGISTER(name, F, A, B) +#define REGISTER_AZ(name) REGISTER(name, F, A, Z) +#define REGISTER_BB(name) REGISTER(name, F, B, B) +#define REGISTER_BZ(name) REGISTER(name, F, B, Z) +#define REGISTER_CZ(name) REGISTER(name, F, C, Z) +#define REGISTER_DZ(name) REGISTER(name, E, D, Z) static const struct efx_nic_reg efx_nic_regs[] = { REGISTER_AZ(ADR_REGION), @@ -292,37 +297,42 @@ static const struct efx_nic_reg efx_nic_regs[] = { REGISTER_AB(XX_TXDRV_CTL), /* XX_PRBS_CTL, XX_PRBS_CHK and XX_PRBS_ERR are not used */ /* XX_CORE_STAT is partly RC */ + REGISTER_DZ(BIU_HW_REV_ID), + REGISTER_DZ(MC_DB_LWRD), + REGISTER_DZ(MC_DB_HWRD), }; struct efx_nic_reg_table { u32 offset:24; - u32 min_revision:2, max_revision:2; + u32 min_revision:3, max_revision:3; u32 step:6, rows:21; }; -#define REGISTER_TABLE_DIMENSIONS(_, offset, min_rev, max_rev, step, rows) { \ +#define REGISTER_TABLE_DIMENSIONS(_, offset, arch, min_rev, max_rev, step, rows) { \ offset, \ - REGISTER_REVISION_ ## min_rev, REGISTER_REVISION_ ## max_rev, \ + REGISTER_REVISION_ ## arch ## min_rev, \ + REGISTER_REVISION_ ## arch ## max_rev, \ step, rows \ } -#define REGISTER_TABLE(name, min_rev, max_rev) \ +#define REGISTER_TABLE(name, arch, min_rev, max_rev) \ REGISTER_TABLE_DIMENSIONS( \ - name, FR_ ## min_rev ## max_rev ## _ ## name, \ - min_rev, max_rev, \ - FR_ ## min_rev ## max_rev ## _ ## name ## _STEP, \ - FR_ ## min_rev ## max_rev ## _ ## name ## _ROWS) -#define REGISTER_TABLE_AA(name) REGISTER_TABLE(name, A, A) -#define REGISTER_TABLE_AZ(name) REGISTER_TABLE(name, A, Z) -#define REGISTER_TABLE_BB(name) REGISTER_TABLE(name, B, B) -#define REGISTER_TABLE_BZ(name) REGISTER_TABLE(name, B, Z) + name, arch ## R_ ## min_rev ## max_rev ## _ ## name, \ + arch, min_rev, max_rev, \ + arch ## R_ ## min_rev ## max_rev ## _ ## name ## _STEP, \ + arch ## R_ ## min_rev ## max_rev ## _ ## name ## _ROWS) +#define REGISTER_TABLE_AA(name) REGISTER_TABLE(name, F, A, A) +#define REGISTER_TABLE_AZ(name) REGISTER_TABLE(name, F, A, Z) +#define REGISTER_TABLE_BB(name) REGISTER_TABLE(name, F, B, B) +#define REGISTER_TABLE_BZ(name) REGISTER_TABLE(name, F, B, Z) #define REGISTER_TABLE_BB_CZ(name) \ - REGISTER_TABLE_DIMENSIONS(name, FR_BZ_ ## name, B, B, \ + REGISTER_TABLE_DIMENSIONS(name, FR_BZ_ ## name, F, B, B, \ FR_BZ_ ## name ## _STEP, \ FR_BB_ ## name ## _ROWS), \ - REGISTER_TABLE_DIMENSIONS(name, FR_BZ_ ## name, C, Z, \ + REGISTER_TABLE_DIMENSIONS(name, FR_BZ_ ## name, F, C, Z, \ FR_BZ_ ## name ## _STEP, \ FR_CZ_ ## name ## _ROWS) -#define REGISTER_TABLE_CZ(name) REGISTER_TABLE(name, C, Z) +#define REGISTER_TABLE_CZ(name) REGISTER_TABLE(name, F, C, Z) +#define REGISTER_TABLE_DZ(name) REGISTER_TABLE(name, E, D, Z) static const struct efx_nic_reg_table efx_nic_reg_tables[] = { /* DRIVER is not used */ @@ -340,9 +350,9 @@ static const struct efx_nic_reg_table efx_nic_reg_tables[] = { * 1K entries allows for some expansion of queue count and * size before we need to change the version. */ REGISTER_TABLE_DIMENSIONS(BUF_FULL_TBL_KER, FR_AA_BUF_FULL_TBL_KER, - A, A, 8, 1024), + F, A, A, 8, 1024), REGISTER_TABLE_DIMENSIONS(BUF_FULL_TBL, FR_BZ_BUF_FULL_TBL, - B, Z, 8, 1024), + F, B, Z, 8, 1024), REGISTER_TABLE_CZ(RX_MAC_FILTER_TBL0), REGISTER_TABLE_BB_CZ(TIMER_TBL), REGISTER_TABLE_BB_CZ(TX_PACE_TBL), @@ -353,6 +363,7 @@ static const struct efx_nic_reg_table efx_nic_reg_tables[] = { /* MSIX_PBA_TABLE is not mapped */ /* SRM_DBG is not mapped (and is redundant with BUF_FLL_TBL) */ REGISTER_TABLE_BZ(RX_FILTER_TBL0), + REGISTER_TABLE_DZ(BIU_MC_SFT_STATUS), }; size_t efx_nic_get_regs_len(struct efx_nic *efx) diff --git a/drivers/net/ethernet/sfc/nic.h b/drivers/net/ethernet/sfc/nic.h index fda29d39032f..08883c8edf0e 100644 --- a/drivers/net/ethernet/sfc/nic.h +++ b/drivers/net/ethernet/sfc/nic.h @@ -30,7 +30,7 @@ static inline int efx_nic_rev(struct efx_nic *efx) return efx->type->revision; } -extern u32 efx_farch_fpga_ver(struct efx_nic *efx); +u32 efx_farch_fpga_ver(struct efx_nic *efx); /* NIC has two interlinked PCI functions for the same port. */ static inline bool efx_nic_is_dual_func(struct efx_nic *efx) @@ -71,6 +71,26 @@ efx_tx_desc(struct efx_tx_queue *tx_queue, unsigned int index) return ((efx_qword_t *) (tx_queue->txd.buf.addr)) + index; } +/* Report whether the NIC considers this TX queue empty, given the + * write_count used for the last doorbell push. May return false + * negative. + */ +static inline bool __efx_nic_tx_is_empty(struct efx_tx_queue *tx_queue, + unsigned int write_count) +{ + unsigned int empty_read_count = ACCESS_ONCE(tx_queue->empty_read_count); + + if (empty_read_count == 0) + return false; + + return ((empty_read_count ^ write_count) & ~EFX_EMPTY_COUNT_VALID) == 0; +} + +static inline bool efx_nic_tx_is_empty(struct efx_tx_queue *tx_queue) +{ + return __efx_nic_tx_is_empty(tx_queue, tx_queue->write_count); +} + /* Decide whether to push a TX descriptor to the NIC vs merely writing * the doorbell. This can reduce latency when we are adding a single * descriptor to an empty queue, but is otherwise pointless. Further, @@ -80,14 +100,10 @@ efx_tx_desc(struct efx_tx_queue *tx_queue, unsigned int index) static inline bool efx_nic_may_push_tx_desc(struct efx_tx_queue *tx_queue, unsigned int write_count) { - unsigned empty_read_count = ACCESS_ONCE(tx_queue->empty_read_count); - - if (empty_read_count == 0) - return false; + bool was_empty = __efx_nic_tx_is_empty(tx_queue, write_count); tx_queue->empty_read_count = 0; - return ((empty_read_count ^ write_count) & ~EFX_EMPTY_COUNT_VALID) == 0 - && tx_queue->write_count - write_count == 1; + return was_empty && tx_queue->write_count - write_count == 1; } /* Returns a pointer to the specified descriptor in the RX descriptor queue */ @@ -389,6 +405,12 @@ enum { EF10_STAT_COUNT }; +/* Maximum number of TX PIO buffers we may allocate to a function. + * This matches the total number of buffers on each SFC9100-family + * controller. + */ +#define EF10_TX_PIOBUF_COUNT 16 + /** * struct efx_ef10_nic_data - EF10 architecture NIC state * @mcdi_buf: DMA buffer for MCDI @@ -397,6 +419,13 @@ enum { * @n_allocated_vis: Number of VIs allocated to this function * @must_realloc_vis: Flag: VIs have yet to be reallocated after MC reboot * @must_restore_filters: Flag: filters have yet to be restored after MC reboot + * @n_piobufs: Number of PIO buffers allocated to this function + * @wc_membase: Base address of write-combining mapping of the memory BAR + * @pio_write_base: Base address for writing PIO buffers + * @pio_write_vi_base: Relative VI number for @pio_write_base + * @piobuf_handle: Handle of each PIO buffer allocated + * @must_restore_piobufs: Flag: PIO buffers have yet to be restored after MC + * reboot * @rx_rss_context: Firmware handle for our RSS context * @stats: Hardware statistics * @workaround_35388: Flag: firmware supports workaround for bug 35388 @@ -412,6 +441,11 @@ struct efx_ef10_nic_data { unsigned int n_allocated_vis; bool must_realloc_vis; bool must_restore_filters; + unsigned int n_piobufs; + void __iomem *wc_membase, *pio_write_base; + unsigned int pio_write_vi_base; + unsigned int piobuf_handle[EF10_TX_PIOBUF_COUNT]; + bool must_restore_piobufs; u32 rx_rss_context; u64 stats[EF10_STAT_COUNT]; bool workaround_35388; @@ -463,18 +497,18 @@ static inline unsigned int efx_vf_size(struct efx_nic *efx) return 1 << efx->vi_scale; } -extern int efx_init_sriov(void); -extern void efx_sriov_probe(struct efx_nic *efx); -extern int efx_sriov_init(struct efx_nic *efx); -extern void efx_sriov_mac_address_changed(struct efx_nic *efx); -extern void efx_sriov_tx_flush_done(struct efx_nic *efx, efx_qword_t *event); -extern void efx_sriov_rx_flush_done(struct efx_nic *efx, efx_qword_t *event); -extern void efx_sriov_event(struct efx_channel *channel, efx_qword_t *event); -extern void efx_sriov_desc_fetch_err(struct efx_nic *efx, unsigned dmaq); -extern void efx_sriov_flr(struct efx_nic *efx, unsigned flr); -extern void efx_sriov_reset(struct efx_nic *efx); -extern void efx_sriov_fini(struct efx_nic *efx); -extern void efx_fini_sriov(void); +int efx_init_sriov(void); +void efx_sriov_probe(struct efx_nic *efx); +int efx_sriov_init(struct efx_nic *efx); +void efx_sriov_mac_address_changed(struct efx_nic *efx); +void efx_sriov_tx_flush_done(struct efx_nic *efx, efx_qword_t *event); +void efx_sriov_rx_flush_done(struct efx_nic *efx, efx_qword_t *event); +void efx_sriov_event(struct efx_channel *channel, efx_qword_t *event); +void efx_sriov_desc_fetch_err(struct efx_nic *efx, unsigned dmaq); +void efx_sriov_flr(struct efx_nic *efx, unsigned flr); +void efx_sriov_reset(struct efx_nic *efx); +void efx_sriov_fini(struct efx_nic *efx); +void efx_fini_sriov(void); #else @@ -500,22 +534,20 @@ static inline void efx_fini_sriov(void) {} #endif -extern int efx_sriov_set_vf_mac(struct net_device *dev, int vf, u8 *mac); -extern int efx_sriov_set_vf_vlan(struct net_device *dev, int vf, - u16 vlan, u8 qos); -extern int efx_sriov_get_vf_config(struct net_device *dev, int vf, - struct ifla_vf_info *ivf); -extern int efx_sriov_set_vf_spoofchk(struct net_device *net_dev, int vf, - bool spoofchk); +int efx_sriov_set_vf_mac(struct net_device *dev, int vf, u8 *mac); +int efx_sriov_set_vf_vlan(struct net_device *dev, int vf, u16 vlan, u8 qos); +int efx_sriov_get_vf_config(struct net_device *dev, int vf, + struct ifla_vf_info *ivf); +int efx_sriov_set_vf_spoofchk(struct net_device *net_dev, int vf, + bool spoofchk); struct ethtool_ts_info; -extern void efx_ptp_probe(struct efx_nic *efx); -extern int efx_ptp_ioctl(struct efx_nic *efx, struct ifreq *ifr, int cmd); -extern void efx_ptp_get_ts_info(struct efx_nic *efx, - struct ethtool_ts_info *ts_info); -extern bool efx_ptp_is_ptp_tx(struct efx_nic *efx, struct sk_buff *skb); -extern int efx_ptp_tx(struct efx_nic *efx, struct sk_buff *skb); -extern void efx_ptp_event(struct efx_nic *efx, efx_qword_t *ev); +void efx_ptp_probe(struct efx_nic *efx); +int efx_ptp_ioctl(struct efx_nic *efx, struct ifreq *ifr, int cmd); +void efx_ptp_get_ts_info(struct efx_nic *efx, struct ethtool_ts_info *ts_info); +bool efx_ptp_is_ptp_tx(struct efx_nic *efx, struct sk_buff *skb); +int efx_ptp_tx(struct efx_nic *efx, struct sk_buff *skb); +void efx_ptp_event(struct efx_nic *efx, efx_qword_t *ev); extern const struct efx_nic_type falcon_a1_nic_type; extern const struct efx_nic_type falcon_b0_nic_type; @@ -529,7 +561,7 @@ extern const struct efx_nic_type efx_hunt_a0_nic_type; ************************************************************************** */ -extern int falcon_probe_board(struct efx_nic *efx, u16 revision_info); +int falcon_probe_board(struct efx_nic *efx, u16 revision_info); /* TX data path */ static inline int efx_nic_probe_tx(struct efx_tx_queue *tx_queue) @@ -597,58 +629,58 @@ static inline void efx_nic_eventq_read_ack(struct efx_channel *channel) { channel->efx->type->ev_read_ack(channel); } -extern void efx_nic_event_test_start(struct efx_channel *channel); +void efx_nic_event_test_start(struct efx_channel *channel); /* Falcon/Siena queue operations */ -extern int efx_farch_tx_probe(struct efx_tx_queue *tx_queue); -extern void efx_farch_tx_init(struct efx_tx_queue *tx_queue); -extern void efx_farch_tx_fini(struct efx_tx_queue *tx_queue); -extern void efx_farch_tx_remove(struct efx_tx_queue *tx_queue); -extern void efx_farch_tx_write(struct efx_tx_queue *tx_queue); -extern int efx_farch_rx_probe(struct efx_rx_queue *rx_queue); -extern void efx_farch_rx_init(struct efx_rx_queue *rx_queue); -extern void efx_farch_rx_fini(struct efx_rx_queue *rx_queue); -extern void efx_farch_rx_remove(struct efx_rx_queue *rx_queue); -extern void efx_farch_rx_write(struct efx_rx_queue *rx_queue); -extern void efx_farch_rx_defer_refill(struct efx_rx_queue *rx_queue); -extern int efx_farch_ev_probe(struct efx_channel *channel); -extern int efx_farch_ev_init(struct efx_channel *channel); -extern void efx_farch_ev_fini(struct efx_channel *channel); -extern void efx_farch_ev_remove(struct efx_channel *channel); -extern int efx_farch_ev_process(struct efx_channel *channel, int quota); -extern void efx_farch_ev_read_ack(struct efx_channel *channel); -extern void efx_farch_ev_test_generate(struct efx_channel *channel); +int efx_farch_tx_probe(struct efx_tx_queue *tx_queue); +void efx_farch_tx_init(struct efx_tx_queue *tx_queue); +void efx_farch_tx_fini(struct efx_tx_queue *tx_queue); +void efx_farch_tx_remove(struct efx_tx_queue *tx_queue); +void efx_farch_tx_write(struct efx_tx_queue *tx_queue); +int efx_farch_rx_probe(struct efx_rx_queue *rx_queue); +void efx_farch_rx_init(struct efx_rx_queue *rx_queue); +void efx_farch_rx_fini(struct efx_rx_queue *rx_queue); +void efx_farch_rx_remove(struct efx_rx_queue *rx_queue); +void efx_farch_rx_write(struct efx_rx_queue *rx_queue); +void efx_farch_rx_defer_refill(struct efx_rx_queue *rx_queue); +int efx_farch_ev_probe(struct efx_channel *channel); +int efx_farch_ev_init(struct efx_channel *channel); +void efx_farch_ev_fini(struct efx_channel *channel); +void efx_farch_ev_remove(struct efx_channel *channel); +int efx_farch_ev_process(struct efx_channel *channel, int quota); +void efx_farch_ev_read_ack(struct efx_channel *channel); +void efx_farch_ev_test_generate(struct efx_channel *channel); /* Falcon/Siena filter operations */ -extern int efx_farch_filter_table_probe(struct efx_nic *efx); -extern void efx_farch_filter_table_restore(struct efx_nic *efx); -extern void efx_farch_filter_table_remove(struct efx_nic *efx); -extern void efx_farch_filter_update_rx_scatter(struct efx_nic *efx); -extern s32 efx_farch_filter_insert(struct efx_nic *efx, - struct efx_filter_spec *spec, bool replace); -extern int efx_farch_filter_remove_safe(struct efx_nic *efx, - enum efx_filter_priority priority, - u32 filter_id); -extern int efx_farch_filter_get_safe(struct efx_nic *efx, - enum efx_filter_priority priority, - u32 filter_id, struct efx_filter_spec *); -extern void efx_farch_filter_clear_rx(struct efx_nic *efx, - enum efx_filter_priority priority); -extern u32 efx_farch_filter_count_rx_used(struct efx_nic *efx, - enum efx_filter_priority priority); -extern u32 efx_farch_filter_get_rx_id_limit(struct efx_nic *efx); -extern s32 efx_farch_filter_get_rx_ids(struct efx_nic *efx, - enum efx_filter_priority priority, - u32 *buf, u32 size); +int efx_farch_filter_table_probe(struct efx_nic *efx); +void efx_farch_filter_table_restore(struct efx_nic *efx); +void efx_farch_filter_table_remove(struct efx_nic *efx); +void efx_farch_filter_update_rx_scatter(struct efx_nic *efx); +s32 efx_farch_filter_insert(struct efx_nic *efx, struct efx_filter_spec *spec, + bool replace); +int efx_farch_filter_remove_safe(struct efx_nic *efx, + enum efx_filter_priority priority, + u32 filter_id); +int efx_farch_filter_get_safe(struct efx_nic *efx, + enum efx_filter_priority priority, u32 filter_id, + struct efx_filter_spec *); +void efx_farch_filter_clear_rx(struct efx_nic *efx, + enum efx_filter_priority priority); +u32 efx_farch_filter_count_rx_used(struct efx_nic *efx, + enum efx_filter_priority priority); +u32 efx_farch_filter_get_rx_id_limit(struct efx_nic *efx); +s32 efx_farch_filter_get_rx_ids(struct efx_nic *efx, + enum efx_filter_priority priority, u32 *buf, + u32 size); #ifdef CONFIG_RFS_ACCEL -extern s32 efx_farch_filter_rfs_insert(struct efx_nic *efx, - struct efx_filter_spec *spec); -extern bool efx_farch_filter_rfs_expire_one(struct efx_nic *efx, u32 flow_id, - unsigned int index); +s32 efx_farch_filter_rfs_insert(struct efx_nic *efx, + struct efx_filter_spec *spec); +bool efx_farch_filter_rfs_expire_one(struct efx_nic *efx, u32 flow_id, + unsigned int index); #endif -extern void efx_farch_filter_sync_rx_mode(struct efx_nic *efx); +void efx_farch_filter_sync_rx_mode(struct efx_nic *efx); -extern bool efx_nic_event_present(struct efx_channel *channel); +bool efx_nic_event_present(struct efx_channel *channel); /* Some statistics are computed as A - B where A and B each increase * linearly with some hardware counter(s) and the counters are read @@ -669,17 +701,17 @@ static inline void efx_update_diff_stat(u64 *stat, u64 diff) } /* Interrupts */ -extern int efx_nic_init_interrupt(struct efx_nic *efx); -extern void efx_nic_irq_test_start(struct efx_nic *efx); -extern void efx_nic_fini_interrupt(struct efx_nic *efx); +int efx_nic_init_interrupt(struct efx_nic *efx); +void efx_nic_irq_test_start(struct efx_nic *efx); +void efx_nic_fini_interrupt(struct efx_nic *efx); /* Falcon/Siena interrupts */ -extern void efx_farch_irq_enable_master(struct efx_nic *efx); -extern void efx_farch_irq_test_generate(struct efx_nic *efx); -extern void efx_farch_irq_disable_master(struct efx_nic *efx); -extern irqreturn_t efx_farch_msi_interrupt(int irq, void *dev_id); -extern irqreturn_t efx_farch_legacy_interrupt(int irq, void *dev_id); -extern irqreturn_t efx_farch_fatal_interrupt(struct efx_nic *efx); +void efx_farch_irq_enable_master(struct efx_nic *efx); +void efx_farch_irq_test_generate(struct efx_nic *efx); +void efx_farch_irq_disable_master(struct efx_nic *efx); +irqreturn_t efx_farch_msi_interrupt(int irq, void *dev_id); +irqreturn_t efx_farch_legacy_interrupt(int irq, void *dev_id); +irqreturn_t efx_farch_fatal_interrupt(struct efx_nic *efx); static inline int efx_nic_event_test_irq_cpu(struct efx_channel *channel) { @@ -691,21 +723,21 @@ static inline int efx_nic_irq_test_irq_cpu(struct efx_nic *efx) } /* Global Resources */ -extern int efx_nic_flush_queues(struct efx_nic *efx); -extern void siena_prepare_flush(struct efx_nic *efx); -extern int efx_farch_fini_dmaq(struct efx_nic *efx); -extern void siena_finish_flush(struct efx_nic *efx); -extern void falcon_start_nic_stats(struct efx_nic *efx); -extern void falcon_stop_nic_stats(struct efx_nic *efx); -extern int falcon_reset_xaui(struct efx_nic *efx); -extern void efx_farch_dimension_resources(struct efx_nic *efx, unsigned sram_lim_qw); -extern void efx_farch_init_common(struct efx_nic *efx); -extern void efx_ef10_handle_drain_event(struct efx_nic *efx); +int efx_nic_flush_queues(struct efx_nic *efx); +void siena_prepare_flush(struct efx_nic *efx); +int efx_farch_fini_dmaq(struct efx_nic *efx); +void siena_finish_flush(struct efx_nic *efx); +void falcon_start_nic_stats(struct efx_nic *efx); +void falcon_stop_nic_stats(struct efx_nic *efx); +int falcon_reset_xaui(struct efx_nic *efx); +void efx_farch_dimension_resources(struct efx_nic *efx, unsigned sram_lim_qw); +void efx_farch_init_common(struct efx_nic *efx); +void efx_ef10_handle_drain_event(struct efx_nic *efx); static inline void efx_nic_push_rx_indir_table(struct efx_nic *efx) { efx->type->rx_push_indir_table(efx); } -extern void efx_farch_rx_push_indir_table(struct efx_nic *efx); +void efx_farch_rx_push_indir_table(struct efx_nic *efx); int efx_nic_alloc_buffer(struct efx_nic *efx, struct efx_buffer *buffer, unsigned int len, gfp_t gfp_flags); @@ -716,24 +748,22 @@ struct efx_farch_register_test { unsigned address; efx_oword_t mask; }; -extern int efx_farch_test_registers(struct efx_nic *efx, - const struct efx_farch_register_test *regs, - size_t n_regs); +int efx_farch_test_registers(struct efx_nic *efx, + const struct efx_farch_register_test *regs, + size_t n_regs); -extern size_t efx_nic_get_regs_len(struct efx_nic *efx); -extern void efx_nic_get_regs(struct efx_nic *efx, void *buf); +size_t efx_nic_get_regs_len(struct efx_nic *efx); +void efx_nic_get_regs(struct efx_nic *efx, void *buf); -extern size_t -efx_nic_describe_stats(const struct efx_hw_stat_desc *desc, size_t count, - const unsigned long *mask, u8 *names); -extern void -efx_nic_update_stats(const struct efx_hw_stat_desc *desc, size_t count, - const unsigned long *mask, - u64 *stats, const void *dma_buf, bool accumulate); +size_t efx_nic_describe_stats(const struct efx_hw_stat_desc *desc, size_t count, + const unsigned long *mask, u8 *names); +void efx_nic_update_stats(const struct efx_hw_stat_desc *desc, size_t count, + const unsigned long *mask, u64 *stats, + const void *dma_buf, bool accumulate); #define EFX_MAX_FLUSH_TIME 5000 -extern void efx_farch_generate_event(struct efx_nic *efx, unsigned int evq, - efx_qword_t *event); +void efx_farch_generate_event(struct efx_nic *efx, unsigned int evq, + efx_qword_t *event); #endif /* EFX_NIC_H */ diff --git a/drivers/net/ethernet/sfc/phy.h b/drivers/net/ethernet/sfc/phy.h index 45eeb7075156..803bf445c08e 100644 --- a/drivers/net/ethernet/sfc/phy.h +++ b/drivers/net/ethernet/sfc/phy.h @@ -15,7 +15,7 @@ */ extern const struct efx_phy_operations falcon_sfx7101_phy_ops; -extern void tenxpress_set_id_led(struct efx_nic *efx, enum efx_led_mode mode); +void tenxpress_set_id_led(struct efx_nic *efx, enum efx_led_mode mode); /**************************************************************************** * AMCC/Quake QT202x PHYs @@ -34,7 +34,7 @@ extern const struct efx_phy_operations falcon_qt202x_phy_ops; #define QUAKE_LED_TXLINK (0) #define QUAKE_LED_RXLINK (8) -extern void falcon_qt202x_set_led(struct efx_nic *p, int led, int state); +void falcon_qt202x_set_led(struct efx_nic *p, int led, int state); /**************************************************************************** * Transwitch CX4 retimer @@ -44,7 +44,7 @@ extern const struct efx_phy_operations falcon_txc_phy_ops; #define TXC_GPIO_DIR_INPUT 0 #define TXC_GPIO_DIR_OUTPUT 1 -extern void falcon_txc_set_gpio_dir(struct efx_nic *efx, int pin, int dir); -extern void falcon_txc_set_gpio_val(struct efx_nic *efx, int pin, int val); +void falcon_txc_set_gpio_dir(struct efx_nic *efx, int pin, int dir); +void falcon_txc_set_gpio_val(struct efx_nic *efx, int pin, int val); #endif diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index 4a596725023f..8f09e686fc23 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c @@ -12,6 +12,7 @@ #include <linux/in.h> #include <linux/slab.h> #include <linux/ip.h> +#include <linux/ipv6.h> #include <linux/tcp.h> #include <linux/udp.h> #include <linux/prefetch.h> @@ -818,44 +819,70 @@ int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb, struct efx_nic *efx = netdev_priv(net_dev); struct efx_channel *channel; struct efx_filter_spec spec; - const struct iphdr *ip; const __be16 *ports; + __be16 ether_type; int nhoff; int rc; - nhoff = skb_network_offset(skb); + /* The core RPS/RFS code has already parsed and validated + * VLAN, IP and transport headers. We assume they are in the + * header area. + */ if (skb->protocol == htons(ETH_P_8021Q)) { - EFX_BUG_ON_PARANOID(skb_headlen(skb) < - nhoff + sizeof(struct vlan_hdr)); - if (((const struct vlan_hdr *)skb->data + nhoff)-> - h_vlan_encapsulated_proto != htons(ETH_P_IP)) - return -EPROTONOSUPPORT; + const struct vlan_hdr *vh = + (const struct vlan_hdr *)skb->data; - /* This is IP over 802.1q VLAN. We can't filter on the - * IP 5-tuple and the vlan together, so just strip the - * vlan header and filter on the IP part. + /* We can't filter on the IP 5-tuple and the vlan + * together, so just strip the vlan header and filter + * on the IP part. */ - nhoff += sizeof(struct vlan_hdr); - } else if (skb->protocol != htons(ETH_P_IP)) { - return -EPROTONOSUPPORT; + EFX_BUG_ON_PARANOID(skb_headlen(skb) < sizeof(*vh)); + ether_type = vh->h_vlan_encapsulated_proto; + nhoff = sizeof(struct vlan_hdr); + } else { + ether_type = skb->protocol; + nhoff = 0; } - /* RFS must validate the IP header length before calling us */ - EFX_BUG_ON_PARANOID(skb_headlen(skb) < nhoff + sizeof(*ip)); - ip = (const struct iphdr *)(skb->data + nhoff); - if (ip_is_fragment(ip)) + if (ether_type != htons(ETH_P_IP) && ether_type != htons(ETH_P_IPV6)) return -EPROTONOSUPPORT; - EFX_BUG_ON_PARANOID(skb_headlen(skb) < nhoff + 4 * ip->ihl + 4); - ports = (const __be16 *)(skb->data + nhoff + 4 * ip->ihl); efx_filter_init_rx(&spec, EFX_FILTER_PRI_HINT, efx->rx_scatter ? EFX_FILTER_FLAG_RX_SCATTER : 0, rxq_index); - rc = efx_filter_set_ipv4_full(&spec, ip->protocol, - ip->daddr, ports[1], ip->saddr, ports[0]); - if (rc) - return rc; + spec.match_flags = + EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_IP_PROTO | + EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_LOC_PORT | + EFX_FILTER_MATCH_REM_HOST | EFX_FILTER_MATCH_REM_PORT; + spec.ether_type = ether_type; + + if (ether_type == htons(ETH_P_IP)) { + const struct iphdr *ip = + (const struct iphdr *)(skb->data + nhoff); + + EFX_BUG_ON_PARANOID(skb_headlen(skb) < nhoff + sizeof(*ip)); + if (ip_is_fragment(ip)) + return -EPROTONOSUPPORT; + spec.ip_proto = ip->protocol; + spec.rem_host[0] = ip->saddr; + spec.loc_host[0] = ip->daddr; + EFX_BUG_ON_PARANOID(skb_headlen(skb) < nhoff + 4 * ip->ihl + 4); + ports = (const __be16 *)(skb->data + nhoff + 4 * ip->ihl); + } else { + const struct ipv6hdr *ip6 = + (const struct ipv6hdr *)(skb->data + nhoff); + + EFX_BUG_ON_PARANOID(skb_headlen(skb) < + nhoff + sizeof(*ip6) + 4); + spec.ip_proto = ip6->nexthdr; + memcpy(spec.rem_host, &ip6->saddr, sizeof(ip6->saddr)); + memcpy(spec.loc_host, &ip6->daddr, sizeof(ip6->daddr)); + ports = (const __be16 *)(ip6 + 1); + } + + spec.rem_port = ports[0]; + spec.loc_port = ports[1]; rc = efx->type->filter_rfs_insert(efx, &spec); if (rc < 0) @@ -866,11 +893,18 @@ int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb, channel = efx_get_channel(efx, skb_get_rx_queue(skb)); ++channel->rfs_filters_added; - netif_info(efx, rx_status, efx->net_dev, - "steering %s %pI4:%u:%pI4:%u to queue %u [flow %u filter %d]\n", - (ip->protocol == IPPROTO_TCP) ? "TCP" : "UDP", - &ip->saddr, ntohs(ports[0]), &ip->daddr, ntohs(ports[1]), - rxq_index, flow_id, rc); + if (ether_type == htons(ETH_P_IP)) + netif_info(efx, rx_status, efx->net_dev, + "steering %s %pI4:%u:%pI4:%u to queue %u [flow %u filter %d]\n", + (spec.ip_proto == IPPROTO_TCP) ? "TCP" : "UDP", + spec.rem_host, ntohs(ports[0]), spec.loc_host, + ntohs(ports[1]), rxq_index, flow_id, rc); + else + netif_info(efx, rx_status, efx->net_dev, + "steering %s [%pI6]:%u:[%pI6]:%u to queue %u [flow %u filter %d]\n", + (spec.ip_proto == IPPROTO_TCP) ? "TCP" : "UDP", + spec.rem_host, ntohs(ports[0]), spec.loc_host, + ntohs(ports[1]), rxq_index, flow_id, rc); return rc; } diff --git a/drivers/net/ethernet/sfc/selftest.h b/drivers/net/ethernet/sfc/selftest.h index 87698ae0bf75..a2f4a06ffa4e 100644 --- a/drivers/net/ethernet/sfc/selftest.h +++ b/drivers/net/ethernet/sfc/selftest.h @@ -43,13 +43,12 @@ struct efx_self_tests { struct efx_loopback_self_tests loopback[LOOPBACK_TEST_MAX + 1]; }; -extern void efx_loopback_rx_packet(struct efx_nic *efx, - const char *buf_ptr, int pkt_len); -extern int efx_selftest(struct efx_nic *efx, - struct efx_self_tests *tests, - unsigned flags); -extern void efx_selftest_async_start(struct efx_nic *efx); -extern void efx_selftest_async_cancel(struct efx_nic *efx); -extern void efx_selftest_async_work(struct work_struct *data); +void efx_loopback_rx_packet(struct efx_nic *efx, const char *buf_ptr, + int pkt_len); +int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests, + unsigned flags); +void efx_selftest_async_start(struct efx_nic *efx); +void efx_selftest_async_cancel(struct efx_nic *efx); +void efx_selftest_async_work(struct work_struct *data); #endif /* EFX_SELFTEST_H */ diff --git a/drivers/net/ethernet/sfc/tx.c b/drivers/net/ethernet/sfc/tx.c index 2ac91c5b5eea..282692c48e6b 100644 --- a/drivers/net/ethernet/sfc/tx.c +++ b/drivers/net/ethernet/sfc/tx.c @@ -17,10 +17,46 @@ #include <net/ipv6.h> #include <linux/if_ether.h> #include <linux/highmem.h> +#include <linux/cache.h> #include "net_driver.h" #include "efx.h" +#include "io.h" #include "nic.h" #include "workarounds.h" +#include "ef10_regs.h" + +#ifdef EFX_USE_PIO + +#define EFX_PIOBUF_SIZE_MAX ER_DZ_TX_PIOBUF_SIZE +#define EFX_PIOBUF_SIZE_DEF ALIGN(256, L1_CACHE_BYTES) +unsigned int efx_piobuf_size __read_mostly = EFX_PIOBUF_SIZE_DEF; + +#endif /* EFX_USE_PIO */ + +static inline unsigned int +efx_tx_queue_get_insert_index(const struct efx_tx_queue *tx_queue) +{ + return tx_queue->insert_count & tx_queue->ptr_mask; +} + +static inline struct efx_tx_buffer * +__efx_tx_queue_get_insert_buffer(const struct efx_tx_queue *tx_queue) +{ + return &tx_queue->buffer[efx_tx_queue_get_insert_index(tx_queue)]; +} + +static inline struct efx_tx_buffer * +efx_tx_queue_get_insert_buffer(const struct efx_tx_queue *tx_queue) +{ + struct efx_tx_buffer *buffer = + __efx_tx_queue_get_insert_buffer(tx_queue); + + EFX_BUG_ON_PARANOID(buffer->len); + EFX_BUG_ON_PARANOID(buffer->flags); + EFX_BUG_ON_PARANOID(buffer->unmap_len); + + return buffer; +} static void efx_dequeue_buffer(struct efx_tx_queue *tx_queue, struct efx_tx_buffer *buffer, @@ -83,8 +119,10 @@ unsigned int efx_tx_max_skb_descs(struct efx_nic *efx) */ unsigned int max_descs = EFX_TSO_MAX_SEGS * 2 + MAX_SKB_FRAGS; - /* Possibly one more per segment for the alignment workaround */ - if (EFX_WORKAROUND_5391(efx)) + /* Possibly one more per segment for the alignment workaround, + * or for option descriptors + */ + if (EFX_WORKAROUND_5391(efx) || efx_nic_rev(efx) >= EFX_REV_HUNT_A0) max_descs += EFX_TSO_MAX_SEGS; /* Possibly more for PCIe page boundaries within input fragments */ @@ -145,6 +183,145 @@ static void efx_tx_maybe_stop_queue(struct efx_tx_queue *txq1) } } +#ifdef EFX_USE_PIO + +struct efx_short_copy_buffer { + int used; + u8 buf[L1_CACHE_BYTES]; +}; + +/* Copy to PIO, respecting that writes to PIO buffers must be dword aligned. + * Advances piobuf pointer. Leaves additional data in the copy buffer. + */ +static void efx_memcpy_toio_aligned(struct efx_nic *efx, u8 __iomem **piobuf, + u8 *data, int len, + struct efx_short_copy_buffer *copy_buf) +{ + int block_len = len & ~(sizeof(copy_buf->buf) - 1); + + memcpy_toio(*piobuf, data, block_len); + *piobuf += block_len; + len -= block_len; + + if (len) { + data += block_len; + BUG_ON(copy_buf->used); + BUG_ON(len > sizeof(copy_buf->buf)); + memcpy(copy_buf->buf, data, len); + copy_buf->used = len; + } +} + +/* Copy to PIO, respecting dword alignment, popping data from copy buffer first. + * Advances piobuf pointer. Leaves additional data in the copy buffer. + */ +static void efx_memcpy_toio_aligned_cb(struct efx_nic *efx, u8 __iomem **piobuf, + u8 *data, int len, + struct efx_short_copy_buffer *copy_buf) +{ + if (copy_buf->used) { + /* if the copy buffer is partially full, fill it up and write */ + int copy_to_buf = + min_t(int, sizeof(copy_buf->buf) - copy_buf->used, len); + + memcpy(copy_buf->buf + copy_buf->used, data, copy_to_buf); + copy_buf->used += copy_to_buf; + + /* if we didn't fill it up then we're done for now */ + if (copy_buf->used < sizeof(copy_buf->buf)) + return; + + memcpy_toio(*piobuf, copy_buf->buf, sizeof(copy_buf->buf)); + *piobuf += sizeof(copy_buf->buf); + data += copy_to_buf; + len -= copy_to_buf; + copy_buf->used = 0; + } + + efx_memcpy_toio_aligned(efx, piobuf, data, len, copy_buf); +} + +static void efx_flush_copy_buffer(struct efx_nic *efx, u8 __iomem *piobuf, + struct efx_short_copy_buffer *copy_buf) +{ + /* if there's anything in it, write the whole buffer, including junk */ + if (copy_buf->used) + memcpy_toio(piobuf, copy_buf->buf, sizeof(copy_buf->buf)); +} + +/* Traverse skb structure and copy fragments in to PIO buffer. + * Advances piobuf pointer. + */ +static void efx_skb_copy_bits_to_pio(struct efx_nic *efx, struct sk_buff *skb, + u8 __iomem **piobuf, + struct efx_short_copy_buffer *copy_buf) +{ + int i; + + efx_memcpy_toio_aligned(efx, piobuf, skb->data, skb_headlen(skb), + copy_buf); + + for (i = 0; i < skb_shinfo(skb)->nr_frags; ++i) { + skb_frag_t *f = &skb_shinfo(skb)->frags[i]; + u8 *vaddr; + + vaddr = kmap_atomic(skb_frag_page(f)); + + efx_memcpy_toio_aligned_cb(efx, piobuf, vaddr + f->page_offset, + skb_frag_size(f), copy_buf); + kunmap_atomic(vaddr); + } + + EFX_BUG_ON_PARANOID(skb_shinfo(skb)->frag_list); +} + +static struct efx_tx_buffer * +efx_enqueue_skb_pio(struct efx_tx_queue *tx_queue, struct sk_buff *skb) +{ + struct efx_tx_buffer *buffer = + efx_tx_queue_get_insert_buffer(tx_queue); + u8 __iomem *piobuf = tx_queue->piobuf; + + /* Copy to PIO buffer. Ensure the writes are padded to the end + * of a cache line, as this is required for write-combining to be + * effective on at least x86. + */ + + if (skb_shinfo(skb)->nr_frags) { + /* The size of the copy buffer will ensure all writes + * are the size of a cache line. + */ + struct efx_short_copy_buffer copy_buf; + + copy_buf.used = 0; + + efx_skb_copy_bits_to_pio(tx_queue->efx, skb, + &piobuf, ©_buf); + efx_flush_copy_buffer(tx_queue->efx, piobuf, ©_buf); + } else { + /* Pad the write to the size of a cache line. + * We can do this because we know the skb_shared_info sruct is + * after the source, and the destination buffer is big enough. + */ + BUILD_BUG_ON(L1_CACHE_BYTES > + SKB_DATA_ALIGN(sizeof(struct skb_shared_info))); + memcpy_toio(tx_queue->piobuf, skb->data, + ALIGN(skb->len, L1_CACHE_BYTES)); + } + + EFX_POPULATE_QWORD_5(buffer->option, + ESF_DZ_TX_DESC_IS_OPT, 1, + ESF_DZ_TX_OPTION_TYPE, ESE_DZ_TX_OPTION_DESC_PIO, + ESF_DZ_TX_PIO_CONT, 0, + ESF_DZ_TX_PIO_BYTE_CNT, skb->len, + ESF_DZ_TX_PIO_BUF_ADDR, + tx_queue->piobuf_offset); + ++tx_queue->pio_packets; + ++tx_queue->insert_count; + return buffer; +} +#endif /* EFX_USE_PIO */ + /* * Add a socket buffer to a TX queue * @@ -167,7 +344,7 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb) struct device *dma_dev = &efx->pci_dev->dev; struct efx_tx_buffer *buffer; skb_frag_t *fragment; - unsigned int len, unmap_len = 0, insert_ptr; + unsigned int len, unmap_len = 0; dma_addr_t dma_addr, unmap_addr = 0; unsigned int dma_len; unsigned short dma_flags; @@ -189,6 +366,17 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb) return NETDEV_TX_OK; } + /* Consider using PIO for short packets */ +#ifdef EFX_USE_PIO + if (skb->len <= efx_piobuf_size && tx_queue->piobuf && + efx_nic_tx_is_empty(tx_queue) && + efx_nic_tx_is_empty(efx_tx_queue_partner(tx_queue))) { + buffer = efx_enqueue_skb_pio(tx_queue, skb); + dma_flags = EFX_TX_BUF_OPTION; + goto finish_packet; + } +#endif + /* Map for DMA. Use dma_map_single rather than dma_map_page * since this is more efficient on machines with sparse * memory. @@ -208,11 +396,7 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb) /* Add to TX queue, splitting across DMA boundaries */ do { - insert_ptr = tx_queue->insert_count & tx_queue->ptr_mask; - buffer = &tx_queue->buffer[insert_ptr]; - EFX_BUG_ON_PARANOID(buffer->flags); - EFX_BUG_ON_PARANOID(buffer->len); - EFX_BUG_ON_PARANOID(buffer->unmap_len); + buffer = efx_tx_queue_get_insert_buffer(tx_queue); dma_len = efx_max_tx_len(efx, dma_addr); if (likely(dma_len >= len)) @@ -245,6 +429,7 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb) } /* Transfer ownership of the skb to the final buffer */ +finish_packet: buffer->skb = skb; buffer->flags = EFX_TX_BUF_SKB | dma_flags; @@ -270,8 +455,7 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb) while (tx_queue->insert_count != tx_queue->write_count) { unsigned int pkts_compl = 0, bytes_compl = 0; --tx_queue->insert_count; - insert_ptr = tx_queue->insert_count & tx_queue->ptr_mask; - buffer = &tx_queue->buffer[insert_ptr]; + buffer = __efx_tx_queue_get_insert_buffer(tx_queue); efx_dequeue_buffer(tx_queue, buffer, &pkts_compl, &bytes_compl); } @@ -628,6 +812,9 @@ void efx_remove_tx_queue(struct efx_tx_queue *tx_queue) * @tcp_off: Offset of TCP header * @header_len: Number of bytes of header * @ip_base_len: IPv4 tot_len or IPv6 payload_len, before TCP payload + * @header_dma_addr: Header DMA address, when using option descriptors + * @header_unmap_len: Header DMA mapped length, or 0 if not using option + * descriptors * * The state used during segmentation. It is put into this data structure * just to make it easy to pass into inline functions. @@ -636,7 +823,7 @@ struct tso_state { /* Output position */ unsigned out_len; unsigned seqnum; - unsigned ipv4_id; + u16 ipv4_id; unsigned packet_space; /* Input position */ @@ -651,6 +838,8 @@ struct tso_state { unsigned int tcp_off; unsigned header_len; unsigned int ip_base_len; + dma_addr_t header_dma_addr; + unsigned int header_unmap_len; }; @@ -737,23 +926,18 @@ static void efx_tx_queue_insert(struct efx_tx_queue *tx_queue, { struct efx_tx_buffer *buffer; struct efx_nic *efx = tx_queue->efx; - unsigned dma_len, insert_ptr; + unsigned dma_len; EFX_BUG_ON_PARANOID(len <= 0); while (1) { - insert_ptr = tx_queue->insert_count & tx_queue->ptr_mask; - buffer = &tx_queue->buffer[insert_ptr]; + buffer = efx_tx_queue_get_insert_buffer(tx_queue); ++tx_queue->insert_count; EFX_BUG_ON_PARANOID(tx_queue->insert_count - tx_queue->read_count >= efx->txq_entries); - EFX_BUG_ON_PARANOID(buffer->len); - EFX_BUG_ON_PARANOID(buffer->unmap_len); - EFX_BUG_ON_PARANOID(buffer->flags); - buffer->dma_addr = dma_addr; dma_len = efx_max_tx_len(efx, dma_addr); @@ -814,19 +998,27 @@ static void efx_enqueue_unwind(struct efx_tx_queue *tx_queue) /* Work backwards until we hit the original insert pointer value */ while (tx_queue->insert_count != tx_queue->write_count) { --tx_queue->insert_count; - buffer = &tx_queue->buffer[tx_queue->insert_count & - tx_queue->ptr_mask]; + buffer = __efx_tx_queue_get_insert_buffer(tx_queue); efx_dequeue_buffer(tx_queue, buffer, NULL, NULL); } } /* Parse the SKB header and initialise state. */ -static void tso_start(struct tso_state *st, const struct sk_buff *skb) +static int tso_start(struct tso_state *st, struct efx_nic *efx, + const struct sk_buff *skb) { + bool use_options = efx_nic_rev(efx) >= EFX_REV_HUNT_A0; + struct device *dma_dev = &efx->pci_dev->dev; + unsigned int header_len, in_len; + dma_addr_t dma_addr; + st->ip_off = skb_network_header(skb) - skb->data; st->tcp_off = skb_transport_header(skb) - skb->data; - st->header_len = st->tcp_off + (tcp_hdr(skb)->doff << 2u); + header_len = st->tcp_off + (tcp_hdr(skb)->doff << 2u); + in_len = skb_headlen(skb) - header_len; + st->header_len = header_len; + st->in_len = in_len; if (st->protocol == htons(ETH_P_IP)) { st->ip_base_len = st->header_len - st->ip_off; st->ipv4_id = ntohs(ip_hdr(skb)->id); @@ -840,9 +1032,34 @@ static void tso_start(struct tso_state *st, const struct sk_buff *skb) EFX_BUG_ON_PARANOID(tcp_hdr(skb)->syn); EFX_BUG_ON_PARANOID(tcp_hdr(skb)->rst); - st->out_len = skb->len - st->header_len; - st->unmap_len = 0; - st->dma_flags = 0; + st->out_len = skb->len - header_len; + + if (!use_options) { + st->header_unmap_len = 0; + + if (likely(in_len == 0)) { + st->dma_flags = 0; + st->unmap_len = 0; + return 0; + } + + dma_addr = dma_map_single(dma_dev, skb->data + header_len, + in_len, DMA_TO_DEVICE); + st->dma_flags = EFX_TX_BUF_MAP_SINGLE; + st->dma_addr = dma_addr; + st->unmap_addr = dma_addr; + st->unmap_len = in_len; + } else { + dma_addr = dma_map_single(dma_dev, skb->data, + skb_headlen(skb), DMA_TO_DEVICE); + st->header_dma_addr = dma_addr; + st->header_unmap_len = skb_headlen(skb); + st->dma_flags = 0; + st->dma_addr = dma_addr + header_len; + st->unmap_len = 0; + } + + return unlikely(dma_mapping_error(dma_dev, dma_addr)) ? -ENOMEM : 0; } static int tso_get_fragment(struct tso_state *st, struct efx_nic *efx, @@ -860,24 +1077,6 @@ static int tso_get_fragment(struct tso_state *st, struct efx_nic *efx, return -ENOMEM; } -static int tso_get_head_fragment(struct tso_state *st, struct efx_nic *efx, - const struct sk_buff *skb) -{ - int hl = st->header_len; - int len = skb_headlen(skb) - hl; - - st->unmap_addr = dma_map_single(&efx->pci_dev->dev, skb->data + hl, - len, DMA_TO_DEVICE); - if (likely(!dma_mapping_error(&efx->pci_dev->dev, st->unmap_addr))) { - st->dma_flags = EFX_TX_BUF_MAP_SINGLE; - st->unmap_len = len; - st->in_len = len; - st->dma_addr = st->unmap_addr; - return 0; - } - return -ENOMEM; -} - /** * tso_fill_packet_with_fragment - form descriptors for the current fragment @@ -944,55 +1143,97 @@ static int tso_start_new_packet(struct efx_tx_queue *tx_queue, struct tso_state *st) { struct efx_tx_buffer *buffer = - &tx_queue->buffer[tx_queue->insert_count & tx_queue->ptr_mask]; - struct tcphdr *tsoh_th; - unsigned ip_length; - u8 *header; - int rc; + efx_tx_queue_get_insert_buffer(tx_queue); + bool is_last = st->out_len <= skb_shinfo(skb)->gso_size; + u8 tcp_flags_clear; - /* Allocate and insert a DMA-mapped header buffer. */ - header = efx_tsoh_get_buffer(tx_queue, buffer, st->header_len); - if (!header) - return -ENOMEM; - - tsoh_th = (struct tcphdr *)(header + st->tcp_off); - - /* Copy and update the headers. */ - memcpy(header, skb->data, st->header_len); - - tsoh_th->seq = htonl(st->seqnum); - st->seqnum += skb_shinfo(skb)->gso_size; - if (st->out_len > skb_shinfo(skb)->gso_size) { - /* This packet will not finish the TSO burst. */ + if (!is_last) { st->packet_space = skb_shinfo(skb)->gso_size; - tsoh_th->fin = 0; - tsoh_th->psh = 0; + tcp_flags_clear = 0x09; /* mask out FIN and PSH */ } else { - /* This packet will be the last in the TSO burst. */ st->packet_space = st->out_len; - tsoh_th->fin = tcp_hdr(skb)->fin; - tsoh_th->psh = tcp_hdr(skb)->psh; + tcp_flags_clear = 0x00; } - ip_length = st->ip_base_len + st->packet_space; - if (st->protocol == htons(ETH_P_IP)) { - struct iphdr *tsoh_iph = (struct iphdr *)(header + st->ip_off); + if (!st->header_unmap_len) { + /* Allocate and insert a DMA-mapped header buffer. */ + struct tcphdr *tsoh_th; + unsigned ip_length; + u8 *header; + int rc; + + header = efx_tsoh_get_buffer(tx_queue, buffer, st->header_len); + if (!header) + return -ENOMEM; - tsoh_iph->tot_len = htons(ip_length); + tsoh_th = (struct tcphdr *)(header + st->tcp_off); + + /* Copy and update the headers. */ + memcpy(header, skb->data, st->header_len); + + tsoh_th->seq = htonl(st->seqnum); + ((u8 *)tsoh_th)[13] &= ~tcp_flags_clear; + + ip_length = st->ip_base_len + st->packet_space; + + if (st->protocol == htons(ETH_P_IP)) { + struct iphdr *tsoh_iph = + (struct iphdr *)(header + st->ip_off); + + tsoh_iph->tot_len = htons(ip_length); + tsoh_iph->id = htons(st->ipv4_id); + } else { + struct ipv6hdr *tsoh_iph = + (struct ipv6hdr *)(header + st->ip_off); + + tsoh_iph->payload_len = htons(ip_length); + } - /* Linux leaves suitable gaps in the IP ID space for us to fill. */ - tsoh_iph->id = htons(st->ipv4_id); - st->ipv4_id++; + rc = efx_tso_put_header(tx_queue, buffer, header); + if (unlikely(rc)) + return rc; } else { - struct ipv6hdr *tsoh_iph = - (struct ipv6hdr *)(header + st->ip_off); + /* Send the original headers with a TSO option descriptor + * in front + */ + u8 tcp_flags = ((u8 *)tcp_hdr(skb))[13] & ~tcp_flags_clear; - tsoh_iph->payload_len = htons(ip_length); + buffer->flags = EFX_TX_BUF_OPTION; + buffer->len = 0; + buffer->unmap_len = 0; + EFX_POPULATE_QWORD_5(buffer->option, + ESF_DZ_TX_DESC_IS_OPT, 1, + ESF_DZ_TX_OPTION_TYPE, + ESE_DZ_TX_OPTION_DESC_TSO, + ESF_DZ_TX_TSO_TCP_FLAGS, tcp_flags, + ESF_DZ_TX_TSO_IP_ID, st->ipv4_id, + ESF_DZ_TX_TSO_TCP_SEQNO, st->seqnum); + ++tx_queue->insert_count; + + /* We mapped the headers in tso_start(). Unmap them + * when the last segment is completed. + */ + buffer = efx_tx_queue_get_insert_buffer(tx_queue); + buffer->dma_addr = st->header_dma_addr; + buffer->len = st->header_len; + if (is_last) { + buffer->flags = EFX_TX_BUF_CONT | EFX_TX_BUF_MAP_SINGLE; + buffer->unmap_len = st->header_unmap_len; + /* Ensure we only unmap them once in case of a + * later DMA mapping error and rollback + */ + st->header_unmap_len = 0; + } else { + buffer->flags = EFX_TX_BUF_CONT; + buffer->unmap_len = 0; + } + ++tx_queue->insert_count; } - rc = efx_tso_put_header(tx_queue, buffer, header); - if (unlikely(rc)) - return rc; + st->seqnum += skb_shinfo(skb)->gso_size; + + /* Linux leaves suitable gaps in the IP ID space for us to fill. */ + ++st->ipv4_id; ++tx_queue->tso_packets; @@ -1023,12 +1264,11 @@ static int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue, EFX_BUG_ON_PARANOID(tx_queue->write_count != tx_queue->insert_count); - tso_start(&state, skb); + rc = tso_start(&state, efx, skb); + if (rc) + goto mem_err; - /* Assume that skb header area contains exactly the headers, and - * all payload is in the frag list. - */ - if (skb_headlen(skb) == state.header_len) { + if (likely(state.in_len == 0)) { /* Grab the first payload fragment. */ EFX_BUG_ON_PARANOID(skb_shinfo(skb)->nr_frags < 1); frag_i = 0; @@ -1037,9 +1277,7 @@ static int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue, if (rc) goto mem_err; } else { - rc = tso_get_head_fragment(&state, efx, skb); - if (rc) - goto mem_err; + /* Payload starts in the header area. */ frag_i = -1; } @@ -1091,6 +1329,11 @@ static int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue, state.unmap_len, DMA_TO_DEVICE); } + /* Free the header DMA mapping, if using option descriptors */ + if (state.header_unmap_len) + dma_unmap_single(&efx->pci_dev->dev, state.header_dma_addr, + state.header_unmap_len, DMA_TO_DEVICE); + efx_enqueue_unwind(tx_queue); return NETDEV_TX_OK; } diff --git a/drivers/net/ethernet/sgi/meth.c b/drivers/net/ethernet/sgi/meth.c index 770036bc2d87..513ed8b1ba58 100644 --- a/drivers/net/ethernet/sgi/meth.c +++ b/drivers/net/ethernet/sgi/meth.c @@ -839,7 +839,7 @@ static int meth_probe(struct platform_device *pdev) dev->watchdog_timeo = timeout; dev->irq = MACE_ETHERNET_IRQ; dev->base_addr = (unsigned long)&mace->eth; - memcpy(dev->dev_addr, o2meth_eaddr, 6); + memcpy(dev->dev_addr, o2meth_eaddr, ETH_ALEN); priv = netdev_priv(dev); spin_lock_init(&priv->meth_lock); diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c index 5fdbc2686eb3..01f8459c3213 100644 --- a/drivers/net/ethernet/smsc/smsc911x.c +++ b/drivers/net/ethernet/smsc/smsc911x.c @@ -2502,7 +2502,7 @@ static int smsc911x_drv_probe(struct platform_device *pdev) SMSC_TRACE(pdata, probe, "MAC Address is specified by configuration"); } else if (is_valid_ether_addr(pdata->config.mac)) { - memcpy(dev->dev_addr, pdata->config.mac, 6); + memcpy(dev->dev_addr, pdata->config.mac, ETH_ALEN); SMSC_TRACE(pdata, probe, "MAC Address specified by platform data"); } else { diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index 7eb8babed2cb..fc94f202a43e 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -451,14 +451,14 @@ struct mac_device_info { struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr); struct mac_device_info *dwmac100_setup(void __iomem *ioaddr); -extern void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6], - unsigned int high, unsigned int low); -extern void stmmac_get_mac_addr(void __iomem *ioaddr, unsigned char *addr, - unsigned int high, unsigned int low); +void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6], + unsigned int high, unsigned int low); +void stmmac_get_mac_addr(void __iomem *ioaddr, unsigned char *addr, + unsigned int high, unsigned int low); -extern void stmmac_set_mac(void __iomem *ioaddr, bool enable); +void stmmac_set_mac(void __iomem *ioaddr, bool enable); -extern void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr); +void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr); extern const struct stmmac_ring_mode_ops ring_mode_ops; extern const struct stmmac_chain_mode_ops chain_mode_ops; diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h index 8e5662ce488b..def266da55db 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h @@ -104,14 +104,13 @@ #define DMA_STATUS_TI 0x00000001 /* Transmit Interrupt */ #define DMA_CONTROL_FTF 0x00100000 /* Flush transmit FIFO */ -extern void dwmac_enable_dma_transmission(void __iomem *ioaddr); -extern void dwmac_enable_dma_irq(void __iomem *ioaddr); -extern void dwmac_disable_dma_irq(void __iomem *ioaddr); -extern void dwmac_dma_start_tx(void __iomem *ioaddr); -extern void dwmac_dma_stop_tx(void __iomem *ioaddr); -extern void dwmac_dma_start_rx(void __iomem *ioaddr); -extern void dwmac_dma_stop_rx(void __iomem *ioaddr); -extern int dwmac_dma_interrupt(void __iomem *ioaddr, - struct stmmac_extra_stats *x); +void dwmac_enable_dma_transmission(void __iomem *ioaddr); +void dwmac_enable_dma_irq(void __iomem *ioaddr); +void dwmac_disable_dma_irq(void __iomem *ioaddr); +void dwmac_dma_start_tx(void __iomem *ioaddr); +void dwmac_dma_stop_tx(void __iomem *ioaddr); +void dwmac_dma_start_rx(void __iomem *ioaddr); +void dwmac_dma_stop_rx(void __iomem *ioaddr); +int dwmac_dma_interrupt(void __iomem *ioaddr, struct stmmac_extra_stats *x); #endif /* __DWMAC_DMA_H__ */ diff --git a/drivers/net/ethernet/stmicro/stmmac/mmc.h b/drivers/net/ethernet/stmicro/stmmac/mmc.h index 48ec001566b5..8607488cbcfc 100644 --- a/drivers/net/ethernet/stmicro/stmmac/mmc.h +++ b/drivers/net/ethernet/stmicro/stmmac/mmc.h @@ -128,8 +128,8 @@ struct stmmac_counters { unsigned int mmc_rx_icmp_err_octets; }; -extern void dwmac_mmc_ctrl(void __iomem *ioaddr, unsigned int mode); -extern void dwmac_mmc_intr_all_mask(void __iomem *ioaddr); -extern void dwmac_mmc_read(void __iomem *ioaddr, struct stmmac_counters *mmc); +void dwmac_mmc_ctrl(void __iomem *ioaddr, unsigned int mode); +void dwmac_mmc_intr_all_mask(void __iomem *ioaddr); +void dwmac_mmc_read(void __iomem *ioaddr, struct stmmac_counters *mmc); #endif /* __MMC_H__ */ diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index f16a9bdf45bb..22f89ffdfd95 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -110,14 +110,14 @@ struct stmmac_priv { extern int phyaddr; -extern int stmmac_mdio_unregister(struct net_device *ndev); -extern int stmmac_mdio_register(struct net_device *ndev); -extern void stmmac_set_ethtool_ops(struct net_device *netdev); +int stmmac_mdio_unregister(struct net_device *ndev); +int stmmac_mdio_register(struct net_device *ndev); +void stmmac_set_ethtool_ops(struct net_device *netdev); extern const struct stmmac_desc_ops enh_desc_ops; extern const struct stmmac_desc_ops ndesc_ops; extern const struct stmmac_hwtimestamp stmmac_ptp; -extern int stmmac_ptp_register(struct stmmac_priv *priv); -extern void stmmac_ptp_unregister(struct stmmac_priv *priv); +int stmmac_ptp_register(struct stmmac_priv *priv); +void stmmac_ptp_unregister(struct stmmac_priv *priv); int stmmac_freeze(struct net_device *ndev); int stmmac_restore(struct net_device *ndev); int stmmac_resume(struct net_device *ndev); diff --git a/drivers/net/ethernet/sun/cassini.c b/drivers/net/ethernet/sun/cassini.c index 759441b29e53..a72ecc42885d 100644 --- a/drivers/net/ethernet/sun/cassini.c +++ b/drivers/net/ethernet/sun/cassini.c @@ -3354,7 +3354,7 @@ use_random_mac_addr: #if defined(CONFIG_SPARC) addr = of_get_property(cp->of_node, "local-mac-address", NULL); if (addr != NULL) { - memcpy(dev_addr, addr, 6); + memcpy(dev_addr, addr, ETH_ALEN); goto done; } #endif diff --git a/drivers/net/ethernet/sun/sungem.c b/drivers/net/ethernet/sun/sungem.c index e62df2b81302..a235bd9fd980 100644 --- a/drivers/net/ethernet/sun/sungem.c +++ b/drivers/net/ethernet/sun/sungem.c @@ -2779,7 +2779,7 @@ static int gem_get_device_address(struct gem *gp) return -1; #endif } - memcpy(dev->dev_addr, addr, 6); + memcpy(dev->dev_addr, addr, ETH_ALEN); #else get_gem_mac_nonobp(gp->pdev, gp->dev->dev_addr); #endif diff --git a/drivers/net/ethernet/sun/sunhme.c b/drivers/net/ethernet/sun/sunhme.c index e37b587b3860..99043b74bf2b 100644 --- a/drivers/net/ethernet/sun/sunhme.c +++ b/drivers/net/ethernet/sun/sunhme.c @@ -2675,10 +2675,10 @@ static int happy_meal_sbus_probe_one(struct platform_device *op, int is_qfe) addr = of_get_property(dp, "local-mac-address", &len); - if (qfe_slot != -1 && addr && len == 6) - memcpy(dev->dev_addr, addr, 6); + if (qfe_slot != -1 && addr && len == ETH_ALEN) + memcpy(dev->dev_addr, addr, ETH_ALEN); else - memcpy(dev->dev_addr, idprom->id_ethaddr, 6); + memcpy(dev->dev_addr, idprom->id_ethaddr, ETH_ALEN); } hp = netdev_priv(dev); @@ -3024,9 +3024,9 @@ static int happy_meal_pci_probe(struct pci_dev *pdev, (addr = of_get_property(dp, "local-mac-address", &len)) != NULL && len == 6) { - memcpy(dev->dev_addr, addr, 6); + memcpy(dev->dev_addr, addr, ETH_ALEN); } else { - memcpy(dev->dev_addr, idprom->id_ethaddr, 6); + memcpy(dev->dev_addr, idprom->id_ethaddr, ETH_ALEN); } #else get_hme_mac_nonsparc(pdev, &dev->dev_addr[0]); diff --git a/drivers/net/ethernet/sun/sunqe.c b/drivers/net/ethernet/sun/sunqe.c index b072f4dba033..5695ae2411de 100644 --- a/drivers/net/ethernet/sun/sunqe.c +++ b/drivers/net/ethernet/sun/sunqe.c @@ -843,7 +843,7 @@ static int qec_ether_init(struct platform_device *op) if (!dev) return -ENOMEM; - memcpy(dev->dev_addr, idprom->id_ethaddr, 6); + memcpy(dev->dev_addr, idprom->id_ethaddr, ETH_ALEN); qe = netdev_priv(dev); diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig index de71b1ec4625..53150c25a96b 100644 --- a/drivers/net/ethernet/ti/Kconfig +++ b/drivers/net/ethernet/ti/Kconfig @@ -49,11 +49,19 @@ config TI_DAVINCI_CPDMA To compile this driver as a module, choose M here: the module will be called davinci_cpdma. This is recommended. +config TI_CPSW_PHY_SEL + boolean "TI CPSW Switch Phy sel Support" + depends on TI_CPSW + ---help--- + This driver supports configuring of the phy mode connected to + the CPSW. + config TI_CPSW tristate "TI CPSW Switch Support" depends on ARM && (ARCH_DAVINCI || SOC_AM33XX) select TI_DAVINCI_CPDMA select TI_DAVINCI_MDIO + select TI_CPSW_PHY_SEL ---help--- This driver supports TI's CPSW Ethernet Switch. diff --git a/drivers/net/ethernet/ti/Makefile b/drivers/net/ethernet/ti/Makefile index c65148e8aa1d..9cfaab8152be 100644 --- a/drivers/net/ethernet/ti/Makefile +++ b/drivers/net/ethernet/ti/Makefile @@ -7,5 +7,6 @@ obj-$(CONFIG_CPMAC) += cpmac.o obj-$(CONFIG_TI_DAVINCI_EMAC) += davinci_emac.o obj-$(CONFIG_TI_DAVINCI_MDIO) += davinci_mdio.o obj-$(CONFIG_TI_DAVINCI_CPDMA) += davinci_cpdma.o +obj-$(CONFIG_TI_CPSW_PHY_SEL) += cpsw-phy-sel.o obj-$(CONFIG_TI_CPSW) += ti_cpsw.o ti_cpsw-y := cpsw_ale.o cpsw.o cpts.o diff --git a/drivers/net/ethernet/ti/cpsw-phy-sel.c b/drivers/net/ethernet/ti/cpsw-phy-sel.c new file mode 100644 index 000000000000..148da9ae8366 --- /dev/null +++ b/drivers/net/ethernet/ti/cpsw-phy-sel.c @@ -0,0 +1,161 @@ +/* Texas Instruments Ethernet Switch Driver + * + * Copyright (C) 2013 Texas Instruments + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/platform_device.h> +#include <linux/module.h> +#include <linux/netdevice.h> +#include <linux/phy.h> +#include <linux/of.h> +#include <linux/of_device.h> + +#include "cpsw.h" + +/* AM33xx SoC specific definitions for the CONTROL port */ +#define AM33XX_GMII_SEL_MODE_MII 0 +#define AM33XX_GMII_SEL_MODE_RMII 1 +#define AM33XX_GMII_SEL_MODE_RGMII 2 + +#define AM33XX_GMII_SEL_RMII2_IO_CLK_EN BIT(7) +#define AM33XX_GMII_SEL_RMII1_IO_CLK_EN BIT(6) + +struct cpsw_phy_sel_priv { + struct device *dev; + u32 __iomem *gmii_sel; + bool rmii_clock_external; + void (*cpsw_phy_sel)(struct cpsw_phy_sel_priv *priv, + phy_interface_t phy_mode, int slave); +}; + + +static void cpsw_gmii_sel_am3352(struct cpsw_phy_sel_priv *priv, + phy_interface_t phy_mode, int slave) +{ + u32 reg; + u32 mask; + u32 mode = 0; + + reg = readl(priv->gmii_sel); + + switch (phy_mode) { + case PHY_INTERFACE_MODE_RMII: + mode = AM33XX_GMII_SEL_MODE_RMII; + break; + + case PHY_INTERFACE_MODE_RGMII: + case PHY_INTERFACE_MODE_RGMII_ID: + case PHY_INTERFACE_MODE_RGMII_RXID: + case PHY_INTERFACE_MODE_RGMII_TXID: + mode = AM33XX_GMII_SEL_MODE_RGMII; + break; + + case PHY_INTERFACE_MODE_MII: + default: + mode = AM33XX_GMII_SEL_MODE_MII; + break; + }; + + mask = 0x3 << (slave * 2) | BIT(slave + 6); + mode <<= slave * 2; + + if (priv->rmii_clock_external) { + if (slave == 0) + mode |= AM33XX_GMII_SEL_RMII1_IO_CLK_EN; + else + mode |= AM33XX_GMII_SEL_RMII2_IO_CLK_EN; + } + + reg &= ~mask; + reg |= mode; + + writel(reg, priv->gmii_sel); +} + +static struct platform_driver cpsw_phy_sel_driver; +static int match(struct device *dev, void *data) +{ + struct device_node *node = (struct device_node *)data; + return dev->of_node == node && + dev->driver == &cpsw_phy_sel_driver.driver; +} + +void cpsw_phy_sel(struct device *dev, phy_interface_t phy_mode, int slave) +{ + struct device_node *node; + struct cpsw_phy_sel_priv *priv; + + node = of_get_child_by_name(dev->of_node, "cpsw-phy-sel"); + if (!node) { + dev_err(dev, "Phy mode driver DT not found\n"); + return; + } + + dev = bus_find_device(&platform_bus_type, NULL, node, match); + priv = dev_get_drvdata(dev); + + priv->cpsw_phy_sel(priv, phy_mode, slave); +} +EXPORT_SYMBOL_GPL(cpsw_phy_sel); + +static const struct of_device_id cpsw_phy_sel_id_table[] = { + { + .compatible = "ti,am3352-cpsw-phy-sel", + .data = &cpsw_gmii_sel_am3352, + }, + {} +}; +MODULE_DEVICE_TABLE(of, cpsw_phy_sel_id_table); + +static int cpsw_phy_sel_probe(struct platform_device *pdev) +{ + struct resource *res; + const struct of_device_id *of_id; + struct cpsw_phy_sel_priv *priv; + + of_id = of_match_node(cpsw_phy_sel_id_table, pdev->dev.of_node); + if (!of_id) + return -EINVAL; + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) { + dev_err(&pdev->dev, "unable to alloc memory for cpsw phy sel\n"); + return -ENOMEM; + } + + priv->cpsw_phy_sel = of_id->data; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "gmii-sel"); + priv->gmii_sel = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(priv->gmii_sel)) + return PTR_ERR(priv->gmii_sel); + + if (of_find_property(pdev->dev.of_node, "rmii-clock-ext", NULL)) + priv->rmii_clock_external = true; + + dev_set_drvdata(&pdev->dev, priv); + + return 0; +} + +static struct platform_driver cpsw_phy_sel_driver = { + .probe = cpsw_phy_sel_probe, + .driver = { + .name = "cpsw-phy-sel", + .owner = THIS_MODULE, + .of_match_table = cpsw_phy_sel_id_table, + }, +}; + +module_platform_driver(cpsw_phy_sel_driver); +MODULE_AUTHOR("Mugunthan V N <mugunthanvnm@ti.com>"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 79974e31187a..7290f11a937d 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -367,8 +367,6 @@ struct cpsw_priv { spinlock_t lock; struct platform_device *pdev; struct net_device *ndev; - struct resource *cpsw_res; - struct resource *cpsw_wr_res; struct napi_struct napi; struct device *dev; struct cpsw_platform_data data; @@ -1023,6 +1021,10 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv) dev_info(priv->dev, "phy found : id is : 0x%x\n", slave->phy->phy_id); phy_start(slave->phy); + + /* Configure GMII_SEL register */ + cpsw_phy_sel(&priv->pdev->dev, slave->phy->interface, + slave->slave_num); } } @@ -1712,62 +1714,55 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data, if (of_property_read_u32(node, "active_slave", &prop)) { pr_err("Missing active_slave property in the DT.\n"); - ret = -EINVAL; - goto error_ret; + return -EINVAL; } data->active_slave = prop; if (of_property_read_u32(node, "cpts_clock_mult", &prop)) { pr_err("Missing cpts_clock_mult property in the DT.\n"); - ret = -EINVAL; - goto error_ret; + return -EINVAL; } data->cpts_clock_mult = prop; if (of_property_read_u32(node, "cpts_clock_shift", &prop)) { pr_err("Missing cpts_clock_shift property in the DT.\n"); - ret = -EINVAL; - goto error_ret; + return -EINVAL; } data->cpts_clock_shift = prop; - data->slave_data = kcalloc(data->slaves, sizeof(struct cpsw_slave_data), - GFP_KERNEL); + data->slave_data = devm_kzalloc(&pdev->dev, data->slaves + * sizeof(struct cpsw_slave_data), + GFP_KERNEL); if (!data->slave_data) - return -EINVAL; + return -ENOMEM; if (of_property_read_u32(node, "cpdma_channels", &prop)) { pr_err("Missing cpdma_channels property in the DT.\n"); - ret = -EINVAL; - goto error_ret; + return -EINVAL; } data->channels = prop; if (of_property_read_u32(node, "ale_entries", &prop)) { pr_err("Missing ale_entries property in the DT.\n"); - ret = -EINVAL; - goto error_ret; + return -EINVAL; } data->ale_entries = prop; if (of_property_read_u32(node, "bd_ram_size", &prop)) { pr_err("Missing bd_ram_size property in the DT.\n"); - ret = -EINVAL; - goto error_ret; + return -EINVAL; } data->bd_ram_size = prop; if (of_property_read_u32(node, "rx_descs", &prop)) { pr_err("Missing rx_descs property in the DT.\n"); - ret = -EINVAL; - goto error_ret; + return -EINVAL; } data->rx_descs = prop; if (of_property_read_u32(node, "mac_control", &prop)) { pr_err("Missing mac_control property in the DT.\n"); - ret = -EINVAL; - goto error_ret; + return -EINVAL; } data->mac_control = prop; @@ -1794,8 +1789,7 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data, parp = of_get_property(slave_node, "phy_id", &lenp); if ((parp == NULL) || (lenp != (sizeof(void *) * 2))) { pr_err("Missing slave[%d] phy_id property\n", i); - ret = -EINVAL; - goto error_ret; + return -EINVAL; } mdio_node = of_find_node_by_phandle(be32_to_cpup(parp)); phyid = be32_to_cpup(parp+1); @@ -1825,10 +1819,6 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data, } return 0; - -error_ret: - kfree(data->slave_data); - return ret; } static int cpsw_probe_dual_emac(struct platform_device *pdev, @@ -1870,7 +1860,6 @@ static int cpsw_probe_dual_emac(struct platform_device *pdev, priv_sl2->coal_intvl = 0; priv_sl2->bus_freq_mhz = priv->bus_freq_mhz; - priv_sl2->cpsw_res = priv->cpsw_res; priv_sl2->regs = priv->regs; priv_sl2->host_port = priv->host_port; priv_sl2->host_port_regs = priv->host_port_regs; @@ -1914,8 +1903,8 @@ static int cpsw_probe(struct platform_device *pdev) struct cpsw_priv *priv; struct cpdma_params dma_params; struct cpsw_ale_params ale_params; - void __iomem *ss_regs, *wr_regs; - struct resource *res; + void __iomem *ss_regs; + struct resource *res, *ss_res; u32 slave_offset, sliver_offset, slave_size; int ret = 0, i, k = 0; @@ -1951,7 +1940,7 @@ static int cpsw_probe(struct platform_device *pdev) if (cpsw_probe_dt(&priv->data, pdev)) { pr_err("cpsw: platform data missing\n"); ret = -ENODEV; - goto clean_ndev_ret; + goto clean_runtime_disable_ret; } data = &priv->data; @@ -1965,11 +1954,12 @@ static int cpsw_probe(struct platform_device *pdev) memcpy(ndev->dev_addr, priv->mac_addr, ETH_ALEN); - priv->slaves = kzalloc(sizeof(struct cpsw_slave) * data->slaves, - GFP_KERNEL); + priv->slaves = devm_kzalloc(&pdev->dev, + sizeof(struct cpsw_slave) * data->slaves, + GFP_KERNEL); if (!priv->slaves) { - ret = -EBUSY; - goto clean_ndev_ret; + ret = -ENOMEM; + goto clean_runtime_disable_ret; } for (i = 0; i < data->slaves; i++) priv->slaves[i].slave_num = i; @@ -1977,55 +1967,31 @@ static int cpsw_probe(struct platform_device *pdev) priv->slaves[0].ndev = ndev; priv->emac_port = 0; - priv->clk = clk_get(&pdev->dev, "fck"); + priv->clk = devm_clk_get(&pdev->dev, "fck"); if (IS_ERR(priv->clk)) { - dev_err(&pdev->dev, "fck is not found\n"); + dev_err(priv->dev, "fck is not found\n"); ret = -ENODEV; - goto clean_slave_ret; + goto clean_runtime_disable_ret; } priv->coal_intvl = 0; priv->bus_freq_mhz = clk_get_rate(priv->clk) / 1000000; - priv->cpsw_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!priv->cpsw_res) { - dev_err(priv->dev, "error getting i/o resource\n"); - ret = -ENOENT; - goto clean_clk_ret; - } - if (!request_mem_region(priv->cpsw_res->start, - resource_size(priv->cpsw_res), ndev->name)) { - dev_err(priv->dev, "failed request i/o region\n"); - ret = -ENXIO; - goto clean_clk_ret; - } - ss_regs = ioremap(priv->cpsw_res->start, resource_size(priv->cpsw_res)); - if (!ss_regs) { - dev_err(priv->dev, "unable to map i/o region\n"); - goto clean_cpsw_iores_ret; + ss_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + ss_regs = devm_ioremap_resource(&pdev->dev, ss_res); + if (IS_ERR(ss_regs)) { + ret = PTR_ERR(ss_regs); + goto clean_runtime_disable_ret; } priv->regs = ss_regs; priv->version = __raw_readl(&priv->regs->id_ver); priv->host_port = HOST_PORT_NUM; - priv->cpsw_wr_res = platform_get_resource(pdev, IORESOURCE_MEM, 1); - if (!priv->cpsw_wr_res) { - dev_err(priv->dev, "error getting i/o resource\n"); - ret = -ENOENT; - goto clean_iomap_ret; - } - if (!request_mem_region(priv->cpsw_wr_res->start, - resource_size(priv->cpsw_wr_res), ndev->name)) { - dev_err(priv->dev, "failed request i/o region\n"); - ret = -ENXIO; - goto clean_iomap_ret; + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + priv->wr_regs = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(priv->wr_regs)) { + ret = PTR_ERR(priv->wr_regs); + goto clean_runtime_disable_ret; } - wr_regs = ioremap(priv->cpsw_wr_res->start, - resource_size(priv->cpsw_wr_res)); - if (!wr_regs) { - dev_err(priv->dev, "unable to map i/o region\n"); - goto clean_cpsw_wr_iores_ret; - } - priv->wr_regs = wr_regs; memset(&dma_params, 0, sizeof(dma_params)); memset(&ale_params, 0, sizeof(ale_params)); @@ -2056,12 +2022,12 @@ static int cpsw_probe(struct platform_device *pdev) slave_size = CPSW2_SLAVE_SIZE; sliver_offset = CPSW2_SLIVER_OFFSET; dma_params.desc_mem_phys = - (u32 __force) priv->cpsw_res->start + CPSW2_BD_OFFSET; + (u32 __force) ss_res->start + CPSW2_BD_OFFSET; break; default: dev_err(priv->dev, "unknown version 0x%08x\n", priv->version); ret = -ENODEV; - goto clean_cpsw_wr_iores_ret; + goto clean_runtime_disable_ret; } for (i = 0; i < priv->data.slaves; i++) { struct cpsw_slave *slave = &priv->slaves[i]; @@ -2089,7 +2055,7 @@ static int cpsw_probe(struct platform_device *pdev) if (!priv->dma) { dev_err(priv->dev, "error initializing dma\n"); ret = -ENOMEM; - goto clean_wr_iomap_ret; + goto clean_runtime_disable_ret; } priv->txch = cpdma_chan_create(priv->dma, tx_chan_num(0), @@ -2124,8 +2090,8 @@ static int cpsw_probe(struct platform_device *pdev) while ((res = platform_get_resource(priv->pdev, IORESOURCE_IRQ, k))) { for (i = res->start; i <= res->end; i++) { - if (request_irq(i, cpsw_interrupt, 0, - dev_name(&pdev->dev), priv)) { + if (devm_request_irq(&pdev->dev, i, cpsw_interrupt, 0, + dev_name(priv->dev), priv)) { dev_err(priv->dev, "error attaching irq\n"); goto clean_ale_ret; } @@ -2147,7 +2113,7 @@ static int cpsw_probe(struct platform_device *pdev) if (ret) { dev_err(priv->dev, "error registering net device\n"); ret = -ENODEV; - goto clean_irq_ret; + goto clean_ale_ret; } if (cpts_register(&pdev->dev, priv->cpts, @@ -2155,44 +2121,27 @@ static int cpsw_probe(struct platform_device *pdev) dev_err(priv->dev, "error registering cpts device\n"); cpsw_notice(priv, probe, "initialized device (regs %x, irq %d)\n", - priv->cpsw_res->start, ndev->irq); + ss_res->start, ndev->irq); if (priv->data.dual_emac) { ret = cpsw_probe_dual_emac(pdev, priv); if (ret) { cpsw_err(priv, probe, "error probe slave 2 emac interface\n"); - goto clean_irq_ret; + goto clean_ale_ret; } } return 0; -clean_irq_ret: - for (i = 0; i < priv->num_irqs; i++) - free_irq(priv->irqs_table[i], priv); clean_ale_ret: cpsw_ale_destroy(priv->ale); clean_dma_ret: cpdma_chan_destroy(priv->txch); cpdma_chan_destroy(priv->rxch); cpdma_ctlr_destroy(priv->dma); -clean_wr_iomap_ret: - iounmap(priv->wr_regs); -clean_cpsw_wr_iores_ret: - release_mem_region(priv->cpsw_wr_res->start, - resource_size(priv->cpsw_wr_res)); -clean_iomap_ret: - iounmap(priv->regs); -clean_cpsw_iores_ret: - release_mem_region(priv->cpsw_res->start, - resource_size(priv->cpsw_res)); -clean_clk_ret: - clk_put(priv->clk); -clean_slave_ret: +clean_runtime_disable_ret: pm_runtime_disable(&pdev->dev); - kfree(priv->slaves); clean_ndev_ret: - kfree(priv->data.slave_data); free_netdev(priv->ndev); return ret; } @@ -2201,30 +2150,18 @@ static int cpsw_remove(struct platform_device *pdev) { struct net_device *ndev = platform_get_drvdata(pdev); struct cpsw_priv *priv = netdev_priv(ndev); - int i; if (priv->data.dual_emac) unregister_netdev(cpsw_get_slave_ndev(priv, 1)); unregister_netdev(ndev); cpts_unregister(priv->cpts); - for (i = 0; i < priv->num_irqs; i++) - free_irq(priv->irqs_table[i], priv); cpsw_ale_destroy(priv->ale); cpdma_chan_destroy(priv->txch); cpdma_chan_destroy(priv->rxch); cpdma_ctlr_destroy(priv->dma); - iounmap(priv->regs); - release_mem_region(priv->cpsw_res->start, - resource_size(priv->cpsw_res)); - iounmap(priv->wr_regs); - release_mem_region(priv->cpsw_wr_res->start, - resource_size(priv->cpsw_wr_res)); pm_runtime_disable(&pdev->dev); - clk_put(priv->clk); - kfree(priv->slaves); - kfree(priv->data.slave_data); if (priv->data.dual_emac) free_netdev(cpsw_get_slave_ndev(priv, 1)); free_netdev(ndev); @@ -2280,7 +2217,7 @@ static struct platform_driver cpsw_driver = { .name = "cpsw", .owner = THIS_MODULE, .pm = &cpsw_pm_ops, - .of_match_table = of_match_ptr(cpsw_of_mtable), + .of_match_table = cpsw_of_mtable, }, .probe = cpsw_probe, .remove = cpsw_remove, diff --git a/drivers/net/ethernet/ti/cpsw.h b/drivers/net/ethernet/ti/cpsw.h index eb3e101ec048..574f49da693f 100644 --- a/drivers/net/ethernet/ti/cpsw.h +++ b/drivers/net/ethernet/ti/cpsw.h @@ -39,4 +39,6 @@ struct cpsw_platform_data { bool dual_emac; /* Enable Dual EMAC mode */ }; +void cpsw_phy_sel(struct device *dev, phy_interface_t phy_mode, int slave); + #endif /* __CPSW_H__ */ diff --git a/drivers/net/ethernet/ti/cpts.h b/drivers/net/ethernet/ti/cpts.h index fe993cdd7e23..1a581ef7eee8 100644 --- a/drivers/net/ethernet/ti/cpts.h +++ b/drivers/net/ethernet/ti/cpts.h @@ -127,8 +127,8 @@ struct cpts { }; #ifdef CONFIG_TI_CPTS -extern void cpts_rx_timestamp(struct cpts *cpts, struct sk_buff *skb); -extern void cpts_tx_timestamp(struct cpts *cpts, struct sk_buff *skb); +void cpts_rx_timestamp(struct cpts *cpts, struct sk_buff *skb); +void cpts_tx_timestamp(struct cpts *cpts, struct sk_buff *skb); #else static inline void cpts_rx_timestamp(struct cpts *cpts, struct sk_buff *skb) { @@ -138,8 +138,7 @@ static inline void cpts_tx_timestamp(struct cpts *cpts, struct sk_buff *skb) } #endif -extern int cpts_register(struct device *dev, struct cpts *cpts, - u32 mult, u32 shift); -extern void cpts_unregister(struct cpts *cpts); +int cpts_register(struct device *dev, struct cpts *cpts, u32 mult, u32 shift); +void cpts_unregister(struct cpts *cpts); #endif diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c index 67df09ea9d04..fba1c489a911 100644 --- a/drivers/net/ethernet/ti/davinci_emac.c +++ b/drivers/net/ethernet/ti/davinci_emac.c @@ -1853,7 +1853,7 @@ static int davinci_emac_probe(struct platform_device *pdev) } /* MAC addr and PHY mask , RMII enable info from platform_data */ - memcpy(priv->mac_addr, pdata->mac_addr, 6); + memcpy(priv->mac_addr, pdata->mac_addr, ETH_ALEN); priv->phy_id = pdata->phy_id; priv->rmii_en = pdata->rmii_en; priv->version = pdata->version; diff --git a/drivers/net/ethernet/tile/tilegx.c b/drivers/net/ethernet/tile/tilegx.c index 13e6fff8ca23..628b736e5ae7 100644 --- a/drivers/net/ethernet/tile/tilegx.c +++ b/drivers/net/ethernet/tile/tilegx.c @@ -2230,7 +2230,7 @@ static void tile_net_dev_init(const char *name, const uint8_t *mac) nz_addr |= mac[i]; if (nz_addr) { - memcpy(dev->dev_addr, mac, 6); + memcpy(dev->dev_addr, mac, ETH_ALEN); dev->addr_len = 6; } else { eth_hw_addr_random(dev); diff --git a/drivers/net/ethernet/toshiba/ps3_gelic_net.h b/drivers/net/ethernet/toshiba/ps3_gelic_net.h index 309abb472aa2..8505196be9f5 100644 --- a/drivers/net/ethernet/toshiba/ps3_gelic_net.h +++ b/drivers/net/ethernet/toshiba/ps3_gelic_net.h @@ -359,27 +359,26 @@ static inline void *port_priv(struct gelic_port *port) } #ifdef CONFIG_PPC_EARLY_DEBUG_PS3GELIC -extern void udbg_shutdown_ps3gelic(void); +void udbg_shutdown_ps3gelic(void); #else static inline void udbg_shutdown_ps3gelic(void) {} #endif -extern int gelic_card_set_irq_mask(struct gelic_card *card, u64 mask); +int gelic_card_set_irq_mask(struct gelic_card *card, u64 mask); /* shared netdev ops */ -extern void gelic_card_up(struct gelic_card *card); -extern void gelic_card_down(struct gelic_card *card); -extern int gelic_net_open(struct net_device *netdev); -extern int gelic_net_stop(struct net_device *netdev); -extern int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev); -extern void gelic_net_set_multi(struct net_device *netdev); -extern void gelic_net_tx_timeout(struct net_device *netdev); -extern int gelic_net_change_mtu(struct net_device *netdev, int new_mtu); -extern int gelic_net_setup_netdev(struct net_device *netdev, - struct gelic_card *card); +void gelic_card_up(struct gelic_card *card); +void gelic_card_down(struct gelic_card *card); +int gelic_net_open(struct net_device *netdev); +int gelic_net_stop(struct net_device *netdev); +int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev); +void gelic_net_set_multi(struct net_device *netdev); +void gelic_net_tx_timeout(struct net_device *netdev); +int gelic_net_change_mtu(struct net_device *netdev, int new_mtu); +int gelic_net_setup_netdev(struct net_device *netdev, struct gelic_card *card); /* shared ethtool ops */ -extern void gelic_net_get_drvinfo(struct net_device *netdev, - struct ethtool_drvinfo *info); -extern void gelic_net_poll_controller(struct net_device *netdev); +void gelic_net_get_drvinfo(struct net_device *netdev, + struct ethtool_drvinfo *info); +void gelic_net_poll_controller(struct net_device *netdev); #endif /* _GELIC_NET_H */ diff --git a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.h b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.h index f7e51b7d7049..11f443d8e4ea 100644 --- a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.h +++ b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.h @@ -320,7 +320,7 @@ struct gelic_eurus_cmd { #define GELIC_WL_PRIV_SET_PSK (SIOCIWFIRSTPRIV + 0) #define GELIC_WL_PRIV_GET_PSK (SIOCIWFIRSTPRIV + 1) -extern int gelic_wl_driver_probe(struct gelic_card *card); -extern int gelic_wl_driver_remove(struct gelic_card *card); -extern void gelic_wl_interrupt(struct net_device *netdev, u64 status); +int gelic_wl_driver_probe(struct gelic_card *card); +int gelic_wl_driver_remove(struct gelic_card *card); +void gelic_wl_interrupt(struct net_device *netdev, u64 status); #endif /* _GELIC_WIRELESS_H */ diff --git a/drivers/net/ethernet/toshiba/spider_net.h b/drivers/net/ethernet/toshiba/spider_net.h index 4ba2135474d1..9b6af0845a11 100644 --- a/drivers/net/ethernet/toshiba/spider_net.h +++ b/drivers/net/ethernet/toshiba/spider_net.h @@ -29,8 +29,8 @@ #include <linux/sungem_phy.h> -extern int spider_net_stop(struct net_device *netdev); -extern int spider_net_open(struct net_device *netdev); +int spider_net_stop(struct net_device *netdev); +int spider_net_open(struct net_device *netdev); extern const struct ethtool_ops spider_net_ethtool_ops; diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c index c8f088ab5fdf..bdf697b184ae 100644 --- a/drivers/net/ethernet/via/via-rhine.c +++ b/drivers/net/ethernet/via/via-rhine.c @@ -32,7 +32,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #define DRV_NAME "via-rhine" -#define DRV_VERSION "1.5.0" +#define DRV_VERSION "1.5.1" #define DRV_RELDATE "2010-10-09" #include <linux/types.h> @@ -1704,7 +1704,12 @@ static netdev_tx_t rhine_start_tx(struct sk_buff *skb, cpu_to_le32(TXDESC | (skb->len >= ETH_ZLEN ? skb->len : ETH_ZLEN)); if (unlikely(vlan_tx_tag_present(skb))) { - rp->tx_ring[entry].tx_status = cpu_to_le32((vlan_tx_tag_get(skb)) << 16); + u16 vid_pcp = vlan_tx_tag_get(skb); + + /* drop CFI/DEI bit, register needs VID and PCP */ + vid_pcp = (vid_pcp & VLAN_VID_MASK) | + ((vid_pcp & VLAN_PRIO_MASK) >> 1); + rp->tx_ring[entry].tx_status = cpu_to_le32((vid_pcp) << 16); /* request tagging */ rp->tx_ring[entry].desc_length |= cpu_to_le32(0x020000); } diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c index b88121f240ca..0029148077a9 100644 --- a/drivers/net/ethernet/xilinx/ll_temac_main.c +++ b/drivers/net/ethernet/xilinx/ll_temac_main.c @@ -297,6 +297,12 @@ static int temac_dma_bd_init(struct net_device *ndev) lp->rx_bd_p + (sizeof(*lp->rx_bd_v) * (RX_BD_NUM - 1))); lp->dma_out(lp, TX_CURDESC_PTR, lp->tx_bd_p); + /* Init descriptor indexes */ + lp->tx_bd_ci = 0; + lp->tx_bd_next = 0; + lp->tx_bd_tail = 0; + lp->rx_bd_ci = 0; + return 0; out: diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c index 4c619ea5189f..74234a51c851 100644 --- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c +++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c @@ -31,7 +31,7 @@ #define DRIVER_NAME "xilinx_emaclite" /* Register offsets for the EmacLite Core */ -#define XEL_TXBUFF_OFFSET 0x0 /* Transmit Buffer */ +#define XEL_TXBUFF_OFFSET 0x0 /* Transmit Buffer */ #define XEL_MDIOADDR_OFFSET 0x07E4 /* MDIO Address Register */ #define XEL_MDIOWR_OFFSET 0x07E8 /* MDIO Write Data Register */ #define XEL_MDIORD_OFFSET 0x07EC /* MDIO Read Data Register */ @@ -63,13 +63,13 @@ #define XEL_MDIOCTRL_MDIOEN_MASK 0x00000008 /* MDIO Enable */ /* Global Interrupt Enable Register (GIER) Bit Masks */ -#define XEL_GIER_GIE_MASK 0x80000000 /* Global Enable */ +#define XEL_GIER_GIE_MASK 0x80000000 /* Global Enable */ /* Transmit Status Register (TSR) Bit Masks */ -#define XEL_TSR_XMIT_BUSY_MASK 0x00000001 /* Tx complete */ -#define XEL_TSR_PROGRAM_MASK 0x00000002 /* Program the MAC address */ -#define XEL_TSR_XMIT_IE_MASK 0x00000008 /* Tx interrupt enable bit */ -#define XEL_TSR_XMIT_ACTIVE_MASK 0x80000000 /* Buffer is active, SW bit +#define XEL_TSR_XMIT_BUSY_MASK 0x00000001 /* Tx complete */ +#define XEL_TSR_PROGRAM_MASK 0x00000002 /* Program the MAC address */ +#define XEL_TSR_XMIT_IE_MASK 0x00000008 /* Tx interrupt enable bit */ +#define XEL_TSR_XMIT_ACTIVE_MASK 0x80000000 /* Buffer is active, SW bit * only. This is not documented * in the HW spec */ @@ -77,21 +77,21 @@ #define XEL_TSR_PROG_MAC_ADDR (XEL_TSR_XMIT_BUSY_MASK | XEL_TSR_PROGRAM_MASK) /* Receive Status Register (RSR) */ -#define XEL_RSR_RECV_DONE_MASK 0x00000001 /* Rx complete */ -#define XEL_RSR_RECV_IE_MASK 0x00000008 /* Rx interrupt enable bit */ +#define XEL_RSR_RECV_DONE_MASK 0x00000001 /* Rx complete */ +#define XEL_RSR_RECV_IE_MASK 0x00000008 /* Rx interrupt enable bit */ /* Transmit Packet Length Register (TPLR) */ -#define XEL_TPLR_LENGTH_MASK 0x0000FFFF /* Tx packet length */ +#define XEL_TPLR_LENGTH_MASK 0x0000FFFF /* Tx packet length */ /* Receive Packet Length Register (RPLR) */ -#define XEL_RPLR_LENGTH_MASK 0x0000FFFF /* Rx packet length */ +#define XEL_RPLR_LENGTH_MASK 0x0000FFFF /* Rx packet length */ -#define XEL_HEADER_OFFSET 12 /* Offset to length field */ -#define XEL_HEADER_SHIFT 16 /* Shift value for length */ +#define XEL_HEADER_OFFSET 12 /* Offset to length field */ +#define XEL_HEADER_SHIFT 16 /* Shift value for length */ /* General Ethernet Definitions */ -#define XEL_ARP_PACKET_SIZE 28 /* Max ARP packet size */ -#define XEL_HEADER_IP_LENGTH_OFFSET 16 /* IP Length Offset */ +#define XEL_ARP_PACKET_SIZE 28 /* Max ARP packet size */ +#define XEL_HEADER_IP_LENGTH_OFFSET 16 /* IP Length Offset */ @@ -1075,14 +1075,9 @@ static int xemaclite_send(struct sk_buff *orig_skb, struct net_device *dev) * This function un maps the IO region of the Emaclite device and frees the net * device. */ -static void xemaclite_remove_ndev(struct net_device *ndev, - struct platform_device *pdev) +static void xemaclite_remove_ndev(struct net_device *ndev) { if (ndev) { - struct net_local *lp = netdev_priv(ndev); - - if (lp->base_addr) - devm_iounmap(&pdev->dev, lp->base_addr); free_netdev(ndev); } } @@ -1177,7 +1172,7 @@ static int xemaclite_of_probe(struct platform_device *ofdev) if (mac_address) /* Set the MAC address. */ - memcpy(ndev->dev_addr, mac_address, 6); + memcpy(ndev->dev_addr, mac_address, ETH_ALEN); else dev_warn(dev, "No MAC address found\n"); @@ -1214,7 +1209,7 @@ static int xemaclite_of_probe(struct platform_device *ofdev) return 0; error: - xemaclite_remove_ndev(ndev, ofdev); + xemaclite_remove_ndev(ndev); return rc; } @@ -1248,7 +1243,7 @@ static int xemaclite_of_remove(struct platform_device *of_dev) of_node_put(lp->phy_node); lp->phy_node = NULL; - xemaclite_remove_ndev(ndev, of_dev); + xemaclite_remove_ndev(ndev); return 0; } diff --git a/drivers/net/fddi/skfp/fplustm.c b/drivers/net/fddi/skfp/fplustm.c index a20ed1a98099..f83993590174 100644 --- a/drivers/net/fddi/skfp/fplustm.c +++ b/drivers/net/fddi/skfp/fplustm.c @@ -453,7 +453,7 @@ static void directed_beacon(struct s_smc *smc) */ * (char *) a = (char) ((long)DBEACON_INFO<<24L) ; a[1] = 0 ; - memcpy((char *)a+1,(char *) &smc->mib.m[MAC0].fddiMACUpstreamNbr,6) ; + memcpy((char *)a+1, (char *) &smc->mib.m[MAC0].fddiMACUpstreamNbr, ETH_ALEN); CHECK_NPP() ; /* set memory address reg for writes */ diff --git a/drivers/net/fddi/skfp/h/smc.h b/drivers/net/fddi/skfp/h/smc.h index 3ca308b28214..bd1166bf8f61 100644 --- a/drivers/net/fddi/skfp/h/smc.h +++ b/drivers/net/fddi/skfp/h/smc.h @@ -469,20 +469,20 @@ struct s_smc { extern const struct fddi_addr fddi_broadcast; -extern void all_selection_criteria(struct s_smc *smc); -extern void card_stop(struct s_smc *smc); -extern void init_board(struct s_smc *smc, u_char *mac_addr); -extern int init_fplus(struct s_smc *smc); -extern void init_plc(struct s_smc *smc); -extern int init_smt(struct s_smc *smc, u_char * mac_addr); -extern void mac1_irq(struct s_smc *smc, u_short stu, u_short stl); -extern void mac2_irq(struct s_smc *smc, u_short code_s2u, u_short code_s2l); -extern void mac3_irq(struct s_smc *smc, u_short code_s3u, u_short code_s3l); -extern int pcm_status_twisted(struct s_smc *smc); -extern void plc1_irq(struct s_smc *smc); -extern void plc2_irq(struct s_smc *smc); -extern void read_address(struct s_smc *smc, u_char * mac_addr); -extern void timer_irq(struct s_smc *smc); +void all_selection_criteria(struct s_smc *smc); +void card_stop(struct s_smc *smc); +void init_board(struct s_smc *smc, u_char *mac_addr); +int init_fplus(struct s_smc *smc); +void init_plc(struct s_smc *smc); +int init_smt(struct s_smc *smc, u_char *mac_addr); +void mac1_irq(struct s_smc *smc, u_short stu, u_short stl); +void mac2_irq(struct s_smc *smc, u_short code_s2u, u_short code_s2l); +void mac3_irq(struct s_smc *smc, u_short code_s3u, u_short code_s3l); +int pcm_status_twisted(struct s_smc *smc); +void plc1_irq(struct s_smc *smc); +void plc2_irq(struct s_smc *smc); +void read_address(struct s_smc *smc, u_char *mac_addr); +void timer_irq(struct s_smc *smc); #endif /* _SCMECM_ */ diff --git a/drivers/net/fddi/skfp/skfddi.c b/drivers/net/fddi/skfp/skfddi.c index f5d7305a5784..713d303a06a9 100644 --- a/drivers/net/fddi/skfp/skfddi.c +++ b/drivers/net/fddi/skfp/skfddi.c @@ -436,7 +436,7 @@ static int skfp_driver_init(struct net_device *dev) } read_address(smc, NULL); pr_debug("HW-Addr: %pMF\n", smc->hw.fddi_canon_addr.a); - memcpy(dev->dev_addr, smc->hw.fddi_canon_addr.a, 6); + memcpy(dev->dev_addr, smc->hw.fddi_canon_addr.a, ETH_ALEN); smt_reset_defaults(smc, 0); @@ -503,7 +503,7 @@ static int skfp_open(struct net_device *dev) * address. */ read_address(smc, NULL); - memcpy(dev->dev_addr, smc->hw.fddi_canon_addr.a, 6); + memcpy(dev->dev_addr, smc->hw.fddi_canon_addr.a, ETH_ALEN); init_smt(smc, NULL); smt_online(smc, 1); @@ -1213,7 +1213,7 @@ static void CheckSourceAddress(unsigned char *frame, unsigned char *hw_addr) if ((unsigned short) frame[1 + 10] != 0) return; SRBit = frame[1 + 6] & 0x01; - memcpy(&frame[1 + 6], hw_addr, 6); + memcpy(&frame[1 + 6], hw_addr, ETH_ALEN); frame[8] |= SRBit; } // CheckSourceAddress diff --git a/drivers/net/hamradio/baycom_ser_fdx.c b/drivers/net/hamradio/baycom_ser_fdx.c index a974727dd9a2..636b65c66d49 100644 --- a/drivers/net/hamradio/baycom_ser_fdx.c +++ b/drivers/net/hamradio/baycom_ser_fdx.c @@ -445,7 +445,7 @@ static int ser12_open(struct net_device *dev) outb(0, FCR(dev->base_addr)); /* disable FIFOs */ outb(0x0d, MCR(dev->base_addr)); outb(0, IER(dev->base_addr)); - if (request_irq(dev->irq, ser12_interrupt, IRQF_DISABLED | IRQF_SHARED, + if (request_irq(dev->irq, ser12_interrupt, IRQF_SHARED, "baycom_ser_fdx", dev)) { release_region(dev->base_addr, SER12_EXTENT); return -EBUSY; diff --git a/drivers/net/hamradio/baycom_ser_hdx.c b/drivers/net/hamradio/baycom_ser_hdx.c index e349d867449b..f9a8976195ba 100644 --- a/drivers/net/hamradio/baycom_ser_hdx.c +++ b/drivers/net/hamradio/baycom_ser_hdx.c @@ -490,7 +490,7 @@ static int ser12_open(struct net_device *dev) outb(0, FCR(dev->base_addr)); /* disable FIFOs */ outb(0x0d, MCR(dev->base_addr)); outb(0, IER(dev->base_addr)); - if (request_irq(dev->irq, ser12_interrupt, IRQF_DISABLED | IRQF_SHARED, + if (request_irq(dev->irq, ser12_interrupt, IRQF_SHARED, "baycom_ser12", dev)) { release_region(dev->base_addr, SER12_EXTENT); return -EBUSY; diff --git a/drivers/net/irda/sir-dev.h b/drivers/net/irda/sir-dev.h index 6d5b1e2b1289..f50b9c1c0639 100644 --- a/drivers/net/irda/sir-dev.h +++ b/drivers/net/irda/sir-dev.h @@ -102,28 +102,29 @@ struct sir_driver { /* exported */ -extern int irda_register_dongle(struct dongle_driver *new); -extern int irda_unregister_dongle(struct dongle_driver *drv); +int irda_register_dongle(struct dongle_driver *new); +int irda_unregister_dongle(struct dongle_driver *drv); -extern struct sir_dev * sirdev_get_instance(const struct sir_driver *drv, const char *name); -extern int sirdev_put_instance(struct sir_dev *self); +struct sir_dev *sirdev_get_instance(const struct sir_driver *drv, + const char *name); +int sirdev_put_instance(struct sir_dev *self); -extern int sirdev_set_dongle(struct sir_dev *dev, IRDA_DONGLE type); -extern void sirdev_write_complete(struct sir_dev *dev); -extern int sirdev_receive(struct sir_dev *dev, const unsigned char *cp, size_t count); +int sirdev_set_dongle(struct sir_dev *dev, IRDA_DONGLE type); +void sirdev_write_complete(struct sir_dev *dev); +int sirdev_receive(struct sir_dev *dev, const unsigned char *cp, size_t count); /* low level helpers for SIR device/dongle setup */ -extern int sirdev_raw_write(struct sir_dev *dev, const char *buf, int len); -extern int sirdev_raw_read(struct sir_dev *dev, char *buf, int len); -extern int sirdev_set_dtr_rts(struct sir_dev *dev, int dtr, int rts); +int sirdev_raw_write(struct sir_dev *dev, const char *buf, int len); +int sirdev_raw_read(struct sir_dev *dev, char *buf, int len); +int sirdev_set_dtr_rts(struct sir_dev *dev, int dtr, int rts); /* not exported */ -extern int sirdev_get_dongle(struct sir_dev *self, IRDA_DONGLE type); -extern int sirdev_put_dongle(struct sir_dev *self); +int sirdev_get_dongle(struct sir_dev *self, IRDA_DONGLE type); +int sirdev_put_dongle(struct sir_dev *self); -extern void sirdev_enable_rx(struct sir_dev *dev); -extern int sirdev_schedule_request(struct sir_dev *dev, int state, unsigned param); +void sirdev_enable_rx(struct sir_dev *dev); +int sirdev_schedule_request(struct sir_dev *dev, int state, unsigned param); /* inline helpers */ diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c index ac22283aaf23..bc71947b1ec3 100644 --- a/drivers/net/phy/at803x.c +++ b/drivers/net/phy/at803x.c @@ -100,6 +100,45 @@ static void at803x_get_wol(struct phy_device *phydev, wol->wolopts |= WAKE_MAGIC; } +static int at803x_suspend(struct phy_device *phydev) +{ + int value; + int wol_enabled; + + mutex_lock(&phydev->lock); + + value = phy_read(phydev, AT803X_INTR_ENABLE); + wol_enabled = value & AT803X_WOL_ENABLE; + + value = phy_read(phydev, MII_BMCR); + + if (wol_enabled) + value |= BMCR_ISOLATE; + else + value |= BMCR_PDOWN; + + phy_write(phydev, MII_BMCR, value); + + mutex_unlock(&phydev->lock); + + return 0; +} + +static int at803x_resume(struct phy_device *phydev) +{ + int value; + + mutex_lock(&phydev->lock); + + value = phy_read(phydev, MII_BMCR); + value &= ~(BMCR_PDOWN | BMCR_ISOLATE); + phy_write(phydev, MII_BMCR, value); + + mutex_unlock(&phydev->lock); + + return 0; +} + static int at803x_config_init(struct phy_device *phydev) { int val; @@ -161,10 +200,12 @@ static struct phy_driver at803x_driver[] = { .config_init = at803x_config_init, .set_wol = at803x_set_wol, .get_wol = at803x_get_wol, + .suspend = at803x_suspend, + .resume = at803x_resume, .features = PHY_GBIT_FEATURES, .flags = PHY_HAS_INTERRUPT, - .config_aneg = &genphy_config_aneg, - .read_status = &genphy_read_status, + .config_aneg = genphy_config_aneg, + .read_status = genphy_read_status, .driver = { .owner = THIS_MODULE, }, @@ -176,10 +217,12 @@ static struct phy_driver at803x_driver[] = { .config_init = at803x_config_init, .set_wol = at803x_set_wol, .get_wol = at803x_get_wol, + .suspend = at803x_suspend, + .resume = at803x_resume, .features = PHY_GBIT_FEATURES, .flags = PHY_HAS_INTERRUPT, - .config_aneg = &genphy_config_aneg, - .read_status = &genphy_read_status, + .config_aneg = genphy_config_aneg, + .read_status = genphy_read_status, .driver = { .owner = THIS_MODULE, }, @@ -191,10 +234,12 @@ static struct phy_driver at803x_driver[] = { .config_init = at803x_config_init, .set_wol = at803x_set_wol, .get_wol = at803x_get_wol, + .suspend = at803x_suspend, + .resume = at803x_resume, .features = PHY_GBIT_FEATURES, .flags = PHY_HAS_INTERRUPT, - .config_aneg = &genphy_config_aneg, - .read_status = &genphy_read_status, + .config_aneg = genphy_config_aneg, + .read_status = genphy_read_status, .driver = { .owner = THIS_MODULE, }, diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index 2e91477362d4..2e3c778ea9bf 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -34,9 +34,9 @@ #include <linux/marvell_phy.h> #include <linux/of.h> -#include <asm/io.h> +#include <linux/io.h> #include <asm/irq.h> -#include <asm/uaccess.h> +#include <linux/uaccess.h> #define MII_MARVELL_PHY_PAGE 22 diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index c31aad0004cb..3ae28f420868 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -287,6 +287,8 @@ static struct phy_driver ksphy_driver[] = { .read_status = genphy_read_status, .ack_interrupt = kszphy_ack_interrupt, .config_intr = ks8737_config_intr, + .suspend = genphy_suspend, + .resume = genphy_resume, .driver = { .owner = THIS_MODULE,}, }, { .phy_id = PHY_ID_KSZ8021, @@ -300,6 +302,8 @@ static struct phy_driver ksphy_driver[] = { .read_status = genphy_read_status, .ack_interrupt = kszphy_ack_interrupt, .config_intr = kszphy_config_intr, + .suspend = genphy_suspend, + .resume = genphy_resume, .driver = { .owner = THIS_MODULE,}, }, { .phy_id = PHY_ID_KSZ8031, @@ -313,6 +317,8 @@ static struct phy_driver ksphy_driver[] = { .read_status = genphy_read_status, .ack_interrupt = kszphy_ack_interrupt, .config_intr = kszphy_config_intr, + .suspend = genphy_suspend, + .resume = genphy_resume, .driver = { .owner = THIS_MODULE,}, }, { .phy_id = PHY_ID_KSZ8041, @@ -326,6 +332,8 @@ static struct phy_driver ksphy_driver[] = { .read_status = genphy_read_status, .ack_interrupt = kszphy_ack_interrupt, .config_intr = kszphy_config_intr, + .suspend = genphy_suspend, + .resume = genphy_resume, .driver = { .owner = THIS_MODULE,}, }, { .phy_id = PHY_ID_KSZ8051, @@ -339,6 +347,8 @@ static struct phy_driver ksphy_driver[] = { .read_status = genphy_read_status, .ack_interrupt = kszphy_ack_interrupt, .config_intr = kszphy_config_intr, + .suspend = genphy_suspend, + .resume = genphy_resume, .driver = { .owner = THIS_MODULE,}, }, { .phy_id = PHY_ID_KSZ8001, @@ -351,6 +361,8 @@ static struct phy_driver ksphy_driver[] = { .read_status = genphy_read_status, .ack_interrupt = kszphy_ack_interrupt, .config_intr = kszphy_config_intr, + .suspend = genphy_suspend, + .resume = genphy_resume, .driver = { .owner = THIS_MODULE,}, }, { .phy_id = PHY_ID_KSZ8081, @@ -363,6 +375,8 @@ static struct phy_driver ksphy_driver[] = { .read_status = genphy_read_status, .ack_interrupt = kszphy_ack_interrupt, .config_intr = kszphy_config_intr, + .suspend = genphy_suspend, + .resume = genphy_resume, .driver = { .owner = THIS_MODULE,}, }, { .phy_id = PHY_ID_KSZ8061, @@ -375,6 +389,8 @@ static struct phy_driver ksphy_driver[] = { .read_status = genphy_read_status, .ack_interrupt = kszphy_ack_interrupt, .config_intr = kszphy_config_intr, + .suspend = genphy_suspend, + .resume = genphy_resume, .driver = { .owner = THIS_MODULE,}, }, { .phy_id = PHY_ID_KSZ9021, @@ -387,6 +403,8 @@ static struct phy_driver ksphy_driver[] = { .read_status = genphy_read_status, .ack_interrupt = kszphy_ack_interrupt, .config_intr = ksz9021_config_intr, + .suspend = genphy_suspend, + .resume = genphy_resume, .driver = { .owner = THIS_MODULE, }, }, { .phy_id = PHY_ID_KSZ9031, @@ -400,6 +418,8 @@ static struct phy_driver ksphy_driver[] = { .read_status = genphy_read_status, .ack_interrupt = kszphy_ack_interrupt, .config_intr = ksz9021_config_intr, + .suspend = genphy_suspend, + .resume = genphy_resume, .driver = { .owner = THIS_MODULE, }, }, { .phy_id = PHY_ID_KSZ8873MLL, @@ -410,6 +430,8 @@ static struct phy_driver ksphy_driver[] = { .config_init = kszphy_config_init, .config_aneg = ksz8873mll_config_aneg, .read_status = ksz8873mll_read_status, + .suspend = genphy_suspend, + .resume = genphy_resume, .driver = { .owner = THIS_MODULE, }, }, { .phy_id = PHY_ID_KSZ886X, @@ -420,6 +442,8 @@ static struct phy_driver ksphy_driver[] = { .config_init = kszphy_config_init, .config_aneg = genphy_config_aneg, .read_status = genphy_read_status, + .suspend = genphy_suspend, + .resume = genphy_resume, .driver = { .owner = THIS_MODULE, }, } }; diff --git a/drivers/net/plip/plip.c b/drivers/net/plip/plip.c index 1f7bef90b467..7b4ff35c8bf7 100644 --- a/drivers/net/plip/plip.c +++ b/drivers/net/plip/plip.c @@ -1002,7 +1002,7 @@ plip_rewrite_address(const struct net_device *dev, struct ethhdr *eth) /* Any address will do - we take the first */ const struct in_ifaddr *ifa = in_dev->ifa_list; if (ifa) { - memcpy(eth->h_source, dev->dev_addr, 6); + memcpy(eth->h_source, dev->dev_addr, ETH_ALEN); memset(eth->h_dest, 0xfc, 2); memcpy(eth->h_dest+2, &ifa->ifa_address, 4); } diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c index a34d6bf5e43b..cc70ecfc7062 100644 --- a/drivers/net/slip/slip.c +++ b/drivers/net/slip/slip.c @@ -429,11 +429,13 @@ static void slip_write_wakeup(struct tty_struct *tty) if (!sl || sl->magic != SLIP_MAGIC || !netif_running(sl->dev)) return; + spin_lock(&sl->lock); if (sl->xleft <= 0) { /* Now serial buffer is almost free & we can start * transmission of another packet */ sl->dev->stats.tx_packets++; clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); + spin_unlock(&sl->lock); sl_unlock(sl); return; } @@ -441,6 +443,7 @@ static void slip_write_wakeup(struct tty_struct *tty) actual = tty->ops->write(tty, sl->xhead, sl->xleft); sl->xleft -= actual; sl->xhead += actual; + spin_unlock(&sl->lock); } static void sl_tx_timeout(struct net_device *dev) diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c index 8d5cac2d8e33..df507e6dbb9c 100644 --- a/drivers/net/usb/catc.c +++ b/drivers/net/usb/catc.c @@ -640,10 +640,10 @@ static void catc_set_multicast_list(struct net_device *netdev) { struct catc *catc = netdev_priv(netdev); struct netdev_hw_addr *ha; - u8 broadcast[6]; + u8 broadcast[ETH_ALEN]; u8 rx = RxEnable | RxPolarity | RxMultiCast; - memset(broadcast, 0xff, 6); + memset(broadcast, 0xff, ETH_ALEN); memset(catc->multicast, 0, 64); catc_multicast(broadcast, catc->multicast); @@ -778,7 +778,7 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id struct usb_device *usbdev = interface_to_usbdev(intf); struct net_device *netdev; struct catc *catc; - u8 broadcast[6]; + u8 broadcast[ETH_ALEN]; int i, pktsz; if (usb_set_interface(usbdev, @@ -882,7 +882,7 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id dev_dbg(dev, "Filling the multicast list.\n"); - memset(broadcast, 0xff, 6); + memset(broadcast, 0xff, ETH_ALEN); catc_multicast(broadcast, catc->multicast); catc_multicast(netdev->dev_addr, catc->multicast); catc_write_mem(catc, 0xfa80, catc->multicast, 64); diff --git a/drivers/net/usb/cdc-phonet.c b/drivers/net/usb/cdc-phonet.c index 7d78669000d7..6358d420e185 100644 --- a/drivers/net/usb/cdc-phonet.c +++ b/drivers/net/usb/cdc-phonet.c @@ -328,7 +328,7 @@ MODULE_DEVICE_TABLE(usb, usbpn_ids); static struct usb_driver usbpn_driver; -int usbpn_probe(struct usb_interface *intf, const struct usb_device_id *id) +static int usbpn_probe(struct usb_interface *intf, const struct usb_device_id *id) { static const char ifname[] = "usbpn%d"; const struct usb_cdc_union_desc *union_header = NULL; diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c index 2dbb9460349d..c6867f926cff 100644 --- a/drivers/net/usb/dm9601.c +++ b/drivers/net/usb/dm9601.c @@ -303,7 +303,7 @@ static void dm9601_set_multicast(struct net_device *net) rx_ctl |= 0x02; } else if (net->flags & IFF_ALLMULTI || netdev_mc_count(net) > DM_MAX_MCAST) { - rx_ctl |= 0x04; + rx_ctl |= 0x08; } else if (!netdev_mc_empty(net)) { struct netdev_hw_addr *ha; diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 6312332afeba..d03b6b6c64c0 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -143,16 +143,22 @@ static const struct net_device_ops qmi_wwan_netdev_ops = { .ndo_validate_addr = eth_validate_addr, }; -/* using a counter to merge subdriver requests with our own into a combined state */ +/* using a counter to merge subdriver requests with our own into a + * combined state + */ static int qmi_wwan_manage_power(struct usbnet *dev, int on) { struct qmi_wwan_state *info = (void *)&dev->data; int rv = 0; - dev_dbg(&dev->intf->dev, "%s() pmcount=%d, on=%d\n", __func__, atomic_read(&info->pmcount), on); + dev_dbg(&dev->intf->dev, "%s() pmcount=%d, on=%d\n", __func__, + atomic_read(&info->pmcount), on); - if ((on && atomic_add_return(1, &info->pmcount) == 1) || (!on && atomic_dec_and_test(&info->pmcount))) { - /* need autopm_get/put here to ensure the usbcore sees the new value */ + if ((on && atomic_add_return(1, &info->pmcount) == 1) || + (!on && atomic_dec_and_test(&info->pmcount))) { + /* need autopm_get/put here to ensure the usbcore sees + * the new value + */ rv = usb_autopm_get_interface(dev->intf); if (rv < 0) goto err; @@ -199,7 +205,8 @@ static int qmi_wwan_register_subdriver(struct usbnet *dev) atomic_set(&info->pmcount, 0); /* register subdriver */ - subdriver = usb_cdc_wdm_register(info->control, &dev->status->desc, 4096, &qmi_wwan_cdc_wdm_manage_power); + subdriver = usb_cdc_wdm_register(info->control, &dev->status->desc, + 4096, &qmi_wwan_cdc_wdm_manage_power); if (IS_ERR(subdriver)) { dev_err(&info->control->dev, "subdriver registration failed\n"); rv = PTR_ERR(subdriver); @@ -228,7 +235,8 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf) struct usb_driver *driver = driver_of(intf); struct qmi_wwan_state *info = (void *)&dev->data; - BUILD_BUG_ON((sizeof(((struct usbnet *)0)->data) < sizeof(struct qmi_wwan_state))); + BUILD_BUG_ON((sizeof(((struct usbnet *)0)->data) < + sizeof(struct qmi_wwan_state))); /* set up initial state */ info->control = intf; @@ -250,7 +258,8 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf) goto err; } if (h->bLength != sizeof(struct usb_cdc_header_desc)) { - dev_dbg(&intf->dev, "CDC header len %u\n", h->bLength); + dev_dbg(&intf->dev, "CDC header len %u\n", + h->bLength); goto err; } break; @@ -260,7 +269,8 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf) goto err; } if (h->bLength != sizeof(struct usb_cdc_union_desc)) { - dev_dbg(&intf->dev, "CDC union len %u\n", h->bLength); + dev_dbg(&intf->dev, "CDC union len %u\n", + h->bLength); goto err; } cdc_union = (struct usb_cdc_union_desc *)buf; @@ -271,15 +281,15 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf) goto err; } if (h->bLength != sizeof(struct usb_cdc_ether_desc)) { - dev_dbg(&intf->dev, "CDC ether len %u\n", h->bLength); + dev_dbg(&intf->dev, "CDC ether len %u\n", + h->bLength); goto err; } cdc_ether = (struct usb_cdc_ether_desc *)buf; break; } - /* - * Remember which CDC functional descriptors we've seen. Works + /* Remember which CDC functional descriptors we've seen. Works * for all types we care about, of which USB_CDC_ETHERNET_TYPE * (0x0f) is the highest numbered */ @@ -293,10 +303,14 @@ next_desc: /* Use separate control and data interfaces if we found a CDC Union */ if (cdc_union) { - info->data = usb_ifnum_to_if(dev->udev, cdc_union->bSlaveInterface0); - if (desc->bInterfaceNumber != cdc_union->bMasterInterface0 || !info->data) { - dev_err(&intf->dev, "bogus CDC Union: master=%u, slave=%u\n", - cdc_union->bMasterInterface0, cdc_union->bSlaveInterface0); + info->data = usb_ifnum_to_if(dev->udev, + cdc_union->bSlaveInterface0); + if (desc->bInterfaceNumber != cdc_union->bMasterInterface0 || + !info->data) { + dev_err(&intf->dev, + "bogus CDC Union: master=%u, slave=%u\n", + cdc_union->bMasterInterface0, + cdc_union->bSlaveInterface0); goto err; } } @@ -374,8 +388,7 @@ static int qmi_wwan_suspend(struct usb_interface *intf, pm_message_t message) struct qmi_wwan_state *info = (void *)&dev->data; int ret; - /* - * Both usbnet_suspend() and subdriver->suspend() MUST return 0 + /* Both usbnet_suspend() and subdriver->suspend() MUST return 0 * in system sleep context, otherwise, the resume callback has * to recover device from previous suspend failure. */ @@ -383,7 +396,8 @@ static int qmi_wwan_suspend(struct usb_interface *intf, pm_message_t message) if (ret < 0) goto err; - if (intf == info->control && info->subdriver && info->subdriver->suspend) + if (intf == info->control && info->subdriver && + info->subdriver->suspend) ret = info->subdriver->suspend(intf, message); if (ret < 0) usbnet_resume(intf); @@ -396,7 +410,8 @@ static int qmi_wwan_resume(struct usb_interface *intf) struct usbnet *dev = usb_get_intfdata(intf); struct qmi_wwan_state *info = (void *)&dev->data; int ret = 0; - bool callsub = (intf == info->control && info->subdriver && info->subdriver->resume); + bool callsub = (intf == info->control && info->subdriver && + info->subdriver->resume); if (callsub) ret = info->subdriver->resume(intf); @@ -714,7 +729,8 @@ static const struct usb_device_id products[] = { {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ {QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */ {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */ - {QMI_FIXED_INTF(0x1e2d, 0x12d1, 4)}, /* Cinterion PLxx */ + {QMI_FIXED_INTF(0x1bc7, 0x1201, 2)}, /* Telit LE920 */ + {QMI_FIXED_INTF(0x1e2d, 0x0060, 4)}, /* Cinterion PLxx */ /* 4. Gobi 1000 devices */ {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ @@ -776,7 +792,8 @@ static const struct usb_device_id products[] = { }; MODULE_DEVICE_TABLE(usb, products); -static int qmi_wwan_probe(struct usb_interface *intf, const struct usb_device_id *prod) +static int qmi_wwan_probe(struct usb_interface *intf, + const struct usb_device_id *prod) { struct usb_device_id *id = (struct usb_device_id *)prod; diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 7b331e613e02..bf94e10a37c8 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -1241,7 +1241,9 @@ static int build_dma_sg(const struct sk_buff *skb, struct urb *urb) if (num_sgs == 1) return 0; - urb->sg = kmalloc(num_sgs * sizeof(struct scatterlist), GFP_ATOMIC); + /* reserve one for zero packet */ + urb->sg = kmalloc((num_sgs + 1) * sizeof(struct scatterlist), + GFP_ATOMIC); if (!urb->sg) return -ENOMEM; @@ -1305,7 +1307,7 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb, if (build_dma_sg(skb, urb) < 0) goto drop; } - entry->length = length = urb->transfer_buffer_length; + length = urb->transfer_buffer_length; /* don't assume the hardware handles USB_ZERO_PACKET * NOTE: strictly conforming cdc-ether devices should expect @@ -1317,15 +1319,18 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb, if (length % dev->maxpacket == 0) { if (!(info->flags & FLAG_SEND_ZLP)) { if (!(info->flags & FLAG_MULTI_PACKET)) { - urb->transfer_buffer_length++; - if (skb_tailroom(skb)) { + length++; + if (skb_tailroom(skb) && !urb->num_sgs) { skb->data[skb->len] = 0; __skb_put(skb, 1); - } + } else if (urb->num_sgs) + sg_set_buf(&urb->sg[urb->num_sgs++], + dev->padding_pkt, 1); } } else urb->transfer_flags |= URB_ZERO_PACKET; } + entry->length = urb->transfer_buffer_length = length; spin_lock_irqsave(&dev->txq.lock, flags); retval = usb_autopm_get_interface_async(dev->intf); @@ -1509,6 +1514,7 @@ void usbnet_disconnect (struct usb_interface *intf) usb_kill_urb(dev->interrupt); usb_free_urb(dev->interrupt); + kfree(dev->padding_pkt); free_netdev(net); } @@ -1679,9 +1685,16 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) /* initialize max rx_qlen and tx_qlen */ usbnet_update_max_qlen(dev); + if (dev->can_dma_sg && !(info->flags & FLAG_SEND_ZLP) && + !(info->flags & FLAG_MULTI_PACKET)) { + dev->padding_pkt = kzalloc(1, GFP_KERNEL); + if (!dev->padding_pkt) + goto out4; + } + status = register_netdev (net); if (status) - goto out4; + goto out5; netif_info(dev, probe, dev->net, "register '%s' at usb-%s-%s, %s, %pM\n", udev->dev.driver->name, @@ -1699,6 +1712,8 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) return 0; +out5: + kfree(dev->padding_pkt); out4: usb_free_urb(dev->interrupt); out3: diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h index a03f358fd58b..12040a35d95d 100644 --- a/drivers/net/vmxnet3/vmxnet3_int.h +++ b/drivers/net/vmxnet3/vmxnet3_int.h @@ -410,9 +410,9 @@ int vmxnet3_create_queues(struct vmxnet3_adapter *adapter, u32 tx_ring_size, u32 rx_ring_size, u32 rx_ring2_size); -extern void vmxnet3_set_ethtool_ops(struct net_device *netdev); +void vmxnet3_set_ethtool_ops(struct net_device *netdev); -extern struct rtnl_link_stats64 * +struct rtnl_link_stats64 * vmxnet3_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats); extern char vmxnet3_driver_name[]; diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index d1292fe746bc..da8479479d01 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -952,8 +952,7 @@ void vxlan_sock_release(struct vxlan_sock *vs) spin_lock(&vn->sock_lock); hlist_del_rcu(&vs->hlist); - smp_wmb(); - vs->sock->sk->sk_user_data = NULL; + rcu_assign_sk_user_data(vs->sock->sk, NULL); vxlan_notify_del_rx_port(sk); spin_unlock(&vn->sock_lock); @@ -1048,8 +1047,7 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb) port = inet_sk(sk)->inet_sport; - smp_read_barrier_depends(); - vs = (struct vxlan_sock *)sk->sk_user_data; + vs = rcu_dereference_sk_user_data(sk); if (!vs) goto drop; @@ -2089,7 +2087,7 @@ static void vxlan_setup(struct net_device *dev) vxlan->age_timer.function = vxlan_cleanup; vxlan->age_timer.data = (unsigned long) vxlan; - inet_get_local_port_range(&low, &high); + inet_get_local_port_range(dev_net(dev), &low, &high); vxlan->port_min = low; vxlan->port_max = high; vxlan->dst_port = htons(vxlan_port); @@ -2302,8 +2300,7 @@ static struct vxlan_sock *vxlan_socket_create(struct net *net, __be16 port, atomic_set(&vs->refcnt, 1); vs->rcv = rcv; vs->data = data; - smp_wmb(); - vs->sock->sk->sk_user_data = vs; + rcu_assign_sk_user_data(vs->sock->sk, vs); spin_lock(&vn->sock_lock); hlist_add_head_rcu(&vs->hlist, vs_head(net, port)); diff --git a/drivers/net/wan/x25_asy.h b/drivers/net/wan/x25_asy.h index 8f0fc2e57e2b..f57ee67836ae 100644 --- a/drivers/net/wan/x25_asy.h +++ b/drivers/net/wan/x25_asy.h @@ -41,6 +41,6 @@ struct x25_asy { #define X25_ASY_MAGIC 0x5303 -extern int x25_asy_init(struct net_device *dev); +int x25_asy_init(struct net_device *dev); #endif /* _LINUX_X25_ASY.H */ diff --git a/drivers/net/wan/z85230.h b/drivers/net/wan/z85230.h index f29d554fc07d..2416a9d60bd6 100644 --- a/drivers/net/wan/z85230.h +++ b/drivers/net/wan/z85230.h @@ -395,20 +395,19 @@ struct z8530_dev extern u8 z8530_dead_port[]; extern u8 z8530_hdlc_kilostream_85230[]; extern u8 z8530_hdlc_kilostream[]; -extern irqreturn_t z8530_interrupt(int, void *); -extern void z8530_describe(struct z8530_dev *, char *mapping, unsigned long io); -extern int z8530_init(struct z8530_dev *); -extern int z8530_shutdown(struct z8530_dev *); -extern int z8530_sync_open(struct net_device *, struct z8530_channel *); -extern int z8530_sync_close(struct net_device *, struct z8530_channel *); -extern int z8530_sync_dma_open(struct net_device *, struct z8530_channel *); -extern int z8530_sync_dma_close(struct net_device *, struct z8530_channel *); -extern int z8530_sync_txdma_open(struct net_device *, struct z8530_channel *); -extern int z8530_sync_txdma_close(struct net_device *, struct z8530_channel *); -extern int z8530_channel_load(struct z8530_channel *, u8 *); -extern netdev_tx_t z8530_queue_xmit(struct z8530_channel *c, - struct sk_buff *skb); -extern void z8530_null_rx(struct z8530_channel *c, struct sk_buff *skb); +irqreturn_t z8530_interrupt(int, void *); +void z8530_describe(struct z8530_dev *, char *mapping, unsigned long io); +int z8530_init(struct z8530_dev *); +int z8530_shutdown(struct z8530_dev *); +int z8530_sync_open(struct net_device *, struct z8530_channel *); +int z8530_sync_close(struct net_device *, struct z8530_channel *); +int z8530_sync_dma_open(struct net_device *, struct z8530_channel *); +int z8530_sync_dma_close(struct net_device *, struct z8530_channel *); +int z8530_sync_txdma_open(struct net_device *, struct z8530_channel *); +int z8530_sync_txdma_close(struct net_device *, struct z8530_channel *); +int z8530_channel_load(struct z8530_channel *, u8 *); +netdev_tx_t z8530_queue_xmit(struct z8530_channel *c, struct sk_buff *skb); +void z8530_null_rx(struct z8530_channel *c, struct sk_buff *skb); /* diff --git a/drivers/net/wimax/i2400m/i2400m-usb.h b/drivers/net/wimax/i2400m/i2400m-usb.h index 9f1e947f3557..649ecad6844c 100644 --- a/drivers/net/wimax/i2400m/i2400m-usb.h +++ b/drivers/net/wimax/i2400m/i2400m-usb.h @@ -256,21 +256,20 @@ void i2400mu_init(struct i2400mu *i2400mu) i2400mu->rx_size_auto_shrink = 1; } -extern int i2400mu_notification_setup(struct i2400mu *); -extern void i2400mu_notification_release(struct i2400mu *); +int i2400mu_notification_setup(struct i2400mu *); +void i2400mu_notification_release(struct i2400mu *); -extern int i2400mu_rx_setup(struct i2400mu *); -extern void i2400mu_rx_release(struct i2400mu *); -extern void i2400mu_rx_kick(struct i2400mu *); +int i2400mu_rx_setup(struct i2400mu *); +void i2400mu_rx_release(struct i2400mu *); +void i2400mu_rx_kick(struct i2400mu *); -extern int i2400mu_tx_setup(struct i2400mu *); -extern void i2400mu_tx_release(struct i2400mu *); -extern void i2400mu_bus_tx_kick(struct i2400m *); +int i2400mu_tx_setup(struct i2400mu *); +void i2400mu_tx_release(struct i2400mu *); +void i2400mu_bus_tx_kick(struct i2400m *); -extern ssize_t i2400mu_bus_bm_cmd_send(struct i2400m *, - const struct i2400m_bootrom_header *, - size_t, int); -extern ssize_t i2400mu_bus_bm_wait_for_ack(struct i2400m *, - struct i2400m_bootrom_header *, - size_t); +ssize_t i2400mu_bus_bm_cmd_send(struct i2400m *, + const struct i2400m_bootrom_header *, size_t, + int); +ssize_t i2400mu_bus_bm_wait_for_ack(struct i2400m *, + struct i2400m_bootrom_header *, size_t); #endif /* #ifndef __I2400M_USB_H__ */ diff --git a/drivers/net/wimax/i2400m/i2400m.h b/drivers/net/wimax/i2400m/i2400m.h index 79c6505b5c20..5a34e72bab9a 100644 --- a/drivers/net/wimax/i2400m/i2400m.h +++ b/drivers/net/wimax/i2400m/i2400m.h @@ -710,18 +710,18 @@ enum i2400m_bri { I2400M_BRI_MAC_REINIT = 1 << 3, }; -extern void i2400m_bm_cmd_prepare(struct i2400m_bootrom_header *); -extern int i2400m_dev_bootstrap(struct i2400m *, enum i2400m_bri); -extern int i2400m_read_mac_addr(struct i2400m *); -extern int i2400m_bootrom_init(struct i2400m *, enum i2400m_bri); -extern int i2400m_is_boot_barker(struct i2400m *, const void *, size_t); +void i2400m_bm_cmd_prepare(struct i2400m_bootrom_header *); +int i2400m_dev_bootstrap(struct i2400m *, enum i2400m_bri); +int i2400m_read_mac_addr(struct i2400m *); +int i2400m_bootrom_init(struct i2400m *, enum i2400m_bri); +int i2400m_is_boot_barker(struct i2400m *, const void *, size_t); static inline int i2400m_is_d2h_barker(const void *buf) { const __le32 *barker = buf; return le32_to_cpu(*barker) == I2400M_D2H_MSG_BARKER; } -extern void i2400m_unknown_barker(struct i2400m *, const void *, size_t); +void i2400m_unknown_barker(struct i2400m *, const void *, size_t); /* Make/grok boot-rom header commands */ @@ -789,32 +789,31 @@ unsigned i2400m_brh_get_signature(const struct i2400m_bootrom_header *hdr) /* * Driver / device setup and internal functions */ -extern void i2400m_init(struct i2400m *); -extern int i2400m_reset(struct i2400m *, enum i2400m_reset_type); -extern void i2400m_netdev_setup(struct net_device *net_dev); -extern int i2400m_sysfs_setup(struct device_driver *); -extern void i2400m_sysfs_release(struct device_driver *); -extern int i2400m_tx_setup(struct i2400m *); -extern void i2400m_wake_tx_work(struct work_struct *); -extern void i2400m_tx_release(struct i2400m *); - -extern int i2400m_rx_setup(struct i2400m *); -extern void i2400m_rx_release(struct i2400m *); - -extern void i2400m_fw_cache(struct i2400m *); -extern void i2400m_fw_uncache(struct i2400m *); - -extern void i2400m_net_rx(struct i2400m *, struct sk_buff *, unsigned, - const void *, int); -extern void i2400m_net_erx(struct i2400m *, struct sk_buff *, - enum i2400m_cs); -extern void i2400m_net_wake_stop(struct i2400m *); +void i2400m_init(struct i2400m *); +int i2400m_reset(struct i2400m *, enum i2400m_reset_type); +void i2400m_netdev_setup(struct net_device *net_dev); +int i2400m_sysfs_setup(struct device_driver *); +void i2400m_sysfs_release(struct device_driver *); +int i2400m_tx_setup(struct i2400m *); +void i2400m_wake_tx_work(struct work_struct *); +void i2400m_tx_release(struct i2400m *); + +int i2400m_rx_setup(struct i2400m *); +void i2400m_rx_release(struct i2400m *); + +void i2400m_fw_cache(struct i2400m *); +void i2400m_fw_uncache(struct i2400m *); + +void i2400m_net_rx(struct i2400m *, struct sk_buff *, unsigned, const void *, + int); +void i2400m_net_erx(struct i2400m *, struct sk_buff *, enum i2400m_cs); +void i2400m_net_wake_stop(struct i2400m *); enum i2400m_pt; -extern int i2400m_tx(struct i2400m *, const void *, size_t, enum i2400m_pt); +int i2400m_tx(struct i2400m *, const void *, size_t, enum i2400m_pt); #ifdef CONFIG_DEBUG_FS -extern int i2400m_debugfs_add(struct i2400m *); -extern void i2400m_debugfs_rm(struct i2400m *); +int i2400m_debugfs_add(struct i2400m *); +void i2400m_debugfs_rm(struct i2400m *); #else static inline int i2400m_debugfs_add(struct i2400m *i2400m) { @@ -824,8 +823,8 @@ static inline void i2400m_debugfs_rm(struct i2400m *i2400m) {} #endif /* Initialize/shutdown the device */ -extern int i2400m_dev_initialize(struct i2400m *); -extern void i2400m_dev_shutdown(struct i2400m *); +int i2400m_dev_initialize(struct i2400m *); +void i2400m_dev_shutdown(struct i2400m *); extern struct attribute_group i2400m_dev_attr_group; @@ -873,21 +872,21 @@ void i2400m_put(struct i2400m *i2400m) dev_put(i2400m->wimax_dev.net_dev); } -extern int i2400m_dev_reset_handle(struct i2400m *, const char *); -extern int i2400m_pre_reset(struct i2400m *); -extern int i2400m_post_reset(struct i2400m *); -extern void i2400m_error_recovery(struct i2400m *); +int i2400m_dev_reset_handle(struct i2400m *, const char *); +int i2400m_pre_reset(struct i2400m *); +int i2400m_post_reset(struct i2400m *); +void i2400m_error_recovery(struct i2400m *); /* * _setup()/_release() are called by the probe/disconnect functions of * the bus-specific drivers. */ -extern int i2400m_setup(struct i2400m *, enum i2400m_bri bm_flags); -extern void i2400m_release(struct i2400m *); +int i2400m_setup(struct i2400m *, enum i2400m_bri bm_flags); +void i2400m_release(struct i2400m *); -extern int i2400m_rx(struct i2400m *, struct sk_buff *); -extern struct i2400m_msg_hdr *i2400m_tx_msg_get(struct i2400m *, size_t *); -extern void i2400m_tx_msg_sent(struct i2400m *); +int i2400m_rx(struct i2400m *, struct sk_buff *); +struct i2400m_msg_hdr *i2400m_tx_msg_get(struct i2400m *, size_t *); +void i2400m_tx_msg_sent(struct i2400m *); /* @@ -900,20 +899,19 @@ struct device *i2400m_dev(struct i2400m *i2400m) return i2400m->wimax_dev.net_dev->dev.parent; } -extern int i2400m_msg_check_status(const struct i2400m_l3l4_hdr *, - char *, size_t); -extern int i2400m_msg_size_check(struct i2400m *, - const struct i2400m_l3l4_hdr *, size_t); -extern struct sk_buff *i2400m_msg_to_dev(struct i2400m *, const void *, size_t); -extern void i2400m_msg_to_dev_cancel_wait(struct i2400m *, int); -extern void i2400m_report_hook(struct i2400m *, - const struct i2400m_l3l4_hdr *, size_t); -extern void i2400m_report_hook_work(struct work_struct *); -extern int i2400m_cmd_enter_powersave(struct i2400m *); -extern int i2400m_cmd_exit_idle(struct i2400m *); -extern struct sk_buff *i2400m_get_device_info(struct i2400m *); -extern int i2400m_firmware_check(struct i2400m *); -extern int i2400m_set_idle_timeout(struct i2400m *, unsigned); +int i2400m_msg_check_status(const struct i2400m_l3l4_hdr *, char *, size_t); +int i2400m_msg_size_check(struct i2400m *, const struct i2400m_l3l4_hdr *, + size_t); +struct sk_buff *i2400m_msg_to_dev(struct i2400m *, const void *, size_t); +void i2400m_msg_to_dev_cancel_wait(struct i2400m *, int); +void i2400m_report_hook(struct i2400m *, const struct i2400m_l3l4_hdr *, + size_t); +void i2400m_report_hook_work(struct work_struct *); +int i2400m_cmd_enter_powersave(struct i2400m *); +int i2400m_cmd_exit_idle(struct i2400m *); +struct sk_buff *i2400m_get_device_info(struct i2400m *); +int i2400m_firmware_check(struct i2400m *); +int i2400m_set_idle_timeout(struct i2400m *, unsigned); static inline struct usb_endpoint_descriptor *usb_get_epd(struct usb_interface *iface, int ep) @@ -921,10 +919,9 @@ struct usb_endpoint_descriptor *usb_get_epd(struct usb_interface *iface, int ep) return &iface->cur_altsetting->endpoint[ep].desc; } -extern int i2400m_op_rfkill_sw_toggle(struct wimax_dev *, - enum wimax_rf_state); -extern void i2400m_report_tlv_rf_switches_status( - struct i2400m *, const struct i2400m_tlv_rf_switches_status *); +int i2400m_op_rfkill_sw_toggle(struct wimax_dev *, enum wimax_rf_state); +void i2400m_report_tlv_rf_switches_status(struct i2400m *, + const struct i2400m_tlv_rf_switches_status *); /* * Helpers for firmware backwards compatibility @@ -968,8 +965,8 @@ void __i2400m_msleep(unsigned ms) /* module initialization helpers */ -extern int i2400m_barker_db_init(const char *); -extern void i2400m_barker_db_exit(void); +int i2400m_barker_db_init(const char *); +void i2400m_barker_db_exit(void); diff --git a/drivers/net/wireless/ath/ath10k/debug.h b/drivers/net/wireless/ath/ath10k/debug.h index fa581486626f..6576b82a8d86 100644 --- a/drivers/net/wireless/ath/ath10k/debug.h +++ b/drivers/net/wireless/ath/ath10k/debug.h @@ -38,9 +38,9 @@ enum ath10k_debug_mask { extern unsigned int ath10k_debug_mask; -extern __printf(1, 2) int ath10k_info(const char *fmt, ...); -extern __printf(1, 2) int ath10k_err(const char *fmt, ...); -extern __printf(1, 2) int ath10k_warn(const char *fmt, ...); +__printf(1, 2) int ath10k_info(const char *fmt, ...); +__printf(1, 2) int ath10k_err(const char *fmt, ...); +__printf(1, 2) int ath10k_warn(const char *fmt, ...); #ifdef CONFIG_ATH10K_DEBUGFS int ath10k_debug_start(struct ath10k *ar); @@ -80,7 +80,7 @@ static inline void ath10k_debug_read_target_stats(struct ath10k *ar, #endif /* CONFIG_ATH10K_DEBUGFS */ #ifdef CONFIG_ATH10K_DEBUG -extern __printf(2, 3) void ath10k_dbg(enum ath10k_debug_mask mask, +__printf(2, 3) void ath10k_dbg(enum ath10k_debug_mask mask, const char *fmt, ...); void ath10k_dbg_dump(enum ath10k_debug_mask mask, const char *msg, const char *prefix, diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 6803ead9b9cf..33cb19eb3d89 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -1761,7 +1761,7 @@ int ath10k_wmi_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid, const u8 *bssid) cmd = (struct wmi_vdev_up_cmd *)skb->data; cmd->vdev_id = __cpu_to_le32(vdev_id); cmd->vdev_assoc_id = __cpu_to_le32(aid); - memcpy(&cmd->vdev_bssid.addr, bssid, 6); + memcpy(&cmd->vdev_bssid.addr, bssid, ETH_ALEN); ath10k_dbg(ATH10K_DBG_WMI, "wmi mgmt vdev up id 0x%x assoc id %d bssid %pM\n", @@ -1921,7 +1921,7 @@ int ath10k_wmi_peer_set_param(struct ath10k *ar, u32 vdev_id, cmd->vdev_id = __cpu_to_le32(vdev_id); cmd->param_id = __cpu_to_le32(param_id); cmd->param_value = __cpu_to_le32(param_value); - memcpy(&cmd->peer_macaddr.addr, peer_addr, 6); + memcpy(&cmd->peer_macaddr.addr, peer_addr, ETH_ALEN); ath10k_dbg(ATH10K_DBG_WMI, "wmi vdev %d peer 0x%pM set param %d value %d\n", diff --git a/drivers/net/wireless/ath/ath6kl/common.h b/drivers/net/wireless/ath/ath6kl/common.h index 98a886154d9c..05debf700a84 100644 --- a/drivers/net/wireless/ath/ath6kl/common.h +++ b/drivers/net/wireless/ath/ath6kl/common.h @@ -22,8 +22,7 @@ #define ATH6KL_MAX_IE 256 -extern __printf(2, 3) -int ath6kl_printk(const char *level, const char *fmt, ...); +__printf(2, 3) int ath6kl_printk(const char *level, const char *fmt, ...); /* * Reflects the version of binary interface exposed by ATH6KL target diff --git a/drivers/net/wireless/ath/ath6kl/debug.h b/drivers/net/wireless/ath/ath6kl/debug.h index 74369de00fb5..ca9ba005f287 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.h +++ b/drivers/net/wireless/ath/ath6kl/debug.h @@ -50,11 +50,10 @@ enum ATH6K_DEBUG_MASK { }; extern unsigned int debug_mask; -extern __printf(2, 3) -int ath6kl_printk(const char *level, const char *fmt, ...); -extern __printf(1, 2) int ath6kl_info(const char *fmt, ...); -extern __printf(1, 2) int ath6kl_err(const char *fmt, ...); -extern __printf(1, 2) int ath6kl_warn(const char *fmt, ...); +__printf(2, 3) int ath6kl_printk(const char *level, const char *fmt, ...); +__printf(1, 2) int ath6kl_info(const char *fmt, ...); +__printf(1, 2) int ath6kl_err(const char *fmt, ...); +__printf(1, 2) int ath6kl_warn(const char *fmt, ...); enum ath6kl_war { ATH6KL_WAR_INVALID_RATE, diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 8878f2dada2d..15afde3c348b 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -954,7 +954,7 @@ void ath9k_ps_restore(struct ath_softc *sc); u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate); void ath_start_rfkill_poll(struct ath_softc *sc); -extern void ath9k_rfkill_poll_state(struct ieee80211_hw *hw); +void ath9k_rfkill_poll_state(struct ieee80211_hw *hw); void ath9k_calculate_iter_data(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ath9k_vif_iter_data *iter_data); diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 4ee472a5a4e4..ab9e3a8410bc 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -1270,13 +1270,6 @@ static void ath9k_antenna_check(struct ath_softc *sc, return; /* - * All MPDUs in an aggregate will use the same LNA - * as the first MPDU. - */ - if (rs->rs_isaggr && !rs->rs_firstaggr) - return; - - /* * Change the default rx antenna if rx diversity * chooses the other antenna 3 times in a row. */ diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 62c93a655df9..13f5434e7f6c 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -399,6 +399,7 @@ static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf) tbf->bf_buf_addr = bf->bf_buf_addr; memcpy(tbf->bf_desc, bf->bf_desc, sc->sc_ah->caps.tx_desc_len); tbf->bf_state = bf->bf_state; + tbf->bf_state.stale = false; return tbf; } @@ -1389,11 +1390,15 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid, u16 *ssn) { struct ath_atx_tid *txtid; + struct ath_txq *txq; struct ath_node *an; u8 density; an = (struct ath_node *)sta->drv_priv; txtid = ATH_AN_2_TID(an, tid); + txq = txtid->ac->txq; + + ath_txq_lock(sc, txq); /* update ampdu factor/density, they may have changed. This may happen * in HT IBSS when a beacon with HT-info is received after the station @@ -1417,6 +1422,8 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, memset(txtid->tx_buf, 0, sizeof(txtid->tx_buf)); txtid->baw_head = txtid->baw_tail = 0; + ath_txq_unlock_complete(sc, txq); + return 0; } @@ -1555,8 +1562,10 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw, __skb_unlink(bf->bf_mpdu, tid_q); list_add_tail(&bf->list, &bf_q); ath_set_rates(tid->an->vif, tid->an->sta, bf); - ath_tx_addto_baw(sc, tid, bf); - bf->bf_state.bf_type &= ~BUF_AGGR; + if (bf_isampdu(bf)) { + ath_tx_addto_baw(sc, tid, bf); + bf->bf_state.bf_type &= ~BUF_AGGR; + } if (bf_tail) bf_tail->bf_next = bf; @@ -1950,7 +1959,9 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, if (bf_is_ampdu_not_probing(bf)) txq->axq_ampdu_depth++; - bf = bf->bf_lastbf->bf_next; + bf_last = bf->bf_lastbf; + bf = bf_last->bf_next; + bf_last->bf_next = NULL; } } } diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c index 61c302a6bdea..5b340769d5bb 100644 --- a/drivers/net/wireless/ath/wil6210/cfg80211.c +++ b/drivers/net/wireless/ath/wil6210/cfg80211.c @@ -316,8 +316,8 @@ static int wil_cfg80211_connect(struct wiphy *wiphy, } conn.channel = ch - 1; - memcpy(conn.bssid, bss->bssid, 6); - memcpy(conn.dst_mac, bss->bssid, 6); + memcpy(conn.bssid, bss->bssid, ETH_ALEN); + memcpy(conn.dst_mac, bss->bssid, ETH_ALEN); /* * FW don't support scan after connection attempt */ diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index b827d51c30a3..a55ae6494c3b 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c @@ -844,18 +844,18 @@ static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev) if (priv->wep_is_on) frame_ctl |= IEEE80211_FCTL_PROTECTED; if (priv->operating_mode == IW_MODE_ADHOC) { - skb_copy_from_linear_data(skb, &header.addr1, 6); - memcpy(&header.addr2, dev->dev_addr, 6); - memcpy(&header.addr3, priv->BSSID, 6); + skb_copy_from_linear_data(skb, &header.addr1, ETH_ALEN); + memcpy(&header.addr2, dev->dev_addr, ETH_ALEN); + memcpy(&header.addr3, priv->BSSID, ETH_ALEN); } else { frame_ctl |= IEEE80211_FCTL_TODS; - memcpy(&header.addr1, priv->CurrentBSSID, 6); - memcpy(&header.addr2, dev->dev_addr, 6); - skb_copy_from_linear_data(skb, &header.addr3, 6); + memcpy(&header.addr1, priv->CurrentBSSID, ETH_ALEN); + memcpy(&header.addr2, dev->dev_addr, ETH_ALEN); + skb_copy_from_linear_data(skb, &header.addr3, ETH_ALEN); } if (priv->use_wpa) - memcpy(&header.addr4, SNAP_RFC1024, 6); + memcpy(&header.addr4, SNAP_RFC1024, ETH_ALEN); header.frame_control = cpu_to_le16(frame_ctl); /* Copy the wireless header into the card */ @@ -929,11 +929,11 @@ static void fast_rx_path(struct atmel_private *priv, } } - memcpy(skbp, header->addr1, 6); /* destination address */ + memcpy(skbp, header->addr1, ETH_ALEN); /* destination address */ if (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FROMDS) - memcpy(&skbp[6], header->addr3, 6); + memcpy(&skbp[ETH_ALEN], header->addr3, ETH_ALEN); else - memcpy(&skbp[6], header->addr2, 6); /* source address */ + memcpy(&skbp[ETH_ALEN], header->addr2, ETH_ALEN); /* source address */ skb->protocol = eth_type_trans(skb, priv->dev); skb->ip_summed = CHECKSUM_NONE; @@ -969,14 +969,14 @@ static void frag_rx_path(struct atmel_private *priv, u16 msdu_size, u16 rx_packet_loc, u32 crc, u16 seq_no, u8 frag_no, int more_frags) { - u8 mac4[6]; - u8 source[6]; + u8 mac4[ETH_ALEN]; + u8 source[ETH_ALEN]; struct sk_buff *skb; if (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FROMDS) - memcpy(source, header->addr3, 6); + memcpy(source, header->addr3, ETH_ALEN); else - memcpy(source, header->addr2, 6); + memcpy(source, header->addr2, ETH_ALEN); rx_packet_loc += 24; /* skip header */ @@ -984,9 +984,9 @@ static void frag_rx_path(struct atmel_private *priv, msdu_size -= 4; if (frag_no == 0) { /* first fragment */ - atmel_copy_to_host(priv->dev, mac4, rx_packet_loc, 6); - msdu_size -= 6; - rx_packet_loc += 6; + atmel_copy_to_host(priv->dev, mac4, rx_packet_loc, ETH_ALEN); + msdu_size -= ETH_ALEN; + rx_packet_loc += ETH_ALEN; if (priv->do_rx_crc) crc = crc32_le(crc, mac4, 6); @@ -994,9 +994,9 @@ static void frag_rx_path(struct atmel_private *priv, priv->frag_seq = seq_no; priv->frag_no = 1; priv->frag_len = msdu_size; - memcpy(priv->frag_source, source, 6); - memcpy(&priv->rx_buf[6], source, 6); - memcpy(priv->rx_buf, header->addr1, 6); + memcpy(priv->frag_source, source, ETH_ALEN); + memcpy(&priv->rx_buf[ETH_ALEN], source, ETH_ALEN); + memcpy(priv->rx_buf, header->addr1, ETH_ALEN); atmel_copy_to_host(priv->dev, &priv->rx_buf[12], rx_packet_loc, msdu_size); @@ -1006,13 +1006,13 @@ static void frag_rx_path(struct atmel_private *priv, atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + msdu_size, 4); if ((crc ^ 0xffffffff) != netcrc) { priv->dev->stats.rx_crc_errors++; - memset(priv->frag_source, 0xff, 6); + memset(priv->frag_source, 0xff, ETH_ALEN); } } } else if (priv->frag_no == frag_no && priv->frag_seq == seq_no && - memcmp(priv->frag_source, source, 6) == 0) { + memcmp(priv->frag_source, source, ETH_ALEN) == 0) { atmel_copy_to_host(priv->dev, &priv->rx_buf[12 + priv->frag_len], rx_packet_loc, msdu_size); @@ -1024,7 +1024,7 @@ static void frag_rx_path(struct atmel_private *priv, atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + msdu_size, 4); if ((crc ^ 0xffffffff) != netcrc) { priv->dev->stats.rx_crc_errors++; - memset(priv->frag_source, 0xff, 6); + memset(priv->frag_source, 0xff, ETH_ALEN); more_frags = 1; /* don't send broken assembly */ } } @@ -1033,7 +1033,7 @@ static void frag_rx_path(struct atmel_private *priv, priv->frag_no++; if (!more_frags) { /* last one */ - memset(priv->frag_source, 0xff, 6); + memset(priv->frag_source, 0xff, ETH_ALEN); if (!(skb = dev_alloc_skb(priv->frag_len + 14))) { priv->dev->stats.rx_dropped++; } else { @@ -1129,7 +1129,7 @@ static void rx_done_irq(struct atmel_private *priv) atmel_copy_to_host(priv->dev, (unsigned char *)&priv->rx_buf, rx_packet_loc + 24, msdu_size); /* we use the same buffer for frag reassembly and control packets */ - memset(priv->frag_source, 0xff, 6); + memset(priv->frag_source, 0xff, ETH_ALEN); if (priv->do_rx_crc) { /* last 4 octets is crc */ @@ -1557,7 +1557,7 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port, priv->last_qual = jiffies; priv->last_beacon_timestamp = 0; memset(priv->frag_source, 0xff, sizeof(priv->frag_source)); - memset(priv->BSSID, 0, 6); + memset(priv->BSSID, 0, ETH_ALEN); priv->CurrentBSSID[0] = 0xFF; /* Initialize to something invalid.... */ priv->station_was_associated = 0; @@ -1718,7 +1718,7 @@ static int atmel_get_wap(struct net_device *dev, char *extra) { struct atmel_private *priv = netdev_priv(dev); - memcpy(awrq->sa_data, priv->CurrentBSSID, 6); + memcpy(awrq->sa_data, priv->CurrentBSSID, ETH_ALEN); awrq->sa_family = ARPHRD_ETHER; return 0; @@ -2356,7 +2356,7 @@ static int atmel_get_scan(struct net_device *dev, for (i = 0; i < priv->BSS_list_entries; i++) { iwe.cmd = SIOCGIWAP; iwe.u.ap_addr.sa_family = ARPHRD_ETHER; - memcpy(iwe.u.ap_addr.sa_data, priv->BSSinfo[i].BSSID, 6); + memcpy(iwe.u.ap_addr.sa_data, priv->BSSinfo[i].BSSID, ETH_ALEN); current_ev = iwe_stream_add_event(info, current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_ADDR_LEN); @@ -2760,7 +2760,7 @@ static void atmel_enter_state(struct atmel_private *priv, int new_state) static void atmel_scan(struct atmel_private *priv, int specific_ssid) { struct { - u8 BSSID[6]; + u8 BSSID[ETH_ALEN]; u8 SSID[MAX_SSID_LENGTH]; u8 scan_type; u8 channel; @@ -2771,7 +2771,7 @@ static void atmel_scan(struct atmel_private *priv, int specific_ssid) u8 SSID_size; } cmd; - memset(cmd.BSSID, 0xff, 6); + memset(cmd.BSSID, 0xff, ETH_ALEN); if (priv->fast_scan) { cmd.SSID_size = priv->SSID_size; @@ -2816,7 +2816,7 @@ static void join(struct atmel_private *priv, int type) cmd.SSID_size = priv->SSID_size; memcpy(cmd.SSID, priv->SSID, priv->SSID_size); - memcpy(cmd.BSSID, priv->CurrentBSSID, 6); + memcpy(cmd.BSSID, priv->CurrentBSSID, ETH_ALEN); cmd.channel = (priv->channel & 0x7f); cmd.BSS_type = type; cmd.timeout = cpu_to_le16(2000); @@ -2837,7 +2837,7 @@ static void start(struct atmel_private *priv, int type) cmd.SSID_size = priv->SSID_size; memcpy(cmd.SSID, priv->SSID, priv->SSID_size); - memcpy(cmd.BSSID, priv->BSSID, 6); + memcpy(cmd.BSSID, priv->BSSID, ETH_ALEN); cmd.BSS_type = type; cmd.channel = (priv->channel & 0x7f); @@ -2883,9 +2883,9 @@ static void send_authentication_request(struct atmel_private *priv, u16 system, header.frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH); header.duration_id = cpu_to_le16(0x8000); header.seq_ctrl = 0; - memcpy(header.addr1, priv->CurrentBSSID, 6); - memcpy(header.addr2, priv->dev->dev_addr, 6); - memcpy(header.addr3, priv->CurrentBSSID, 6); + memcpy(header.addr1, priv->CurrentBSSID, ETH_ALEN); + memcpy(header.addr2, priv->dev->dev_addr, ETH_ALEN); + memcpy(header.addr3, priv->CurrentBSSID, ETH_ALEN); if (priv->wep_is_on && priv->CurrentAuthentTransactionSeqNum != 1) /* no WEP for authentication frames with TrSeqNo 1 */ @@ -2916,7 +2916,7 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc) struct ass_req_format { __le16 capability; __le16 listen_interval; - u8 ap[6]; /* nothing after here directly accessible */ + u8 ap[ETH_ALEN]; /* nothing after here directly accessible */ u8 ssid_el_id; u8 ssid_len; u8 ssid[MAX_SSID_LENGTH]; @@ -2930,9 +2930,9 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc) header.duration_id = cpu_to_le16(0x8000); header.seq_ctrl = 0; - memcpy(header.addr1, priv->CurrentBSSID, 6); - memcpy(header.addr2, priv->dev->dev_addr, 6); - memcpy(header.addr3, priv->CurrentBSSID, 6); + memcpy(header.addr1, priv->CurrentBSSID, ETH_ALEN); + memcpy(header.addr2, priv->dev->dev_addr, ETH_ALEN); + memcpy(header.addr3, priv->CurrentBSSID, ETH_ALEN); body.capability = cpu_to_le16(WLAN_CAPABILITY_ESS); if (priv->wep_is_on) @@ -2944,7 +2944,7 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc) /* current AP address - only in reassoc frame */ if (is_reassoc) { - memcpy(body.ap, priv->CurrentBSSID, 6); + memcpy(body.ap, priv->CurrentBSSID, ETH_ALEN); ssid_el_p = &body.ssid_el_id; bodysize = 18 + priv->SSID_size; } else { @@ -3021,7 +3021,7 @@ static void store_bss_info(struct atmel_private *priv, int i, index; for (index = -1, i = 0; i < priv->BSS_list_entries; i++) - if (memcmp(bss, priv->BSSinfo[i].BSSID, 6) == 0) + if (memcmp(bss, priv->BSSinfo[i].BSSID, ETH_ALEN) == 0) index = i; /* If we process a probe and an entry from this BSS exists @@ -3032,7 +3032,7 @@ static void store_bss_info(struct atmel_private *priv, if (priv->BSS_list_entries == MAX_BSS_ENTRIES) return; index = priv->BSS_list_entries++; - memcpy(priv->BSSinfo[index].BSSID, bss, 6); + memcpy(priv->BSSinfo[index].BSSID, bss, ETH_ALEN); priv->BSSinfo[index].RSSI = rssi; } else { if (rssi > priv->BSSinfo[index].RSSI) @@ -3235,7 +3235,7 @@ static void atmel_join_bss(struct atmel_private *priv, int bss_index) { struct bss_info *bss = &priv->BSSinfo[bss_index]; - memcpy(priv->CurrentBSSID, bss->BSSID, 6); + memcpy(priv->CurrentBSSID, bss->BSSID, ETH_ALEN); memcpy(priv->SSID, bss->SSID, priv->SSID_size = bss->SSIDsize); /* The WPA stuff cares about the current AP address */ @@ -3767,7 +3767,7 @@ static int probe_atmel_card(struct net_device *dev) 0x00, 0x04, 0x25, 0x00, 0x00, 0x00 }; printk(KERN_ALERT "%s: *** Invalid MAC address. UPGRADE Firmware ****\n", dev->name); - memcpy(dev->dev_addr, default_mac, 6); + memcpy(dev->dev_addr, default_mac, ETH_ALEN); } } @@ -3819,7 +3819,7 @@ static void build_wpa_mib(struct atmel_private *priv) struct { /* NB this is matched to the hardware, don't change. */ u8 cipher_default_key_value[MAX_ENCRYPTION_KEYS][MAX_ENCRYPTION_KEY_SIZE]; - u8 receiver_address[6]; + u8 receiver_address[ETH_ALEN]; u8 wep_is_on; u8 default_key; /* 0..3 */ u8 group_key; @@ -3837,7 +3837,7 @@ static void build_wpa_mib(struct atmel_private *priv) mib.wep_is_on = priv->wep_is_on; mib.exclude_unencrypted = priv->exclude_unencrypted; - memcpy(mib.receiver_address, priv->CurrentBSSID, 6); + memcpy(mib.receiver_address, priv->CurrentBSSID, ETH_ALEN); /* zero all the keys before adding in valid ones. */ memset(mib.cipher_default_key_value, 0, sizeof(mib.cipher_default_key_value)); diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index 8cb206a89083..4ae63f4ddfb2 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c @@ -278,7 +278,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, else txhdr->phy_rate = b43_plcp_get_ratecode_cck(rate); txhdr->mac_frame_ctl = wlhdr->frame_control; - memcpy(txhdr->tx_receiver, wlhdr->addr1, 6); + memcpy(txhdr->tx_receiver, wlhdr->addr1, ETH_ALEN); /* Calculate duration for fallback rate */ if ((rate_fb == rate) || diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c index 849a28c80302..86588c9ff0f2 100644 --- a/drivers/net/wireless/b43legacy/xmit.c +++ b/drivers/net/wireless/b43legacy/xmit.c @@ -215,7 +215,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, rate_fb_ofdm = b43legacy_is_ofdm_rate(rate_fb->hw_value); txhdr->mac_frame_ctl = wlhdr->frame_control; - memcpy(txhdr->tx_receiver, wlhdr->addr1, 6); + memcpy(txhdr->tx_receiver, wlhdr->addr1, ETH_ALEN); /* Calculate duration for fallback rate */ if ((rate_fb->hw_value == rate) || diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c index 091c905871cc..2a23bf2b904d 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -459,8 +459,6 @@ static struct sdio_driver brcmf_sdmmc_driver = { static int brcmf_sdio_pd_probe(struct platform_device *pdev) { - int ret; - brcmf_dbg(SDIO, "Enter\n"); brcmfmac_sdio_pdata = dev_get_platdata(&pdev->dev); @@ -468,11 +466,7 @@ static int brcmf_sdio_pd_probe(struct platform_device *pdev) if (brcmfmac_sdio_pdata->power_on) brcmfmac_sdio_pdata->power_on(); - ret = sdio_register_driver(&brcmf_sdmmc_driver); - if (ret) - brcmf_err("sdio_register_driver failed: %d\n", ret); - - return ret; + return 0; } static int brcmf_sdio_pd_remove(struct platform_device *pdev) @@ -495,6 +489,15 @@ static struct platform_driver brcmf_sdio_pd = { } }; +void brcmf_sdio_register(void) +{ + int ret; + + ret = sdio_register_driver(&brcmf_sdmmc_driver); + if (ret) + brcmf_err("sdio_register_driver failed: %d\n", ret); +} + void brcmf_sdio_exit(void) { brcmf_dbg(SDIO, "Enter\n"); @@ -505,18 +508,13 @@ void brcmf_sdio_exit(void) sdio_unregister_driver(&brcmf_sdmmc_driver); } -void brcmf_sdio_init(void) +void __init brcmf_sdio_init(void) { int ret; brcmf_dbg(SDIO, "Enter\n"); ret = platform_driver_probe(&brcmf_sdio_pd, brcmf_sdio_pd_probe); - if (ret == -ENODEV) { - brcmf_dbg(SDIO, "No platform data available, registering without.\n"); - ret = sdio_register_driver(&brcmf_sdmmc_driver); - } - - if (ret) - brcmf_err("driver registration failed: %d\n", ret); + if (ret == -ENODEV) + brcmf_dbg(SDIO, "No platform data available.\n"); } diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index 4de9aac6666d..899a2ada5b82 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h @@ -630,29 +630,29 @@ struct brcmf_skb_reorder_data { u8 *reorder; }; -extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev); +int brcmf_netdev_wait_pend8021x(struct net_device *ndev); /* Return pointer to interface name */ -extern char *brcmf_ifname(struct brcmf_pub *drvr, int idx); +char *brcmf_ifname(struct brcmf_pub *drvr, int idx); /* Query dongle */ -extern int brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, - uint cmd, void *buf, uint len); -extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, - void *buf, uint len); +int brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, + void *buf, uint len); +int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, + void *buf, uint len); /* Remove any protocol-specific data header. */ -extern int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx, - struct sk_buff *rxp); +int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx, + struct sk_buff *rxp); -extern int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked); -extern struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, - s32 ifidx, char *name, u8 *mac_addr); -extern void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx); +int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked); +struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx, + char *name, u8 *mac_addr); +void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx); void brcmf_txflowblock_if(struct brcmf_if *ifp, enum brcmf_netif_stop_reason reason, bool state); -extern u32 brcmf_get_chip_info(struct brcmf_if *ifp); -extern void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, - bool success); +u32 brcmf_get_chip_info(struct brcmf_if *ifp); +void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, + bool success); #endif /* _BRCMF_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h index 200ee9b485bf..a6eb09e5d46f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h @@ -132,34 +132,34 @@ struct pktq *brcmf_bus_gettxq(struct brcmf_bus *bus) * interface functions from common layer */ -extern bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, - struct sk_buff *pkt, int prec); +bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, struct sk_buff *pkt, + int prec); /* Receive frame for delivery to OS. Callee disposes of rxp. */ -extern void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp); +void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp); /* Indication from bus module regarding presence/insertion of dongle. */ -extern int brcmf_attach(uint bus_hdrlen, struct device *dev); +int brcmf_attach(uint bus_hdrlen, struct device *dev); /* Indication from bus module regarding removal/absence of dongle */ -extern void brcmf_detach(struct device *dev); +void brcmf_detach(struct device *dev); /* Indication from bus module that dongle should be reset */ -extern void brcmf_dev_reset(struct device *dev); +void brcmf_dev_reset(struct device *dev); /* Indication from bus module to change flow-control state */ -extern void brcmf_txflowblock(struct device *dev, bool state); +void brcmf_txflowblock(struct device *dev, bool state); /* Notify the bus has transferred the tx packet to firmware */ -extern void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, - bool success); +void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success); -extern int brcmf_bus_start(struct device *dev); +int brcmf_bus_start(struct device *dev); #ifdef CONFIG_BRCMFMAC_SDIO -extern void brcmf_sdio_exit(void); -extern void brcmf_sdio_init(void); +void brcmf_sdio_exit(void); +void brcmf_sdio_init(void); +void brcmf_sdio_register(void); #endif #ifdef CONFIG_BRCMFMAC_USB -extern void brcmf_usb_exit(void); -extern void brcmf_usb_init(void); +void brcmf_usb_exit(void); +void brcmf_usb_register(void); #endif #endif /* _BRCMF_BUS_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index 42bf19a2eeee..64e9cff241b9 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -1225,21 +1225,23 @@ u32 brcmf_get_chip_info(struct brcmf_if *ifp) return bus->chip << 4 | bus->chiprev; } -static void brcmf_driver_init(struct work_struct *work) +static void brcmf_driver_register(struct work_struct *work) { - brcmf_debugfs_init(); - #ifdef CONFIG_BRCMFMAC_SDIO - brcmf_sdio_init(); + brcmf_sdio_register(); #endif #ifdef CONFIG_BRCMFMAC_USB - brcmf_usb_init(); + brcmf_usb_register(); #endif } -static DECLARE_WORK(brcmf_driver_work, brcmf_driver_init); +static DECLARE_WORK(brcmf_driver_work, brcmf_driver_register); static int __init brcmfmac_module_init(void) { + brcmf_debugfs_init(); +#ifdef CONFIG_BRCMFMAC_SDIO + brcmf_sdio_init(); +#endif if (!schedule_work(&brcmf_driver_work)) return -EBUSY; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h index ef9179883748..53c6e710f2cb 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h @@ -22,21 +22,21 @@ */ /* Linkage, sets prot link and updates hdrlen in pub */ -extern int brcmf_proto_attach(struct brcmf_pub *drvr); +int brcmf_proto_attach(struct brcmf_pub *drvr); /* Unlink, frees allocated protocol memory (including brcmf_proto) */ -extern void brcmf_proto_detach(struct brcmf_pub *drvr); +void brcmf_proto_detach(struct brcmf_pub *drvr); /* Stop protocol: sync w/dongle state. */ -extern void brcmf_proto_stop(struct brcmf_pub *drvr); +void brcmf_proto_stop(struct brcmf_pub *drvr); /* Add any protocol-specific data header. * Caller must reserve prot_hdrlen prepend space. */ -extern void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx, u8 offset, - struct sk_buff *txp); +void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx, u8 offset, + struct sk_buff *txp); /* Sets dongle media info (drv_version, mac address). */ -extern int brcmf_c_preinit_dcmds(struct brcmf_if *ifp); +int brcmf_c_preinit_dcmds(struct brcmf_if *ifp); #endif /* _BRCMF_PROTO_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h index 076b83c7c896..507c61c991fa 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h @@ -223,17 +223,16 @@ struct sdpcmd_regs { u16 PAD[0x80]; }; -extern int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev, - struct chip_info **ci_ptr, u32 regs); -extern void brcmf_sdio_chip_detach(struct chip_info **ci_ptr); -extern void brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci, - u32 drivestrength); -extern u8 brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid); -extern void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci); -extern bool brcmf_sdio_chip_exit_download(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci, char *nvram_dat, - uint nvram_sz); +int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev, + struct chip_info **ci_ptr, u32 regs); +void brcmf_sdio_chip_detach(struct chip_info **ci_ptr); +void brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, + struct chip_info *ci, u32 drivestrength); +u8 brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid); +void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev, + struct chip_info *ci); +bool brcmf_sdio_chip_exit_download(struct brcmf_sdio_dev *sdiodev, + struct chip_info *ci, char *nvram_dat, + uint nvram_sz); #endif /* _BRCMFMAC_SDIO_CHIP_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h index 2b5407f002e5..c9b06b4e71f7 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h @@ -181,18 +181,18 @@ struct brcmf_sdio_dev { }; /* Register/deregister interrupt handler. */ -extern int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev); -extern int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev); +int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev); +int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev); /* sdio device register access interface */ -extern u8 brcmf_sdio_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret); -extern u32 brcmf_sdio_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret); -extern void brcmf_sdio_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr, - u8 data, int *ret); -extern void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr, - u32 data, int *ret); -extern int brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, - void *data, bool write); +u8 brcmf_sdio_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret); +u32 brcmf_sdio_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret); +void brcmf_sdio_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr, u8 data, + int *ret); +void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr, u32 data, + int *ret); +int brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, + void *data, bool write); /* Buffer transfer to/from device (client) core via cmd53. * fn: function number @@ -206,22 +206,17 @@ extern int brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, * Returns 0 or error code. * NOTE: Async operation is not currently supported. */ -extern int -brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, - uint flags, struct sk_buff_head *pktq); -extern int -brcmf_sdcard_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, - uint flags, u8 *buf, uint nbytes); - -extern int -brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, - uint flags, struct sk_buff *pkt); -extern int -brcmf_sdcard_recv_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, - uint flags, u8 *buf, uint nbytes); -extern int -brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, - uint flags, struct sk_buff_head *pktq); +int brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, + uint flags, struct sk_buff_head *pktq); +int brcmf_sdcard_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, + uint flags, u8 *buf, uint nbytes); + +int brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, + uint flags, struct sk_buff *pkt); +int brcmf_sdcard_recv_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, + uint flags, u8 *buf, uint nbytes); +int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, + uint flags, struct sk_buff_head *pktq); /* Flags bits */ @@ -237,46 +232,43 @@ brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, * nbytes: number of bytes to transfer to/from buf * Returns 0 or error code. */ -extern int brcmf_sdcard_rwdata(struct brcmf_sdio_dev *sdiodev, uint rw, - u32 addr, u8 *buf, uint nbytes); -extern int brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, - u32 address, u8 *data, uint size); +int brcmf_sdcard_rwdata(struct brcmf_sdio_dev *sdiodev, uint rw, u32 addr, + u8 *buf, uint nbytes); +int brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address, + u8 *data, uint size); /* Issue an abort to the specified function */ -extern int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn); +int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn); /* platform specific/high level functions */ -extern int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev); -extern int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev); +int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev); +int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev); /* attach, return handler on success, NULL if failed. * The handler shall be provided by all subsequent calls. No local cache * cfghdl points to the starting address of pci device mapped memory */ -extern int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev); -extern void brcmf_sdioh_detach(struct brcmf_sdio_dev *sdiodev); +int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev); +void brcmf_sdioh_detach(struct brcmf_sdio_dev *sdiodev); /* read or write one byte using cmd52 */ -extern int brcmf_sdioh_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw, - uint fnc, uint addr, u8 *byte); +int brcmf_sdioh_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw, uint fnc, + uint addr, u8 *byte); /* read or write 2/4 bytes using cmd53 */ -extern int -brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev, - uint rw, uint fnc, uint addr, - u32 *word, uint nbyte); +int brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev, uint rw, uint fnc, + uint addr, u32 *word, uint nbyte); /* Watchdog timer interface for pm ops */ -extern void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev, - bool enable); +void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev, bool enable); -extern void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev); -extern void brcmf_sdbrcm_disconnect(void *ptr); -extern void brcmf_sdbrcm_isr(void *arg); +void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev); +void brcmf_sdbrcm_disconnect(void *ptr); +void brcmf_sdbrcm_isr(void *arg); -extern void brcmf_sdbrcm_wd_timer(struct brcmf_sdio *bus, uint wdtick); +void brcmf_sdbrcm_wd_timer(struct brcmf_sdio *bus, uint wdtick); -extern void brcmf_pm_resume_wait(struct brcmf_sdio_dev *sdiodev, - wait_queue_head_t *wq); -extern bool brcmf_pm_resume_error(struct brcmf_sdio_dev *sdiodev); +void brcmf_pm_resume_wait(struct brcmf_sdio_dev *sdiodev, + wait_queue_head_t *wq); +bool brcmf_pm_resume_error(struct brcmf_sdio_dev *sdiodev); #endif /* _BRCM_SDH_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index bf6758d95600..422f44c63175 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c @@ -1536,7 +1536,7 @@ void brcmf_usb_exit(void) brcmf_release_fw(&fw_image_list); } -void brcmf_usb_init(void) +void brcmf_usb_register(void) { brcmf_dbg(USB, "Enter\n"); INIT_LIST_HEAD(&fw_image_list); diff --git a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h index a8a267b5b87a..2d08c155c23b 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h @@ -172,19 +172,19 @@ struct si_info { /* AMBA Interconnect exported externs */ -extern u32 ai_core_cflags(struct bcma_device *core, u32 mask, u32 val); +u32 ai_core_cflags(struct bcma_device *core, u32 mask, u32 val); /* === exported functions === */ -extern struct si_pub *ai_attach(struct bcma_bus *pbus); -extern void ai_detach(struct si_pub *sih); -extern uint ai_cc_reg(struct si_pub *sih, uint regoff, u32 mask, u32 val); -extern void ai_clkctl_init(struct si_pub *sih); -extern u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih); -extern bool ai_clkctl_cc(struct si_pub *sih, enum bcma_clkmode mode); -extern bool ai_deviceremoved(struct si_pub *sih); +struct si_pub *ai_attach(struct bcma_bus *pbus); +void ai_detach(struct si_pub *sih); +uint ai_cc_reg(struct si_pub *sih, uint regoff, u32 mask, u32 val); +void ai_clkctl_init(struct si_pub *sih); +u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih); +bool ai_clkctl_cc(struct si_pub *sih, enum bcma_clkmode mode); +bool ai_deviceremoved(struct si_pub *sih); /* Enable Ex-PA for 4313 */ -extern void ai_epa_4313war(struct si_pub *sih); +void ai_epa_4313war(struct si_pub *sih); static inline u32 ai_get_cccaps(struct si_pub *sih) { diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h index 73d01e586109..03bdcf29bd50 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h @@ -37,17 +37,17 @@ struct brcms_ampdu_session { u16 dma_len; }; -extern void brcms_c_ampdu_reset_session(struct brcms_ampdu_session *session, - struct brcms_c_info *wlc); -extern int brcms_c_ampdu_add_frame(struct brcms_ampdu_session *session, - struct sk_buff *p); -extern void brcms_c_ampdu_finalize(struct brcms_ampdu_session *session); +void brcms_c_ampdu_reset_session(struct brcms_ampdu_session *session, + struct brcms_c_info *wlc); +int brcms_c_ampdu_add_frame(struct brcms_ampdu_session *session, + struct sk_buff *p); +void brcms_c_ampdu_finalize(struct brcms_ampdu_session *session); -extern struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc); -extern void brcms_c_ampdu_detach(struct ampdu_info *ampdu); -extern void brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, - struct sk_buff *p, struct tx_status *txs); -extern void brcms_c_ampdu_macaddr_upd(struct brcms_c_info *wlc); -extern void brcms_c_ampdu_shm_upd(struct ampdu_info *ampdu); +struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc); +void brcms_c_ampdu_detach(struct ampdu_info *ampdu); +void brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, + struct sk_buff *p, struct tx_status *txs); +void brcms_c_ampdu_macaddr_upd(struct brcms_c_info *wlc); +void brcms_c_ampdu_shm_upd(struct ampdu_info *ampdu); #endif /* _BRCM_AMPDU_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmsmac/antsel.h b/drivers/net/wireless/brcm80211/brcmsmac/antsel.h index 97ea3881a8ec..a3d487ab1964 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/antsel.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/antsel.h @@ -17,13 +17,11 @@ #ifndef _BRCM_ANTSEL_H_ #define _BRCM_ANTSEL_H_ -extern struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc); -extern void brcms_c_antsel_detach(struct antsel_info *asi); -extern void brcms_c_antsel_init(struct antsel_info *asi); -extern void brcms_c_antsel_antcfg_get(struct antsel_info *asi, bool usedef, - bool sel, - u8 id, u8 fbid, u8 *antcfg, - u8 *fbantcfg); -extern u8 brcms_c_antsel_antsel2id(struct antsel_info *asi, u16 antsel); +struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc); +void brcms_c_antsel_detach(struct antsel_info *asi); +void brcms_c_antsel_init(struct antsel_info *asi); +void brcms_c_antsel_antcfg_get(struct antsel_info *asi, bool usedef, bool sel, + u8 id, u8 fbid, u8 *antcfg, u8 *fbantcfg); +u8 brcms_c_antsel_antsel2id(struct antsel_info *asi, u16 antsel); #endif /* _BRCM_ANTSEL_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.h b/drivers/net/wireless/brcm80211/brcmsmac/channel.h index 006483a0abe6..39dd3a5b2979 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/channel.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.h @@ -32,20 +32,16 @@ #define BRCMS_DFS_EU (BRCMS_DFS_TPC | BRCMS_RADAR_TYPE_EU) /* Flag for DFS EU */ -extern struct brcms_cm_info * -brcms_c_channel_mgr_attach(struct brcms_c_info *wlc); +struct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc); -extern void brcms_c_channel_mgr_detach(struct brcms_cm_info *wlc_cm); +void brcms_c_channel_mgr_detach(struct brcms_cm_info *wlc_cm); -extern bool brcms_c_valid_chanspec_db(struct brcms_cm_info *wlc_cm, - u16 chspec); +bool brcms_c_valid_chanspec_db(struct brcms_cm_info *wlc_cm, u16 chspec); -extern void brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, - u16 chanspec, - struct txpwr_limits *txpwr); -extern void brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, - u16 chanspec, - u8 local_constraint_qdbm); -extern void brcms_c_regd_init(struct brcms_c_info *wlc); +void brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, u16 chanspec, + struct txpwr_limits *txpwr); +void brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, u16 chanspec, + u8 local_constraint_qdbm); +void brcms_c_regd_init(struct brcms_c_info *wlc); #endif /* _WLC_CHANNEL_H */ diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index 3a6544710c8a..edc5d105ff98 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c @@ -457,6 +457,8 @@ static int brcms_ops_start(struct ieee80211_hw *hw) if (err != 0) brcms_err(wl->wlc->hw->d11core, "%s: brcms_up() returned %d\n", __func__, err); + + bcma_core_pci_power_save(wl->wlc->hw->d11core->bus, true); return err; } @@ -479,6 +481,8 @@ static void brcms_ops_stop(struct ieee80211_hw *hw) return; } + bcma_core_pci_power_save(wl->wlc->hw->d11core->bus, false); + /* put driver in down state */ spin_lock_bh(&wl->lock); brcms_down(wl); diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h index 4090032e81a2..198053dfc310 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h @@ -88,26 +88,26 @@ struct brcms_info { }; /* misc callbacks */ -extern void brcms_init(struct brcms_info *wl); -extern uint brcms_reset(struct brcms_info *wl); -extern void brcms_intrson(struct brcms_info *wl); -extern u32 brcms_intrsoff(struct brcms_info *wl); -extern void brcms_intrsrestore(struct brcms_info *wl, u32 macintmask); -extern int brcms_up(struct brcms_info *wl); -extern void brcms_down(struct brcms_info *wl); -extern void brcms_txflowcontrol(struct brcms_info *wl, struct brcms_if *wlif, - bool state, int prio); -extern bool brcms_rfkill_set_hw_state(struct brcms_info *wl); +void brcms_init(struct brcms_info *wl); +uint brcms_reset(struct brcms_info *wl); +void brcms_intrson(struct brcms_info *wl); +u32 brcms_intrsoff(struct brcms_info *wl); +void brcms_intrsrestore(struct brcms_info *wl, u32 macintmask); +int brcms_up(struct brcms_info *wl); +void brcms_down(struct brcms_info *wl); +void brcms_txflowcontrol(struct brcms_info *wl, struct brcms_if *wlif, + bool state, int prio); +bool brcms_rfkill_set_hw_state(struct brcms_info *wl); /* timer functions */ -extern struct brcms_timer *brcms_init_timer(struct brcms_info *wl, - void (*fn) (void *arg), void *arg, - const char *name); -extern void brcms_free_timer(struct brcms_timer *timer); -extern void brcms_add_timer(struct brcms_timer *timer, uint ms, int periodic); -extern bool brcms_del_timer(struct brcms_timer *timer); -extern void brcms_dpc(unsigned long data); -extern void brcms_timer(struct brcms_timer *t); -extern void brcms_fatal_error(struct brcms_info *wl); +struct brcms_timer *brcms_init_timer(struct brcms_info *wl, + void (*fn) (void *arg), void *arg, + const char *name); +void brcms_free_timer(struct brcms_timer *timer); +void brcms_add_timer(struct brcms_timer *timer, uint ms, int periodic); +bool brcms_del_timer(struct brcms_timer *timer); +void brcms_dpc(unsigned long data); +void brcms_timer(struct brcms_timer *t); +void brcms_fatal_error(struct brcms_info *wl); #endif /* _BRCM_MAC80211_IF_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index 4608e0eb1493..69b14dc4dd55 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c @@ -1906,14 +1906,14 @@ static void brcms_c_get_macaddr(struct brcms_hardware *wlc_hw, u8 etheraddr[ETH_ /* If macaddr exists, use it (Sromrev4, CIS, ...). */ if (!is_zero_ether_addr(sprom->il0mac)) { - memcpy(etheraddr, sprom->il0mac, 6); + memcpy(etheraddr, sprom->il0mac, ETH_ALEN); return; } if (wlc_hw->_nbands > 1) - memcpy(etheraddr, sprom->et1mac, 6); + memcpy(etheraddr, sprom->et1mac, ETH_ALEN); else - memcpy(etheraddr, sprom->il0mac, 6); + memcpy(etheraddr, sprom->il0mac, ETH_ALEN); } /* power both the pll and external oscillator on/off */ diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.h b/drivers/net/wireless/brcm80211/brcmsmac/main.h index b5d7a38b53fe..c4d135cff04a 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h @@ -616,66 +616,54 @@ struct brcms_bss_cfg { struct brcms_bss_info *current_bss; }; -extern int brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, - struct sk_buff *p); -extern int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo, - uint *blocks); - -extern int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config); -extern void brcms_c_mac_promisc(struct brcms_c_info *wlc, uint filter_flags); -extern u16 brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec, - uint mac_len); -extern u32 brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc, - u32 rspec, - bool use_rspec, u16 mimo_ctlchbw); -extern u16 brcms_c_compute_rtscts_dur(struct brcms_c_info *wlc, bool cts_only, - u32 rts_rate, - u32 frame_rate, - u8 rts_preamble_type, - u8 frame_preamble_type, uint frame_len, - bool ba); -extern void brcms_c_inval_dma_pkts(struct brcms_hardware *hw, - struct ieee80211_sta *sta, - void (*dma_callback_fn)); -extern void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend); -extern int brcms_c_set_nmode(struct brcms_c_info *wlc); -extern void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc, - u32 bcn_rate); -extern void brcms_b_antsel_type_set(struct brcms_hardware *wlc_hw, - u8 antsel_type); -extern void brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, - u16 chanspec, - bool mute, struct txpwr_limits *txpwr); -extern void brcms_b_write_shm(struct brcms_hardware *wlc_hw, uint offset, - u16 v); -extern u16 brcms_b_read_shm(struct brcms_hardware *wlc_hw, uint offset); -extern void brcms_b_mhf(struct brcms_hardware *wlc_hw, u8 idx, u16 mask, - u16 val, int bands); -extern void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags); -extern void brcms_b_mctrl(struct brcms_hardware *wlc_hw, u32 mask, u32 val); -extern void brcms_b_phy_reset(struct brcms_hardware *wlc_hw); -extern void brcms_b_bw_set(struct brcms_hardware *wlc_hw, u16 bw); -extern void brcms_b_core_phypll_reset(struct brcms_hardware *wlc_hw); -extern void brcms_c_ucode_wake_override_set(struct brcms_hardware *wlc_hw, - u32 override_bit); -extern void brcms_c_ucode_wake_override_clear(struct brcms_hardware *wlc_hw, - u32 override_bit); -extern void brcms_b_write_template_ram(struct brcms_hardware *wlc_hw, - int offset, int len, void *buf); -extern u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate); -extern void brcms_b_copyto_objmem(struct brcms_hardware *wlc_hw, - uint offset, const void *buf, int len, - u32 sel); -extern void brcms_b_copyfrom_objmem(struct brcms_hardware *wlc_hw, uint offset, - void *buf, int len, u32 sel); -extern void brcms_b_switch_macfreq(struct brcms_hardware *wlc_hw, u8 spurmode); -extern u16 brcms_b_get_txant(struct brcms_hardware *wlc_hw); -extern void brcms_b_phyclk_fgc(struct brcms_hardware *wlc_hw, bool clk); -extern void brcms_b_macphyclk_set(struct brcms_hardware *wlc_hw, bool clk); -extern void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on); -extern void brcms_b_txant_set(struct brcms_hardware *wlc_hw, u16 phytxant); -extern void brcms_b_band_stf_ss_set(struct brcms_hardware *wlc_hw, - u8 stf_mode); -extern void brcms_c_init_scb(struct scb *scb); +int brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p); +int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo, + uint *blocks); + +int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config); +void brcms_c_mac_promisc(struct brcms_c_info *wlc, uint filter_flags); +u16 brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec, uint mac_len); +u32 brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc, u32 rspec, + bool use_rspec, u16 mimo_ctlchbw); +u16 brcms_c_compute_rtscts_dur(struct brcms_c_info *wlc, bool cts_only, + u32 rts_rate, u32 frame_rate, + u8 rts_preamble_type, u8 frame_preamble_type, + uint frame_len, bool ba); +void brcms_c_inval_dma_pkts(struct brcms_hardware *hw, + struct ieee80211_sta *sta, void (*dma_callback_fn)); +void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend); +int brcms_c_set_nmode(struct brcms_c_info *wlc); +void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc, u32 bcn_rate); +void brcms_b_antsel_type_set(struct brcms_hardware *wlc_hw, u8 antsel_type); +void brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, u16 chanspec, + bool mute, struct txpwr_limits *txpwr); +void brcms_b_write_shm(struct brcms_hardware *wlc_hw, uint offset, u16 v); +u16 brcms_b_read_shm(struct brcms_hardware *wlc_hw, uint offset); +void brcms_b_mhf(struct brcms_hardware *wlc_hw, u8 idx, u16 mask, u16 val, + int bands); +void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags); +void brcms_b_mctrl(struct brcms_hardware *wlc_hw, u32 mask, u32 val); +void brcms_b_phy_reset(struct brcms_hardware *wlc_hw); +void brcms_b_bw_set(struct brcms_hardware *wlc_hw, u16 bw); +void brcms_b_core_phypll_reset(struct brcms_hardware *wlc_hw); +void brcms_c_ucode_wake_override_set(struct brcms_hardware *wlc_hw, + u32 override_bit); +void brcms_c_ucode_wake_override_clear(struct brcms_hardware *wlc_hw, + u32 override_bit); +void brcms_b_write_template_ram(struct brcms_hardware *wlc_hw, int offset, + int len, void *buf); +u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate); +void brcms_b_copyto_objmem(struct brcms_hardware *wlc_hw, uint offset, + const void *buf, int len, u32 sel); +void brcms_b_copyfrom_objmem(struct brcms_hardware *wlc_hw, uint offset, + void *buf, int len, u32 sel); +void brcms_b_switch_macfreq(struct brcms_hardware *wlc_hw, u8 spurmode); +u16 brcms_b_get_txant(struct brcms_hardware *wlc_hw); +void brcms_b_phyclk_fgc(struct brcms_hardware *wlc_hw, bool clk); +void brcms_b_macphyclk_set(struct brcms_hardware *wlc_hw, bool clk); +void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on); +void brcms_b_txant_set(struct brcms_hardware *wlc_hw, u16 phytxant); +void brcms_b_band_stf_ss_set(struct brcms_hardware *wlc_hw, u8 stf_mode); +void brcms_c_init_scb(struct scb *scb); #endif /* _BRCM_MAIN_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_hal.h b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_hal.h index e34a71e7d242..4d3734f48d9c 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_hal.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_hal.h @@ -179,121 +179,106 @@ struct shared_phy_params { }; -extern struct shared_phy *wlc_phy_shared_attach(struct shared_phy_params *shp); -extern struct brcms_phy_pub *wlc_phy_attach(struct shared_phy *sh, - struct bcma_device *d11core, - int bandtype, struct wiphy *wiphy); -extern void wlc_phy_detach(struct brcms_phy_pub *ppi); - -extern bool wlc_phy_get_phyversion(struct brcms_phy_pub *pih, u16 *phytype, - u16 *phyrev, u16 *radioid, - u16 *radiover); -extern bool wlc_phy_get_encore(struct brcms_phy_pub *pih); -extern u32 wlc_phy_get_coreflags(struct brcms_phy_pub *pih); - -extern void wlc_phy_hw_clk_state_upd(struct brcms_phy_pub *ppi, bool newstate); -extern void wlc_phy_hw_state_upd(struct brcms_phy_pub *ppi, bool newstate); -extern void wlc_phy_init(struct brcms_phy_pub *ppi, u16 chanspec); -extern void wlc_phy_watchdog(struct brcms_phy_pub *ppi); -extern int wlc_phy_down(struct brcms_phy_pub *ppi); -extern u32 wlc_phy_clk_bwbits(struct brcms_phy_pub *pih); -extern void wlc_phy_cal_init(struct brcms_phy_pub *ppi); -extern void wlc_phy_antsel_init(struct brcms_phy_pub *ppi, bool lut_init); - -extern void wlc_phy_chanspec_set(struct brcms_phy_pub *ppi, - u16 chanspec); -extern u16 wlc_phy_chanspec_get(struct brcms_phy_pub *ppi); -extern void wlc_phy_chanspec_radio_set(struct brcms_phy_pub *ppi, - u16 newch); -extern u16 wlc_phy_bw_state_get(struct brcms_phy_pub *ppi); -extern void wlc_phy_bw_state_set(struct brcms_phy_pub *ppi, u16 bw); - -extern int wlc_phy_rssi_compute(struct brcms_phy_pub *pih, - struct d11rxhdr *rxh); -extern void wlc_phy_por_inform(struct brcms_phy_pub *ppi); -extern void wlc_phy_noise_sample_intr(struct brcms_phy_pub *ppi); -extern bool wlc_phy_bist_check_phy(struct brcms_phy_pub *ppi); - -extern void wlc_phy_set_deaf(struct brcms_phy_pub *ppi, bool user_flag); - -extern void wlc_phy_switch_radio(struct brcms_phy_pub *ppi, bool on); -extern void wlc_phy_anacore(struct brcms_phy_pub *ppi, bool on); - - -extern void wlc_phy_BSSinit(struct brcms_phy_pub *ppi, bool bonlyap, int rssi); - -extern void wlc_phy_chanspec_ch14_widefilter_set(struct brcms_phy_pub *ppi, - bool wide_filter); -extern void wlc_phy_chanspec_band_validch(struct brcms_phy_pub *ppi, uint band, - struct brcms_chanvec *channels); -extern u16 wlc_phy_chanspec_band_firstch(struct brcms_phy_pub *ppi, - uint band); - -extern void wlc_phy_txpower_sromlimit(struct brcms_phy_pub *ppi, uint chan, - u8 *_min_, u8 *_max_, int rate); -extern void wlc_phy_txpower_sromlimit_max_get(struct brcms_phy_pub *ppi, - uint chan, u8 *_max_, u8 *_min_); -extern void wlc_phy_txpower_boardlimit_band(struct brcms_phy_pub *ppi, - uint band, s32 *, s32 *, u32 *); -extern void wlc_phy_txpower_limit_set(struct brcms_phy_pub *ppi, - struct txpwr_limits *, - u16 chanspec); -extern int wlc_phy_txpower_get(struct brcms_phy_pub *ppi, uint *qdbm, - bool *override); -extern int wlc_phy_txpower_set(struct brcms_phy_pub *ppi, uint qdbm, - bool override); -extern void wlc_phy_txpower_target_set(struct brcms_phy_pub *ppi, - struct txpwr_limits *); -extern bool wlc_phy_txpower_hw_ctrl_get(struct brcms_phy_pub *ppi); -extern void wlc_phy_txpower_hw_ctrl_set(struct brcms_phy_pub *ppi, - bool hwpwrctrl); -extern u8 wlc_phy_txpower_get_target_min(struct brcms_phy_pub *ppi); -extern u8 wlc_phy_txpower_get_target_max(struct brcms_phy_pub *ppi); -extern bool wlc_phy_txpower_ipa_ison(struct brcms_phy_pub *pih); - -extern void wlc_phy_stf_chain_init(struct brcms_phy_pub *pih, u8 txchain, - u8 rxchain); -extern void wlc_phy_stf_chain_set(struct brcms_phy_pub *pih, u8 txchain, - u8 rxchain); -extern void wlc_phy_stf_chain_get(struct brcms_phy_pub *pih, u8 *txchain, - u8 *rxchain); -extern u8 wlc_phy_stf_chain_active_get(struct brcms_phy_pub *pih); -extern s8 wlc_phy_stf_ssmode_get(struct brcms_phy_pub *pih, - u16 chanspec); -extern void wlc_phy_ldpc_override_set(struct brcms_phy_pub *ppi, bool val); - -extern void wlc_phy_cal_perical(struct brcms_phy_pub *ppi, u8 reason); -extern void wlc_phy_noise_sample_request_external(struct brcms_phy_pub *ppi); -extern void wlc_phy_edcrs_lock(struct brcms_phy_pub *pih, bool lock); -extern void wlc_phy_cal_papd_recal(struct brcms_phy_pub *ppi); - -extern void wlc_phy_ant_rxdiv_set(struct brcms_phy_pub *ppi, u8 val); -extern void wlc_phy_clear_tssi(struct brcms_phy_pub *ppi); -extern void wlc_phy_hold_upd(struct brcms_phy_pub *ppi, u32 id, bool val); -extern void wlc_phy_mute_upd(struct brcms_phy_pub *ppi, bool val, u32 flags); - -extern void wlc_phy_antsel_type_set(struct brcms_phy_pub *ppi, u8 antsel_type); - -extern void wlc_phy_txpower_get_current(struct brcms_phy_pub *ppi, - struct tx_power *power, uint channel); - -extern void wlc_phy_initcal_enable(struct brcms_phy_pub *pih, bool initcal); -extern bool wlc_phy_test_ison(struct brcms_phy_pub *ppi); -extern void wlc_phy_txpwr_percent_set(struct brcms_phy_pub *ppi, - u8 txpwr_percent); -extern void wlc_phy_ofdm_rateset_war(struct brcms_phy_pub *pih, bool war); -extern void wlc_phy_bf_preempt_enable(struct brcms_phy_pub *pih, - bool bf_preempt); -extern void wlc_phy_machwcap_set(struct brcms_phy_pub *ppi, u32 machwcap); - -extern void wlc_phy_runbist_config(struct brcms_phy_pub *ppi, bool start_end); - -extern void wlc_phy_freqtrack_start(struct brcms_phy_pub *ppi); -extern void wlc_phy_freqtrack_end(struct brcms_phy_pub *ppi); - -extern const u8 *wlc_phy_get_ofdm_rate_lookup(void); - -extern s8 wlc_phy_get_tx_power_offset_by_mcs(struct brcms_phy_pub *ppi, - u8 mcs_offset); -extern s8 wlc_phy_get_tx_power_offset(struct brcms_phy_pub *ppi, u8 tbl_offset); +struct shared_phy *wlc_phy_shared_attach(struct shared_phy_params *shp); +struct brcms_phy_pub *wlc_phy_attach(struct shared_phy *sh, + struct bcma_device *d11core, int bandtype, + struct wiphy *wiphy); +void wlc_phy_detach(struct brcms_phy_pub *ppi); + +bool wlc_phy_get_phyversion(struct brcms_phy_pub *pih, u16 *phytype, + u16 *phyrev, u16 *radioid, u16 *radiover); +bool wlc_phy_get_encore(struct brcms_phy_pub *pih); +u32 wlc_phy_get_coreflags(struct brcms_phy_pub *pih); + +void wlc_phy_hw_clk_state_upd(struct brcms_phy_pub *ppi, bool newstate); +void wlc_phy_hw_state_upd(struct brcms_phy_pub *ppi, bool newstate); +void wlc_phy_init(struct brcms_phy_pub *ppi, u16 chanspec); +void wlc_phy_watchdog(struct brcms_phy_pub *ppi); +int wlc_phy_down(struct brcms_phy_pub *ppi); +u32 wlc_phy_clk_bwbits(struct brcms_phy_pub *pih); +void wlc_phy_cal_init(struct brcms_phy_pub *ppi); +void wlc_phy_antsel_init(struct brcms_phy_pub *ppi, bool lut_init); + +void wlc_phy_chanspec_set(struct brcms_phy_pub *ppi, u16 chanspec); +u16 wlc_phy_chanspec_get(struct brcms_phy_pub *ppi); +void wlc_phy_chanspec_radio_set(struct brcms_phy_pub *ppi, u16 newch); +u16 wlc_phy_bw_state_get(struct brcms_phy_pub *ppi); +void wlc_phy_bw_state_set(struct brcms_phy_pub *ppi, u16 bw); + +int wlc_phy_rssi_compute(struct brcms_phy_pub *pih, struct d11rxhdr *rxh); +void wlc_phy_por_inform(struct brcms_phy_pub *ppi); +void wlc_phy_noise_sample_intr(struct brcms_phy_pub *ppi); +bool wlc_phy_bist_check_phy(struct brcms_phy_pub *ppi); + +void wlc_phy_set_deaf(struct brcms_phy_pub *ppi, bool user_flag); + +void wlc_phy_switch_radio(struct brcms_phy_pub *ppi, bool on); +void wlc_phy_anacore(struct brcms_phy_pub *ppi, bool on); + + +void wlc_phy_BSSinit(struct brcms_phy_pub *ppi, bool bonlyap, int rssi); + +void wlc_phy_chanspec_ch14_widefilter_set(struct brcms_phy_pub *ppi, + bool wide_filter); +void wlc_phy_chanspec_band_validch(struct brcms_phy_pub *ppi, uint band, + struct brcms_chanvec *channels); +u16 wlc_phy_chanspec_band_firstch(struct brcms_phy_pub *ppi, uint band); + +void wlc_phy_txpower_sromlimit(struct brcms_phy_pub *ppi, uint chan, u8 *_min_, + u8 *_max_, int rate); +void wlc_phy_txpower_sromlimit_max_get(struct brcms_phy_pub *ppi, uint chan, + u8 *_max_, u8 *_min_); +void wlc_phy_txpower_boardlimit_band(struct brcms_phy_pub *ppi, uint band, + s32 *, s32 *, u32 *); +void wlc_phy_txpower_limit_set(struct brcms_phy_pub *ppi, struct txpwr_limits *, + u16 chanspec); +int wlc_phy_txpower_get(struct brcms_phy_pub *ppi, uint *qdbm, bool *override); +int wlc_phy_txpower_set(struct brcms_phy_pub *ppi, uint qdbm, bool override); +void wlc_phy_txpower_target_set(struct brcms_phy_pub *ppi, + struct txpwr_limits *); +bool wlc_phy_txpower_hw_ctrl_get(struct brcms_phy_pub *ppi); +void wlc_phy_txpower_hw_ctrl_set(struct brcms_phy_pub *ppi, bool hwpwrctrl); +u8 wlc_phy_txpower_get_target_min(struct brcms_phy_pub *ppi); +u8 wlc_phy_txpower_get_target_max(struct brcms_phy_pub *ppi); +bool wlc_phy_txpower_ipa_ison(struct brcms_phy_pub *pih); + +void wlc_phy_stf_chain_init(struct brcms_phy_pub *pih, u8 txchain, u8 rxchain); +void wlc_phy_stf_chain_set(struct brcms_phy_pub *pih, u8 txchain, u8 rxchain); +void wlc_phy_stf_chain_get(struct brcms_phy_pub *pih, u8 *txchain, u8 *rxchain); +u8 wlc_phy_stf_chain_active_get(struct brcms_phy_pub *pih); +s8 wlc_phy_stf_ssmode_get(struct brcms_phy_pub *pih, u16 chanspec); +void wlc_phy_ldpc_override_set(struct brcms_phy_pub *ppi, bool val); + +void wlc_phy_cal_perical(struct brcms_phy_pub *ppi, u8 reason); +void wlc_phy_noise_sample_request_external(struct brcms_phy_pub *ppi); +void wlc_phy_edcrs_lock(struct brcms_phy_pub *pih, bool lock); +void wlc_phy_cal_papd_recal(struct brcms_phy_pub *ppi); + +void wlc_phy_ant_rxdiv_set(struct brcms_phy_pub *ppi, u8 val); +void wlc_phy_clear_tssi(struct brcms_phy_pub *ppi); +void wlc_phy_hold_upd(struct brcms_phy_pub *ppi, u32 id, bool val); +void wlc_phy_mute_upd(struct brcms_phy_pub *ppi, bool val, u32 flags); + +void wlc_phy_antsel_type_set(struct brcms_phy_pub *ppi, u8 antsel_type); + +void wlc_phy_txpower_get_current(struct brcms_phy_pub *ppi, + struct tx_power *power, uint channel); + +void wlc_phy_initcal_enable(struct brcms_phy_pub *pih, bool initcal); +bool wlc_phy_test_ison(struct brcms_phy_pub *ppi); +void wlc_phy_txpwr_percent_set(struct brcms_phy_pub *ppi, u8 txpwr_percent); +void wlc_phy_ofdm_rateset_war(struct brcms_phy_pub *pih, bool war); +void wlc_phy_bf_preempt_enable(struct brcms_phy_pub *pih, bool bf_preempt); +void wlc_phy_machwcap_set(struct brcms_phy_pub *ppi, u32 machwcap); + +void wlc_phy_runbist_config(struct brcms_phy_pub *ppi, bool start_end); + +void wlc_phy_freqtrack_start(struct brcms_phy_pub *ppi); +void wlc_phy_freqtrack_end(struct brcms_phy_pub *ppi); + +const u8 *wlc_phy_get_ofdm_rate_lookup(void); + +s8 wlc_phy_get_tx_power_offset_by_mcs(struct brcms_phy_pub *ppi, + u8 mcs_offset); +s8 wlc_phy_get_tx_power_offset(struct brcms_phy_pub *ppi, u8 tbl_offset); #endif /* _BRCM_PHY_HAL_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h index 1dc767c31653..4960f7d26804 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h @@ -910,113 +910,103 @@ struct lcnphy_radio_regs { u8 do_init_g; }; -extern u16 read_phy_reg(struct brcms_phy *pi, u16 addr); -extern void write_phy_reg(struct brcms_phy *pi, u16 addr, u16 val); -extern void and_phy_reg(struct brcms_phy *pi, u16 addr, u16 val); -extern void or_phy_reg(struct brcms_phy *pi, u16 addr, u16 val); -extern void mod_phy_reg(struct brcms_phy *pi, u16 addr, u16 mask, u16 val); - -extern u16 read_radio_reg(struct brcms_phy *pi, u16 addr); -extern void or_radio_reg(struct brcms_phy *pi, u16 addr, u16 val); -extern void and_radio_reg(struct brcms_phy *pi, u16 addr, u16 val); -extern void mod_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask, - u16 val); -extern void xor_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask); - -extern void write_radio_reg(struct brcms_phy *pi, u16 addr, u16 val); - -extern void wlc_phyreg_enter(struct brcms_phy_pub *pih); -extern void wlc_phyreg_exit(struct brcms_phy_pub *pih); -extern void wlc_radioreg_enter(struct brcms_phy_pub *pih); -extern void wlc_radioreg_exit(struct brcms_phy_pub *pih); - -extern void wlc_phy_read_table(struct brcms_phy *pi, - const struct phytbl_info *ptbl_info, - u16 tblAddr, u16 tblDataHi, - u16 tblDatalo); -extern void wlc_phy_write_table(struct brcms_phy *pi, - const struct phytbl_info *ptbl_info, - u16 tblAddr, u16 tblDataHi, u16 tblDatalo); -extern void wlc_phy_table_addr(struct brcms_phy *pi, uint tbl_id, - uint tbl_offset, u16 tblAddr, u16 tblDataHi, - u16 tblDataLo); -extern void wlc_phy_table_data_write(struct brcms_phy *pi, uint width, u32 val); - -extern void write_phy_channel_reg(struct brcms_phy *pi, uint val); -extern void wlc_phy_txpower_update_shm(struct brcms_phy *pi); - -extern u8 wlc_phy_nbits(s32 value); -extern void wlc_phy_compute_dB(u32 *cmplx_pwr, s8 *p_dB, u8 core); - -extern uint wlc_phy_init_radio_regs_allbands(struct brcms_phy *pi, - struct radio_20xx_regs *radioregs); -extern uint wlc_phy_init_radio_regs(struct brcms_phy *pi, - const struct radio_regs *radioregs, - u16 core_offset); - -extern void wlc_phy_txpower_ipa_upd(struct brcms_phy *pi); - -extern void wlc_phy_do_dummy_tx(struct brcms_phy *pi, bool ofdm, bool pa_on); -extern void wlc_phy_papd_decode_epsilon(u32 epsilon, s32 *eps_real, - s32 *eps_imag); - -extern void wlc_phy_cal_perical_mphase_reset(struct brcms_phy *pi); -extern void wlc_phy_cal_perical_mphase_restart(struct brcms_phy *pi); - -extern bool wlc_phy_attach_nphy(struct brcms_phy *pi); -extern bool wlc_phy_attach_lcnphy(struct brcms_phy *pi); - -extern void wlc_phy_detach_lcnphy(struct brcms_phy *pi); - -extern void wlc_phy_init_nphy(struct brcms_phy *pi); -extern void wlc_phy_init_lcnphy(struct brcms_phy *pi); - -extern void wlc_phy_cal_init_nphy(struct brcms_phy *pi); -extern void wlc_phy_cal_init_lcnphy(struct brcms_phy *pi); - -extern void wlc_phy_chanspec_set_nphy(struct brcms_phy *pi, - u16 chanspec); -extern void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi, - u16 chanspec); -extern void wlc_phy_chanspec_set_fixup_lcnphy(struct brcms_phy *pi, - u16 chanspec); -extern int wlc_phy_channel2freq(uint channel); -extern int wlc_phy_chanspec_freq2bandrange_lpssn(uint); -extern int wlc_phy_chanspec_bandrange_get(struct brcms_phy *, u16 chanspec); - -extern void wlc_lcnphy_set_tx_pwr_ctrl(struct brcms_phy *pi, u16 mode); -extern s8 wlc_lcnphy_get_current_tx_pwr_idx(struct brcms_phy *pi); - -extern void wlc_phy_txpower_recalc_target_nphy(struct brcms_phy *pi); -extern void wlc_lcnphy_txpower_recalc_target(struct brcms_phy *pi); -extern void wlc_phy_txpower_recalc_target_lcnphy(struct brcms_phy *pi); - -extern void wlc_lcnphy_set_tx_pwr_by_index(struct brcms_phy *pi, int index); -extern void wlc_lcnphy_tx_pu(struct brcms_phy *pi, bool bEnable); -extern void wlc_lcnphy_stop_tx_tone(struct brcms_phy *pi); -extern void wlc_lcnphy_start_tx_tone(struct brcms_phy *pi, s32 f_kHz, - u16 max_val, bool iqcalmode); - -extern void wlc_phy_txpower_sromlimit_get_nphy(struct brcms_phy *pi, uint chan, - u8 *max_pwr, u8 rate_id); -extern void wlc_phy_ofdm_to_mcs_powers_nphy(u8 *power, u8 rate_mcs_start, - u8 rate_mcs_end, - u8 rate_ofdm_start); -extern void wlc_phy_mcs_to_ofdm_powers_nphy(u8 *power, - u8 rate_ofdm_start, - u8 rate_ofdm_end, - u8 rate_mcs_start); - -extern u16 wlc_lcnphy_tempsense(struct brcms_phy *pi, bool mode); -extern s16 wlc_lcnphy_tempsense_new(struct brcms_phy *pi, bool mode); -extern s8 wlc_lcnphy_tempsense_degree(struct brcms_phy *pi, bool mode); -extern s8 wlc_lcnphy_vbatsense(struct brcms_phy *pi, bool mode); -extern void wlc_phy_carrier_suppress_lcnphy(struct brcms_phy *pi); -extern void wlc_lcnphy_crsuprs(struct brcms_phy *pi, int channel); -extern void wlc_lcnphy_epa_switch(struct brcms_phy *pi, bool mode); -extern void wlc_2064_vco_cal(struct brcms_phy *pi); - -extern void wlc_phy_txpower_recalc_target(struct brcms_phy *pi); +u16 read_phy_reg(struct brcms_phy *pi, u16 addr); +void write_phy_reg(struct brcms_phy *pi, u16 addr, u16 val); +void and_phy_reg(struct brcms_phy *pi, u16 addr, u16 val); +void or_phy_reg(struct brcms_phy *pi, u16 addr, u16 val); +void mod_phy_reg(struct brcms_phy *pi, u16 addr, u16 mask, u16 val); + +u16 read_radio_reg(struct brcms_phy *pi, u16 addr); +void or_radio_reg(struct brcms_phy *pi, u16 addr, u16 val); +void and_radio_reg(struct brcms_phy *pi, u16 addr, u16 val); +void mod_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask, u16 val); +void xor_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask); + +void write_radio_reg(struct brcms_phy *pi, u16 addr, u16 val); + +void wlc_phyreg_enter(struct brcms_phy_pub *pih); +void wlc_phyreg_exit(struct brcms_phy_pub *pih); +void wlc_radioreg_enter(struct brcms_phy_pub *pih); +void wlc_radioreg_exit(struct brcms_phy_pub *pih); + +void wlc_phy_read_table(struct brcms_phy *pi, + const struct phytbl_info *ptbl_info, + u16 tblAddr, u16 tblDataHi, u16 tblDatalo); +void wlc_phy_write_table(struct brcms_phy *pi, + const struct phytbl_info *ptbl_info, + u16 tblAddr, u16 tblDataHi, u16 tblDatalo); +void wlc_phy_table_addr(struct brcms_phy *pi, uint tbl_id, uint tbl_offset, + u16 tblAddr, u16 tblDataHi, u16 tblDataLo); +void wlc_phy_table_data_write(struct brcms_phy *pi, uint width, u32 val); + +void write_phy_channel_reg(struct brcms_phy *pi, uint val); +void wlc_phy_txpower_update_shm(struct brcms_phy *pi); + +u8 wlc_phy_nbits(s32 value); +void wlc_phy_compute_dB(u32 *cmplx_pwr, s8 *p_dB, u8 core); + +uint wlc_phy_init_radio_regs_allbands(struct brcms_phy *pi, + struct radio_20xx_regs *radioregs); +uint wlc_phy_init_radio_regs(struct brcms_phy *pi, + const struct radio_regs *radioregs, + u16 core_offset); + +void wlc_phy_txpower_ipa_upd(struct brcms_phy *pi); + +void wlc_phy_do_dummy_tx(struct brcms_phy *pi, bool ofdm, bool pa_on); +void wlc_phy_papd_decode_epsilon(u32 epsilon, s32 *eps_real, s32 *eps_imag); + +void wlc_phy_cal_perical_mphase_reset(struct brcms_phy *pi); +void wlc_phy_cal_perical_mphase_restart(struct brcms_phy *pi); + +bool wlc_phy_attach_nphy(struct brcms_phy *pi); +bool wlc_phy_attach_lcnphy(struct brcms_phy *pi); + +void wlc_phy_detach_lcnphy(struct brcms_phy *pi); + +void wlc_phy_init_nphy(struct brcms_phy *pi); +void wlc_phy_init_lcnphy(struct brcms_phy *pi); + +void wlc_phy_cal_init_nphy(struct brcms_phy *pi); +void wlc_phy_cal_init_lcnphy(struct brcms_phy *pi); + +void wlc_phy_chanspec_set_nphy(struct brcms_phy *pi, u16 chanspec); +void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi, u16 chanspec); +void wlc_phy_chanspec_set_fixup_lcnphy(struct brcms_phy *pi, u16 chanspec); +int wlc_phy_channel2freq(uint channel); +int wlc_phy_chanspec_freq2bandrange_lpssn(uint); +int wlc_phy_chanspec_bandrange_get(struct brcms_phy *, u16 chanspec); + +void wlc_lcnphy_set_tx_pwr_ctrl(struct brcms_phy *pi, u16 mode); +s8 wlc_lcnphy_get_current_tx_pwr_idx(struct brcms_phy *pi); + +void wlc_phy_txpower_recalc_target_nphy(struct brcms_phy *pi); +void wlc_lcnphy_txpower_recalc_target(struct brcms_phy *pi); +void wlc_phy_txpower_recalc_target_lcnphy(struct brcms_phy *pi); + +void wlc_lcnphy_set_tx_pwr_by_index(struct brcms_phy *pi, int index); +void wlc_lcnphy_tx_pu(struct brcms_phy *pi, bool bEnable); +void wlc_lcnphy_stop_tx_tone(struct brcms_phy *pi); +void wlc_lcnphy_start_tx_tone(struct brcms_phy *pi, s32 f_kHz, u16 max_val, + bool iqcalmode); + +void wlc_phy_txpower_sromlimit_get_nphy(struct brcms_phy *pi, uint chan, + u8 *max_pwr, u8 rate_id); +void wlc_phy_ofdm_to_mcs_powers_nphy(u8 *power, u8 rate_mcs_start, + u8 rate_mcs_end, u8 rate_ofdm_start); +void wlc_phy_mcs_to_ofdm_powers_nphy(u8 *power, u8 rate_ofdm_start, + u8 rate_ofdm_end, u8 rate_mcs_start); + +u16 wlc_lcnphy_tempsense(struct brcms_phy *pi, bool mode); +s16 wlc_lcnphy_tempsense_new(struct brcms_phy *pi, bool mode); +s8 wlc_lcnphy_tempsense_degree(struct brcms_phy *pi, bool mode); +s8 wlc_lcnphy_vbatsense(struct brcms_phy *pi, bool mode); +void wlc_phy_carrier_suppress_lcnphy(struct brcms_phy *pi); +void wlc_lcnphy_crsuprs(struct brcms_phy *pi, int channel); +void wlc_lcnphy_epa_switch(struct brcms_phy *pi, bool mode); +void wlc_2064_vco_cal(struct brcms_phy *pi); + +void wlc_phy_txpower_recalc_target(struct brcms_phy *pi); #define LCNPHY_TBL_ID_PAPDCOMPDELTATBL 0x18 #define LCNPHY_TX_POWER_TABLE_SIZE 128 @@ -1030,26 +1020,24 @@ extern void wlc_phy_txpower_recalc_target(struct brcms_phy *pi); #define LCNPHY_TX_PWR_CTRL_TEMPBASED 0xE001 -extern void wlc_lcnphy_write_table(struct brcms_phy *pi, - const struct phytbl_info *pti); -extern void wlc_lcnphy_read_table(struct brcms_phy *pi, - struct phytbl_info *pti); -extern void wlc_lcnphy_set_tx_iqcc(struct brcms_phy *pi, u16 a, u16 b); -extern void wlc_lcnphy_set_tx_locc(struct brcms_phy *pi, u16 didq); -extern void wlc_lcnphy_get_tx_iqcc(struct brcms_phy *pi, u16 *a, u16 *b); -extern u16 wlc_lcnphy_get_tx_locc(struct brcms_phy *pi); -extern void wlc_lcnphy_get_radio_loft(struct brcms_phy *pi, u8 *ei0, - u8 *eq0, u8 *fi0, u8 *fq0); -extern void wlc_lcnphy_calib_modes(struct brcms_phy *pi, uint mode); -extern void wlc_lcnphy_deaf_mode(struct brcms_phy *pi, bool mode); -extern bool wlc_phy_tpc_isenabled_lcnphy(struct brcms_phy *pi); -extern void wlc_lcnphy_tx_pwr_update_npt(struct brcms_phy *pi); -extern s32 wlc_lcnphy_tssi2dbm(s32 tssi, s32 a1, s32 b0, s32 b1); -extern void wlc_lcnphy_get_tssi(struct brcms_phy *pi, s8 *ofdm_pwr, - s8 *cck_pwr); -extern void wlc_lcnphy_tx_power_adjustment(struct brcms_phy_pub *ppi); - -extern s32 wlc_lcnphy_rx_signal_power(struct brcms_phy *pi, s32 gain_index); +void wlc_lcnphy_write_table(struct brcms_phy *pi, + const struct phytbl_info *pti); +void wlc_lcnphy_read_table(struct brcms_phy *pi, struct phytbl_info *pti); +void wlc_lcnphy_set_tx_iqcc(struct brcms_phy *pi, u16 a, u16 b); +void wlc_lcnphy_set_tx_locc(struct brcms_phy *pi, u16 didq); +void wlc_lcnphy_get_tx_iqcc(struct brcms_phy *pi, u16 *a, u16 *b); +u16 wlc_lcnphy_get_tx_locc(struct brcms_phy *pi); +void wlc_lcnphy_get_radio_loft(struct brcms_phy *pi, u8 *ei0, u8 *eq0, u8 *fi0, + u8 *fq0); +void wlc_lcnphy_calib_modes(struct brcms_phy *pi, uint mode); +void wlc_lcnphy_deaf_mode(struct brcms_phy *pi, bool mode); +bool wlc_phy_tpc_isenabled_lcnphy(struct brcms_phy *pi); +void wlc_lcnphy_tx_pwr_update_npt(struct brcms_phy *pi); +s32 wlc_lcnphy_tssi2dbm(s32 tssi, s32 a1, s32 b0, s32 b1); +void wlc_lcnphy_get_tssi(struct brcms_phy *pi, s8 *ofdm_pwr, s8 *cck_pwr); +void wlc_lcnphy_tx_power_adjustment(struct brcms_phy_pub *ppi); + +s32 wlc_lcnphy_rx_signal_power(struct brcms_phy *pi, s32 gain_index); #define NPHY_MAX_HPVGA1_INDEX 10 #define NPHY_DEF_HPVGA1_INDEXLIMIT 7 @@ -1060,9 +1048,8 @@ struct phy_iq_est { u32 q_pwr; }; -extern void wlc_phy_stay_in_carriersearch_nphy(struct brcms_phy *pi, - bool enable); -extern void wlc_nphy_deaf_mode(struct brcms_phy *pi, bool mode); +void wlc_phy_stay_in_carriersearch_nphy(struct brcms_phy *pi, bool enable); +void wlc_nphy_deaf_mode(struct brcms_phy *pi, bool mode); #define wlc_phy_write_table_nphy(pi, pti) \ wlc_phy_write_table(pi, pti, 0x72, 0x74, 0x73) @@ -1076,10 +1063,10 @@ extern void wlc_nphy_deaf_mode(struct brcms_phy *pi, bool mode); #define wlc_nphy_table_data_write(pi, w, v) \ wlc_phy_table_data_write((pi), (w), (v)) -extern void wlc_phy_table_read_nphy(struct brcms_phy *pi, u32, u32 l, u32 o, - u32 w, void *d); -extern void wlc_phy_table_write_nphy(struct brcms_phy *pi, u32, u32, u32, - u32, const void *); +void wlc_phy_table_read_nphy(struct brcms_phy *pi, u32, u32 l, u32 o, u32 w, + void *d); +void wlc_phy_table_write_nphy(struct brcms_phy *pi, u32, u32, u32, u32, + const void *); #define PHY_IPA(pi) \ ((pi->ipa2g_on && CHSPEC_IS2G(pi->radio_chanspec)) || \ @@ -1089,73 +1076,67 @@ extern void wlc_phy_table_write_nphy(struct brcms_phy *pi, u32, u32, u32, if (NREV_LT((pi)->pubpi.phy_rev, 3)) \ (void)bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) -extern void wlc_phy_cal_perical_nphy_run(struct brcms_phy *pi, u8 caltype); -extern void wlc_phy_aci_reset_nphy(struct brcms_phy *pi); -extern void wlc_phy_pa_override_nphy(struct brcms_phy *pi, bool en); - -extern u8 wlc_phy_get_chan_freq_range_nphy(struct brcms_phy *pi, uint chan); -extern void wlc_phy_switch_radio_nphy(struct brcms_phy *pi, bool on); - -extern void wlc_phy_stf_chain_upd_nphy(struct brcms_phy *pi); - -extern void wlc_phy_force_rfseq_nphy(struct brcms_phy *pi, u8 cmd); -extern s16 wlc_phy_tempsense_nphy(struct brcms_phy *pi); - -extern u16 wlc_phy_classifier_nphy(struct brcms_phy *pi, u16 mask, u16 val); - -extern void wlc_phy_rx_iq_est_nphy(struct brcms_phy *pi, struct phy_iq_est *est, - u16 num_samps, u8 wait_time, - u8 wait_for_crs); - -extern void wlc_phy_rx_iq_coeffs_nphy(struct brcms_phy *pi, u8 write, - struct nphy_iq_comp *comp); -extern void wlc_phy_aci_and_noise_reduction_nphy(struct brcms_phy *pi); - -extern void wlc_phy_rxcore_setstate_nphy(struct brcms_phy_pub *pih, - u8 rxcore_bitmask); -extern u8 wlc_phy_rxcore_getstate_nphy(struct brcms_phy_pub *pih); - -extern void wlc_phy_txpwrctrl_enable_nphy(struct brcms_phy *pi, u8 ctrl_type); -extern void wlc_phy_txpwr_fixpower_nphy(struct brcms_phy *pi); -extern void wlc_phy_txpwr_apply_nphy(struct brcms_phy *pi); -extern void wlc_phy_txpwr_papd_cal_nphy(struct brcms_phy *pi); -extern u16 wlc_phy_txpwr_idx_get_nphy(struct brcms_phy *pi); - -extern struct nphy_txgains wlc_phy_get_tx_gain_nphy(struct brcms_phy *pi); -extern int wlc_phy_cal_txiqlo_nphy(struct brcms_phy *pi, - struct nphy_txgains target_gain, - bool full, bool m); -extern int wlc_phy_cal_rxiq_nphy(struct brcms_phy *pi, - struct nphy_txgains target_gain, - u8 type, bool d); -extern void wlc_phy_txpwr_index_nphy(struct brcms_phy *pi, u8 core_mask, - s8 txpwrindex, bool res); -extern void wlc_phy_rssisel_nphy(struct brcms_phy *pi, u8 core, u8 rssi_type); -extern int wlc_phy_poll_rssi_nphy(struct brcms_phy *pi, u8 rssi_type, - s32 *rssi_buf, u8 nsamps); -extern void wlc_phy_rssi_cal_nphy(struct brcms_phy *pi); -extern int wlc_phy_aci_scan_nphy(struct brcms_phy *pi); -extern void wlc_phy_cal_txgainctrl_nphy(struct brcms_phy *pi, - s32 dBm_targetpower, bool debug); -extern int wlc_phy_tx_tone_nphy(struct brcms_phy *pi, u32 f_kHz, u16 max_val, - u8 mode, u8, bool); -extern void wlc_phy_stopplayback_nphy(struct brcms_phy *pi); -extern void wlc_phy_est_tonepwr_nphy(struct brcms_phy *pi, s32 *qdBm_pwrbuf, - u8 num_samps); -extern void wlc_phy_radio205x_vcocal_nphy(struct brcms_phy *pi); - -extern int wlc_phy_rssi_compute_nphy(struct brcms_phy *pi, - struct d11rxhdr *rxh); +void wlc_phy_cal_perical_nphy_run(struct brcms_phy *pi, u8 caltype); +void wlc_phy_aci_reset_nphy(struct brcms_phy *pi); +void wlc_phy_pa_override_nphy(struct brcms_phy *pi, bool en); + +u8 wlc_phy_get_chan_freq_range_nphy(struct brcms_phy *pi, uint chan); +void wlc_phy_switch_radio_nphy(struct brcms_phy *pi, bool on); + +void wlc_phy_stf_chain_upd_nphy(struct brcms_phy *pi); + +void wlc_phy_force_rfseq_nphy(struct brcms_phy *pi, u8 cmd); +s16 wlc_phy_tempsense_nphy(struct brcms_phy *pi); + +u16 wlc_phy_classifier_nphy(struct brcms_phy *pi, u16 mask, u16 val); + +void wlc_phy_rx_iq_est_nphy(struct brcms_phy *pi, struct phy_iq_est *est, + u16 num_samps, u8 wait_time, u8 wait_for_crs); + +void wlc_phy_rx_iq_coeffs_nphy(struct brcms_phy *pi, u8 write, + struct nphy_iq_comp *comp); +void wlc_phy_aci_and_noise_reduction_nphy(struct brcms_phy *pi); + +void wlc_phy_rxcore_setstate_nphy(struct brcms_phy_pub *pih, u8 rxcore_bitmask); +u8 wlc_phy_rxcore_getstate_nphy(struct brcms_phy_pub *pih); + +void wlc_phy_txpwrctrl_enable_nphy(struct brcms_phy *pi, u8 ctrl_type); +void wlc_phy_txpwr_fixpower_nphy(struct brcms_phy *pi); +void wlc_phy_txpwr_apply_nphy(struct brcms_phy *pi); +void wlc_phy_txpwr_papd_cal_nphy(struct brcms_phy *pi); +u16 wlc_phy_txpwr_idx_get_nphy(struct brcms_phy *pi); + +struct nphy_txgains wlc_phy_get_tx_gain_nphy(struct brcms_phy *pi); +int wlc_phy_cal_txiqlo_nphy(struct brcms_phy *pi, + struct nphy_txgains target_gain, bool full, bool m); +int wlc_phy_cal_rxiq_nphy(struct brcms_phy *pi, struct nphy_txgains target_gain, + u8 type, bool d); +void wlc_phy_txpwr_index_nphy(struct brcms_phy *pi, u8 core_mask, + s8 txpwrindex, bool res); +void wlc_phy_rssisel_nphy(struct brcms_phy *pi, u8 core, u8 rssi_type); +int wlc_phy_poll_rssi_nphy(struct brcms_phy *pi, u8 rssi_type, + s32 *rssi_buf, u8 nsamps); +void wlc_phy_rssi_cal_nphy(struct brcms_phy *pi); +int wlc_phy_aci_scan_nphy(struct brcms_phy *pi); +void wlc_phy_cal_txgainctrl_nphy(struct brcms_phy *pi, s32 dBm_targetpower, + bool debug); +int wlc_phy_tx_tone_nphy(struct brcms_phy *pi, u32 f_kHz, u16 max_val, u8 mode, + u8, bool); +void wlc_phy_stopplayback_nphy(struct brcms_phy *pi); +void wlc_phy_est_tonepwr_nphy(struct brcms_phy *pi, s32 *qdBm_pwrbuf, + u8 num_samps); +void wlc_phy_radio205x_vcocal_nphy(struct brcms_phy *pi); + +int wlc_phy_rssi_compute_nphy(struct brcms_phy *pi, struct d11rxhdr *rxh); #define NPHY_TESTPATTERN_BPHY_EVM 0 #define NPHY_TESTPATTERN_BPHY_RFCS 1 -extern void wlc_phy_nphy_tkip_rifs_war(struct brcms_phy *pi, u8 rifs); +void wlc_phy_nphy_tkip_rifs_war(struct brcms_phy *pi, u8 rifs); void wlc_phy_get_pwrdet_offsets(struct brcms_phy *pi, s8 *cckoffset, s8 *ofdmoffset); -extern s8 wlc_phy_upd_rssi_offset(struct brcms_phy *pi, s8 rssi, - u16 chanspec); +s8 wlc_phy_upd_rssi_offset(struct brcms_phy *pi, s8 rssi, u16 chanspec); -extern bool wlc_phy_n_txpower_ipa_ison(struct brcms_phy *pih); +bool wlc_phy_n_txpower_ipa_ison(struct brcms_phy *pih); #endif /* _BRCM_PHY_INT_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h b/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h index 2c5b66b75970..dd8774717ade 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h @@ -124,56 +124,49 @@ struct brcms_phy; -extern struct phy_shim_info *wlc_phy_shim_attach(struct brcms_hardware *wlc_hw, - struct brcms_info *wl, - struct brcms_c_info *wlc); -extern void wlc_phy_shim_detach(struct phy_shim_info *physhim); +struct phy_shim_info *wlc_phy_shim_attach(struct brcms_hardware *wlc_hw, + struct brcms_info *wl, + struct brcms_c_info *wlc); +void wlc_phy_shim_detach(struct phy_shim_info *physhim); /* PHY to WL utility functions */ -extern struct wlapi_timer *wlapi_init_timer(struct phy_shim_info *physhim, - void (*fn) (struct brcms_phy *pi), - void *arg, const char *name); -extern void wlapi_free_timer(struct wlapi_timer *t); -extern void wlapi_add_timer(struct wlapi_timer *t, uint ms, int periodic); -extern bool wlapi_del_timer(struct wlapi_timer *t); -extern void wlapi_intrson(struct phy_shim_info *physhim); -extern u32 wlapi_intrsoff(struct phy_shim_info *physhim); -extern void wlapi_intrsrestore(struct phy_shim_info *physhim, - u32 macintmask); - -extern void wlapi_bmac_write_shm(struct phy_shim_info *physhim, uint offset, - u16 v); -extern u16 wlapi_bmac_read_shm(struct phy_shim_info *physhim, uint offset); -extern void wlapi_bmac_mhf(struct phy_shim_info *physhim, u8 idx, - u16 mask, u16 val, int bands); -extern void wlapi_bmac_corereset(struct phy_shim_info *physhim, u32 flags); -extern void wlapi_suspend_mac_and_wait(struct phy_shim_info *physhim); -extern void wlapi_switch_macfreq(struct phy_shim_info *physhim, u8 spurmode); -extern void wlapi_enable_mac(struct phy_shim_info *physhim); -extern void wlapi_bmac_mctrl(struct phy_shim_info *physhim, u32 mask, - u32 val); -extern void wlapi_bmac_phy_reset(struct phy_shim_info *physhim); -extern void wlapi_bmac_bw_set(struct phy_shim_info *physhim, u16 bw); -extern void wlapi_bmac_phyclk_fgc(struct phy_shim_info *physhim, bool clk); -extern void wlapi_bmac_macphyclk_set(struct phy_shim_info *physhim, bool clk); -extern void wlapi_bmac_core_phypll_ctl(struct phy_shim_info *physhim, bool on); -extern void wlapi_bmac_core_phypll_reset(struct phy_shim_info *physhim); -extern void wlapi_bmac_ucode_wake_override_phyreg_set(struct phy_shim_info * - physhim); -extern void wlapi_bmac_ucode_wake_override_phyreg_clear(struct phy_shim_info * - physhim); -extern void wlapi_bmac_write_template_ram(struct phy_shim_info *physhim, int o, - int len, void *buf); -extern u16 wlapi_bmac_rate_shm_offset(struct phy_shim_info *physhim, - u8 rate); -extern void wlapi_ucode_sample_init(struct phy_shim_info *physhim); -extern void wlapi_copyfrom_objmem(struct phy_shim_info *physhim, uint, - void *buf, int, u32 sel); -extern void wlapi_copyto_objmem(struct phy_shim_info *physhim, uint, - const void *buf, int, u32); - -extern void wlapi_high_update_phy_mode(struct phy_shim_info *physhim, - u32 phy_mode); -extern u16 wlapi_bmac_get_txant(struct phy_shim_info *physhim); +struct wlapi_timer *wlapi_init_timer(struct phy_shim_info *physhim, + void (*fn)(struct brcms_phy *pi), + void *arg, const char *name); +void wlapi_free_timer(struct wlapi_timer *t); +void wlapi_add_timer(struct wlapi_timer *t, uint ms, int periodic); +bool wlapi_del_timer(struct wlapi_timer *t); +void wlapi_intrson(struct phy_shim_info *physhim); +u32 wlapi_intrsoff(struct phy_shim_info *physhim); +void wlapi_intrsrestore(struct phy_shim_info *physhim, u32 macintmask); + +void wlapi_bmac_write_shm(struct phy_shim_info *physhim, uint offset, u16 v); +u16 wlapi_bmac_read_shm(struct phy_shim_info *physhim, uint offset); +void wlapi_bmac_mhf(struct phy_shim_info *physhim, u8 idx, u16 mask, u16 val, + int bands); +void wlapi_bmac_corereset(struct phy_shim_info *physhim, u32 flags); +void wlapi_suspend_mac_and_wait(struct phy_shim_info *physhim); +void wlapi_switch_macfreq(struct phy_shim_info *physhim, u8 spurmode); +void wlapi_enable_mac(struct phy_shim_info *physhim); +void wlapi_bmac_mctrl(struct phy_shim_info *physhim, u32 mask, u32 val); +void wlapi_bmac_phy_reset(struct phy_shim_info *physhim); +void wlapi_bmac_bw_set(struct phy_shim_info *physhim, u16 bw); +void wlapi_bmac_phyclk_fgc(struct phy_shim_info *physhim, bool clk); +void wlapi_bmac_macphyclk_set(struct phy_shim_info *physhim, bool clk); +void wlapi_bmac_core_phypll_ctl(struct phy_shim_info *physhim, bool on); +void wlapi_bmac_core_phypll_reset(struct phy_shim_info *physhim); +void wlapi_bmac_ucode_wake_override_phyreg_set(struct phy_shim_info *physhim); +void wlapi_bmac_ucode_wake_override_phyreg_clear(struct phy_shim_info *physhim); +void wlapi_bmac_write_template_ram(struct phy_shim_info *physhim, int o, + int len, void *buf); +u16 wlapi_bmac_rate_shm_offset(struct phy_shim_info *physhim, u8 rate); +void wlapi_ucode_sample_init(struct phy_shim_info *physhim); +void wlapi_copyfrom_objmem(struct phy_shim_info *physhim, uint, void *buf, + int, u32 sel); +void wlapi_copyto_objmem(struct phy_shim_info *physhim, uint, const void *buf, + int, u32); + +void wlapi_high_update_phy_mode(struct phy_shim_info *physhim, u32 phy_mode); +u16 wlapi_bmac_get_txant(struct phy_shim_info *physhim); #endif /* _BRCM_PHY_SHIM_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pmu.h b/drivers/net/wireless/brcm80211/brcmsmac/pmu.h index 20e2012d5a3a..a014bbc4f935 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/pmu.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/pmu.h @@ -20,7 +20,7 @@ #include "types.h" -extern u16 si_pmu_fast_pwrup_delay(struct si_pub *sih); -extern u32 si_pmu_measure_alpclk(struct si_pub *sih); +u16 si_pmu_fast_pwrup_delay(struct si_pub *sih); +u32 si_pmu_measure_alpclk(struct si_pub *sih); #endif /* _BRCM_PMU_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pub.h b/drivers/net/wireless/brcm80211/brcmsmac/pub.h index d36ea5e1cc49..4da38cb4f318 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h @@ -266,83 +266,76 @@ struct brcms_antselcfg { }; /* common functions for every port */ -extern struct brcms_c_info * -brcms_c_attach(struct brcms_info *wl, struct bcma_device *core, uint unit, - bool piomode, uint *perr); -extern uint brcms_c_detach(struct brcms_c_info *wlc); -extern int brcms_c_up(struct brcms_c_info *wlc); -extern uint brcms_c_down(struct brcms_c_info *wlc); - -extern bool brcms_c_chipmatch(struct bcma_device *core); -extern void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx); -extern void brcms_c_reset(struct brcms_c_info *wlc); - -extern void brcms_c_intrson(struct brcms_c_info *wlc); -extern u32 brcms_c_intrsoff(struct brcms_c_info *wlc); -extern void brcms_c_intrsrestore(struct brcms_c_info *wlc, u32 macintmask); -extern bool brcms_c_intrsupd(struct brcms_c_info *wlc); -extern bool brcms_c_isr(struct brcms_c_info *wlc); -extern bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded); -extern bool brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, - struct sk_buff *sdu, - struct ieee80211_hw *hw); -extern bool brcms_c_aggregatable(struct brcms_c_info *wlc, u8 tid); -extern void brcms_c_protection_upd(struct brcms_c_info *wlc, uint idx, - int val); -extern int brcms_c_get_header_len(void); -extern void brcms_c_set_addrmatch(struct brcms_c_info *wlc, - int match_reg_offset, - const u8 *addr); -extern void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci, - const struct ieee80211_tx_queue_params *arg, - bool suspend); -extern struct brcms_pub *brcms_c_pub(struct brcms_c_info *wlc); -extern void brcms_c_ampdu_flush(struct brcms_c_info *wlc, - struct ieee80211_sta *sta, u16 tid); -extern void brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid, - u8 ba_wsize, uint max_rx_ampdu_bytes); -extern int brcms_c_module_register(struct brcms_pub *pub, - const char *name, struct brcms_info *hdl, - int (*down_fn)(void *handle)); -extern int brcms_c_module_unregister(struct brcms_pub *pub, const char *name, - struct brcms_info *hdl); -extern void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc); -extern void brcms_c_enable_mac(struct brcms_c_info *wlc); -extern void brcms_c_associate_upd(struct brcms_c_info *wlc, bool state); -extern void brcms_c_scan_start(struct brcms_c_info *wlc); -extern void brcms_c_scan_stop(struct brcms_c_info *wlc); -extern int brcms_c_get_curband(struct brcms_c_info *wlc); -extern int brcms_c_set_channel(struct brcms_c_info *wlc, u16 channel); -extern int brcms_c_set_rate_limit(struct brcms_c_info *wlc, u16 srl, u16 lrl); -extern void brcms_c_get_current_rateset(struct brcms_c_info *wlc, +struct brcms_c_info *brcms_c_attach(struct brcms_info *wl, + struct bcma_device *core, uint unit, + bool piomode, uint *perr); +uint brcms_c_detach(struct brcms_c_info *wlc); +int brcms_c_up(struct brcms_c_info *wlc); +uint brcms_c_down(struct brcms_c_info *wlc); + +bool brcms_c_chipmatch(struct bcma_device *core); +void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx); +void brcms_c_reset(struct brcms_c_info *wlc); + +void brcms_c_intrson(struct brcms_c_info *wlc); +u32 brcms_c_intrsoff(struct brcms_c_info *wlc); +void brcms_c_intrsrestore(struct brcms_c_info *wlc, u32 macintmask); +bool brcms_c_intrsupd(struct brcms_c_info *wlc); +bool brcms_c_isr(struct brcms_c_info *wlc); +bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded); +bool brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu, + struct ieee80211_hw *hw); +bool brcms_c_aggregatable(struct brcms_c_info *wlc, u8 tid); +void brcms_c_protection_upd(struct brcms_c_info *wlc, uint idx, int val); +int brcms_c_get_header_len(void); +void brcms_c_set_addrmatch(struct brcms_c_info *wlc, int match_reg_offset, + const u8 *addr); +void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci, + const struct ieee80211_tx_queue_params *arg, + bool suspend); +struct brcms_pub *brcms_c_pub(struct brcms_c_info *wlc); +void brcms_c_ampdu_flush(struct brcms_c_info *wlc, struct ieee80211_sta *sta, + u16 tid); +void brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid, + u8 ba_wsize, uint max_rx_ampdu_bytes); +int brcms_c_module_register(struct brcms_pub *pub, const char *name, + struct brcms_info *hdl, + int (*down_fn)(void *handle)); +int brcms_c_module_unregister(struct brcms_pub *pub, const char *name, + struct brcms_info *hdl); +void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc); +void brcms_c_enable_mac(struct brcms_c_info *wlc); +void brcms_c_associate_upd(struct brcms_c_info *wlc, bool state); +void brcms_c_scan_start(struct brcms_c_info *wlc); +void brcms_c_scan_stop(struct brcms_c_info *wlc); +int brcms_c_get_curband(struct brcms_c_info *wlc); +int brcms_c_set_channel(struct brcms_c_info *wlc, u16 channel); +int brcms_c_set_rate_limit(struct brcms_c_info *wlc, u16 srl, u16 lrl); +void brcms_c_get_current_rateset(struct brcms_c_info *wlc, struct brcm_rateset *currs); -extern int brcms_c_set_rateset(struct brcms_c_info *wlc, - struct brcm_rateset *rs); -extern int brcms_c_set_beacon_period(struct brcms_c_info *wlc, u16 period); -extern u16 brcms_c_get_phy_type(struct brcms_c_info *wlc, int phyidx); -extern void brcms_c_set_shortslot_override(struct brcms_c_info *wlc, +int brcms_c_set_rateset(struct brcms_c_info *wlc, struct brcm_rateset *rs); +int brcms_c_set_beacon_period(struct brcms_c_info *wlc, u16 period); +u16 brcms_c_get_phy_type(struct brcms_c_info *wlc, int phyidx); +void brcms_c_set_shortslot_override(struct brcms_c_info *wlc, s8 sslot_override); -extern void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, - u8 interval); -extern u64 brcms_c_tsf_get(struct brcms_c_info *wlc); -extern void brcms_c_tsf_set(struct brcms_c_info *wlc, u64 tsf); -extern int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr); -extern int brcms_c_get_tx_power(struct brcms_c_info *wlc); -extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc); -extern void brcms_c_mute(struct brcms_c_info *wlc, bool on); -extern bool brcms_c_tx_flush_completed(struct brcms_c_info *wlc); -extern void brcms_c_start_station(struct brcms_c_info *wlc, u8 *addr); -extern void brcms_c_start_ap(struct brcms_c_info *wlc, u8 *addr, - const u8 *bssid, u8 *ssid, size_t ssid_len); -extern void brcms_c_start_adhoc(struct brcms_c_info *wlc, u8 *addr); -extern void brcms_c_update_beacon(struct brcms_c_info *wlc); -extern void brcms_c_set_new_beacon(struct brcms_c_info *wlc, - struct sk_buff *beacon, u16 tim_offset, - u16 dtim_period); -extern void brcms_c_set_new_probe_resp(struct brcms_c_info *wlc, - struct sk_buff *probe_resp); -extern void brcms_c_enable_probe_resp(struct brcms_c_info *wlc, bool enable); -extern void brcms_c_set_ssid(struct brcms_c_info *wlc, u8 *ssid, - size_t ssid_len); +void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, u8 interval); +u64 brcms_c_tsf_get(struct brcms_c_info *wlc); +void brcms_c_tsf_set(struct brcms_c_info *wlc, u64 tsf); +int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr); +int brcms_c_get_tx_power(struct brcms_c_info *wlc); +bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc); +void brcms_c_mute(struct brcms_c_info *wlc, bool on); +bool brcms_c_tx_flush_completed(struct brcms_c_info *wlc); +void brcms_c_start_station(struct brcms_c_info *wlc, u8 *addr); +void brcms_c_start_ap(struct brcms_c_info *wlc, u8 *addr, const u8 *bssid, + u8 *ssid, size_t ssid_len); +void brcms_c_start_adhoc(struct brcms_c_info *wlc, u8 *addr); +void brcms_c_update_beacon(struct brcms_c_info *wlc); +void brcms_c_set_new_beacon(struct brcms_c_info *wlc, struct sk_buff *beacon, + u16 tim_offset, u16 dtim_period); +void brcms_c_set_new_probe_resp(struct brcms_c_info *wlc, + struct sk_buff *probe_resp); +void brcms_c_enable_probe_resp(struct brcms_c_info *wlc, bool enable); +void brcms_c_set_ssid(struct brcms_c_info *wlc, u8 *ssid, size_t ssid_len); #endif /* _BRCM_PUB_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmsmac/rate.h b/drivers/net/wireless/brcm80211/brcmsmac/rate.h index 980d578825cc..5bb88b78ed64 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/rate.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/rate.h @@ -216,34 +216,30 @@ static inline u8 cck_phy2mac_rate(u8 signal) /* sanitize, and sort a rateset with the basic bit(s) preserved, validate * rateset */ -extern bool -brcms_c_rate_hwrs_filter_sort_validate(struct brcms_c_rateset *rs, - const struct brcms_c_rateset *hw_rs, - bool check_brate, u8 txstreams); +bool brcms_c_rate_hwrs_filter_sort_validate(struct brcms_c_rateset *rs, + const struct brcms_c_rateset *hw_rs, + bool check_brate, u8 txstreams); /* copy rateset src to dst as-is (no masking or sorting) */ -extern void brcms_c_rateset_copy(const struct brcms_c_rateset *src, - struct brcms_c_rateset *dst); +void brcms_c_rateset_copy(const struct brcms_c_rateset *src, + struct brcms_c_rateset *dst); /* would be nice to have these documented ... */ -extern u32 brcms_c_compute_rspec(struct d11rxhdr *rxh, u8 *plcp); - -extern void brcms_c_rateset_filter(struct brcms_c_rateset *src, - struct brcms_c_rateset *dst, bool basic_only, u8 rates, uint xmask, - bool mcsallow); - -extern void -brcms_c_rateset_default(struct brcms_c_rateset *rs_tgt, - const struct brcms_c_rateset *rs_hw, uint phy_type, - int bandtype, bool cck_only, uint rate_mask, - bool mcsallow, u8 bw, u8 txstreams); - -extern s16 brcms_c_rate_legacy_phyctl(uint rate); - -extern void brcms_c_rateset_mcs_upd(struct brcms_c_rateset *rs, u8 txstreams); -extern void brcms_c_rateset_mcs_clear(struct brcms_c_rateset *rateset); -extern void brcms_c_rateset_mcs_build(struct brcms_c_rateset *rateset, - u8 txstreams); -extern void brcms_c_rateset_bw_mcs_filter(struct brcms_c_rateset *rateset, - u8 bw); +u32 brcms_c_compute_rspec(struct d11rxhdr *rxh, u8 *plcp); + +void brcms_c_rateset_filter(struct brcms_c_rateset *src, + struct brcms_c_rateset *dst, bool basic_only, + u8 rates, uint xmask, bool mcsallow); + +void brcms_c_rateset_default(struct brcms_c_rateset *rs_tgt, + const struct brcms_c_rateset *rs_hw, uint phy_type, + int bandtype, bool cck_only, uint rate_mask, + bool mcsallow, u8 bw, u8 txstreams); + +s16 brcms_c_rate_legacy_phyctl(uint rate); + +void brcms_c_rateset_mcs_upd(struct brcms_c_rateset *rs, u8 txstreams); +void brcms_c_rateset_mcs_clear(struct brcms_c_rateset *rateset); +void brcms_c_rateset_mcs_build(struct brcms_c_rateset *rateset, u8 txstreams); +void brcms_c_rateset_bw_mcs_filter(struct brcms_c_rateset *rateset, u8 bw); #endif /* _BRCM_RATE_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmsmac/stf.h b/drivers/net/wireless/brcm80211/brcmsmac/stf.h index 19f6580f69be..ba9493009a33 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/stf.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/stf.h @@ -19,24 +19,19 @@ #include "types.h" -extern int brcms_c_stf_attach(struct brcms_c_info *wlc); -extern void brcms_c_stf_detach(struct brcms_c_info *wlc); +int brcms_c_stf_attach(struct brcms_c_info *wlc); +void brcms_c_stf_detach(struct brcms_c_info *wlc); -extern void brcms_c_tempsense_upd(struct brcms_c_info *wlc); -extern void brcms_c_stf_ss_algo_channel_get(struct brcms_c_info *wlc, - u16 *ss_algo_channel, - u16 chanspec); -extern int brcms_c_stf_ss_update(struct brcms_c_info *wlc, - struct brcms_band *band); -extern void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc); -extern int brcms_c_stf_txchain_set(struct brcms_c_info *wlc, s32 int_val, - bool force); -extern bool brcms_c_stf_stbc_rx_set(struct brcms_c_info *wlc, s32 int_val); -extern void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc); -extern void brcms_c_stf_phy_chain_calc(struct brcms_c_info *wlc); -extern u16 brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc, - u32 rspec); -extern u16 brcms_c_stf_d11hdrs_phyctl_txant(struct brcms_c_info *wlc, - u32 rspec); +void brcms_c_tempsense_upd(struct brcms_c_info *wlc); +void brcms_c_stf_ss_algo_channel_get(struct brcms_c_info *wlc, + u16 *ss_algo_channel, u16 chanspec); +int brcms_c_stf_ss_update(struct brcms_c_info *wlc, struct brcms_band *band); +void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc); +int brcms_c_stf_txchain_set(struct brcms_c_info *wlc, s32 int_val, bool force); +bool brcms_c_stf_stbc_rx_set(struct brcms_c_info *wlc, s32 int_val); +void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc); +void brcms_c_stf_phy_chain_calc(struct brcms_c_info *wlc); +u16 brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc, u32 rspec); +u16 brcms_c_stf_d11hdrs_phyctl_txant(struct brcms_c_info *wlc, u32 rspec); #endif /* _BRCM_STF_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.h b/drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.h index 18750a814b4f..c87dd89bcb78 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.h @@ -43,16 +43,14 @@ struct brcms_ucode { u32 *bcm43xx_bomminor; }; -extern int -brcms_ucode_data_init(struct brcms_info *wl, struct brcms_ucode *ucode); +int brcms_ucode_data_init(struct brcms_info *wl, struct brcms_ucode *ucode); -extern void brcms_ucode_data_free(struct brcms_ucode *ucode); +void brcms_ucode_data_free(struct brcms_ucode *ucode); -extern int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf, - unsigned int idx); -extern int brcms_ucode_init_uint(struct brcms_info *wl, size_t *n_bytes, - unsigned int idx); -extern void brcms_ucode_free_buf(void *); -extern int brcms_check_firmwares(struct brcms_info *wl); +int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf, unsigned int idx); +int brcms_ucode_init_uint(struct brcms_info *wl, size_t *n_bytes, + unsigned int idx); +void brcms_ucode_free_buf(void *); +int brcms_check_firmwares(struct brcms_info *wl); #endif /* _BRCM_UCODE_H_ */ diff --git a/drivers/net/wireless/brcm80211/include/brcmu_d11.h b/drivers/net/wireless/brcm80211/include/brcmu_d11.h index 92623f02b1c0..8660a2cba098 100644 --- a/drivers/net/wireless/brcm80211/include/brcmu_d11.h +++ b/drivers/net/wireless/brcm80211/include/brcmu_d11.h @@ -140,6 +140,6 @@ struct brcmu_d11inf { void (*decchspec)(struct brcmu_chan *ch); }; -extern void brcmu_d11_attach(struct brcmu_d11inf *d11inf); +void brcmu_d11_attach(struct brcmu_d11inf *d11inf); #endif /* _BRCMU_CHANNELS_H_ */ diff --git a/drivers/net/wireless/brcm80211/include/brcmu_utils.h b/drivers/net/wireless/brcm80211/include/brcmu_utils.h index 898cacb8d01d..8ba445b3fd72 100644 --- a/drivers/net/wireless/brcm80211/include/brcmu_utils.h +++ b/drivers/net/wireless/brcm80211/include/brcmu_utils.h @@ -114,31 +114,29 @@ static inline struct sk_buff *pktq_ppeek_tail(struct pktq *pq, int prec) return skb_peek_tail(&pq->q[prec].skblist); } -extern struct sk_buff *brcmu_pktq_penq(struct pktq *pq, int prec, - struct sk_buff *p); -extern struct sk_buff *brcmu_pktq_penq_head(struct pktq *pq, int prec, - struct sk_buff *p); -extern struct sk_buff *brcmu_pktq_pdeq(struct pktq *pq, int prec); -extern struct sk_buff *brcmu_pktq_pdeq_tail(struct pktq *pq, int prec); -extern struct sk_buff *brcmu_pktq_pdeq_match(struct pktq *pq, int prec, - bool (*match_fn)(struct sk_buff *p, - void *arg), - void *arg); +struct sk_buff *brcmu_pktq_penq(struct pktq *pq, int prec, struct sk_buff *p); +struct sk_buff *brcmu_pktq_penq_head(struct pktq *pq, int prec, + struct sk_buff *p); +struct sk_buff *brcmu_pktq_pdeq(struct pktq *pq, int prec); +struct sk_buff *brcmu_pktq_pdeq_tail(struct pktq *pq, int prec); +struct sk_buff *brcmu_pktq_pdeq_match(struct pktq *pq, int prec, + bool (*match_fn)(struct sk_buff *p, + void *arg), + void *arg); /* packet primitives */ -extern struct sk_buff *brcmu_pkt_buf_get_skb(uint len); -extern void brcmu_pkt_buf_free_skb(struct sk_buff *skb); +struct sk_buff *brcmu_pkt_buf_get_skb(uint len); +void brcmu_pkt_buf_free_skb(struct sk_buff *skb); /* Empty the queue at particular precedence level */ /* callback function fn(pkt, arg) returns true if pkt belongs to if */ -extern void brcmu_pktq_pflush(struct pktq *pq, int prec, - bool dir, bool (*fn)(struct sk_buff *, void *), void *arg); +void brcmu_pktq_pflush(struct pktq *pq, int prec, bool dir, + bool (*fn)(struct sk_buff *, void *), void *arg); /* operations on a set of precedences in packet queue */ -extern int brcmu_pktq_mlen(struct pktq *pq, uint prec_bmp); -extern struct sk_buff *brcmu_pktq_mdeq(struct pktq *pq, uint prec_bmp, - int *prec_out); +int brcmu_pktq_mlen(struct pktq *pq, uint prec_bmp); +struct sk_buff *brcmu_pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out); /* operations on packet queue as a whole */ @@ -167,11 +165,11 @@ static inline bool pktq_empty(struct pktq *pq) return pq->len == 0; } -extern void brcmu_pktq_init(struct pktq *pq, int num_prec, int max_len); +void brcmu_pktq_init(struct pktq *pq, int num_prec, int max_len); /* prec_out may be NULL if caller is not interested in return value */ -extern struct sk_buff *brcmu_pktq_peek_tail(struct pktq *pq, int *prec_out); -extern void brcmu_pktq_flush(struct pktq *pq, bool dir, - bool (*fn)(struct sk_buff *, void *), void *arg); +struct sk_buff *brcmu_pktq_peek_tail(struct pktq *pq, int *prec_out); +void brcmu_pktq_flush(struct pktq *pq, bool dir, + bool (*fn)(struct sk_buff *, void *), void *arg); /* externs */ /* ip address */ @@ -204,13 +202,13 @@ static inline u16 brcmu_maskget16(u16 var, u16 mask, u8 shift) /* externs */ /* format/print */ #ifdef DEBUG -extern void brcmu_prpkt(const char *msg, struct sk_buff *p0); +void brcmu_prpkt(const char *msg, struct sk_buff *p0); #else #define brcmu_prpkt(a, b) #endif /* DEBUG */ #ifdef DEBUG -extern __printf(3, 4) +__printf(3, 4) void brcmu_dbg_hex_dump(const void *data, size_t size, const char *fmt, ...); #else __printf(3, 4) diff --git a/drivers/net/wireless/cw1200/cw1200_spi.c b/drivers/net/wireless/cw1200/cw1200_spi.c index e310752f0e33..8057143849ce 100644 --- a/drivers/net/wireless/cw1200/cw1200_spi.c +++ b/drivers/net/wireless/cw1200/cw1200_spi.c @@ -42,7 +42,6 @@ struct hwbus_priv { spinlock_t lock; /* Serialize all bus operations */ wait_queue_head_t wq; int claimed; - int irq_disabled; }; #define SDIO_TO_SPI_ADDR(addr) ((addr & 0x1f)>>2) @@ -238,8 +237,6 @@ static irqreturn_t cw1200_spi_irq_handler(int irq, void *dev_id) struct hwbus_priv *self = dev_id; if (self->core) { - disable_irq_nosync(self->func->irq); - self->irq_disabled = 1; cw1200_irq_handler(self->core); return IRQ_HANDLED; } else { @@ -253,9 +250,10 @@ static int cw1200_spi_irq_subscribe(struct hwbus_priv *self) pr_debug("SW IRQ subscribe\n"); - ret = request_any_context_irq(self->func->irq, cw1200_spi_irq_handler, - IRQF_TRIGGER_HIGH, - "cw1200_wlan_irq", self); + ret = request_threaded_irq(self->func->irq, NULL, + cw1200_spi_irq_handler, + IRQF_TRIGGER_HIGH | IRQF_ONESHOT, + "cw1200_wlan_irq", self); if (WARN_ON(ret < 0)) goto exit; @@ -273,22 +271,13 @@ exit: static int cw1200_spi_irq_unsubscribe(struct hwbus_priv *self) { + int ret = 0; + pr_debug("SW IRQ unsubscribe\n"); disable_irq_wake(self->func->irq); free_irq(self->func->irq, self); - return 0; -} - -static int cw1200_spi_irq_enable(struct hwbus_priv *self, int enable) -{ - /* Disables are handled by the interrupt handler */ - if (enable && self->irq_disabled) { - enable_irq(self->func->irq); - self->irq_disabled = 0; - } - - return 0; + return ret; } static int cw1200_spi_off(const struct cw1200_platform_data_spi *pdata) @@ -368,7 +357,6 @@ static struct hwbus_ops cw1200_spi_hwbus_ops = { .unlock = cw1200_spi_unlock, .align_size = cw1200_spi_align_size, .power_mgmt = cw1200_spi_pm, - .irq_enable = cw1200_spi_irq_enable, }; /* Probe Function to be called by SPI stack when device is discovered */ diff --git a/drivers/net/wireless/cw1200/fwio.c b/drivers/net/wireless/cw1200/fwio.c index 0b2061bbc68b..acdff0f7f952 100644 --- a/drivers/net/wireless/cw1200/fwio.c +++ b/drivers/net/wireless/cw1200/fwio.c @@ -485,7 +485,7 @@ int cw1200_load_firmware(struct cw1200_common *priv) /* Enable interrupt signalling */ priv->hwbus_ops->lock(priv->hwbus_priv); - ret = __cw1200_irq_enable(priv, 2); + ret = __cw1200_irq_enable(priv, 1); priv->hwbus_ops->unlock(priv->hwbus_priv); if (ret < 0) goto unsubscribe; diff --git a/drivers/net/wireless/cw1200/hwbus.h b/drivers/net/wireless/cw1200/hwbus.h index 51dfb3a90735..8b2fc831c3de 100644 --- a/drivers/net/wireless/cw1200/hwbus.h +++ b/drivers/net/wireless/cw1200/hwbus.h @@ -28,7 +28,6 @@ struct hwbus_ops { void (*unlock)(struct hwbus_priv *self); size_t (*align_size)(struct hwbus_priv *self, size_t size); int (*power_mgmt)(struct hwbus_priv *self, bool suspend); - int (*irq_enable)(struct hwbus_priv *self, int enable); }; #endif /* CW1200_HWBUS_H */ diff --git a/drivers/net/wireless/cw1200/hwio.c b/drivers/net/wireless/cw1200/hwio.c index 41bd7615ccaa..ff230b7aeedd 100644 --- a/drivers/net/wireless/cw1200/hwio.c +++ b/drivers/net/wireless/cw1200/hwio.c @@ -273,21 +273,6 @@ int __cw1200_irq_enable(struct cw1200_common *priv, int enable) u16 val16; int ret; - /* We need to do this hack because the SPI layer can sleep on I/O - and the general path involves I/O to the device in interrupt - context. - - However, the initial enable call needs to go to the hardware. - - We don't worry about shutdown because we do a full reset which - clears the interrupt enabled bits. - */ - if (priv->hwbus_ops->irq_enable) { - ret = priv->hwbus_ops->irq_enable(priv->hwbus_priv, enable); - if (ret || enable < 2) - return ret; - } - if (HIF_8601_SILICON == priv->hw_type) { ret = __cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, &val32); if (ret < 0) { diff --git a/drivers/net/wireless/hostap/hostap_info.c b/drivers/net/wireless/hostap/hostap_info.c index 970a48baaf80..de7c4ffec309 100644 --- a/drivers/net/wireless/hostap/hostap_info.c +++ b/drivers/net/wireless/hostap/hostap_info.c @@ -217,7 +217,7 @@ static void prism2_host_roaming(local_info_t *local) } } - memcpy(req.bssid, selected->bssid, 6); + memcpy(req.bssid, selected->bssid, ETH_ALEN); req.channel = selected->chid; spin_unlock_irqrestore(&local->lock, flags); diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index f394af777cf5..81903e33d5b1 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c @@ -2698,7 +2698,7 @@ static u16 eeprom_read_u16(struct ipw_priv *priv, u8 addr) /* data's copy of the eeprom data */ static void eeprom_parse_mac(struct ipw_priv *priv, u8 * mac) { - memcpy(mac, &priv->eeprom[EEPROM_MAC_ADDRESS], 6); + memcpy(mac, &priv->eeprom[EEPROM_MAC_ADDRESS], ETH_ALEN); } static void ipw_read_eeprom(struct ipw_priv *priv) diff --git a/drivers/net/wireless/ipw2x00/libipw.h b/drivers/net/wireless/ipw2x00/libipw.h index 6eede52ad8c0..5ce2f59d3378 100644 --- a/drivers/net/wireless/ipw2x00/libipw.h +++ b/drivers/net/wireless/ipw2x00/libipw.h @@ -950,66 +950,55 @@ static inline int libipw_is_cck_rate(u8 rate) } /* libipw.c */ -extern void free_libipw(struct net_device *dev, int monitor); -extern struct net_device *alloc_libipw(int sizeof_priv, int monitor); -extern int libipw_change_mtu(struct net_device *dev, int new_mtu); +void free_libipw(struct net_device *dev, int monitor); +struct net_device *alloc_libipw(int sizeof_priv, int monitor); +int libipw_change_mtu(struct net_device *dev, int new_mtu); -extern void libipw_networks_age(struct libipw_device *ieee, - unsigned long age_secs); +void libipw_networks_age(struct libipw_device *ieee, unsigned long age_secs); -extern int libipw_set_encryption(struct libipw_device *ieee); +int libipw_set_encryption(struct libipw_device *ieee); /* libipw_tx.c */ -extern netdev_tx_t libipw_xmit(struct sk_buff *skb, - struct net_device *dev); -extern void libipw_txb_free(struct libipw_txb *); +netdev_tx_t libipw_xmit(struct sk_buff *skb, struct net_device *dev); +void libipw_txb_free(struct libipw_txb *); /* libipw_rx.c */ -extern void libipw_rx_any(struct libipw_device *ieee, - struct sk_buff *skb, struct libipw_rx_stats *stats); -extern int libipw_rx(struct libipw_device *ieee, struct sk_buff *skb, - struct libipw_rx_stats *rx_stats); +void libipw_rx_any(struct libipw_device *ieee, struct sk_buff *skb, + struct libipw_rx_stats *stats); +int libipw_rx(struct libipw_device *ieee, struct sk_buff *skb, + struct libipw_rx_stats *rx_stats); /* make sure to set stats->len */ -extern void libipw_rx_mgt(struct libipw_device *ieee, - struct libipw_hdr_4addr *header, - struct libipw_rx_stats *stats); -extern void libipw_network_reset(struct libipw_network *network); +void libipw_rx_mgt(struct libipw_device *ieee, struct libipw_hdr_4addr *header, + struct libipw_rx_stats *stats); +void libipw_network_reset(struct libipw_network *network); /* libipw_geo.c */ -extern const struct libipw_geo *libipw_get_geo(struct libipw_device - *ieee); -extern void libipw_set_geo(struct libipw_device *ieee, - const struct libipw_geo *geo); - -extern int libipw_is_valid_channel(struct libipw_device *ieee, - u8 channel); -extern int libipw_channel_to_index(struct libipw_device *ieee, - u8 channel); -extern u8 libipw_freq_to_channel(struct libipw_device *ieee, u32 freq); -extern u8 libipw_get_channel_flags(struct libipw_device *ieee, - u8 channel); -extern const struct libipw_channel *libipw_get_channel(struct - libipw_device - *ieee, u8 channel); -extern u32 libipw_channel_to_freq(struct libipw_device * ieee, - u8 channel); +const struct libipw_geo *libipw_get_geo(struct libipw_device *ieee); +void libipw_set_geo(struct libipw_device *ieee, const struct libipw_geo *geo); + +int libipw_is_valid_channel(struct libipw_device *ieee, u8 channel); +int libipw_channel_to_index(struct libipw_device *ieee, u8 channel); +u8 libipw_freq_to_channel(struct libipw_device *ieee, u32 freq); +u8 libipw_get_channel_flags(struct libipw_device *ieee, u8 channel); +const struct libipw_channel *libipw_get_channel(struct libipw_device *ieee, + u8 channel); +u32 libipw_channel_to_freq(struct libipw_device *ieee, u8 channel); /* libipw_wx.c */ -extern int libipw_wx_get_scan(struct libipw_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *key); -extern int libipw_wx_set_encode(struct libipw_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *key); -extern int libipw_wx_get_encode(struct libipw_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *key); -extern int libipw_wx_set_encodeext(struct libipw_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); -extern int libipw_wx_get_encodeext(struct libipw_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); +int libipw_wx_get_scan(struct libipw_device *ieee, struct iw_request_info *info, + union iwreq_data *wrqu, char *key); +int libipw_wx_set_encode(struct libipw_device *ieee, + struct iw_request_info *info, union iwreq_data *wrqu, + char *key); +int libipw_wx_get_encode(struct libipw_device *ieee, + struct iw_request_info *info, union iwreq_data *wrqu, + char *key); +int libipw_wx_set_encodeext(struct libipw_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); +int libipw_wx_get_encodeext(struct libipw_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); static inline void libipw_increment_scans(struct libipw_device *ieee) { diff --git a/drivers/net/wireless/iwlegacy/3945.h b/drivers/net/wireless/iwlegacy/3945.h index 9a8703def0ba..00030d43a194 100644 --- a/drivers/net/wireless/iwlegacy/3945.h +++ b/drivers/net/wireless/iwlegacy/3945.h @@ -189,15 +189,14 @@ struct il3945_ibss_seq { * for use by iwl-*.c * *****************************************************************************/ -extern int il3945_calc_db_from_ratio(int sig_ratio); -extern void il3945_rx_replenish(void *data); -extern void il3945_rx_queue_reset(struct il_priv *il, struct il_rx_queue *rxq); -extern unsigned int il3945_fill_beacon_frame(struct il_priv *il, - struct ieee80211_hdr *hdr, - int left); -extern int il3945_dump_nic_event_log(struct il_priv *il, bool full_log, - char **buf, bool display); -extern void il3945_dump_nic_error_log(struct il_priv *il); +int il3945_calc_db_from_ratio(int sig_ratio); +void il3945_rx_replenish(void *data); +void il3945_rx_queue_reset(struct il_priv *il, struct il_rx_queue *rxq); +unsigned int il3945_fill_beacon_frame(struct il_priv *il, + struct ieee80211_hdr *hdr, int left); +int il3945_dump_nic_event_log(struct il_priv *il, bool full_log, char **buf, + bool display); +void il3945_dump_nic_error_log(struct il_priv *il); /****************************************************************************** * @@ -215,39 +214,36 @@ extern void il3945_dump_nic_error_log(struct il_priv *il); * il3945_mac_ <-- mac80211 callback * ****************************************************************************/ -extern void il3945_hw_handler_setup(struct il_priv *il); -extern void il3945_hw_setup_deferred_work(struct il_priv *il); -extern void il3945_hw_cancel_deferred_work(struct il_priv *il); -extern int il3945_hw_rxq_stop(struct il_priv *il); -extern int il3945_hw_set_hw_params(struct il_priv *il); -extern int il3945_hw_nic_init(struct il_priv *il); -extern int il3945_hw_nic_stop_master(struct il_priv *il); -extern void il3945_hw_txq_ctx_free(struct il_priv *il); -extern void il3945_hw_txq_ctx_stop(struct il_priv *il); -extern int il3945_hw_nic_reset(struct il_priv *il); -extern int il3945_hw_txq_attach_buf_to_tfd(struct il_priv *il, - struct il_tx_queue *txq, - dma_addr_t addr, u16 len, u8 reset, - u8 pad); -extern void il3945_hw_txq_free_tfd(struct il_priv *il, struct il_tx_queue *txq); -extern int il3945_hw_get_temperature(struct il_priv *il); -extern int il3945_hw_tx_queue_init(struct il_priv *il, struct il_tx_queue *txq); -extern unsigned int il3945_hw_get_beacon_cmd(struct il_priv *il, - struct il3945_frame *frame, - u8 rate); +void il3945_hw_handler_setup(struct il_priv *il); +void il3945_hw_setup_deferred_work(struct il_priv *il); +void il3945_hw_cancel_deferred_work(struct il_priv *il); +int il3945_hw_rxq_stop(struct il_priv *il); +int il3945_hw_set_hw_params(struct il_priv *il); +int il3945_hw_nic_init(struct il_priv *il); +int il3945_hw_nic_stop_master(struct il_priv *il); +void il3945_hw_txq_ctx_free(struct il_priv *il); +void il3945_hw_txq_ctx_stop(struct il_priv *il); +int il3945_hw_nic_reset(struct il_priv *il); +int il3945_hw_txq_attach_buf_to_tfd(struct il_priv *il, struct il_tx_queue *txq, + dma_addr_t addr, u16 len, u8 reset, u8 pad); +void il3945_hw_txq_free_tfd(struct il_priv *il, struct il_tx_queue *txq); +int il3945_hw_get_temperature(struct il_priv *il); +int il3945_hw_tx_queue_init(struct il_priv *il, struct il_tx_queue *txq); +unsigned int il3945_hw_get_beacon_cmd(struct il_priv *il, + struct il3945_frame *frame, u8 rate); void il3945_hw_build_tx_cmd_rate(struct il_priv *il, struct il_device_cmd *cmd, struct ieee80211_tx_info *info, struct ieee80211_hdr *hdr, int sta_id); -extern int il3945_hw_reg_send_txpower(struct il_priv *il); -extern int il3945_hw_reg_set_txpower(struct il_priv *il, s8 power); -extern void il3945_hdl_stats(struct il_priv *il, struct il_rx_buf *rxb); +int il3945_hw_reg_send_txpower(struct il_priv *il); +int il3945_hw_reg_set_txpower(struct il_priv *il, s8 power); +void il3945_hdl_stats(struct il_priv *il, struct il_rx_buf *rxb); void il3945_hdl_c_stats(struct il_priv *il, struct il_rx_buf *rxb); -extern void il3945_disable_events(struct il_priv *il); -extern int il4965_get_temperature(const struct il_priv *il); -extern void il3945_post_associate(struct il_priv *il); -extern void il3945_config_ap(struct il_priv *il); +void il3945_disable_events(struct il_priv *il); +int il4965_get_temperature(const struct il_priv *il); +void il3945_post_associate(struct il_priv *il); +void il3945_config_ap(struct il_priv *il); -extern int il3945_commit_rxon(struct il_priv *il); +int il3945_commit_rxon(struct il_priv *il); /** * il3945_hw_find_station - Find station id for a given BSSID @@ -257,14 +253,14 @@ extern int il3945_commit_rxon(struct il_priv *il); * not yet been merged into a single common layer for managing the * station tables. */ -extern u8 il3945_hw_find_station(struct il_priv *il, const u8 * bssid); +u8 il3945_hw_find_station(struct il_priv *il, const u8 *bssid); -extern __le32 il3945_get_antenna_flags(const struct il_priv *il); -extern int il3945_init_hw_rate_table(struct il_priv *il); -extern void il3945_reg_txpower_periodic(struct il_priv *il); -extern int il3945_txpower_set_from_eeprom(struct il_priv *il); +__le32 il3945_get_antenna_flags(const struct il_priv *il); +int il3945_init_hw_rate_table(struct il_priv *il); +void il3945_reg_txpower_periodic(struct il_priv *il); +int il3945_txpower_set_from_eeprom(struct il_priv *il); -extern int il3945_rs_next_rate(struct il_priv *il, int rate); +int il3945_rs_next_rate(struct il_priv *il, int rate); /* scanning */ int il3945_request_scan(struct il_priv *il, struct ieee80211_vif *vif); diff --git a/drivers/net/wireless/iwlegacy/4965.h b/drivers/net/wireless/iwlegacy/4965.h index 1b15b0b2292b..337dfcf3bbde 100644 --- a/drivers/net/wireless/iwlegacy/4965.h +++ b/drivers/net/wireless/iwlegacy/4965.h @@ -272,7 +272,7 @@ il4965_hw_valid_rtc_data_addr(u32 addr) ((t) < IL_TX_POWER_TEMPERATURE_MIN || \ (t) > IL_TX_POWER_TEMPERATURE_MAX) -extern void il4965_temperature_calib(struct il_priv *il); +void il4965_temperature_calib(struct il_priv *il); /********************* END TEMPERATURE ***************************************/ /********************* START TXPOWER *****************************************/ diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h index 83f8ed8a5528..ad123d66ab6c 100644 --- a/drivers/net/wireless/iwlegacy/common.h +++ b/drivers/net/wireless/iwlegacy/common.h @@ -858,9 +858,9 @@ struct il_hw_params { * il4965_mac_ <-- mac80211 callback * ****************************************************************************/ -extern void il4965_update_chain_flags(struct il_priv *il); +void il4965_update_chain_flags(struct il_priv *il); extern const u8 il_bcast_addr[ETH_ALEN]; -extern int il_queue_space(const struct il_queue *q); +int il_queue_space(const struct il_queue *q); static inline int il_queue_used(const struct il_queue *q, int i) { @@ -1727,7 +1727,7 @@ int il_alloc_txq_mem(struct il_priv *il); void il_free_txq_mem(struct il_priv *il); #ifdef CONFIG_IWLEGACY_DEBUGFS -extern void il_update_stats(struct il_priv *il, bool is_tx, __le16 fc, u16 len); +void il_update_stats(struct il_priv *il, bool is_tx, __le16 fc, u16 len); #else static inline void il_update_stats(struct il_priv *il, bool is_tx, __le16 fc, u16 len) @@ -1760,12 +1760,12 @@ void il_chswitch_done(struct il_priv *il, bool is_success); /***************************************************** * TX ******************************************************/ -extern void il_txq_update_write_ptr(struct il_priv *il, struct il_tx_queue *txq); -extern int il_tx_queue_init(struct il_priv *il, u32 txq_id); -extern void il_tx_queue_reset(struct il_priv *il, u32 txq_id); -extern void il_tx_queue_unmap(struct il_priv *il, int txq_id); -extern void il_tx_queue_free(struct il_priv *il, int txq_id); -extern void il_setup_watchdog(struct il_priv *il); +void il_txq_update_write_ptr(struct il_priv *il, struct il_tx_queue *txq); +int il_tx_queue_init(struct il_priv *il, u32 txq_id); +void il_tx_queue_reset(struct il_priv *il, u32 txq_id); +void il_tx_queue_unmap(struct il_priv *il, int txq_id); +void il_tx_queue_free(struct il_priv *il, int txq_id); +void il_setup_watchdog(struct il_priv *il); /***************************************************** * TX power ****************************************************/ @@ -1931,10 +1931,10 @@ il_is_ready_rf(struct il_priv *il) return il_is_ready(il); } -extern void il_send_bt_config(struct il_priv *il); -extern int il_send_stats_request(struct il_priv *il, u8 flags, bool clear); -extern void il_apm_stop(struct il_priv *il); -extern void _il_apm_stop(struct il_priv *il); +void il_send_bt_config(struct il_priv *il); +int il_send_stats_request(struct il_priv *il, u8 flags, bool clear); +void il_apm_stop(struct il_priv *il); +void _il_apm_stop(struct il_priv *il); int il_apm_init(struct il_priv *il); @@ -1968,15 +1968,15 @@ void il_tx_cmd_protection(struct il_priv *il, struct ieee80211_tx_info *info, irqreturn_t il_isr(int irq, void *data); -extern void il_set_bit(struct il_priv *p, u32 r, u32 m); -extern void il_clear_bit(struct il_priv *p, u32 r, u32 m); -extern bool _il_grab_nic_access(struct il_priv *il); -extern int _il_poll_bit(struct il_priv *il, u32 addr, u32 bits, u32 mask, int timeout); -extern int il_poll_bit(struct il_priv *il, u32 addr, u32 mask, int timeout); -extern u32 il_rd_prph(struct il_priv *il, u32 reg); -extern void il_wr_prph(struct il_priv *il, u32 addr, u32 val); -extern u32 il_read_targ_mem(struct il_priv *il, u32 addr); -extern void il_write_targ_mem(struct il_priv *il, u32 addr, u32 val); +void il_set_bit(struct il_priv *p, u32 r, u32 m); +void il_clear_bit(struct il_priv *p, u32 r, u32 m); +bool _il_grab_nic_access(struct il_priv *il); +int _il_poll_bit(struct il_priv *il, u32 addr, u32 bits, u32 mask, int timeout); +int il_poll_bit(struct il_priv *il, u32 addr, u32 mask, int timeout); +u32 il_rd_prph(struct il_priv *il, u32 reg); +void il_wr_prph(struct il_priv *il, u32 addr, u32 val); +u32 il_read_targ_mem(struct il_priv *il, u32 addr); +void il_write_targ_mem(struct il_priv *il, u32 addr, u32 val); static inline void _il_write8(struct il_priv *il, u32 ofs, u8 val) @@ -2868,13 +2868,13 @@ il4965_first_antenna(u8 mask) * The specific throughput table used is based on the type of network * the associated with, including A, B, G, and G w/ TGG protection */ -extern void il3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id); +void il3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id); /* Initialize station's rate scaling information after adding station */ -extern void il4965_rs_rate_init(struct il_priv *il, struct ieee80211_sta *sta, - u8 sta_id); -extern void il3945_rs_rate_init(struct il_priv *il, struct ieee80211_sta *sta, - u8 sta_id); +void il4965_rs_rate_init(struct il_priv *il, struct ieee80211_sta *sta, + u8 sta_id); +void il3945_rs_rate_init(struct il_priv *il, struct ieee80211_sta *sta, + u8 sta_id); /** * il_rate_control_register - Register the rate control algorithm callbacks @@ -2886,8 +2886,8 @@ extern void il3945_rs_rate_init(struct il_priv *il, struct ieee80211_sta *sta, * ieee80211_register_hw * */ -extern int il4965_rate_control_register(void); -extern int il3945_rate_control_register(void); +int il4965_rate_control_register(void); +int il3945_rate_control_register(void); /** * il_rate_control_unregister - Unregister the rate control callbacks @@ -2895,11 +2895,11 @@ extern int il3945_rate_control_register(void); * This should be called after calling ieee80211_unregister_hw, but before * the driver is unloaded. */ -extern void il4965_rate_control_unregister(void); -extern void il3945_rate_control_unregister(void); +void il4965_rate_control_unregister(void); +void il3945_rate_control_unregister(void); -extern int il_power_update_mode(struct il_priv *il, bool force); -extern void il_power_initialize(struct il_priv *il); +int il_power_update_mode(struct il_priv *il, bool force); +void il_power_initialize(struct il_priv *il); extern u32 il_debug_level; diff --git a/drivers/net/wireless/iwlwifi/dvm/agn.h b/drivers/net/wireless/iwlwifi/dvm/agn.h index f2a86ffc3b4c..23d5f0275ce9 100644 --- a/drivers/net/wireless/iwlwifi/dvm/agn.h +++ b/drivers/net/wireless/iwlwifi/dvm/agn.h @@ -397,7 +397,7 @@ static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags) return cpu_to_le32(flags|(u32)rate); } -extern int iwl_alive_start(struct iwl_priv *priv); +int iwl_alive_start(struct iwl_priv *priv); #ifdef CONFIG_IWLWIFI_DEBUG void iwl_print_rx_config_cmd(struct iwl_priv *priv, diff --git a/drivers/net/wireless/iwlwifi/dvm/dev.h b/drivers/net/wireless/iwlwifi/dvm/dev.h index a79fdd137f95..7434d9edf3b7 100644 --- a/drivers/net/wireless/iwlwifi/dvm/dev.h +++ b/drivers/net/wireless/iwlwifi/dvm/dev.h @@ -270,7 +270,7 @@ struct iwl_sensitivity_ranges { * iwlXXXX_ <-- Hardware specific (implemented in iwl-XXXX.c for XXXX) * ****************************************************************************/ -extern void iwl_update_chain_flags(struct iwl_priv *priv); +void iwl_update_chain_flags(struct iwl_priv *priv); extern const u8 iwl_bcast_addr[ETH_ALEN]; #define IWL_OPERATION_MODE_AUTO 0 diff --git a/drivers/net/wireless/iwlwifi/dvm/rs.h b/drivers/net/wireless/iwlwifi/dvm/rs.h index 5d83cab22d62..26fc550cd68c 100644 --- a/drivers/net/wireless/iwlwifi/dvm/rs.h +++ b/drivers/net/wireless/iwlwifi/dvm/rs.h @@ -407,8 +407,8 @@ static inline u8 first_antenna(u8 mask) /* Initialize station's rate scaling information after adding station */ -extern void iwl_rs_rate_init(struct iwl_priv *priv, - struct ieee80211_sta *sta, u8 sta_id); +void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, + u8 sta_id); /** * iwl_rate_control_register - Register the rate control algorithm callbacks @@ -420,7 +420,7 @@ extern void iwl_rs_rate_init(struct iwl_priv *priv, * ieee80211_register_hw * */ -extern int iwlagn_rate_control_register(void); +int iwlagn_rate_control_register(void); /** * iwl_rate_control_unregister - Unregister the rate control callbacks @@ -428,6 +428,6 @@ extern int iwlagn_rate_control_register(void); * This should be called after calling ieee80211_unregister_hw, but before * the driver is unloaded. */ -extern void iwlagn_rate_control_unregister(void); +void iwlagn_rate_control_unregister(void); #endif /* __iwl_agn__rs__ */ diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.h b/drivers/net/wireless/iwlwifi/mvm/rs.h index 335cf1682902..465d40ee176f 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.h +++ b/drivers/net/wireless/iwlwifi/mvm/rs.h @@ -314,9 +314,8 @@ static inline u8 num_of_ant(u8 mask) } /* Initialize station's rate scaling information after adding station */ -extern void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, - struct ieee80211_sta *sta, - enum ieee80211_band band); +void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, + enum ieee80211_band band); /** * iwl_rate_control_register - Register the rate control algorithm callbacks @@ -328,7 +327,7 @@ extern void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, * ieee80211_register_hw * */ -extern int iwl_mvm_rate_control_register(void); +int iwl_mvm_rate_control_register(void); /** * iwl_rate_control_unregister - Unregister the rate control callbacks @@ -336,7 +335,7 @@ extern int iwl_mvm_rate_control_register(void); * This should be called after calling ieee80211_unregister_hw, but before * the driver is unloaded. */ -extern void iwl_mvm_rate_control_unregister(void); +void iwl_mvm_rate_control_unregister(void); struct iwl_mvm_sta; diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c index 21c688264708..1214c587fd08 100644 --- a/drivers/net/wireless/mwifiex/11n_aggr.c +++ b/drivers/net/wireless/mwifiex/11n_aggr.c @@ -150,7 +150,7 @@ mwifiex_11n_form_amsdu_txpd(struct mwifiex_private *priv, */ int mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, - struct mwifiex_ra_list_tbl *pra_list, int headroom, + struct mwifiex_ra_list_tbl *pra_list, int ptrindex, unsigned long ra_list_flags) __releases(&priv->wmm.ra_list_spinlock) { @@ -160,6 +160,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, int pad = 0, ret; struct mwifiex_tx_param tx_param; struct txpd *ptx_pd = NULL; + int headroom = adapter->iface_type == MWIFIEX_USB ? 0 : INTF_HEADER_LEN; skb_src = skb_peek(&pra_list->skb_head); if (!skb_src) { diff --git a/drivers/net/wireless/mwifiex/11n_aggr.h b/drivers/net/wireless/mwifiex/11n_aggr.h index 900e1c62a0cc..892098d6a696 100644 --- a/drivers/net/wireless/mwifiex/11n_aggr.h +++ b/drivers/net/wireless/mwifiex/11n_aggr.h @@ -26,7 +26,7 @@ int mwifiex_11n_deaggregate_pkt(struct mwifiex_private *priv, struct sk_buff *skb); int mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, - struct mwifiex_ra_list_tbl *ptr, int headroom, + struct mwifiex_ra_list_tbl *ptr, int ptr_index, unsigned long flags) __releases(&priv->wmm.ra_list_spinlock); diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index 2d761477d15e..a6c46f3b6e3a 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -1155,7 +1155,7 @@ int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv, uint32_t conditions = le32_to_cpu(phs_cfg->params.hs_config.conditions); if (phs_cfg->action == cpu_to_le16(HS_ACTIVATE) && - adapter->iface_type == MWIFIEX_SDIO) { + adapter->iface_type != MWIFIEX_USB) { mwifiex_hs_activated_event(priv, true); return 0; } else { @@ -1167,8 +1167,7 @@ int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv, } if (conditions != HS_CFG_CANCEL) { adapter->is_hs_configured = true; - if (adapter->iface_type == MWIFIEX_USB || - adapter->iface_type == MWIFIEX_PCIE) + if (adapter->iface_type == MWIFIEX_USB) mwifiex_hs_activated_event(priv, true); } else { adapter->is_hs_configured = false; diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c index 2472d4b7f00e..1c70b8d09227 100644 --- a/drivers/net/wireless/mwifiex/usb.c +++ b/drivers/net/wireless/mwifiex/usb.c @@ -447,9 +447,6 @@ static int mwifiex_usb_suspend(struct usb_interface *intf, pm_message_t message) */ adapter->is_suspended = true; - for (i = 0; i < adapter->priv_num; i++) - netif_carrier_off(adapter->priv[i]->netdev); - if (atomic_read(&card->rx_cmd_urb_pending) && card->rx_cmd.urb) usb_kill_urb(card->rx_cmd.urb); @@ -509,10 +506,6 @@ static int mwifiex_usb_resume(struct usb_interface *intf) MWIFIEX_RX_CMD_BUF_SIZE); } - for (i = 0; i < adapter->priv_num; i++) - if (adapter->priv[i]->media_connected) - netif_carrier_on(adapter->priv[i]->netdev); - /* Disable Host Sleep */ if (adapter->hs_activated) mwifiex_cancel_hs(mwifiex_get_priv(adapter, diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 2e8f9cdea54d..95fa3599b407 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c @@ -1239,8 +1239,7 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter) if (enable_tx_amsdu && mwifiex_is_amsdu_allowed(priv, tid) && mwifiex_is_11n_aggragation_possible(priv, ptr, adapter->tx_buf_size)) - mwifiex_11n_aggregate_pkt(priv, ptr, INTF_HEADER_LEN, - ptr_index, flags); + mwifiex_11n_aggregate_pkt(priv, ptr, ptr_index, flags); /* ra_list_spinlock has been freed in mwifiex_11n_aggregate_pkt() */ else diff --git a/drivers/net/wireless/mwifiex/wmm.h b/drivers/net/wireless/mwifiex/wmm.h index 644d6e0c51cc..0f129d498fb1 100644 --- a/drivers/net/wireless/mwifiex/wmm.h +++ b/drivers/net/wireless/mwifiex/wmm.h @@ -83,11 +83,10 @@ mwifiex_wmm_is_ra_list_empty(struct list_head *ra_list_hhead) } void mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv, - struct sk_buff *skb); + struct sk_buff *skb); void mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra); void mwifiex_rotate_priolists(struct mwifiex_private *priv, - struct mwifiex_ra_list_tbl *ra, - int tid); + struct mwifiex_ra_list_tbl *ra, int tid); int mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter); void mwifiex_wmm_process_tx(struct mwifiex_adapter *adapter); @@ -95,21 +94,18 @@ int mwifiex_is_ralist_valid(struct mwifiex_private *priv, struct mwifiex_ra_list_tbl *ra_list, int tid); u8 mwifiex_wmm_compute_drv_pkt_delay(struct mwifiex_private *priv, - const struct sk_buff *skb); + const struct sk_buff *skb); void mwifiex_wmm_init(struct mwifiex_adapter *adapter); -extern u32 mwifiex_wmm_process_association_req(struct mwifiex_private *priv, - u8 **assoc_buf, - struct ieee_types_wmm_parameter - *wmmie, - struct ieee80211_ht_cap - *htcap); +u32 mwifiex_wmm_process_association_req(struct mwifiex_private *priv, + u8 **assoc_buf, + struct ieee_types_wmm_parameter *wmmie, + struct ieee80211_ht_cap *htcap); void mwifiex_wmm_setup_queue_priorities(struct mwifiex_private *priv, - struct ieee_types_wmm_parameter - *wmm_ie); + struct ieee_types_wmm_parameter *wmm_ie); void mwifiex_wmm_setup_ac_downgrade(struct mwifiex_private *priv); -extern int mwifiex_ret_wmm_get_status(struct mwifiex_private *priv, - const struct host_cmd_ds_command *resp); +int mwifiex_ret_wmm_get_status(struct mwifiex_private *priv, + const struct host_cmd_ds_command *resp); #endif /* !_MWIFIEX_WMM_H_ */ diff --git a/drivers/net/wireless/orinoco/orinoco.h b/drivers/net/wireless/orinoco/orinoco.h index 3bb936b9558c..eebd2be21ee9 100644 --- a/drivers/net/wireless/orinoco/orinoco.h +++ b/drivers/net/wireless/orinoco/orinoco.h @@ -182,23 +182,20 @@ extern int orinoco_debug; /* Exported prototypes */ /********************************************************************/ -extern struct orinoco_private *alloc_orinocodev( - int sizeof_card, struct device *device, - int (*hard_reset)(struct orinoco_private *), - int (*stop_fw)(struct orinoco_private *, int)); -extern void free_orinocodev(struct orinoco_private *priv); -extern int orinoco_init(struct orinoco_private *priv); -extern int orinoco_if_add(struct orinoco_private *priv, - unsigned long base_addr, - unsigned int irq, - const struct net_device_ops *ops); -extern void orinoco_if_del(struct orinoco_private *priv); -extern int orinoco_up(struct orinoco_private *priv); -extern void orinoco_down(struct orinoco_private *priv); -extern irqreturn_t orinoco_interrupt(int irq, void *dev_id); - -extern void __orinoco_ev_info(struct net_device *dev, struct hermes *hw); -extern void __orinoco_ev_rx(struct net_device *dev, struct hermes *hw); +struct orinoco_private *alloc_orinocodev(int sizeof_card, struct device *device, + int (*hard_reset)(struct orinoco_private *), + int (*stop_fw)(struct orinoco_private *, int)); +void free_orinocodev(struct orinoco_private *priv); +int orinoco_init(struct orinoco_private *priv); +int orinoco_if_add(struct orinoco_private *priv, unsigned long base_addr, + unsigned int irq, const struct net_device_ops *ops); +void orinoco_if_del(struct orinoco_private *priv); +int orinoco_up(struct orinoco_private *priv); +void orinoco_down(struct orinoco_private *priv); +irqreturn_t orinoco_interrupt(int irq, void *dev_id); + +void __orinoco_ev_info(struct net_device *dev, struct hermes *hw); +void __orinoco_ev_rx(struct net_device *dev, struct hermes *hw); int orinoco_process_xmit_skb(struct sk_buff *skb, struct net_device *dev, diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index b9deef66cf4b..e328d3058c41 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c @@ -83,6 +83,7 @@ static struct usb_device_id p54u_table[] = { {USB_DEVICE(0x06a9, 0x000e)}, /* Westell 802.11g USB (A90-211WG-01) */ {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */ {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */ + {USB_DEVICE(0x07aa, 0x0020)}, /* Corega WLUSB2GTST USB */ {USB_DEVICE(0x0803, 0x4310)}, /* Zoom 4410a */ {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */ {USB_DEVICE(0x083a, 0x4531)}, /* T-Com Sinus 154 data II */ @@ -979,6 +980,7 @@ static int p54u_load_firmware(struct ieee80211_hw *dev, if (err) { dev_err(&priv->udev->dev, "(p54usb) cannot load firmware %s " "(%d)!\n", p54u_fwlist[i].fw, err); + usb_put_dev(udev); } return err; diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c index 1c22b81e6ef3..8863a6cb2388 100644 --- a/drivers/net/wireless/prism54/isl_ioctl.c +++ b/drivers/net/wireless/prism54/isl_ioctl.c @@ -183,7 +183,7 @@ prism54_update_stats(struct work_struct *work) data = r.ptr; /* copy this MAC to the bss */ - memcpy(bss.address, data, 6); + memcpy(bss.address, data, ETH_ALEN); kfree(data); /* now ask for the corresponding bss */ @@ -531,7 +531,7 @@ prism54_set_wap(struct net_device *ndev, struct iw_request_info *info, return -EINVAL; /* prepare the structure for the set object */ - memcpy(&bssid[0], awrq->sa_data, 6); + memcpy(&bssid[0], awrq->sa_data, ETH_ALEN); /* set the bssid -- does this make sense when in AP mode? */ rvalue = mgt_set_request(priv, DOT11_OID_BSSID, 0, &bssid); @@ -550,7 +550,7 @@ prism54_get_wap(struct net_device *ndev, struct iw_request_info *info, int rvalue; rvalue = mgt_get_request(priv, DOT11_OID_BSSID, 0, NULL, &r); - memcpy(awrq->sa_data, r.ptr, 6); + memcpy(awrq->sa_data, r.ptr, ETH_ALEN); awrq->sa_family = ARPHRD_ETHER; kfree(r.ptr); @@ -582,7 +582,7 @@ prism54_translate_bss(struct net_device *ndev, struct iw_request_info *info, size_t wpa_ie_len; /* The first entry must be the MAC address */ - memcpy(iwe.u.ap_addr.sa_data, bss->address, 6); + memcpy(iwe.u.ap_addr.sa_data, bss->address, ETH_ALEN); iwe.u.ap_addr.sa_family = ARPHRD_ETHER; iwe.cmd = SIOCGIWAP; current_ev = iwe_stream_add_event(info, current_ev, end_buf, @@ -2489,7 +2489,7 @@ prism54_set_mac_address(struct net_device *ndev, void *addr) &((struct sockaddr *) addr)->sa_data); if (!ret) memcpy(priv->ndev->dev_addr, - &((struct sockaddr *) addr)->sa_data, 6); + &((struct sockaddr *) addr)->sa_data, ETH_ALEN); return ret; } diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c index 5970ff6f40cc..41a16d30c79c 100644 --- a/drivers/net/wireless/prism54/islpci_dev.c +++ b/drivers/net/wireless/prism54/islpci_dev.c @@ -837,7 +837,7 @@ islpci_setup(struct pci_dev *pdev) /* ndev->set_multicast_list = &islpci_set_multicast_list; */ ndev->addr_len = ETH_ALEN; /* Get a non-zero dummy MAC address for nameif. Jean II */ - memcpy(ndev->dev_addr, dummy_mac, 6); + memcpy(ndev->dev_addr, dummy_mac, ETH_ALEN); ndev->watchdog_timeo = ISLPCI_TX_TIMEOUT; diff --git a/drivers/net/wireless/prism54/oid_mgt.c b/drivers/net/wireless/prism54/oid_mgt.c index a01606b36e03..056af38e72e3 100644 --- a/drivers/net/wireless/prism54/oid_mgt.c +++ b/drivers/net/wireless/prism54/oid_mgt.c @@ -682,7 +682,7 @@ mgt_update_addr(islpci_private *priv) isl_oid[GEN_OID_MACADDRESS].size, &res); if ((ret == 0) && res && (res->header->operation != PIMFOR_OP_ERROR)) - memcpy(priv->ndev->dev_addr, res->data, 6); + memcpy(priv->ndev->dev_addr, res->data, ETH_ALEN); else ret = -EIO; if (res) diff --git a/drivers/net/wireless/rtlwifi/cam.h b/drivers/net/wireless/rtlwifi/cam.h index 35e00086a520..0105e6c1901e 100644 --- a/drivers/net/wireless/rtlwifi/cam.h +++ b/drivers/net/wireless/rtlwifi/cam.h @@ -41,12 +41,12 @@ #define CAM_CONFIG_USEDK 1 #define CAM_CONFIG_NO_USEDK 0 -extern void rtl_cam_reset_all_entry(struct ieee80211_hw *hw); -extern u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr, - u32 ul_key_id, u32 ul_entry_idx, u32 ul_enc_alg, - u32 ul_default_key, u8 *key_content); +void rtl_cam_reset_all_entry(struct ieee80211_hw *hw); +u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr, + u32 ul_key_id, u32 ul_entry_idx, u32 ul_enc_alg, + u32 ul_default_key, u8 *key_content); int rtl_cam_delete_one_entry(struct ieee80211_hw *hw, u8 *mac_addr, - u32 ul_key_id); + u32 ul_key_id); void rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index); void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index); void rtl_cam_reset_sec_info(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index 733b7ce7f0e2..210ce7cd94d8 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c @@ -115,7 +115,7 @@ static void rtl_op_stop(struct ieee80211_hw *hw) mutex_lock(&rtlpriv->locks.conf_mutex); mac->link_state = MAC80211_NOLINK; - memset(mac->bssid, 0, 6); + memset(mac->bssid, 0, ETH_ALEN); mac->vendor = PEER_UNKNOWN; /*reset sec info */ @@ -280,7 +280,7 @@ static void rtl_op_remove_interface(struct ieee80211_hw *hw, mac->p2p = 0; mac->vif = NULL; mac->link_state = MAC80211_NOLINK; - memset(mac->bssid, 0, 6); + memset(mac->bssid, 0, ETH_ALEN); mac->vendor = PEER_UNKNOWN; mac->opmode = NL80211_IFTYPE_UNSPECIFIED; rtlpriv->cfg->ops->set_network_type(hw, mac->opmode); @@ -721,7 +721,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, mac->link_state = MAC80211_LINKED; mac->cnt_after_linked = 0; mac->assoc_id = bss_conf->aid; - memcpy(mac->bssid, bss_conf->bssid, 6); + memcpy(mac->bssid, bss_conf->bssid, ETH_ALEN); if (rtlpriv->cfg->ops->linked_set_reg) rtlpriv->cfg->ops->linked_set_reg(hw); @@ -750,7 +750,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, if (ppsc->p2p_ps_info.p2p_ps_mode > P2P_PS_NONE) rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE); mac->link_state = MAC80211_NOLINK; - memset(mac->bssid, 0, 6); + memset(mac->bssid, 0, ETH_ALEN); mac->vendor = PEER_UNKNOWN; if (rtlpriv->dm.supp_phymode_switch) { @@ -826,7 +826,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, bss_conf->bssid); mac->vendor = PEER_UNKNOWN; - memcpy(mac->bssid, bss_conf->bssid, 6); + memcpy(mac->bssid, bss_conf->bssid, ETH_ALEN); rtlpriv->cfg->ops->set_network_type(hw, vif->type); rcu_read_lock(); diff --git a/drivers/net/wireless/rtlwifi/efuse.h b/drivers/net/wireless/rtlwifi/efuse.h index 395a326acfb4..1663b3afd41e 100644 --- a/drivers/net/wireless/rtlwifi/efuse.h +++ b/drivers/net/wireless/rtlwifi/efuse.h @@ -104,20 +104,19 @@ struct efuse_priv { u8 tx_power_g[14]; }; -extern void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf); -extern void efuse_initialize(struct ieee80211_hw *hw); -extern u8 efuse_read_1byte(struct ieee80211_hw *hw, u16 address); -extern void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value); -extern void read_efuse(struct ieee80211_hw *hw, u16 _offset, - u16 _size_byte, u8 *pbuf); -extern void efuse_shadow_read(struct ieee80211_hw *hw, u8 type, - u16 offset, u32 *value); -extern void efuse_shadow_write(struct ieee80211_hw *hw, u8 type, - u16 offset, u32 value); -extern bool efuse_shadow_update(struct ieee80211_hw *hw); -extern bool efuse_shadow_update_chk(struct ieee80211_hw *hw); -extern void rtl_efuse_shadow_map_update(struct ieee80211_hw *hw); -extern void efuse_force_write_vendor_Id(struct ieee80211_hw *hw); -extern void efuse_re_pg_section(struct ieee80211_hw *hw, u8 section_idx); +void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf); +void efuse_initialize(struct ieee80211_hw *hw); +u8 efuse_read_1byte(struct ieee80211_hw *hw, u16 address); +void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value); +void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf); +void efuse_shadow_read(struct ieee80211_hw *hw, u8 type, u16 offset, + u32 *value); +void efuse_shadow_write(struct ieee80211_hw *hw, u8 type, u16 offset, + u32 value); +bool efuse_shadow_update(struct ieee80211_hw *hw); +bool efuse_shadow_update_chk(struct ieee80211_hw *hw); +void rtl_efuse_shadow_map_update(struct ieee80211_hw *hw); +void efuse_force_write_vendor_Id(struct ieee80211_hw *hw); +void efuse_re_pg_section(struct ieee80211_hw *hw, u8 section_idx); #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/phy.h b/drivers/net/wireless/rtlwifi/rtl8188ee/phy.h index d4545f06e185..89f0f1ef1465 100644 --- a/drivers/net/wireless/rtlwifi/rtl8188ee/phy.h +++ b/drivers/net/wireless/rtlwifi/rtl8188ee/phy.h @@ -200,35 +200,35 @@ enum _ANT_DIV_TYPE { CGCS_RX_SW_ANTDIV = 0x05, }; -extern u32 rtl88e_phy_query_bb_reg(struct ieee80211_hw *hw, - u32 regaddr, u32 bitmask); -extern void rtl88e_phy_set_bb_reg(struct ieee80211_hw *hw, - u32 regaddr, u32 bitmask, u32 data); -extern u32 rtl88e_phy_query_rf_reg(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 regaddr, - u32 bitmask); -extern void rtl88e_phy_set_rf_reg(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 regaddr, - u32 bitmask, u32 data); -extern bool rtl88e_phy_mac_config(struct ieee80211_hw *hw); -extern bool rtl88e_phy_bb_config(struct ieee80211_hw *hw); -extern bool rtl88e_phy_rf_config(struct ieee80211_hw *hw); -extern void rtl88e_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); -extern void rtl88e_phy_get_txpower_level(struct ieee80211_hw *hw, - long *powerlevel); -extern void rtl88e_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel); -extern void rtl88e_phy_set_bw_mode_callback(struct ieee80211_hw *hw); -extern void rtl88e_phy_set_bw_mode(struct ieee80211_hw *hw, - enum nl80211_channel_type ch_type); -extern void rtl88e_phy_sw_chnl_callback(struct ieee80211_hw *hw); -extern u8 rtl88e_phy_sw_chnl(struct ieee80211_hw *hw); -extern void rtl88e_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery); +u32 rtl88e_phy_query_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask); +void rtl88e_phy_set_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, u32 data); +u32 rtl88e_phy_query_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask); +void rtl88e_phy_set_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask, u32 data); +bool rtl88e_phy_mac_config(struct ieee80211_hw *hw); +bool rtl88e_phy_bb_config(struct ieee80211_hw *hw); +bool rtl88e_phy_rf_config(struct ieee80211_hw *hw); +void rtl88e_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); +void rtl88e_phy_get_txpower_level(struct ieee80211_hw *hw, + long *powerlevel); +void rtl88e_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel); +void rtl88e_phy_set_bw_mode_callback(struct ieee80211_hw *hw); +void rtl88e_phy_set_bw_mode(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type); +void rtl88e_phy_sw_chnl_callback(struct ieee80211_hw *hw); +u8 rtl88e_phy_sw_chnl(struct ieee80211_hw *hw); +void rtl88e_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery); void rtl88e_phy_lc_calibrate(struct ieee80211_hw *hw); void rtl88e_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain); bool rtl88e_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, enum radio_path rfpath); bool rtl88e_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); -extern bool rtl88e_phy_set_rf_power_state(struct ieee80211_hw *hw, - enum rf_pwrstate rfpwr_state); +bool rtl88e_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state); #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h index aeb268b190c6..94486cca4000 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h @@ -186,34 +186,29 @@ struct tx_power_struct { }; bool rtl92c_phy_bb_config(struct ieee80211_hw *hw); -u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, - u32 regaddr, u32 bitmask); -void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, - u32 regaddr, u32 bitmask, u32 data); -u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 regaddr, - u32 bitmask); -extern void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 regaddr, - u32 bitmask, u32 data); +u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask); +void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask, + u32 data); +u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, + u32 regaddr, u32 bitmask); +void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, + u32 regaddr, u32 bitmask, u32 data); bool rtl92c_phy_mac_config(struct ieee80211_hw *hw); bool rtl92ce_phy_bb_config(struct ieee80211_hw *hw); bool rtl92c_phy_rf_config(struct ieee80211_hw *hw); bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw, - enum radio_path rfpath); + enum radio_path rfpath); void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); -void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, - long *powerlevel); +void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel); void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel); bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm); void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, - enum nl80211_channel_type ch_type); + enum nl80211_channel_type ch_type); void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw); u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw); void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery); -void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw, - u16 beaconinterval); +void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw, u16 beaconinterval); void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta); void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw); void _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t); @@ -221,27 +216,25 @@ void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain); bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, enum radio_path rfpath); bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, - u32 rfpath); + u32 rfpath); bool rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, - enum rf_pwrstate rfpwr_state); + enum rf_pwrstate rfpwr_state); void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw); bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); void rtl92c_phy_set_io(struct ieee80211_hw *hw); void rtl92c_bb_block_on(struct ieee80211_hw *hw); -u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset); +u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, enum radio_path rfpath, + u32 offset); u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset); + enum radio_path rfpath, u32 offset); u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask); void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset, - u32 data); + enum radio_path rfpath, u32 offset, u32 data); void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset, - u32 data); + enum radio_path rfpath, u32 offset, + u32 data); void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw, - u32 regaddr, u32 bitmask, - u32 data); + u32 regaddr, u32 bitmask, u32 data); bool _rtl92ce_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw); bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h index 6c8d56efceae..d8fe68b389d2 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h @@ -34,11 +34,10 @@ #define RF6052_MAX_REG 0x3F #define RF6052_MAX_PATH 2 -extern void rtl92ce_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, - u8 bandwidth); -extern void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, - u8 *ppowerlevel); -extern void rtl92ce_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, - u8 *ppowerlevel, u8 channel); -extern bool rtl92ce_phy_rf6052_config(struct ieee80211_hw *hw); +void rtl92ce_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth); +void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel); +void rtl92ce_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel); +bool rtl92ce_phy_rf6052_config(struct ieee80211_hw *hw); #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h index 090fd33a158d..11b439d6b671 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h @@ -34,15 +34,14 @@ #define RF6052_MAX_REG 0x3F #define RF6052_MAX_PATH 2 -extern void rtl92cu_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, - u8 bandwidth); -extern void rtl92c_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, - u8 *ppowerlevel); -extern void rtl92c_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, - u8 *ppowerlevel, u8 channel); +void rtl92cu_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth); +void rtl92c_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel); +void rtl92c_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel); bool rtl92cu_phy_rf6052_config(struct ieee80211_hw *hw); bool rtl92cu_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, - enum radio_path rfpath); + enum radio_path rfpath); void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, u8 *ppowerlevel); void rtl92cu_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.h b/drivers/net/wireless/rtlwifi/rtl8192de/hw.h index 7c9f7a2f1e42..1bc7b1a96d4a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.h @@ -55,10 +55,9 @@ void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr, bool is_group, u8 enc_algo, bool is_wepkey, bool clear_all); -extern void rtl92de_write_dword_dbi(struct ieee80211_hw *hw, u16 offset, - u32 value, u8 direct); -extern u32 rtl92de_read_dword_dbi(struct ieee80211_hw *hw, u16 offset, - u8 direct); +void rtl92de_write_dword_dbi(struct ieee80211_hw *hw, u16 offset, u32 value, + u8 direct); +u32 rtl92de_read_dword_dbi(struct ieee80211_hw *hw, u16 offset, u8 direct); void rtl92de_suspend(struct ieee80211_hw *hw); void rtl92de_resume(struct ieee80211_hw *hw); void rtl92d_linked_set_reg(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.h b/drivers/net/wireless/rtlwifi/rtl8192de/phy.h index bef3040555dd..48d5c6835b6a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.h @@ -125,32 +125,32 @@ static inline void rtl92d_release_cckandrw_pagea_ctl(struct ieee80211_hw *hw, *flag); } -extern u32 rtl92d_phy_query_bb_reg(struct ieee80211_hw *hw, - u32 regaddr, u32 bitmask); -extern void rtl92d_phy_set_bb_reg(struct ieee80211_hw *hw, - u32 regaddr, u32 bitmask, u32 data); -extern u32 rtl92d_phy_query_rf_reg(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 regaddr, - u32 bitmask); -extern void rtl92d_phy_set_rf_reg(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 regaddr, - u32 bitmask, u32 data); -extern bool rtl92d_phy_mac_config(struct ieee80211_hw *hw); -extern bool rtl92d_phy_bb_config(struct ieee80211_hw *hw); -extern bool rtl92d_phy_rf_config(struct ieee80211_hw *hw); -extern bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw, - enum radio_path rfpath); -extern void rtl92d_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); -extern void rtl92d_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel); -extern void rtl92d_phy_set_bw_mode(struct ieee80211_hw *hw, - enum nl80211_channel_type ch_type); -extern u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw); +u32 rtl92d_phy_query_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask); +void rtl92d_phy_set_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, u32 data); +u32 rtl92d_phy_query_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask); +void rtl92d_phy_set_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask, u32 data); +bool rtl92d_phy_mac_config(struct ieee80211_hw *hw); +bool rtl92d_phy_bb_config(struct ieee80211_hw *hw); +bool rtl92d_phy_rf_config(struct ieee80211_hw *hw); +bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw, + enum radio_path rfpath); +void rtl92d_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); +void rtl92d_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel); +void rtl92d_phy_set_bw_mode(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type); +u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw); bool rtl92d_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, enum rf_content content, enum radio_path rfpath); bool rtl92d_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); -extern bool rtl92d_phy_set_rf_power_state(struct ieee80211_hw *hw, - enum rf_pwrstate rfpwr_state); +bool rtl92d_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state); void rtl92d_phy_config_macphymode(struct ieee80211_hw *hw); void rtl92d_phy_config_macphymode_info(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/rf.h b/drivers/net/wireless/rtlwifi/rtl8192de/rf.h index 0fe1a48593e8..7303d12c266f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/rf.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/rf.h @@ -30,15 +30,13 @@ #ifndef __RTL92D_RF_H__ #define __RTL92D_RF_H__ -extern void rtl92d_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, - u8 bandwidth); -extern void rtl92d_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, - u8 *ppowerlevel); -extern void rtl92d_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, - u8 *ppowerlevel, u8 channel); -extern bool rtl92d_phy_rf6052_config(struct ieee80211_hw *hw); -extern bool rtl92d_phy_enable_anotherphy(struct ieee80211_hw *hw, bool bmac0); -extern void rtl92d_phy_powerdown_anotherphy(struct ieee80211_hw *hw, - bool bmac0); +void rtl92d_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth); +void rtl92d_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel); +void rtl92d_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel); +bool rtl92d_phy_rf6052_config(struct ieee80211_hw *hw); +bool rtl92d_phy_enable_anotherphy(struct ieee80211_hw *hw, bool bmac0); +void rtl92d_phy_powerdown_anotherphy(struct ieee80211_hw *hw, bool bmac0); #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/phy.h b/drivers/net/wireless/rtlwifi/rtl8723ae/phy.h index 3d8f9e3aad76..007ebdbbe108 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723ae/phy.h +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/phy.h @@ -183,40 +183,40 @@ struct tx_power_struct { u32 mcs_original_offset[4][16]; }; -extern u32 rtl8723ae_phy_query_bb_reg(struct ieee80211_hw *hw, - u32 regaddr, u32 bitmask); -extern void rtl8723ae_phy_set_bb_reg(struct ieee80211_hw *hw, - u32 regaddr, u32 bitmask, u32 data); -extern u32 rtl8723ae_phy_query_rf_reg(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 regaddr, - u32 bitmask); -extern void rtl8723ae_phy_set_rf_reg(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 regaddr, - u32 bitmask, u32 data); -extern bool rtl8723ae_phy_mac_config(struct ieee80211_hw *hw); -extern bool rtl8723ae_phy_bb_config(struct ieee80211_hw *hw); -extern bool rtl8723ae_phy_rf_config(struct ieee80211_hw *hw); -extern bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw, - enum radio_path rfpath); -extern void rtl8723ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); -extern void rtl8723ae_phy_get_txpower_level(struct ieee80211_hw *hw, - long *powerlevel); -extern void rtl8723ae_phy_set_txpower_level(struct ieee80211_hw *hw, - u8 channel); -extern bool rtl8723ae_phy_update_txpower_dbm(struct ieee80211_hw *hw, - long power_indbm); -extern void rtl8723ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw); -extern void rtl8723ae_phy_set_bw_mode(struct ieee80211_hw *hw, - enum nl80211_channel_type ch_type); -extern void rtl8723ae_phy_sw_chnl_callback(struct ieee80211_hw *hw); -extern u8 rtl8723ae_phy_sw_chnl(struct ieee80211_hw *hw); -extern void rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery); +u32 rtl8723ae_phy_query_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask); +void rtl8723ae_phy_set_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, u32 data); +u32 rtl8723ae_phy_query_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask); +void rtl8723ae_phy_set_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask, u32 data); +bool rtl8723ae_phy_mac_config(struct ieee80211_hw *hw); +bool rtl8723ae_phy_bb_config(struct ieee80211_hw *hw); +bool rtl8723ae_phy_rf_config(struct ieee80211_hw *hw); +bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw, + enum radio_path rfpath); +void rtl8723ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); +void rtl8723ae_phy_get_txpower_level(struct ieee80211_hw *hw, + long *powerlevel); +void rtl8723ae_phy_set_txpower_level(struct ieee80211_hw *hw, + u8 channel); +bool rtl8723ae_phy_update_txpower_dbm(struct ieee80211_hw *hw, + long power_indbm); +void rtl8723ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw); +void rtl8723ae_phy_set_bw_mode(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type); +void rtl8723ae_phy_sw_chnl_callback(struct ieee80211_hw *hw); +u8 rtl8723ae_phy_sw_chnl(struct ieee80211_hw *hw); +void rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery); void rtl8723ae_phy_lc_calibrate(struct ieee80211_hw *hw); void rtl8723ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain); bool rtl8723ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, enum radio_path rfpath); bool rtl8723ae_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); -extern bool rtl8723ae_phy_set_rf_power_state(struct ieee80211_hw *hw, - enum rf_pwrstate rfpwr_state); +bool rtl8723ae_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state); #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/rf.h b/drivers/net/wireless/rtlwifi/rtl8723ae/rf.h index d0f9dd79abea..57f1933ee663 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723ae/rf.h +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/rf.h @@ -32,12 +32,11 @@ #define RF6052_MAX_TX_PWR 0x3F -extern void rtl8723ae_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, - u8 bandwidth); -extern void rtl8723ae_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, - u8 *ppowerlevel); -extern void rtl8723ae_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, - u8 *ppowerlevel, u8 channel); -extern bool rtl8723ae_phy_rf6052_config(struct ieee80211_hw *hw); +void rtl8723ae_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth); +void rtl8723ae_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel); +void rtl8723ae_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel); +bool rtl8723ae_phy_rf6052_config(struct ieee80211_hw *hw); #endif diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index 96763dcff5ae..d224dc3bb092 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h @@ -2055,7 +2055,7 @@ struct rtl_priv { that it points to the data allocated beyond this structure like: rtl_pci_priv or rtl_usb_priv */ - u8 priv[0]; + u8 priv[0] __aligned(sizeof(void *)); }; #define rtl_priv(hw) (((struct rtl_priv *)(hw)->priv)) diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index f3e591c611de..d0b0feb035fb 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c @@ -47,6 +47,14 @@ #include <asm/xen/hypercall.h> #include <asm/xen/page.h> +/* SKB control block overlay is used to store useful information when + * doing guest RX. + */ +struct skb_cb_overlay { + int meta_slots_used; + int peek_slots_count; +}; + /* Provide an option to disable split event channels at load time as * event channels are limited resource. Split event channels are * enabled by default. @@ -212,49 +220,6 @@ static bool start_new_rx_buffer(int offset, unsigned long size, int head) return false; } -struct xenvif_count_slot_state { - unsigned long copy_off; - bool head; -}; - -unsigned int xenvif_count_frag_slots(struct xenvif *vif, - unsigned long offset, unsigned long size, - struct xenvif_count_slot_state *state) -{ - unsigned count = 0; - - offset &= ~PAGE_MASK; - - while (size > 0) { - unsigned long bytes; - - bytes = PAGE_SIZE - offset; - - if (bytes > size) - bytes = size; - - if (start_new_rx_buffer(state->copy_off, bytes, state->head)) { - count++; - state->copy_off = 0; - } - - if (state->copy_off + bytes > MAX_BUFFER_OFFSET) - bytes = MAX_BUFFER_OFFSET - state->copy_off; - - state->copy_off += bytes; - - offset += bytes; - size -= bytes; - - if (offset == PAGE_SIZE) - offset = 0; - - state->head = false; - } - - return count; -} - /* * Figure out how many ring slots we're going to need to send @skb to * the guest. This function is essentially a dry run of @@ -262,40 +227,53 @@ unsigned int xenvif_count_frag_slots(struct xenvif *vif, */ unsigned int xenvif_count_skb_slots(struct xenvif *vif, struct sk_buff *skb) { - struct xenvif_count_slot_state state; unsigned int count; - unsigned char *data; - unsigned i; + int i, copy_off; + struct skb_cb_overlay *sco; - state.head = true; - state.copy_off = 0; + count = DIV_ROUND_UP(skb_headlen(skb), PAGE_SIZE); - /* Slot for the first (partial) page of data. */ - count = 1; + copy_off = skb_headlen(skb) % PAGE_SIZE; - /* Need a slot for the GSO prefix for GSO extra data? */ if (skb_shinfo(skb)->gso_size) count++; - data = skb->data; - while (data < skb_tail_pointer(skb)) { - unsigned long offset = offset_in_page(data); - unsigned long size = PAGE_SIZE - offset; + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + unsigned long size = skb_frag_size(&skb_shinfo(skb)->frags[i]); + unsigned long offset = skb_shinfo(skb)->frags[i].page_offset; + unsigned long bytes; - if (data + size > skb_tail_pointer(skb)) - size = skb_tail_pointer(skb) - data; + offset &= ~PAGE_MASK; - count += xenvif_count_frag_slots(vif, offset, size, &state); + while (size > 0) { + BUG_ON(offset >= PAGE_SIZE); + BUG_ON(copy_off > MAX_BUFFER_OFFSET); - data += size; - } + bytes = PAGE_SIZE - offset; - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - unsigned long size = skb_frag_size(&skb_shinfo(skb)->frags[i]); - unsigned long offset = skb_shinfo(skb)->frags[i].page_offset; + if (bytes > size) + bytes = size; + + if (start_new_rx_buffer(copy_off, bytes, 0)) { + count++; + copy_off = 0; + } - count += xenvif_count_frag_slots(vif, offset, size, &state); + if (copy_off + bytes > MAX_BUFFER_OFFSET) + bytes = MAX_BUFFER_OFFSET - copy_off; + + copy_off += bytes; + + offset += bytes; + size -= bytes; + + if (offset == PAGE_SIZE) + offset = 0; + } } + + sco = (struct skb_cb_overlay *)skb->cb; + sco->peek_slots_count = count; return count; } @@ -327,14 +305,11 @@ static struct xenvif_rx_meta *get_next_rx_buffer(struct xenvif *vif, return meta; } -/* - * Set up the grant operations for this fragment. If it's a flipping - * interface, we also set up the unmap request from here. - */ +/* Set up the grant operations for this fragment. */ static void xenvif_gop_frag_copy(struct xenvif *vif, struct sk_buff *skb, struct netrx_pending_operations *npo, struct page *page, unsigned long size, - unsigned long offset, int *head) + unsigned long offset, int head, int *first) { struct gnttab_copy *copy_gop; struct xenvif_rx_meta *meta; @@ -358,12 +333,12 @@ static void xenvif_gop_frag_copy(struct xenvif *vif, struct sk_buff *skb, if (bytes > size) bytes = size; - if (start_new_rx_buffer(npo->copy_off, bytes, *head)) { + if (start_new_rx_buffer(npo->copy_off, bytes, head)) { /* * Netfront requires there to be some data in the head * buffer. */ - BUG_ON(*head); + BUG_ON(*first); meta = get_next_rx_buffer(vif, npo); } @@ -397,10 +372,10 @@ static void xenvif_gop_frag_copy(struct xenvif *vif, struct sk_buff *skb, } /* Leave a gap for the GSO descriptor. */ - if (*head && skb_shinfo(skb)->gso_size && !vif->gso_prefix) + if (*first && skb_shinfo(skb)->gso_size && !vif->gso_prefix) vif->rx.req_cons++; - *head = 0; /* There must be something in this buffer now. */ + *first = 0; /* There must be something in this buffer now. */ } } @@ -426,7 +401,7 @@ static int xenvif_gop_skb(struct sk_buff *skb, struct xen_netif_rx_request *req; struct xenvif_rx_meta *meta; unsigned char *data; - int head = 1; + int first = 1; int old_meta_prod; old_meta_prod = npo->meta_prod; @@ -462,7 +437,7 @@ static int xenvif_gop_skb(struct sk_buff *skb, len = skb_tail_pointer(skb) - data; xenvif_gop_frag_copy(vif, skb, npo, - virt_to_page(data), len, offset, &head); + virt_to_page(data), len, offset, 1, &first); data += len; } @@ -471,7 +446,7 @@ static int xenvif_gop_skb(struct sk_buff *skb, skb_frag_page(&skb_shinfo(skb)->frags[i]), skb_frag_size(&skb_shinfo(skb)->frags[i]), skb_shinfo(skb)->frags[i].page_offset, - &head); + 0, &first); } return npo->meta_prod - old_meta_prod; @@ -529,10 +504,6 @@ static void xenvif_add_frag_responses(struct xenvif *vif, int status, } } -struct skb_cb_overlay { - int meta_slots_used; -}; - static void xenvif_kick_thread(struct xenvif *vif) { wake_up(&vif->wq); @@ -563,19 +534,26 @@ void xenvif_rx_action(struct xenvif *vif) count = 0; while ((skb = skb_dequeue(&vif->rx_queue)) != NULL) { + RING_IDX old_rx_req_cons; + vif = netdev_priv(skb->dev); nr_frags = skb_shinfo(skb)->nr_frags; + old_rx_req_cons = vif->rx.req_cons; sco = (struct skb_cb_overlay *)skb->cb; sco->meta_slots_used = xenvif_gop_skb(skb, &npo); - count += nr_frags + 1; + count += vif->rx.req_cons - old_rx_req_cons; __skb_queue_tail(&rxq, skb); + skb = skb_peek(&vif->rx_queue); + if (skb == NULL) + break; + sco = (struct skb_cb_overlay *)skb->cb; + /* Filled the batch queue? */ - /* XXX FIXME: RX path dependent on MAX_SKB_FRAGS */ - if (count + MAX_SKB_FRAGS >= XEN_NETIF_RX_RING_SIZE) + if (count + sco->peek_slots_count >= XEN_NETIF_RX_RING_SIZE) break; } diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c index a53782ef1540..b45bce20ad76 100644 --- a/drivers/net/xen-netback/xenbus.c +++ b/drivers/net/xen-netback/xenbus.c @@ -24,6 +24,12 @@ struct backend_info { struct xenbus_device *dev; struct xenvif *vif; + + /* This is the state that will be reflected in xenstore when any + * active hotplug script completes. + */ + enum xenbus_state state; + enum xenbus_state frontend_state; struct xenbus_watch hotplug_status_watch; u8 have_hotplug_status_watch:1; @@ -136,6 +142,8 @@ static int netback_probe(struct xenbus_device *dev, if (err) goto fail; + be->state = XenbusStateInitWait; + /* This kicks hotplug scripts, so do it immediately. */ backend_create_xenvif(be); @@ -208,24 +216,113 @@ static void backend_create_xenvif(struct backend_info *be) kobject_uevent(&dev->dev.kobj, KOBJ_ONLINE); } - -static void disconnect_backend(struct xenbus_device *dev) +static void backend_disconnect(struct backend_info *be) { - struct backend_info *be = dev_get_drvdata(&dev->dev); - if (be->vif) xenvif_disconnect(be->vif); } -static void destroy_backend(struct xenbus_device *dev) +static void backend_connect(struct backend_info *be) { - struct backend_info *be = dev_get_drvdata(&dev->dev); + if (be->vif) + connect(be); +} - if (be->vif) { - kobject_uevent(&dev->dev.kobj, KOBJ_OFFLINE); - xenbus_rm(XBT_NIL, dev->nodename, "hotplug-status"); - xenvif_free(be->vif); - be->vif = NULL; +static inline void backend_switch_state(struct backend_info *be, + enum xenbus_state state) +{ + struct xenbus_device *dev = be->dev; + + pr_debug("%s -> %s\n", dev->nodename, xenbus_strstate(state)); + be->state = state; + + /* If we are waiting for a hotplug script then defer the + * actual xenbus state change. + */ + if (!be->have_hotplug_status_watch) + xenbus_switch_state(dev, state); +} + +/* Handle backend state transitions: + * + * The backend state starts in InitWait and the following transitions are + * allowed. + * + * InitWait -> Connected + * + * ^ \ | + * | \ | + * | \ | + * | \ | + * | \ | + * | \ | + * | V V + * + * Closed <-> Closing + * + * The state argument specifies the eventual state of the backend and the + * function transitions to that state via the shortest path. + */ +static void set_backend_state(struct backend_info *be, + enum xenbus_state state) +{ + while (be->state != state) { + switch (be->state) { + case XenbusStateClosed: + switch (state) { + case XenbusStateInitWait: + case XenbusStateConnected: + pr_info("%s: prepare for reconnect\n", + be->dev->nodename); + backend_switch_state(be, XenbusStateInitWait); + break; + case XenbusStateClosing: + backend_switch_state(be, XenbusStateClosing); + break; + default: + BUG(); + } + break; + case XenbusStateInitWait: + switch (state) { + case XenbusStateConnected: + backend_connect(be); + backend_switch_state(be, XenbusStateConnected); + break; + case XenbusStateClosing: + case XenbusStateClosed: + backend_switch_state(be, XenbusStateClosing); + break; + default: + BUG(); + } + break; + case XenbusStateConnected: + switch (state) { + case XenbusStateInitWait: + case XenbusStateClosing: + case XenbusStateClosed: + backend_disconnect(be); + backend_switch_state(be, XenbusStateClosing); + break; + default: + BUG(); + } + break; + case XenbusStateClosing: + switch (state) { + case XenbusStateInitWait: + case XenbusStateConnected: + case XenbusStateClosed: + backend_switch_state(be, XenbusStateClosed); + break; + default: + BUG(); + } + break; + default: + BUG(); + } } } @@ -237,40 +334,33 @@ static void frontend_changed(struct xenbus_device *dev, { struct backend_info *be = dev_get_drvdata(&dev->dev); - pr_debug("frontend state %s\n", xenbus_strstate(frontend_state)); + pr_debug("%s -> %s\n", dev->otherend, xenbus_strstate(frontend_state)); be->frontend_state = frontend_state; switch (frontend_state) { case XenbusStateInitialising: - if (dev->state == XenbusStateClosed) { - pr_info("%s: prepare for reconnect\n", dev->nodename); - xenbus_switch_state(dev, XenbusStateInitWait); - } + set_backend_state(be, XenbusStateInitWait); break; case XenbusStateInitialised: break; case XenbusStateConnected: - if (dev->state == XenbusStateConnected) - break; - if (be->vif) - connect(be); + set_backend_state(be, XenbusStateConnected); break; case XenbusStateClosing: - disconnect_backend(dev); - xenbus_switch_state(dev, XenbusStateClosing); + set_backend_state(be, XenbusStateClosing); break; case XenbusStateClosed: - xenbus_switch_state(dev, XenbusStateClosed); + set_backend_state(be, XenbusStateClosed); if (xenbus_dev_is_online(dev)) break; - destroy_backend(dev); /* fall through if not online */ case XenbusStateUnknown: + set_backend_state(be, XenbusStateClosed); device_unregister(&dev->dev); break; @@ -363,7 +453,9 @@ static void hotplug_status_changed(struct xenbus_watch *watch, if (IS_ERR(str)) return; if (len == sizeof("connected")-1 && !memcmp(str, "connected", len)) { - xenbus_switch_state(be->dev, XenbusStateConnected); + /* Complete any pending state change */ + xenbus_switch_state(be->dev, be->state); + /* Not interested in this watch anymore. */ unregister_hotplug_status_watch(be); } @@ -393,12 +485,8 @@ static void connect(struct backend_info *be) err = xenbus_watch_pathfmt(dev, &be->hotplug_status_watch, hotplug_status_changed, "%s/%s", dev->nodename, "hotplug-status"); - if (err) { - /* Switch now, since we can't do a watch. */ - xenbus_switch_state(dev, XenbusStateConnected); - } else { + if (!err) be->have_hotplug_status_watch = 1; - } netif_wake_queue(be->vif->dev); } diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 36808bf25677..dd1011e55cb5 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -952,7 +952,7 @@ static int handle_incoming_queue(struct net_device *dev, u64_stats_update_end(&stats->syncp); /* Pass it up. */ - netif_receive_skb(skb); + napi_gro_receive(&np->napi, skb); } return packets_dropped; @@ -1051,6 +1051,8 @@ err: if (work_done < budget) { int more_to_do = 0; + napi_gro_flush(napi, false); + local_irq_save(flags); RING_FINAL_CHECK_FOR_RESPONSES(&np->rx, more_to_do); diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 7c29ee4ed0ae..b0299e6d9a3f 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -47,6 +47,9 @@ static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context) if (event != ACPI_NOTIFY_DEVICE_WAKE || !pci_dev) return; + if (pci_dev->pme_poll) + pci_dev->pme_poll = false; + if (pci_dev->current_state == PCI_D3cold) { pci_wakeup_event(pci_dev); pm_runtime_resume(&pci_dev->dev); @@ -57,9 +60,6 @@ static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context) if (pci_dev->pme_support) pci_check_pme_status(pci_dev); - if (pci_dev->pme_poll) - pci_dev->pme_poll = false; - pci_wakeup_event(pci_dev); pm_runtime_resume(&pci_dev->dev); diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index e8ccf6c0f08a..bdd64b1b4817 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1155,8 +1155,14 @@ static void pci_enable_bridge(struct pci_dev *dev) pci_enable_bridge(dev->bus->self); - if (pci_is_enabled(dev)) + if (pci_is_enabled(dev)) { + if (!dev->is_busmaster) { + dev_warn(&dev->dev, "driver skip pci_set_master, fix it!\n"); + pci_set_master(dev); + } return; + } + retval = pci_enable_device(dev); if (retval) dev_err(&dev->dev, "Error enabling bridge (%d), continuing\n", diff --git a/drivers/regulator/da9063-regulator.c b/drivers/regulator/da9063-regulator.c index 1a7816390773..b9f2653e4ef9 100644 --- a/drivers/regulator/da9063-regulator.c +++ b/drivers/regulator/da9063-regulator.c @@ -709,7 +709,7 @@ static struct da9063_regulators_pdata *da9063_parse_regulators_dt( struct of_regulator_match **da9063_reg_matches) { da9063_reg_matches = NULL; - return PTR_ERR(-ENODEV); + return ERR_PTR(-ENODEV); } #endif diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index 488dfe7ce9a6..7e2b165972e6 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -201,13 +201,7 @@ static unsigned int palmas_smps_ramp_delay[4] = {0, 10000, 5000, 2500}; #define SMPS_CTRL_MODE_ECO 0x02 #define SMPS_CTRL_MODE_PWM 0x03 -/* These values are derived from the data sheet. And are the number of steps - * where there is a voltage change, the ranges at beginning and end of register - * max/min values where there are no change are ommitted. - * - * So they are basically (maxV-minV)/stepV - */ -#define PALMAS_SMPS_NUM_VOLTAGES 117 +#define PALMAS_SMPS_NUM_VOLTAGES 122 #define PALMAS_SMPS10_NUM_VOLTAGES 2 #define PALMAS_LDO_NUM_VOLTAGES 50 @@ -979,6 +973,7 @@ static int palmas_regulators_probe(struct platform_device *pdev) pmic->desc[id].min_uV = 900000; pmic->desc[id].uV_step = 50000; pmic->desc[id].linear_min_sel = 1; + pmic->desc[id].enable_time = 500; pmic->desc[id].vsel_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, palmas_regs_info[id].vsel_addr); @@ -997,6 +992,11 @@ static int palmas_regulators_probe(struct platform_device *pdev) pmic->desc[id].min_uV = 450000; pmic->desc[id].uV_step = 25000; } + + /* LOD6 in vibrator mode will have enable time 2000us */ + if (pdata && pdata->ldo6_vibrator && + (id == PALMAS_REG_LDO6)) + pmic->desc[id].enable_time = 2000; } else { pmic->desc[id].n_voltages = 1; pmic->desc[id].ops = &palmas_ops_extreg; diff --git a/drivers/regulator/ti-abb-regulator.c b/drivers/regulator/ti-abb-regulator.c index d8e3e1262bc2..20c271d49dcb 100644 --- a/drivers/regulator/ti-abb-regulator.c +++ b/drivers/regulator/ti-abb-regulator.c @@ -279,8 +279,12 @@ static int ti_abb_set_opp(struct regulator_dev *rdev, struct ti_abb *abb, ti_abb_rmw(regs->opp_sel_mask, info->opp_sel, regs->control_reg, abb->base); - /* program LDO VBB vset override if needed */ - if (abb->ldo_base) + /* + * program LDO VBB vset override if needed for !bypass mode + * XXX: Do not switch sequence - for !bypass, LDO override reset *must* + * be performed *before* switch to bias mode else VBB glitches. + */ + if (abb->ldo_base && info->opp_sel != TI_ABB_NOMINAL_OPP) ti_abb_program_ldovbb(dev, abb, info); /* Initiate ABB ldo change */ @@ -295,6 +299,14 @@ static int ti_abb_set_opp(struct regulator_dev *rdev, struct ti_abb *abb, if (ret) goto out; + /* + * Reset LDO VBB vset override bypass mode + * XXX: Do not switch sequence - for bypass, LDO override reset *must* + * be performed *after* switch to bypass else VBB glitches. + */ + if (abb->ldo_base && info->opp_sel == TI_ABB_NOMINAL_OPP) + ti_abb_program_ldovbb(dev, abb, info); + out: return ret; } diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c index 1432b26ef2e9..2205fbc2c37b 100644 --- a/drivers/regulator/wm831x-ldo.c +++ b/drivers/regulator/wm831x-ldo.c @@ -63,7 +63,7 @@ static irqreturn_t wm831x_ldo_uv_irq(int irq, void *data) */ static const struct regulator_linear_range wm831x_gp_ldo_ranges[] = { - { .min_uV = 900000, .max_uV = 1650000, .min_sel = 0, .max_sel = 14, + { .min_uV = 900000, .max_uV = 1600000, .min_sel = 0, .max_sel = 14, .uV_step = 50000 }, { .min_uV = 1700000, .max_uV = 3300000, .min_sel = 15, .max_sel = 31, .uV_step = 100000 }, @@ -332,7 +332,7 @@ static struct platform_driver wm831x_gp_ldo_driver = { */ static const struct regulator_linear_range wm831x_aldo_ranges[] = { - { .min_uV = 1000000, .max_uV = 1650000, .min_sel = 0, .max_sel = 12, + { .min_uV = 1000000, .max_uV = 1600000, .min_sel = 0, .max_sel = 12, .uV_step = 50000 }, { .min_uV = 1700000, .max_uV = 3500000, .min_sel = 13, .max_sel = 31, .uV_step = 100000 }, diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c index 835b5f0f344e..61ca9292a429 100644 --- a/drivers/regulator/wm8350-regulator.c +++ b/drivers/regulator/wm8350-regulator.c @@ -543,7 +543,7 @@ static int wm8350_dcdc_set_suspend_mode(struct regulator_dev *rdev, } static const struct regulator_linear_range wm8350_ldo_ranges[] = { - { .min_uV = 900000, .max_uV = 1750000, .min_sel = 0, .max_sel = 15, + { .min_uV = 900000, .max_uV = 1650000, .min_sel = 0, .max_sel = 15, .uV_step = 50000 }, { .min_uV = 1800000, .max_uV = 3300000, .min_sel = 16, .max_sel = 31, .uV_step = 100000 }, diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index a84aab47a113..f73287eab373 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -96,6 +96,15 @@ config COMEDI_SKEL To compile this driver as a module, choose M here: the module will be called skel. +config COMEDI_SSV_DNP + tristate "SSV Embedded Systems DIL/Net-PC support" + depends on X86_32 || COMPILE_TEST + ---help--- + Enable support for SSV Embedded Systems DIL/Net-PC + + To compile this driver as a module, choose M here: the module will be + called ssv_dnp. + endif # COMEDI_MISC_DRIVERS menuconfig COMEDI_ISA_DRIVERS @@ -386,6 +395,14 @@ config COMEDI_DMM32AT To compile this driver as a module, choose M here: the module will be called dmm32at. +config COMEDI_UNIOXX5 + tristate "Fastwel UNIOxx-5 analog and digital io board support" + ---help--- + Enable support for Fastwel UNIOxx-5 (analog and digital i/o) boards + + To compile this driver as a module, choose M here: the module will be + called unioxx5. + config COMEDI_FL512 tristate "FL512 ISA card support" ---help--- @@ -855,14 +872,6 @@ config COMEDI_DYNA_PCI10XX To compile this driver as a module, choose M here: the module will be called dyna_pci10xx. -config COMEDI_UNIOXX5 - tristate "Fastwel UNIOxx-5 analog and digital io board support" - ---help--- - Enable support for Fastwel UNIOxx-5 (analog and digital i/o) boards - - To compile this driver as a module, choose M here: the module will be - called unioxx5. - config COMEDI_GSC_HPDI tristate "General Standards PCI-HPDI32 / PMC-HPDI32 support" select COMEDI_FC @@ -1085,14 +1094,6 @@ config COMEDI_S626 To compile this driver as a module, choose M here: the module will be called s626. -config COMEDI_SSV_DNP - tristate "SSV Embedded Systems DIL/Net-PC support" - ---help--- - Enable support for SSV Embedded Systems DIL/Net-PC - - To compile this driver as a module, choose M here: the module will be - called ssv_dnp. - config COMEDI_MITE depends on HAS_DMA tristate diff --git a/drivers/staging/dgap/dgap_driver.c b/drivers/staging/dgap/dgap_driver.c index 724a685753dd..40ef785a0428 100644 --- a/drivers/staging/dgap/dgap_driver.c +++ b/drivers/staging/dgap/dgap_driver.c @@ -474,7 +474,7 @@ static void dgap_cleanup_board(struct board_t *brd) DGAP_LOCK(dgap_global_lock, flags); brd->msgbuf = NULL; - printk(brd->msgbuf_head); + printk("%s", brd->msgbuf_head); kfree(brd->msgbuf_head); brd->msgbuf_head = NULL; DGAP_UNLOCK(dgap_global_lock, flags); @@ -628,7 +628,7 @@ static int dgap_found_board(struct pci_dev *pdev, int id) DPR_INIT(("dgap_scan(%d) - printing out the msgbuf\n", i)); DGAP_LOCK(dgap_global_lock, flags); brd->msgbuf = NULL; - printk(brd->msgbuf_head); + printk("%s", brd->msgbuf_head); kfree(brd->msgbuf_head); brd->msgbuf_head = NULL; DGAP_UNLOCK(dgap_global_lock, flags); @@ -955,25 +955,28 @@ static void dgap_mbuf(struct board_t *brd, const char *fmt, ...) { char buf[1024]; int i; unsigned long flags; + size_t length; DGAP_LOCK(dgap_global_lock, flags); /* Format buf using fmt and arguments contained in ap. */ va_start(ap, fmt); - i = vsprintf(buf, fmt, ap); + i = vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); DPR((buf)); if (!brd || !brd->msgbuf) { - printk(buf); + printk("%s", buf); DGAP_UNLOCK(dgap_global_lock, flags); return; } - memcpy(brd->msgbuf, buf, strlen(buf)); - brd->msgbuf += strlen(buf); - *brd->msgbuf = 0; + length = strlen(buf) + 1; + if (brd->msgbuf - brd->msgbuf_head < length) + length = brd->msgbuf - brd->msgbuf_head; + memcpy(brd->msgbuf, buf, length); + brd->msgbuf += length; DGAP_UNLOCK(dgap_global_lock, flags); } diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index f8c1e22585d6..71d2b83cc3a1 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -454,7 +454,7 @@ static void dgnc_cleanup_board(struct board_t *brd) DGNC_LOCK(dgnc_global_lock, flags); brd->msgbuf = NULL; - printk(brd->msgbuf_head); + printk("%s", brd->msgbuf_head); kfree(brd->msgbuf_head); brd->msgbuf_head = NULL; DGNC_UNLOCK(dgnc_global_lock, flags); @@ -710,7 +710,7 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) DPR_INIT(("dgnc_scan(%d) - printing out the msgbuf\n", i)); DGNC_LOCK(dgnc_global_lock, flags); brd->msgbuf = NULL; - printk(brd->msgbuf_head); + printk("%s", brd->msgbuf_head); kfree(brd->msgbuf_head); brd->msgbuf_head = NULL; DGNC_UNLOCK(dgnc_global_lock, flags); diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig index db4d6dc03243..b36feb080cba 100644 --- a/drivers/staging/iio/Kconfig +++ b/drivers/staging/iio/Kconfig @@ -37,7 +37,7 @@ config IIO_SIMPLE_DUMMY_EVENTS config IIO_SIMPLE_DUMMY_BUFFER boolean "Buffered capture support" - depends on IIO_KFIFO_BUF + select IIO_KFIFO_BUF help Add buffered data capture to the simple dummy driver. diff --git a/drivers/staging/iio/light/isl29018.c b/drivers/staging/iio/light/isl29018.c index 351936c3efd6..e4998e4d4434 100644 --- a/drivers/staging/iio/light/isl29018.c +++ b/drivers/staging/iio/light/isl29018.c @@ -563,6 +563,7 @@ static int isl29018_probe(struct i2c_client *client, mutex_init(&chip->lock); chip->lux_scale = 1; + chip->lux_uscale = 0; chip->range = 1000; chip->adc_bit = 16; chip->suspended = false; diff --git a/drivers/staging/iio/magnetometer/hmc5843.c b/drivers/staging/iio/magnetometer/hmc5843.c index d2748c329eae..c3f3f539e787 100644 --- a/drivers/staging/iio/magnetometer/hmc5843.c +++ b/drivers/staging/iio/magnetometer/hmc5843.c @@ -229,7 +229,7 @@ static int hmc5843_read_measurement(struct iio_dev *indio_dev, if (result < 0) return -EINVAL; - *val = result; + *val = sign_extend32(result, 15); return IIO_VAL_INT; } diff --git a/drivers/staging/iio/meter/ade7854-spi.c b/drivers/staging/iio/meter/ade7854-spi.c index a802cf2491d6..4c6d2041260b 100644 --- a/drivers/staging/iio/meter/ade7854-spi.c +++ b/drivers/staging/iio/meter/ade7854-spi.c @@ -299,7 +299,7 @@ static int ade7854_spi_probe(struct spi_device *spi) if (ret) iio_device_free(indio_dev); - return 0; + return ret; } static int ade7854_spi_remove(struct spi_device *spi) diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index 47c5888461ff..a2e52a0c53c9 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -41,7 +41,6 @@ struct imx_drm_device { struct list_head encoder_list; struct list_head connector_list; struct mutex mutex; - int references; int pipes; struct drm_fbdev_cma *fbhelper; }; @@ -241,8 +240,6 @@ struct drm_device *imx_drm_device_get(void) } } - imxdrm->references++; - return imxdrm->drm; unwind_crtc: @@ -280,8 +277,6 @@ void imx_drm_device_put(void) list_for_each_entry(enc, &imxdrm->encoder_list, list) module_put(enc->owner); - imxdrm->references--; - mutex_unlock(&imxdrm->mutex); } EXPORT_SYMBOL_GPL(imx_drm_device_put); @@ -485,7 +480,7 @@ int imx_drm_add_crtc(struct drm_crtc *crtc, mutex_lock(&imxdrm->mutex); - if (imxdrm->references) { + if (imxdrm->drm->open_count) { ret = -EBUSY; goto err_busy; } @@ -564,7 +559,7 @@ int imx_drm_add_encoder(struct drm_encoder *encoder, mutex_lock(&imxdrm->mutex); - if (imxdrm->references) { + if (imxdrm->drm->open_count) { ret = -EBUSY; goto err_busy; } @@ -709,7 +704,7 @@ int imx_drm_add_connector(struct drm_connector *connector, mutex_lock(&imxdrm->mutex); - if (imxdrm->references) { + if (imxdrm->drm->open_count) { ret = -EBUSY; goto err_busy; } diff --git a/drivers/staging/line6/toneport.c b/drivers/staging/line6/toneport.c index 2f44d56700af..776d3632dc7d 100644 --- a/drivers/staging/line6/toneport.c +++ b/drivers/staging/line6/toneport.c @@ -244,13 +244,17 @@ static int snd_toneport_source_put(struct snd_kcontrol *kcontrol, struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); struct usb_line6_toneport *toneport = (struct usb_line6_toneport *)line6pcm->line6; + unsigned int source; - if (ucontrol->value.enumerated.item[0] == toneport->source) + source = ucontrol->value.enumerated.item[0]; + if (source >= ARRAY_SIZE(toneport_source_info)) + return -EINVAL; + if (source == toneport->source) return 0; - toneport->source = ucontrol->value.enumerated.item[0]; + toneport->source = source; toneport_send_cmd(toneport->line6.usbdev, - toneport_source_info[toneport->source].code, 0x0000); + toneport_source_info[source].code, 0x0000); return 1; } diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c index 086ca3d7241b..26b49a24b3df 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c @@ -1802,7 +1802,7 @@ kiblnd_recv (lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg, int delayed, int kiblnd_thread_start(int (*fn)(void *arg), void *arg, char *name) { - struct task_struct *task = kthread_run(fn, arg, name); + struct task_struct *task = kthread_run(fn, arg, "%s", name); if (IS_ERR(task)) return PTR_ERR(task); diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c index 2c581b7fa8ad..68a4f52ec998 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c @@ -1005,7 +1005,7 @@ ksocknal_send(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg) int ksocknal_thread_start(int (*fn)(void *arg), void *arg, char *name) { - struct task_struct *task = kthread_run(fn, arg, name); + struct task_struct *task = kthread_run(fn, arg, "%s", name); if (IS_ERR(task)) return PTR_ERR(task); diff --git a/drivers/staging/lustre/lustre/Kconfig b/drivers/staging/lustre/lustre/Kconfig index 4e898e491860..2156a44d0740 100644 --- a/drivers/staging/lustre/lustre/Kconfig +++ b/drivers/staging/lustre/lustre/Kconfig @@ -1,6 +1,6 @@ config LUSTRE_FS tristate "Lustre file system client support" - depends on INET && m + depends on INET && m && !MIPS && !XTENSA && !SUPERH select LNET select CRYPTO select CRYPTO_CRC32 @@ -52,7 +52,7 @@ config LUSTRE_DEBUG_EXPENSIVE_CHECK config LUSTRE_TRANSLATE_ERRNOS bool depends on LUSTRE_FS && !X86 - default true + default y config LUSTRE_LLITE_LLOOP bool "Lustre virtual block device" diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c index 3916bda3004c..a100a0b96381 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c @@ -800,9 +800,9 @@ static int ldlm_bl_thread_start(struct ldlm_bl_pool *blp) init_completion(&bltd.bltd_comp); bltd.bltd_num = atomic_read(&blp->blp_num_threads); - snprintf(bltd.bltd_name, sizeof(bltd.bltd_name) - 1, + snprintf(bltd.bltd_name, sizeof(bltd.bltd_name), "ldlm_bl_%02d", bltd.bltd_num); - task = kthread_run(ldlm_bl_thread_main, &bltd, bltd.bltd_name); + task = kthread_run(ldlm_bl_thread_main, &bltd, "%s", bltd.bltd_name); if (IS_ERR(task)) { CERROR("cannot start LDLM thread ldlm_bl_%02d: rc %ld\n", atomic_read(&blp->blp_num_threads), PTR_ERR(task)); diff --git a/drivers/staging/lustre/lustre/libcfs/workitem.c b/drivers/staging/lustre/lustre/libcfs/workitem.c index 462172d1a756..1a55c81892e0 100644 --- a/drivers/staging/lustre/lustre/libcfs/workitem.c +++ b/drivers/staging/lustre/lustre/libcfs/workitem.c @@ -397,7 +397,7 @@ cfs_wi_sched_create(char *name, struct cfs_cpt_table *cptab, sched->ws_name, sched->ws_nthreads); } - task = kthread_run(cfs_wi_scheduler, sched, name); + task = kthread_run(cfs_wi_scheduler, sched, "%s", name); if (!IS_ERR(task)) { nthrs--; continue; diff --git a/drivers/staging/lustre/lustre/obdecho/echo_client.c b/drivers/staging/lustre/lustre/obdecho/echo_client.c index 2644edf438c1..c8b43442dc74 100644 --- a/drivers/staging/lustre/lustre/obdecho/echo_client.c +++ b/drivers/staging/lustre/lustre/obdecho/echo_client.c @@ -1387,7 +1387,7 @@ echo_copyout_lsm (struct lov_stripe_md *lsm, void *_ulsm, int ulsm_nob) if (nob > ulsm_nob) return (-EINVAL); - if (copy_to_user (ulsm, lsm, sizeof(ulsm))) + if (copy_to_user (ulsm, lsm, sizeof(*ulsm))) return (-EFAULT); for (i = 0; i < lsm->lsm_stripe_count; i++) { diff --git a/drivers/staging/lustre/lustre/ptlrpc/pinger.c b/drivers/staging/lustre/lustre/ptlrpc/pinger.c index 227a0ae9593b..5dec771d70ee 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/pinger.c +++ b/drivers/staging/lustre/lustre/ptlrpc/pinger.c @@ -383,8 +383,8 @@ int ptlrpc_start_pinger(void) /* CLONE_VM and CLONE_FILES just avoid a needless copy, because we * just drop the VM and FILES in cfs_daemonize_ctxt() right away. */ - rc = PTR_ERR(kthread_run(ptlrpc_pinger_main, - &pinger_thread, pinger_thread.t_name)); + rc = PTR_ERR(kthread_run(ptlrpc_pinger_main, &pinger_thread, + "%s", pinger_thread.t_name)); if (IS_ERR_VALUE(rc)) { CERROR("cannot start thread: %d\n", rc); return rc; diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c index fbdeff65d059..89c9be96f454 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c +++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c @@ -615,7 +615,7 @@ int ptlrpcd_start(int index, int max, const char *name, struct ptlrpcd_ctl *pc) init_completion(&pc->pc_starting); init_completion(&pc->pc_finishing); spin_lock_init(&pc->pc_lock); - strncpy(pc->pc_name, name, sizeof(pc->pc_name) - 1); + strlcpy(pc->pc_name, name, sizeof(pc->pc_name)); pc->pc_set = ptlrpc_prep_set(); if (pc->pc_set == NULL) GOTO(out, rc = -ENOMEM); @@ -638,7 +638,7 @@ int ptlrpcd_start(int index, int max, const char *name, struct ptlrpcd_ctl *pc) GOTO(out, rc); } - task = kthread_run(ptlrpcd, pc, pc->pc_name); + task = kthread_run(ptlrpcd, pc, "%s", pc->pc_name); if (IS_ERR(task)) GOTO(out, rc = PTR_ERR(task)); @@ -745,7 +745,7 @@ static int ptlrpcd_init(void) if (ptlrpcds == NULL) GOTO(out, rc = -ENOMEM); - snprintf(name, 15, "ptlrpcd_rcv"); + snprintf(name, sizeof(name), "ptlrpcd_rcv"); set_bit(LIOD_RECOVERY, &ptlrpcds->pd_thread_rcv.pc_flags); rc = ptlrpcd_start(-1, nthreads, name, &ptlrpcds->pd_thread_rcv); if (rc < 0) @@ -764,7 +764,7 @@ static int ptlrpcd_init(void) * unnecessary dependency. But how to distribute async RPCs load * among all the ptlrpc daemons becomes another trouble. */ for (i = 0; i < nthreads; i++) { - snprintf(name, 15, "ptlrpcd_%d", i); + snprintf(name, sizeof(name), "ptlrpcd_%d", i); rc = ptlrpcd_start(i, nthreads, name, &ptlrpcds->pd_threads[i]); if (rc < 0) GOTO(out, rc); diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c b/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c index e90c8fb7da6a..6547f46a7729 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c +++ b/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c @@ -59,8 +59,8 @@ ****************************************/ -#define PTRS_PER_PAGE (PAGE_CACHE_SIZE / sizeof(void *)) -#define PAGES_PER_POOL (PTRS_PER_PAGE) +#define POINTERS_PER_PAGE (PAGE_CACHE_SIZE / sizeof(void *)) +#define PAGES_PER_POOL (POINTERS_PER_PAGE) #define IDLE_IDX_MAX (100) #define IDLE_IDX_WEIGHT (3) diff --git a/drivers/staging/lustre/lustre/ptlrpc/service.c b/drivers/staging/lustre/lustre/ptlrpc/service.c index ac8b5fd2300b..acf75f3873d1 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/service.c +++ b/drivers/staging/lustre/lustre/ptlrpc/service.c @@ -2718,15 +2718,15 @@ int ptlrpc_start_thread(struct ptlrpc_service_part *svcpt, int wait) spin_unlock(&svcpt->scp_lock); if (svcpt->scp_cpt >= 0) { - snprintf(thread->t_name, PTLRPC_THR_NAME_LEN, "%s%02d_%03d", + snprintf(thread->t_name, sizeof(thread->t_name), "%s%02d_%03d", svc->srv_thread_name, svcpt->scp_cpt, thread->t_id); } else { - snprintf(thread->t_name, PTLRPC_THR_NAME_LEN, "%s_%04d", + snprintf(thread->t_name, sizeof(thread->t_name), "%s_%04d", svc->srv_thread_name, thread->t_id); } CDEBUG(D_RPCTRACE, "starting thread '%s'\n", thread->t_name); - rc = PTR_ERR(kthread_run(ptlrpc_main, thread, thread->t_name)); + rc = PTR_ERR(kthread_run(ptlrpc_main, thread, "%s", thread->t_name)); if (IS_ERR_VALUE(rc)) { CERROR("cannot start thread '%s': rc %d\n", thread->t_name, rc); diff --git a/drivers/staging/octeon-usb/cvmx-usb.c b/drivers/staging/octeon-usb/cvmx-usb.c index d7b3c82b5ead..45dfe94199ae 100644 --- a/drivers/staging/octeon-usb/cvmx-usb.c +++ b/drivers/staging/octeon-usb/cvmx-usb.c @@ -604,7 +604,7 @@ int cvmx_usb_initialize(struct cvmx_usb_state *state, int usb_port_number, } } - memset(usb, 0, sizeof(usb)); + memset(usb, 0, sizeof(*usb)); usb->init_flags = flags; /* Initialize the USB state structure */ diff --git a/drivers/staging/rtl8188eu/core/rtw_ieee80211.c b/drivers/staging/rtl8188eu/core/rtw_ieee80211.c index 3605c5da822d..6fc77428e83a 100644 --- a/drivers/staging/rtl8188eu/core/rtw_ieee80211.c +++ b/drivers/staging/rtl8188eu/core/rtw_ieee80211.c @@ -157,8 +157,8 @@ _func_enter_; *frlen = *frlen + (len + 2); - return pbuf + len + 2; _func_exit_; + return pbuf + len + 2; } inline u8 *rtw_set_ie_ch_switch (u8 *buf, u32 *buf_len, u8 ch_switch_mode, diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c index 8b2ba26ba38d..4b2eb8e9b562 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c @@ -1827,13 +1827,13 @@ unsigned int OnAction_back(struct adapter *padapter, union recv_frame *precv_fra #ifdef CONFIG_88EU_P2P -static int get_reg_classes_full_count(struct p2p_channels channel_list) +static int get_reg_classes_full_count(struct p2p_channels *channel_list) { int cnt = 0; int i; - for (i = 0; i < channel_list.reg_classes; i++) { - cnt += channel_list.reg_class[i].channels; + for (i = 0; i < channel_list->reg_classes; i++) { + cnt += channel_list->reg_class[i].channels; } return cnt; @@ -2065,7 +2065,7 @@ void issue_p2p_GO_request(struct adapter *padapter, u8 *raddr) /* + number of channels in all classes */ len_channellist_attr = 3 + (1 + 1) * (u16)(pmlmeext->channel_list.reg_classes) - + get_reg_classes_full_count(pmlmeext->channel_list); + + get_reg_classes_full_count(&pmlmeext->channel_list); *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr); p2pielen += 2; @@ -2437,7 +2437,7 @@ static void issue_p2p_GO_response(struct adapter *padapter, u8 *raddr, u8 *frame /* + number of channels in all classes */ len_channellist_attr = 3 + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes - + get_reg_classes_full_count(pmlmeext->channel_list); + + get_reg_classes_full_count(&pmlmeext->channel_list); *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr); @@ -2859,7 +2859,7 @@ void issue_p2p_invitation_request(struct adapter *padapter, u8 *raddr) /* + number of channels in all classes */ len_channellist_attr = 3 + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes - + get_reg_classes_full_count(pmlmeext->channel_list); + + get_reg_classes_full_count(&pmlmeext->channel_list); *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr); @@ -3120,7 +3120,7 @@ void issue_p2p_invitation_response(struct adapter *padapter, u8 *raddr, u8 dialo /* + number of channels in all classes */ len_channellist_attr = 3 + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes - + get_reg_classes_full_count(pmlmeext->channel_list); + + get_reg_classes_full_count(&pmlmeext->channel_list); *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr); p2pielen += 2; diff --git a/drivers/staging/rtl8188eu/core/rtw_mp.c b/drivers/staging/rtl8188eu/core/rtw_mp.c index c7ff2e4d1f23..9832dcbbd07f 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mp.c +++ b/drivers/staging/rtl8188eu/core/rtw_mp.c @@ -907,7 +907,7 @@ u32 mp_query_psd(struct adapter *pAdapter, u8 *data) sscanf(data, "pts =%d, start =%d, stop =%d", &psd_pts, &psd_start, &psd_stop); } - _rtw_memset(data, '\0', sizeof(data)); + _rtw_memset(data, '\0', sizeof(*data)); i = psd_start; while (i < psd_stop) { diff --git a/drivers/staging/rtl8188eu/core/rtw_wlan_util.c b/drivers/staging/rtl8188eu/core/rtw_wlan_util.c index 013ea487e7ac..8018edd3d42e 100644 --- a/drivers/staging/rtl8188eu/core/rtw_wlan_util.c +++ b/drivers/staging/rtl8188eu/core/rtw_wlan_util.c @@ -631,7 +631,7 @@ void WMMOnAssocRsp(struct adapter *padapter) inx[0] = 0; inx[1] = 1; inx[2] = 2; inx[3] = 3; if (pregpriv->wifi_spec == 1) { - u32 j, tmp, change_inx; + u32 j, tmp, change_inx = false; /* entry indx: 0->vo, 1->vi, 2->be, 3->bk. */ for (i = 0; i < 4; i++) { diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_dm.c b/drivers/staging/rtl8188eu/hal/rtl8188e_dm.c index 9c2e7a20c09e..ec0028d4e61a 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188e_dm.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188e_dm.c @@ -57,7 +57,7 @@ static void Init_ODM_ComInfo_88E(struct adapter *Adapter) u8 cut_ver, fab_ver; /* Init Value */ - _rtw_memset(dm_odm, 0, sizeof(dm_odm)); + _rtw_memset(dm_odm, 0, sizeof(*dm_odm)); dm_odm->Adapter = Adapter; diff --git a/drivers/staging/rtl8188eu/include/odm.h b/drivers/staging/rtl8188eu/include/odm.h index 2bfe72841921..4787bacdcad8 100644 --- a/drivers/staging/rtl8188eu/include/odm.h +++ b/drivers/staging/rtl8188eu/include/odm.h @@ -1010,7 +1010,7 @@ enum dm_dig_op { #define DM_false_ALARM_THRESH_LOW 400 #define DM_false_ALARM_THRESH_HIGH 1000 -#define DM_DIG_MAX_NIC 0x3e +#define DM_DIG_MAX_NIC 0x4e #define DM_DIG_MIN_NIC 0x1e /* 0x22/0x1c */ #define DM_DIG_MAX_AP 0x32 diff --git a/drivers/staging/rtl8188eu/include/rtl8188e_hal.h b/drivers/staging/rtl8188eu/include/rtl8188e_hal.h index 52b280165a92..555c801d2ded 100644 --- a/drivers/staging/rtl8188eu/include/rtl8188e_hal.h +++ b/drivers/staging/rtl8188eu/include/rtl8188e_hal.h @@ -188,7 +188,7 @@ enum ChannelPlan { struct txpowerinfo24g { u8 IndexCCK_Base[MAX_RF_PATH][MAX_CHNL_GROUP_24G]; - u8 IndexBW40_Base[MAX_RF_PATH][MAX_CHNL_GROUP_24G-1]; + u8 IndexBW40_Base[MAX_RF_PATH][MAX_CHNL_GROUP_24G]; /* If only one tx, only BW20 and OFDM are used. */ s8 CCK_Diff[MAX_RF_PATH][MAX_TX_COUNT]; s8 OFDM_Diff[MAX_RF_PATH][MAX_TX_COUNT]; diff --git a/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h b/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h index a96b018e5e6a..853ab80a2b86 100644 --- a/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h +++ b/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h @@ -870,6 +870,7 @@ static struct fwevent wlanevents[] = { {0, NULL}, {0, NULL}, {0, &rtw_cpwm_event_callback}, + {0, NULL}, }; #endif/* _RTL_MLME_EXT_C_ */ diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c index cd4100fb3645..95953ebc0279 100644 --- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c @@ -6973,7 +6973,7 @@ static int rtw_mp_ctx(struct net_device *dev, stop = strncmp(extra, "stop", 4); sscanf(extra, "count =%d, pkt", &count); - _rtw_memset(extra, '\0', sizeof(extra)); + _rtw_memset(extra, '\0', sizeof(*extra)); if (stop == 0) { bStartTest = 0; /* To set Stop */ diff --git a/drivers/staging/rtl8188eu/os_dep/usb_intf.c b/drivers/staging/rtl8188eu/os_dep/usb_intf.c index d3078d200e50..9ca3180ebaa0 100644 --- a/drivers/staging/rtl8188eu/os_dep/usb_intf.c +++ b/drivers/staging/rtl8188eu/os_dep/usb_intf.c @@ -54,6 +54,7 @@ static struct usb_device_id rtw_usb_id_tbl[] = { /*=== Customer ID ===*/ /****** 8188EUS ********/ {USB_DEVICE(0x8179, 0x07B8)}, /* Abocom - Abocom */ + {USB_DEVICE(0x2001, 0x330F)}, /* DLink DWA-125 REV D1 */ {} /* Terminating entry */ }; diff --git a/drivers/staging/rtl8192u/r819xU_cmdpkt.c b/drivers/staging/rtl8192u/r819xU_cmdpkt.c index 5bc361b16d4c..56144014b7c9 100644 --- a/drivers/staging/rtl8192u/r819xU_cmdpkt.c +++ b/drivers/staging/rtl8192u/r819xU_cmdpkt.c @@ -37,6 +37,8 @@ rt_status SendTxCommandPacket(struct net_device *dev, void *pData, u32 DataLen) /* Get TCB and local buffer from common pool. (It is shared by CmdQ, MgntQ, and USB coalesce DataQ) */ skb = dev_alloc_skb(USB_HWDESC_HEADER_LEN + DataLen + 4); + if (!skb) + return RT_STATUS_FAILURE; memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev)); tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); tcb_desc->queue_index = TXCMD_QUEUE; diff --git a/drivers/staging/vt6656/card.c b/drivers/staging/vt6656/card.c index dbf11ecb794e..19d3cf451b88 100644 --- a/drivers/staging/vt6656/card.c +++ b/drivers/staging/vt6656/card.c @@ -172,8 +172,8 @@ static u16 swGetOFDMControlRate(struct vnt_private *pDevice, u16 wRateIdx) if (!CARDbIsOFDMinBasicRate(pDevice)) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "swGetOFDMControlRate:(NO OFDM) %d\n", wRateIdx); - if (wRateIdx > RATE_24M) - wRateIdx = RATE_24M; + if (wRateIdx > RATE_24M) + wRateIdx = RATE_24M; return wRateIdx; } diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c index d0cf7d8a20e5..8872e0f84f40 100644 --- a/drivers/staging/vt6656/iwctl.c +++ b/drivers/staging/vt6656/iwctl.c @@ -1634,6 +1634,9 @@ int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info, if (pMgmt == NULL) return -EFAULT; + if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) + return -ENODEV; + buf = kzalloc(sizeof(struct viawget_wpa_param), GFP_KERNEL); if (buf == NULL) return -ENOMEM; diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index 536971786ae8..6f9d28182445 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -1098,6 +1098,8 @@ static int device_close(struct net_device *dev) memset(pMgmt->abyCurrBSSID, 0, 6); pMgmt->eCurrState = WMAC_STATE_IDLE; + pDevice->flags &= ~DEVICE_FLAGS_OPENED; + device_free_tx_bufs(pDevice); device_free_rx_bufs(pDevice); device_free_int_bufs(pDevice); @@ -1109,7 +1111,6 @@ static int device_close(struct net_device *dev) usb_free_urb(pDevice->pInterruptURB); BSSvClearNodeDBTable(pDevice, 0); - pDevice->flags &=(~DEVICE_FLAGS_OPENED); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close2 \n"); diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index fb743a8811bb..14f3e852215d 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c @@ -148,6 +148,8 @@ static void *s_vGetFreeContext(struct vnt_private *pDevice) DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"GetFreeContext()\n"); for (ii = 0; ii < pDevice->cbTD; ii++) { + if (!pDevice->apTD[ii]) + return NULL; pContext = pDevice->apTD[ii]; if (pContext->bBoolInUse == false) { pContext->bBoolInUse = true; diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index efc56987a60b..7db6f03a0054 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -2054,7 +2054,7 @@ static int xillybus_init_chrdev(struct xilly_endpoint *endpoint, NULL, MKDEV(major, i), NULL, - devname); + "%s", devname); if (IS_ERR(device)) { pr_warn("xillybus: Failed to create %s " diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c index 91d94b564433..2c4ed52ca849 100644 --- a/drivers/staging/zram/zram_drv.c +++ b/drivers/staging/zram/zram_drv.c @@ -981,4 +981,3 @@ MODULE_PARM_DESC(num_devices, "Number of zram devices"); MODULE_LICENSE("Dual BSD/GPL"); MODULE_AUTHOR("Nitin Gupta <ngupta@vflare.org>"); MODULE_DESCRIPTION("Compressed RAM Block Device"); -MODULE_ALIAS("devname:zram"); diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index c9a9ddd1d0bc..01bf5eb4f238 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1758,8 +1758,7 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) canon_change = (old->c_lflag ^ tty->termios.c_lflag) & ICANON; if (canon_change) { bitmap_zero(ldata->read_flags, N_TTY_BUF_SIZE); - ldata->line_start = 0; - ldata->canon_head = ldata->read_tail; + ldata->line_start = ldata->canon_head = ldata->read_tail; ldata->erasing = 0; ldata->lnext = 0; } diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 52379e56a31e..44077c0b7670 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -667,30 +667,21 @@ static int pop_tx_x(struct eg20t_port *priv, unsigned char *buf) static int dma_push_rx(struct eg20t_port *priv, int size) { - struct tty_struct *tty; int room; struct uart_port *port = &priv->port; struct tty_port *tport = &port->state->port; - port = &priv->port; - tty = tty_port_tty_get(tport); - if (!tty) { - dev_dbg(priv->port.dev, "%s:tty is busy now", __func__); - return 0; - } - room = tty_buffer_request_room(tport, size); if (room < size) dev_warn(port->dev, "Rx overrun: dropping %u bytes\n", size - room); if (!room) - return room; + return 0; tty_insert_flip_string(tport, sg_virt(&priv->sg_rx), size); port->icount.rx += room; - tty_kref_put(tty); return room; } @@ -1098,6 +1089,8 @@ static void pch_uart_err_ir(struct eg20t_port *priv, unsigned int lsr) if (tty == NULL) { for (i = 0; error_msg[i] != NULL; i++) dev_err(&priv->pdev->dev, error_msg[i]); + } else { + tty_kref_put(tty); } } diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c index d0d972f7e43e..0489a2bdcdf9 100644 --- a/drivers/tty/serial/serial-tegra.c +++ b/drivers/tty/serial/serial-tegra.c @@ -732,7 +732,7 @@ static irqreturn_t tegra_uart_isr(int irq, void *data) static void tegra_uart_stop_rx(struct uart_port *u) { struct tegra_uart_port *tup = to_tegra_uport(u); - struct tty_struct *tty = tty_port_tty_get(&tup->uport.state->port); + struct tty_struct *tty; struct tty_port *port = &u->state->port; struct dma_tx_state state; unsigned long ier; @@ -744,6 +744,8 @@ static void tegra_uart_stop_rx(struct uart_port *u) if (!tup->rx_in_progress) return; + tty = tty_port_tty_get(&tup->uport.state->port); + tegra_uart_wait_sym_time(tup, 1); /* wait a character interval */ ier = tup->ier_shadow; diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index 03ba081c5772..6fd60fece6b4 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c @@ -1201,6 +1201,9 @@ int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, } return 0; case TCFLSH: + retval = tty_check_change(tty); + if (retval) + return retval; return __tty_perform_flush(tty, arg); default: /* Try the mode commands */ diff --git a/drivers/usb/chipidea/Kconfig b/drivers/usb/chipidea/Kconfig index 4a851e15e58c..77b47d82c9a6 100644 --- a/drivers/usb/chipidea/Kconfig +++ b/drivers/usb/chipidea/Kconfig @@ -1,6 +1,6 @@ config USB_CHIPIDEA tristate "ChipIdea Highspeed Dual Role Controller" - depends on (USB_EHCI_HCD && USB_GADGET) || (USB_EHCI_HCD && !USB_GADGET) || (!USB_EHCI_HCD && USB_GADGET) + depends on ((USB_EHCI_HCD && USB_GADGET) || (USB_EHCI_HCD && !USB_GADGET) || (!USB_EHCI_HCD && USB_GADGET)) && HAS_DMA help Say Y here if your system has a dual role high speed USB controller based on ChipIdea silicon IP. Currently, only the diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index 74d998d9b45b..be822a2c1776 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c @@ -131,7 +131,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) if (ret) { dev_err(&pdev->dev, "usbmisc init failed, ret=%d\n", ret); - goto err_clk; + goto err_phy; } } @@ -143,7 +143,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) dev_err(&pdev->dev, "Can't register ci_hdrc platform device, err=%d\n", ret); - goto err_clk; + goto err_phy; } if (data->usbmisc_data) { @@ -164,6 +164,9 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) disable_device: ci_hdrc_remove_device(data->ci_pdev); +err_phy: + if (data->phy) + usb_phy_shutdown(data->phy); err_clk: clk_disable_unprepare(data->clk); return ret; diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 94626409559a..23763dcec069 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -605,6 +605,7 @@ static int ci_hdrc_remove(struct platform_device *pdev) dbg_remove_files(ci); free_irq(ci->irq, ci); ci_role_destroy(ci); + kfree(ci->hw_bank.regmap); return 0; } diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 6b4c2f2eb946..9333083dd111 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -1600,6 +1600,8 @@ static void destroy_eps(struct ci_hdrc *ci) for (i = 0; i < ci->hw_ep_max; i++) { struct ci_hw_ep *hwep = &ci->ci_hw_ep[i]; + if (hwep->pending_td) + free_pending_td(hwep); dma_pool_free(ci->qh_pool, hwep->qh.ptr, hwep->qh.dma); } } @@ -1667,13 +1669,13 @@ static int ci_udc_stop(struct usb_gadget *gadget, if (ci->platdata->notify_event) ci->platdata->notify_event(ci, CI_HDRC_CONTROLLER_STOPPED_EVENT); - ci->driver = NULL; spin_unlock_irqrestore(&ci->lock, flags); _gadget_stop_activity(&ci->gadget); spin_lock_irqsave(&ci->lock, flags); pm_runtime_put(&ci->gadget.dev); } + ci->driver = NULL; spin_unlock_irqrestore(&ci->lock, flags); return 0; diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 737e3c19967b..71dc5d768fa5 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -742,6 +742,22 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, if ((index & ~USB_DIR_IN) == 0) return 0; ret = findintfep(ps->dev, index); + if (ret < 0) { + /* + * Some not fully compliant Win apps seem to get + * index wrong and have the endpoint number here + * rather than the endpoint address (with the + * correct direction). Win does let this through, + * so we'll not reject it here but leave it to + * the device to not break KVM. But we warn. + */ + ret = findintfep(ps->dev, index ^ 0x80); + if (ret >= 0) + dev_info(&ps->dev->dev, + "%s: process %i (%s) requesting ep %02x but needs %02x\n", + __func__, task_pid_nr(current), + current->comm, index, index ^ 0x80); + } if (ret >= 0) ret = checkintf(ps, ret); break; diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index dde4c83516a1..e6b682c6c236 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -3426,6 +3426,9 @@ static int usb_req_set_sel(struct usb_device *udev, enum usb3_link_state state) unsigned long long u2_pel; int ret; + if (udev->state != USB_STATE_CONFIGURED) + return 0; + /* Convert SEL and PEL stored in ns to us */ u1_sel = DIV_ROUND_UP(udev->u1_params.sel, 1000); u1_pel = DIV_ROUND_UP(udev->u1_params.pel, 1000); diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index b870872e020f..70fc43027a5c 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -1,7 +1,6 @@ config USB_DWC3 tristate "DesignWare USB3 DRD Core Support" depends on (USB || USB_GADGET) && HAS_DMA - depends on EXTCON select USB_XHCI_PLATFORM if USB_SUPPORT && USB_XHCI_HCD help Say Y or M here if your system has a Dual Role SuperSpeed diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 9b138129e856..2e252aae51ca 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -28,6 +28,8 @@ /* FIXME define these in <linux/pci_ids.h> */ #define PCI_VENDOR_ID_SYNOPSYS 0x16c3 #define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 0xabcd +#define PCI_DEVICE_ID_INTEL_BYT 0x0f37 +#define PCI_DEVICE_ID_INTEL_MRFLD 0x119e struct dwc3_pci { struct device *dev; @@ -187,6 +189,8 @@ static DEFINE_PCI_DEVICE_TABLE(dwc3_pci_id_table) = { PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS, PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3), }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT), }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MRFLD), }, { } /* Terminating Entry */ }; MODULE_DEVICE_TABLE(pci, dwc3_pci_id_table); diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index f168eaebdef8..5452c0fce360 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2611,15 +2611,13 @@ int dwc3_gadget_init(struct dwc3 *dwc) ret = usb_add_gadget_udc(dwc->dev, &dwc->gadget); if (ret) { dev_err(dwc->dev, "failed to register udc\n"); - goto err5; + goto err4; } return 0; -err5: - dwc3_gadget_free_endpoints(dwc); - err4: + dwc3_gadget_free_endpoints(dwc); dma_free_coherent(dwc->dev, DWC3_EP0_BOUNCE_SIZE, dwc->ep0_bounce, dwc->ep0_bounce_addr); diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c index 5a5acf22c694..e126b6b248e6 100644 --- a/drivers/usb/gadget/cdc2.c +++ b/drivers/usb/gadget/cdc2.c @@ -113,12 +113,6 @@ static int __init cdc_do_config(struct usb_configuration *c) c->bmAttributes |= USB_CONFIG_ATT_WAKEUP; } - fi_ecm = usb_get_function_instance("ecm"); - if (IS_ERR(fi_ecm)) { - status = PTR_ERR(fi_ecm); - goto err_func_ecm; - } - f_ecm = usb_get_function(fi_ecm); if (IS_ERR(f_ecm)) { status = PTR_ERR(f_ecm); @@ -129,35 +123,24 @@ static int __init cdc_do_config(struct usb_configuration *c) if (status) goto err_add_ecm; - fi_serial = usb_get_function_instance("acm"); - if (IS_ERR(fi_serial)) { - status = PTR_ERR(fi_serial); - goto err_get_acm; - } - f_acm = usb_get_function(fi_serial); if (IS_ERR(f_acm)) { status = PTR_ERR(f_acm); - goto err_func_acm; + goto err_get_acm; } status = usb_add_function(c, f_acm); if (status) goto err_add_acm; - return 0; err_add_acm: usb_put_function(f_acm); -err_func_acm: - usb_put_function_instance(fi_serial); err_get_acm: usb_remove_function(c, f_ecm); err_add_ecm: usb_put_function(f_ecm); err_get_ecm: - usb_put_function_instance(fi_ecm); -err_func_ecm: return status; } diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 06ecd08fd57a..b8a2376971a4 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -923,8 +923,9 @@ static int dummy_udc_stop(struct usb_gadget *g, struct dummy_hcd *dum_hcd = gadget_to_dummy_hcd(g); struct dummy *dum = dum_hcd->dum; - dev_dbg(udc_dev(dum), "unregister gadget driver '%s'\n", - driver->driver.name); + if (driver) + dev_dbg(udc_dev(dum), "unregister gadget driver '%s'\n", + driver->driver.name); dum->driver = NULL; @@ -1000,8 +1001,8 @@ static int dummy_udc_remove(struct platform_device *pdev) { struct dummy *dum = platform_get_drvdata(pdev); - usb_del_gadget_udc(&dum->gadget); device_remove_file(&dum->gadget.dev, &dev_attr_function); + usb_del_gadget_udc(&dum->gadget); return 0; } diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c index edab45da3741..8d9e6f7e8f1a 100644 --- a/drivers/usb/gadget/f_ecm.c +++ b/drivers/usb/gadget/f_ecm.c @@ -995,7 +995,7 @@ static void ecm_unbind(struct usb_configuration *c, struct usb_function *f) usb_ep_free_request(ecm->notify, ecm->notify_req); } -struct usb_function *ecm_alloc(struct usb_function_instance *fi) +static struct usb_function *ecm_alloc(struct usb_function_instance *fi) { struct f_ecm *ecm; struct f_ecm_opts *opts; diff --git a/drivers/usb/gadget/f_eem.c b/drivers/usb/gadget/f_eem.c index d00392d879db..d61c11d765d0 100644 --- a/drivers/usb/gadget/f_eem.c +++ b/drivers/usb/gadget/f_eem.c @@ -624,7 +624,7 @@ static void eem_unbind(struct usb_configuration *c, struct usb_function *f) usb_free_all_descriptors(f); } -struct usb_function *eem_alloc(struct usb_function_instance *fi) +static struct usb_function *eem_alloc(struct usb_function_instance *fi) { struct f_eem *eem; struct f_eem_opts *opts; diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index 1a66c5baa0d1..0658908d8968 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c @@ -1034,37 +1034,19 @@ struct ffs_sb_fill_data { struct ffs_file_perms perms; umode_t root_mode; const char *dev_name; - union { - /* set by ffs_fs_mount(), read by ffs_sb_fill() */ - void *private_data; - /* set by ffs_sb_fill(), read by ffs_fs_mount */ - struct ffs_data *ffs_data; - }; + struct ffs_data *ffs_data; }; static int ffs_sb_fill(struct super_block *sb, void *_data, int silent) { struct ffs_sb_fill_data *data = _data; struct inode *inode; - struct ffs_data *ffs; + struct ffs_data *ffs = data->ffs_data; ENTER(); - /* Initialise data */ - ffs = ffs_data_new(); - if (unlikely(!ffs)) - goto Enomem; - ffs->sb = sb; - ffs->dev_name = kstrdup(data->dev_name, GFP_KERNEL); - if (unlikely(!ffs->dev_name)) - goto Enomem; - ffs->file_perms = data->perms; - ffs->private_data = data->private_data; - - /* used by the caller of this function */ - data->ffs_data = ffs; - + data->ffs_data = NULL; sb->s_fs_info = ffs; sb->s_blocksize = PAGE_CACHE_SIZE; sb->s_blocksize_bits = PAGE_CACHE_SHIFT; @@ -1080,17 +1062,14 @@ static int ffs_sb_fill(struct super_block *sb, void *_data, int silent) &data->perms); sb->s_root = d_make_root(inode); if (unlikely(!sb->s_root)) - goto Enomem; + return -ENOMEM; /* EP0 file */ if (unlikely(!ffs_sb_create_file(sb, "ep0", ffs, &ffs_ep0_operations, NULL))) - goto Enomem; + return -ENOMEM; return 0; - -Enomem: - return -ENOMEM; } static int ffs_fs_parse_opts(struct ffs_sb_fill_data *data, char *opts) @@ -1193,6 +1172,7 @@ ffs_fs_mount(struct file_system_type *t, int flags, struct dentry *rv; int ret; void *ffs_dev; + struct ffs_data *ffs; ENTER(); @@ -1200,18 +1180,30 @@ ffs_fs_mount(struct file_system_type *t, int flags, if (unlikely(ret < 0)) return ERR_PTR(ret); + ffs = ffs_data_new(); + if (unlikely(!ffs)) + return ERR_PTR(-ENOMEM); + ffs->file_perms = data.perms; + + ffs->dev_name = kstrdup(dev_name, GFP_KERNEL); + if (unlikely(!ffs->dev_name)) { + ffs_data_put(ffs); + return ERR_PTR(-ENOMEM); + } + ffs_dev = functionfs_acquire_dev_callback(dev_name); - if (IS_ERR(ffs_dev)) - return ffs_dev; + if (IS_ERR(ffs_dev)) { + ffs_data_put(ffs); + return ERR_CAST(ffs_dev); + } + ffs->private_data = ffs_dev; + data.ffs_data = ffs; - data.dev_name = dev_name; - data.private_data = ffs_dev; rv = mount_nodev(t, flags, &data, ffs_sb_fill); - - /* data.ffs_data is set by ffs_sb_fill */ - if (IS_ERR(rv)) + if (IS_ERR(rv) && data.ffs_data) { functionfs_release_dev_callback(data.ffs_data); - + ffs_data_put(data.ffs_data); + } return rv; } diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 313b835eedfd..a01d7d38c016 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -2260,10 +2260,12 @@ reset: /* Disable the endpoints */ if (fsg->bulk_in_enabled) { usb_ep_disable(fsg->bulk_in); + fsg->bulk_in->driver_data = NULL; fsg->bulk_in_enabled = 0; } if (fsg->bulk_out_enabled) { usb_ep_disable(fsg->bulk_out); + fsg->bulk_out->driver_data = NULL; fsg->bulk_out_enabled = 0; } diff --git a/drivers/usb/gadget/fotg210-udc.c b/drivers/usb/gadget/fotg210-udc.c index 32db2eee2d87..bbbfd1948778 100644 --- a/drivers/usb/gadget/fotg210-udc.c +++ b/drivers/usb/gadget/fotg210-udc.c @@ -1214,6 +1214,6 @@ static struct platform_driver fotg210_driver = { module_platform_driver(fotg210_driver); -MODULE_AUTHOR("Yuan-Hsin Chen <yhchen@faraday-tech.com>"); +MODULE_AUTHOR("Yuan-Hsin Chen, Feng-Hsin Chiang <john453@faraday-tech.com>"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION(DRIVER_DESC); diff --git a/drivers/usb/gadget/fusb300_udc.c b/drivers/usb/gadget/fusb300_udc.c index f1dd6daabe21..b278abe52453 100644 --- a/drivers/usb/gadget/fusb300_udc.c +++ b/drivers/usb/gadget/fusb300_udc.c @@ -22,7 +22,7 @@ MODULE_DESCRIPTION("FUSB300 USB gadget driver"); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Yuan Hsin Chen <yhchen@faraday-tech.com>"); +MODULE_AUTHOR("Yuan-Hsin Chen, Feng-Hsin Chiang <john453@faraday-tech.com>"); MODULE_ALIAS("platform:fusb300_udc"); #define DRIVER_VERSION "20 October 2010" diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c index 2a1ebefd8f9e..23393254a8a3 100644 --- a/drivers/usb/gadget/multi.c +++ b/drivers/usb/gadget/multi.c @@ -179,7 +179,7 @@ err_conf: return ret; } -static int rndis_config_register(struct usb_composite_dev *cdev) +static __ref int rndis_config_register(struct usb_composite_dev *cdev) { static struct usb_configuration config = { .bConfigurationValue = MULTI_RNDIS_CONFIG_NUM, @@ -194,7 +194,7 @@ static int rndis_config_register(struct usb_composite_dev *cdev) #else -static int rndis_config_register(struct usb_composite_dev *cdev) +static __ref int rndis_config_register(struct usb_composite_dev *cdev) { return 0; } @@ -241,7 +241,7 @@ err_conf: return ret; } -static int cdc_config_register(struct usb_composite_dev *cdev) +static __ref int cdc_config_register(struct usb_composite_dev *cdev) { static struct usb_configuration config = { .bConfigurationValue = MULTI_CDC_CONFIG_NUM, @@ -256,7 +256,7 @@ static int cdc_config_register(struct usb_composite_dev *cdev) #else -static int cdc_config_register(struct usb_composite_dev *cdev) +static __ref int cdc_config_register(struct usb_composite_dev *cdev) { return 0; } diff --git a/drivers/usb/gadget/mv_u3d_core.c b/drivers/usb/gadget/mv_u3d_core.c index bbb6e98c4384..561b30efb8ee 100644 --- a/drivers/usb/gadget/mv_u3d_core.c +++ b/drivers/usb/gadget/mv_u3d_core.c @@ -645,6 +645,7 @@ static int mv_u3d_ep_disable(struct usb_ep *_ep) struct mv_u3d_ep *ep; struct mv_u3d_ep_context *ep_context; u32 epxcr, direction; + unsigned long flags; if (!_ep) return -EINVAL; @@ -661,7 +662,9 @@ static int mv_u3d_ep_disable(struct usb_ep *_ep) direction = mv_u3d_ep_dir(ep); /* nuke all pending requests (does flush) */ + spin_lock_irqsave(&u3d->lock, flags); mv_u3d_nuke(ep, -ESHUTDOWN); + spin_unlock_irqrestore(&u3d->lock, flags); /* Disable the endpoint for Rx or Tx and reset the endpoint type */ if (direction == MV_U3D_EP_DIR_OUT) { diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index d69b36a99dbc..6bddf1aa2347 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -2475,8 +2475,6 @@ irq_retry: if (gintsts & GINTSTS_ErlySusp) { dev_dbg(hsotg->dev, "GINTSTS_ErlySusp\n"); writel(GINTSTS_ErlySusp, hsotg->regs + GINTSTS); - - s3c_hsotg_disconnect(hsotg); } /* @@ -2962,9 +2960,6 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget, if (!hsotg) return -ENODEV; - if (!driver || driver != hsotg->driver || !driver->unbind) - return -EINVAL; - /* all endpoints should be shutdown */ for (ep = 0; ep < hsotg->num_of_eps; ep++) s3c_hsotg_ep_disable(&hsotg->eps[ep].ep); @@ -2972,15 +2967,15 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget, spin_lock_irqsave(&hsotg->lock, flags); s3c_hsotg_phy_disable(hsotg); - regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); - hsotg->driver = NULL; + if (!driver) + hsotg->driver = NULL; + hsotg->gadget.speed = USB_SPEED_UNKNOWN; spin_unlock_irqrestore(&hsotg->lock, flags); - dev_info(hsotg->dev, "unregistered gadget driver '%s'\n", - driver->driver.name); + regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); return 0; } diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 947b009009f1..f2407b2e8a99 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -130,7 +130,7 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver, } /* Enable USB controller, 83xx or 8536 */ - if (pdata->have_sysif_regs) + if (pdata->have_sysif_regs && pdata->controller_ver < FSL_USB_VER_1_6) setbits32(hcd->regs + FSL_SOC_USB_CTRL, 0x4); /* Don't need to set host mode here. It will be done by tdi_reset() */ @@ -232,15 +232,9 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd, case FSL_USB2_PHY_ULPI: if (pdata->have_sysif_regs && pdata->controller_ver) { /* controller version 1.6 or above */ + clrbits32(non_ehci + FSL_SOC_USB_CTRL, UTMI_PHY_EN); setbits32(non_ehci + FSL_SOC_USB_CTRL, - ULPI_PHY_CLK_SEL); - /* - * Due to controller issue of PHY_CLK_VALID in ULPI - * mode, we set USB_CTRL_USB_EN before checking - * PHY_CLK_VALID, otherwise PHY_CLK_VALID doesn't work. - */ - clrsetbits_be32(non_ehci + FSL_SOC_USB_CTRL, - UTMI_PHY_EN, USB_CTRL_USB_EN); + ULPI_PHY_CLK_SEL | USB_CTRL_USB_EN); } portsc |= PORT_PTS_ULPI; break; @@ -270,8 +264,9 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd, if (pdata->have_sysif_regs && pdata->controller_ver && (phy_mode == FSL_USB2_PHY_ULPI)) { /* check PHY_CLK_VALID to get phy clk valid */ - if (!spin_event_timeout(in_be32(non_ehci + FSL_SOC_USB_CTRL) & - PHY_CLK_VALID, FSL_USB_PHY_CLK_TIMEOUT, 0)) { + if (!(spin_event_timeout(in_be32(non_ehci + FSL_SOC_USB_CTRL) & + PHY_CLK_VALID, FSL_USB_PHY_CLK_TIMEOUT, 0) || + in_be32(non_ehci + FSL_SOC_USB_PRICTRL))) { printk(KERN_WARNING "fsl-ehci: USB PHY clock invalid\n"); return -EINVAL; } @@ -669,7 +664,7 @@ static const struct hc_driver ehci_fsl_hc_driver = { * generic hardware linkage */ .irq = ehci_irq, - .flags = HCD_USB2 | HCD_MEMORY | HCD_BH, + .flags = HCD_USB2 | HCD_MEMORY, /* * basic lifecycle operations diff --git a/drivers/usb/host/ehci-grlib.c b/drivers/usb/host/ehci-grlib.c index b52a66ce92e8..83ab51af250f 100644 --- a/drivers/usb/host/ehci-grlib.c +++ b/drivers/usb/host/ehci-grlib.c @@ -43,7 +43,7 @@ static const struct hc_driver ehci_grlib_hc_driver = { * generic hardware linkage */ .irq = ehci_irq, - .flags = HCD_MEMORY | HCD_USB2 | HCD_BH, + .flags = HCD_MEMORY | HCD_USB2, /* * basic lifecycle operations diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 5d6022f30ebe..86ab9fd9fe9e 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1158,7 +1158,7 @@ static const struct hc_driver ehci_hc_driver = { * generic hardware linkage */ .irq = ehci_irq, - .flags = HCD_MEMORY | HCD_USB2 | HCD_BH, + .flags = HCD_MEMORY | HCD_USB2, /* * basic lifecycle operations diff --git a/drivers/usb/host/ehci-mv.c b/drivers/usb/host/ehci-mv.c index 417c10da9450..35cdbd88bbbe 100644 --- a/drivers/usb/host/ehci-mv.c +++ b/drivers/usb/host/ehci-mv.c @@ -96,7 +96,7 @@ static const struct hc_driver mv_ehci_hc_driver = { * generic hardware linkage */ .irq = ehci_irq, - .flags = HCD_MEMORY | HCD_USB2 | HCD_BH, + .flags = HCD_MEMORY | HCD_USB2, /* * basic lifecycle operations diff --git a/drivers/usb/host/ehci-octeon.c b/drivers/usb/host/ehci-octeon.c index ab0397e4d8f3..45cc00158412 100644 --- a/drivers/usb/host/ehci-octeon.c +++ b/drivers/usb/host/ehci-octeon.c @@ -51,7 +51,7 @@ static const struct hc_driver ehci_octeon_hc_driver = { * generic hardware linkage */ .irq = ehci_irq, - .flags = HCD_MEMORY | HCD_USB2 | HCD_BH, + .flags = HCD_MEMORY | HCD_USB2, /* * basic lifecycle operations diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 6bd299e61f58..854c2ec7b699 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -361,7 +361,7 @@ static struct pci_driver ehci_pci_driver = { .remove = usb_hcd_pci_remove, .shutdown = usb_hcd_pci_shutdown, -#ifdef CONFIG_PM_SLEEP +#ifdef CONFIG_PM .driver = { .pm = &usb_hcd_pci_pm_ops }, diff --git a/drivers/usb/host/ehci-pmcmsp.c b/drivers/usb/host/ehci-pmcmsp.c index 893b707f0000..601e208bd782 100644 --- a/drivers/usb/host/ehci-pmcmsp.c +++ b/drivers/usb/host/ehci-pmcmsp.c @@ -286,7 +286,7 @@ static const struct hc_driver ehci_msp_hc_driver = { #else .irq = ehci_irq, #endif - .flags = HCD_MEMORY | HCD_USB2 | HCD_BH, + .flags = HCD_MEMORY | HCD_USB2, /* * basic lifecycle operations diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c index 6cc5567bf9c8..932293fa32de 100644 --- a/drivers/usb/host/ehci-ppc-of.c +++ b/drivers/usb/host/ehci-ppc-of.c @@ -28,7 +28,7 @@ static const struct hc_driver ehci_ppc_of_hc_driver = { * generic hardware linkage */ .irq = ehci_irq, - .flags = HCD_MEMORY | HCD_USB2 | HCD_BH, + .flags = HCD_MEMORY | HCD_USB2, /* * basic lifecycle operations diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c index 8188542ba17e..fd983771b025 100644 --- a/drivers/usb/host/ehci-ps3.c +++ b/drivers/usb/host/ehci-ps3.c @@ -71,7 +71,7 @@ static const struct hc_driver ps3_ehci_hc_driver = { .product_desc = "PS3 EHCI Host Controller", .hcd_priv_size = sizeof(struct ehci_hcd), .irq = ehci_irq, - .flags = HCD_MEMORY | HCD_USB2 | HCD_BH, + .flags = HCD_MEMORY | HCD_USB2, .reset = ps3_ehci_hc_reset, .start = ehci_run, .stop = ehci_stop, diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index e321804c3475..a7f776a13eb1 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -247,6 +247,8 @@ static int qtd_copy_status ( static void ehci_urb_done(struct ehci_hcd *ehci, struct urb *urb, int status) +__releases(ehci->lock) +__acquires(ehci->lock) { if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT) { /* ... update hc-wide periodic stats */ @@ -272,8 +274,11 @@ ehci_urb_done(struct ehci_hcd *ehci, struct urb *urb, int status) urb->actual_length, urb->transfer_buffer_length); #endif + /* complete() can reenter this HCD */ usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb); + spin_unlock (&ehci->lock); usb_hcd_giveback_urb(ehci_to_hcd(ehci), urb, status); + spin_lock (&ehci->lock); } static int qh_schedule (struct ehci_hcd *ehci, struct ehci_qh *qh); diff --git a/drivers/usb/host/ehci-sead3.c b/drivers/usb/host/ehci-sead3.c index 8a734498079b..b2de52d39614 100644 --- a/drivers/usb/host/ehci-sead3.c +++ b/drivers/usb/host/ehci-sead3.c @@ -55,7 +55,7 @@ const struct hc_driver ehci_sead3_hc_driver = { * generic hardware linkage */ .irq = ehci_irq, - .flags = HCD_MEMORY | HCD_USB2 | HCD_BH, + .flags = HCD_MEMORY | HCD_USB2, /* * basic lifecycle operations diff --git a/drivers/usb/host/ehci-sh.c b/drivers/usb/host/ehci-sh.c index dc899eb2b861..93e59a13bc1f 100644 --- a/drivers/usb/host/ehci-sh.c +++ b/drivers/usb/host/ehci-sh.c @@ -36,7 +36,7 @@ static const struct hc_driver ehci_sh_hc_driver = { * generic hardware linkage */ .irq = ehci_irq, - .flags = HCD_USB2 | HCD_MEMORY | HCD_BH, + .flags = HCD_USB2 | HCD_MEMORY, /* * basic lifecycle operations diff --git a/drivers/usb/host/ehci-tilegx.c b/drivers/usb/host/ehci-tilegx.c index 67026ffbf9a8..cca4be90a864 100644 --- a/drivers/usb/host/ehci-tilegx.c +++ b/drivers/usb/host/ehci-tilegx.c @@ -61,7 +61,7 @@ static const struct hc_driver ehci_tilegx_hc_driver = { * Generic hardware linkage. */ .irq = ehci_irq, - .flags = HCD_MEMORY | HCD_USB2 | HCD_BH, + .flags = HCD_MEMORY | HCD_USB2, /* * Basic lifecycle operations. diff --git a/drivers/usb/host/ehci-w90x900.c b/drivers/usb/host/ehci-w90x900.c index 1c370dfbee0d..59e0e24c753f 100644 --- a/drivers/usb/host/ehci-w90x900.c +++ b/drivers/usb/host/ehci-w90x900.c @@ -108,7 +108,7 @@ static const struct hc_driver ehci_w90x900_hc_driver = { * generic hardware linkage */ .irq = ehci_irq, - .flags = HCD_USB2|HCD_MEMORY|HCD_BH, + .flags = HCD_USB2|HCD_MEMORY, /* * basic lifecycle operations diff --git a/drivers/usb/host/ehci-xilinx-of.c b/drivers/usb/host/ehci-xilinx-of.c index 95979f9f4381..eba962e6ebfb 100644 --- a/drivers/usb/host/ehci-xilinx-of.c +++ b/drivers/usb/host/ehci-xilinx-of.c @@ -79,7 +79,7 @@ static const struct hc_driver ehci_xilinx_of_hc_driver = { * generic hardware linkage */ .irq = ehci_irq, - .flags = HCD_MEMORY | HCD_USB2 | HCD_BH, + .flags = HCD_MEMORY | HCD_USB2, /* * basic lifecycle operations diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c index 9e0020d9e4c8..abd5050a4899 100644 --- a/drivers/usb/host/fsl-mph-dr-of.c +++ b/drivers/usb/host/fsl-mph-dr-of.c @@ -24,7 +24,7 @@ struct fsl_usb2_dev_data { enum fsl_usb2_operating_modes op_mode; /* operating mode */ }; -struct fsl_usb2_dev_data dr_mode_data[] = { +static struct fsl_usb2_dev_data dr_mode_data[] = { { .dr_mode = "host", .drivers = { "fsl-ehci", NULL, NULL, }, @@ -42,7 +42,7 @@ struct fsl_usb2_dev_data dr_mode_data[] = { }, }; -struct fsl_usb2_dev_data *get_dr_mode_data(struct device_node *np) +static struct fsl_usb2_dev_data *get_dr_mode_data(struct device_node *np) { const unsigned char *prop; int i; @@ -75,7 +75,7 @@ static enum fsl_usb2_phy_modes determine_usb_phy(const char *phy_type) return FSL_USB2_PHY_NONE; } -struct platform_device *fsl_usb2_device_register( +static struct platform_device *fsl_usb2_device_register( struct platform_device *ofdev, struct fsl_usb2_platform_data *pdata, const char *name, int id) diff --git a/drivers/usb/host/imx21-hcd.c b/drivers/usb/host/imx21-hcd.c index 60a5de505ca1..adb01d950a16 100644 --- a/drivers/usb/host/imx21-hcd.c +++ b/drivers/usb/host/imx21-hcd.c @@ -824,13 +824,13 @@ static int imx21_hc_urb_enqueue_isoc(struct usb_hcd *hcd, i = DIV_ROUND_UP(wrap_frame( cur_frame - urb->start_frame), urb->interval); - if (urb->transfer_flags & URB_ISO_ASAP) { + + /* Treat underruns as if URB_ISO_ASAP was set */ + if ((urb->transfer_flags & URB_ISO_ASAP) || + i >= urb->number_of_packets) { urb->start_frame = wrap_frame(urb->start_frame + i * urb->interval); i = 0; - } else if (i >= urb->number_of_packets) { - ret = -EXDEV; - goto alloc_dmem_failed; } } } diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 8f6b695af6a4..604cad1bcf9c 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -216,31 +216,26 @@ static int ohci_urb_enqueue ( frame &= ~(ed->interval - 1); frame |= ed->branch; urb->start_frame = frame; + ed->last_iso = frame + ed->interval * (size - 1); } } else if (ed->type == PIPE_ISOCHRONOUS) { u16 next = ohci_frame_no(ohci) + 1; u16 frame = ed->last_iso + ed->interval; + u16 length = ed->interval * (size - 1); /* Behind the scheduling threshold? */ if (unlikely(tick_before(frame, next))) { - /* USB_ISO_ASAP: Round up to the first available slot */ + /* URB_ISO_ASAP: Round up to the first available slot */ if (urb->transfer_flags & URB_ISO_ASAP) { frame += (next - frame + ed->interval - 1) & -ed->interval; /* - * Not ASAP: Use the next slot in the stream. If - * the entire URB falls before the threshold, fail. + * Not ASAP: Use the next slot in the stream, + * no matter what. */ } else { - if (tick_before(frame + ed->interval * - (urb->number_of_packets - 1), next)) { - retval = -EXDEV; - usb_hcd_unlink_urb_from_ep(hcd, urb); - goto fail; - } - /* * Some OHCI hardware doesn't handle late TDs * correctly. After retiring them it proceeds @@ -251,9 +246,16 @@ static int ohci_urb_enqueue ( urb_priv->td_cnt = DIV_ROUND_UP( (u16) (next - frame), ed->interval); + if (urb_priv->td_cnt >= urb_priv->length) { + ++urb_priv->td_cnt; /* Mark it */ + ohci_dbg(ohci, "iso underrun %p (%u+%u < %u)\n", + urb, frame, length, + next); + } } } urb->start_frame = frame; + ed->last_iso = frame + length; } /* fill the TDs and link them to the ed; and diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index df4a6707322d..e7f577e63624 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c @@ -41,9 +41,13 @@ finish_urb(struct ohci_hcd *ohci, struct urb *urb, int status) __releases(ohci->lock) __acquires(ohci->lock) { - struct device *dev = ohci_to_hcd(ohci)->self.controller; + struct device *dev = ohci_to_hcd(ohci)->self.controller; + struct usb_host_endpoint *ep = urb->ep; + struct urb_priv *urb_priv; + // ASSERT (urb->hcpriv != 0); + restart: urb_free_priv (ohci, urb->hcpriv); urb->hcpriv = NULL; if (likely(status == -EINPROGRESS)) @@ -80,6 +84,21 @@ __acquires(ohci->lock) ohci->hc_control &= ~(OHCI_CTRL_PLE|OHCI_CTRL_IE); ohci_writel (ohci, ohci->hc_control, &ohci->regs->control); } + + /* + * An isochronous URB that is sumitted too late won't have any TDs + * (marked by the fact that the td_cnt value is larger than the + * actual number of TDs). If the next URB on this endpoint is like + * that, give it back now. + */ + if (!list_empty(&ep->urb_list)) { + urb = list_first_entry(&ep->urb_list, struct urb, urb_list); + urb_priv = urb->hcpriv; + if (urb_priv->td_cnt > urb_priv->length) { + status = 0; + goto restart; + } + } } @@ -546,7 +565,6 @@ td_fill (struct ohci_hcd *ohci, u32 info, td->hwCBP = cpu_to_hc32 (ohci, data & 0xFFFFF000); *ohci_hwPSWp(ohci, td, 0) = cpu_to_hc16 (ohci, (data & 0x0FFF) | 0xE000); - td->ed->last_iso = info & 0xffff; } else { td->hwCBP = cpu_to_hc32 (ohci, data); } @@ -996,7 +1014,7 @@ rescan_this: urb_priv->td_cnt++; /* if URB is done, clean up */ - if (urb_priv->td_cnt == urb_priv->length) { + if (urb_priv->td_cnt >= urb_priv->length) { modified = completed = 1; finish_urb(ohci, urb, 0); } @@ -1086,7 +1104,7 @@ static void takeback_td(struct ohci_hcd *ohci, struct td *td) urb_priv->td_cnt++; /* If all this urb's TDs are done, call complete() */ - if (urb_priv->td_cnt == urb_priv->length) + if (urb_priv->td_cnt >= urb_priv->length) finish_urb(ohci, urb, status); /* clean schedule: unlink EDs that are no longer busy */ diff --git a/drivers/usb/host/uhci-pci.c b/drivers/usb/host/uhci-pci.c index c300bd2f7d1c..0f228c46eeda 100644 --- a/drivers/usb/host/uhci-pci.c +++ b/drivers/usb/host/uhci-pci.c @@ -293,7 +293,7 @@ static struct pci_driver uhci_pci_driver = { .remove = usb_hcd_pci_remove, .shutdown = uhci_shutdown, -#ifdef CONFIG_PM_SLEEP +#ifdef CONFIG_PM .driver = { .pm = &usb_hcd_pci_pm_ops }, diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index 041c6ddb695c..da6f56d996ce 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c @@ -1303,7 +1303,7 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb, } /* Fell behind? */ - if (uhci_frame_before_eq(frame, next)) { + if (!uhci_frame_before_eq(next, frame)) { /* USB_ISO_ASAP: Round up to the first available slot */ if (urb->transfer_flags & URB_ISO_ASAP) @@ -1311,13 +1311,17 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb, -qh->period; /* - * Not ASAP: Use the next slot in the stream. If - * the entire URB falls before the threshold, fail. + * Not ASAP: Use the next slot in the stream, + * no matter what. */ else if (!uhci_frame_before_eq(next, frame + (urb->number_of_packets - 1) * qh->period)) - return -EXDEV; + dev_dbg(uhci_dev(uhci), "iso underrun %p (%u+%u < %u)\n", + urb, frame, + (urb->number_of_packets - 1) * + qh->period, + next); } } diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index fae697ed0b70..773a6b28c4f1 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -287,7 +287,7 @@ static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend) if (virt_dev->eps[i].ring && virt_dev->eps[i].ring->dequeue) xhci_queue_stop_endpoint(xhci, slot_id, i, suspend); } - cmd->command_trb = xhci->cmd_ring->enqueue; + cmd->command_trb = xhci_find_next_enqueue(xhci->cmd_ring); list_add_tail(&cmd->cmd_list, &virt_dev->cmd_list); xhci_queue_stop_endpoint(xhci, slot_id, 0, suspend); xhci_ring_cmd_db(xhci); @@ -552,11 +552,15 @@ void xhci_del_comp_mod_timer(struct xhci_hcd *xhci, u32 status, u16 wIndex) * - Mark a port as being done with device resume, * and ring the endpoint doorbells. * - Stop the Synopsys redriver Compliance Mode polling. + * - Drop and reacquire the xHCI lock, in order to wait for port resume. */ static u32 xhci_get_port_status(struct usb_hcd *hcd, struct xhci_bus_state *bus_state, __le32 __iomem **port_array, - u16 wIndex, u32 raw_port_status) + u16 wIndex, u32 raw_port_status, + unsigned long flags) + __releases(&xhci->lock) + __acquires(&xhci->lock) { struct xhci_hcd *xhci = hcd_to_xhci(hcd); u32 status = 0; @@ -591,21 +595,42 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd, return 0xffffffff; if (time_after_eq(jiffies, bus_state->resume_done[wIndex])) { + int time_left; + xhci_dbg(xhci, "Resume USB2 port %d\n", wIndex + 1); bus_state->resume_done[wIndex] = 0; clear_bit(wIndex, &bus_state->resuming_ports); + + set_bit(wIndex, &bus_state->rexit_ports); xhci_set_link_state(xhci, port_array, wIndex, XDEV_U0); - xhci_dbg(xhci, "set port %d resume\n", - wIndex + 1); - slot_id = xhci_find_slot_id_by_port(hcd, xhci, - wIndex + 1); - if (!slot_id) { - xhci_dbg(xhci, "slot_id is zero\n"); - return 0xffffffff; + + spin_unlock_irqrestore(&xhci->lock, flags); + time_left = wait_for_completion_timeout( + &bus_state->rexit_done[wIndex], + msecs_to_jiffies( + XHCI_MAX_REXIT_TIMEOUT)); + spin_lock_irqsave(&xhci->lock, flags); + + if (time_left) { + slot_id = xhci_find_slot_id_by_port(hcd, + xhci, wIndex + 1); + if (!slot_id) { + xhci_dbg(xhci, "slot_id is zero\n"); + return 0xffffffff; + } + xhci_ring_device(xhci, slot_id); + } else { + int port_status = xhci_readl(xhci, + port_array[wIndex]); + xhci_warn(xhci, "Port resume took longer than %i msec, port status = 0x%x\n", + XHCI_MAX_REXIT_TIMEOUT, + port_status); + status |= USB_PORT_STAT_SUSPEND; + clear_bit(wIndex, &bus_state->rexit_ports); } - xhci_ring_device(xhci, slot_id); + bus_state->port_c_suspend |= 1 << wIndex; bus_state->suspended_ports &= ~(1 << wIndex); } else { @@ -728,7 +753,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, break; } status = xhci_get_port_status(hcd, bus_state, port_array, - wIndex, temp); + wIndex, temp, flags); if (status == 0xffffffff) goto error; diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 53b972c2a09f..83bcd13622c3 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -2428,6 +2428,8 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) for (i = 0; i < USB_MAXCHILDREN; ++i) { xhci->bus_state[0].resume_done[i] = 0; xhci->bus_state[1].resume_done[i] = 0; + /* Only the USB 2.0 completions will ever be used. */ + init_completion(&xhci->bus_state[1].rexit_done[i]); } if (scratchpad_alloc(xhci, flags)) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index c2d495057eb5..236c3aabe940 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -351,7 +351,7 @@ static struct pci_driver xhci_pci_driver = { /* suspend and resume implemented later */ .shutdown = usb_hcd_pci_shutdown, -#ifdef CONFIG_PM_SLEEP +#ifdef CONFIG_PM .driver = { .pm = &usb_hcd_pci_pm_ops }, diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 411da1fc7ae8..6bfbd80ec2b9 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -123,6 +123,16 @@ static int enqueue_is_link_trb(struct xhci_ring *ring) return TRB_TYPE_LINK_LE32(link->control); } +union xhci_trb *xhci_find_next_enqueue(struct xhci_ring *ring) +{ + /* Enqueue pointer can be left pointing to the link TRB, + * we must handle that + */ + if (TRB_TYPE_LINK_LE32(ring->enqueue->link.control)) + return ring->enq_seg->next->trbs; + return ring->enqueue; +} + /* Updates trb to point to the next TRB in the ring, and updates seg if the next * TRB is in a new segment. This does not skip over link TRBs, and it does not * effect the ring dequeue or enqueue pointers. @@ -859,8 +869,12 @@ remove_finished_td: /* Otherwise ring the doorbell(s) to restart queued transfers */ ring_doorbell_for_active_rings(xhci, slot_id, ep_index); } - ep->stopped_td = NULL; - ep->stopped_trb = NULL; + + /* Clear stopped_td and stopped_trb if endpoint is not halted */ + if (!(ep->ep_state & EP_HALTED)) { + ep->stopped_td = NULL; + ep->stopped_trb = NULL; + } /* * Drop the lock and complete the URBs in the cancelled TD list. @@ -1414,6 +1428,12 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, inc_deq(xhci, xhci->cmd_ring); return; } + /* There is no command to handle if we get a stop event when the + * command ring is empty, event->cmd_trb points to the next + * unset command + */ + if (xhci->cmd_ring->dequeue == xhci->cmd_ring->enqueue) + return; } switch (le32_to_cpu(xhci->cmd_ring->dequeue->generic.field[3]) @@ -1743,6 +1763,19 @@ static void handle_port_status(struct xhci_hcd *xhci, } } + /* + * Check to see if xhci-hub.c is waiting on RExit to U0 transition (or + * RExit to a disconnect state). If so, let the the driver know it's + * out of the RExit state. + */ + if (!DEV_SUPERSPEED(temp) && + test_and_clear_bit(faked_port_index, + &bus_state->rexit_ports)) { + complete(&bus_state->rexit_done[faked_port_index]); + bogus_port_status = true; + goto cleanup; + } + if (hcd->speed != HCD_USB3) xhci_test_and_clear_bit(xhci, port_array, faked_port_index, PORT_PLC); diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 49b6edb84a79..1e36dbb48366 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -2598,15 +2598,7 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, if (command) { cmd_completion = command->completion; cmd_status = &command->status; - command->command_trb = xhci->cmd_ring->enqueue; - - /* Enqueue pointer can be left pointing to the link TRB, - * we must handle that - */ - if (TRB_TYPE_LINK_LE32(command->command_trb->link.control)) - command->command_trb = - xhci->cmd_ring->enq_seg->next->trbs; - + command->command_trb = xhci_find_next_enqueue(xhci->cmd_ring); list_add_tail(&command->cmd_list, &virt_dev->cmd_list); } else { cmd_completion = &virt_dev->cmd_completion; @@ -2614,7 +2606,7 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, } init_completion(cmd_completion); - cmd_trb = xhci->cmd_ring->dequeue; + cmd_trb = xhci_find_next_enqueue(xhci->cmd_ring); if (!ctx_change) ret = xhci_queue_configure_endpoint(xhci, in_ctx->dma, udev->slot_id, must_succeed); @@ -3439,14 +3431,7 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev) /* Attempt to submit the Reset Device command to the command ring */ spin_lock_irqsave(&xhci->lock, flags); - reset_device_cmd->command_trb = xhci->cmd_ring->enqueue; - - /* Enqueue pointer can be left pointing to the link TRB, - * we must handle that - */ - if (TRB_TYPE_LINK_LE32(reset_device_cmd->command_trb->link.control)) - reset_device_cmd->command_trb = - xhci->cmd_ring->enq_seg->next->trbs; + reset_device_cmd->command_trb = xhci_find_next_enqueue(xhci->cmd_ring); list_add_tail(&reset_device_cmd->cmd_list, &virt_dev->cmd_list); ret = xhci_queue_reset_device(xhci, slot_id); @@ -3650,7 +3635,7 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) union xhci_trb *cmd_trb; spin_lock_irqsave(&xhci->lock, flags); - cmd_trb = xhci->cmd_ring->dequeue; + cmd_trb = xhci_find_next_enqueue(xhci->cmd_ring); ret = xhci_queue_slot_control(xhci, TRB_ENABLE_SLOT, 0); if (ret) { spin_unlock_irqrestore(&xhci->lock, flags); @@ -3785,7 +3770,7 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) slot_ctx->dev_info >> 27); spin_lock_irqsave(&xhci->lock, flags); - cmd_trb = xhci->cmd_ring->dequeue; + cmd_trb = xhci_find_next_enqueue(xhci->cmd_ring); ret = xhci_queue_address_device(xhci, virt_dev->in_ctx->dma, udev->slot_id); if (ret) { diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 46aa14894148..289fbfbae746 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1412,8 +1412,18 @@ struct xhci_bus_state { unsigned long resume_done[USB_MAXCHILDREN]; /* which ports have started to resume */ unsigned long resuming_ports; + /* Which ports are waiting on RExit to U0 transition. */ + unsigned long rexit_ports; + struct completion rexit_done[USB_MAXCHILDREN]; }; + +/* + * It can take up to 20 ms to transition from RExit to U0 on the + * Intel Lynx Point LP xHCI host. + */ +#define XHCI_MAX_REXIT_TIMEOUT (20 * 1000) + static inline unsigned int hcd_index(struct usb_hcd *hcd) { if (hcd->speed == HCD_USB3) @@ -1840,6 +1850,7 @@ int xhci_cancel_cmd(struct xhci_hcd *xhci, struct xhci_command *command, union xhci_trb *cmd_trb); void xhci_ring_ep_doorbell(struct xhci_hcd *xhci, unsigned int slot_id, unsigned int ep_index, unsigned int stream_id); +union xhci_trb *xhci_find_next_enqueue(struct xhci_ring *ring); /* xHCI roothub code */ void xhci_set_link_state(struct xhci_hcd *xhci, __le32 __iomem **port_array, diff --git a/drivers/usb/phy/phy-omap-usb3.c b/drivers/usb/phy/phy-omap-usb3.c index fc15694d3031..4e8a0405f956 100644 --- a/drivers/usb/phy/phy-omap-usb3.c +++ b/drivers/usb/phy/phy-omap-usb3.c @@ -79,7 +79,7 @@ static struct usb_dpll_params *omap_usb3_get_dpll_params(unsigned long rate) return &dpll_map[i].params; } - return 0; + return NULL; } static int omap_usb3_suspend(struct usb_phy *x, int suspend) diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index c454bfa22a10..ddb9c51f2c99 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig @@ -60,7 +60,7 @@ config USB_SERIAL_SIMPLE - Suunto ANT+ USB device. - Fundamental Software dongle. - HP4x calculators - - a number of Motoroloa phones + - a number of Motorola phones - Siemens USB/MPI adapter. - ViVOtech ViVOpay USB device. - Infineon Modem Flashloader USB interface diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index e7a84f0f5179..bedf8e47713b 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -139,6 +139,7 @@ enum pl2303_type { HX_TA, /* HX(A) / X(A) / TA version */ /* TODO: improve */ HXD_EA_RA_SA, /* HXD / EA / RA / SA version */ /* TODO: improve */ TB, /* TB version */ + HX_CLONE, /* Cheap and less functional clone of the HX chip */ }; /* * NOTE: don't know the difference between type 0 and type 1, @@ -206,8 +207,23 @@ static int pl2303_startup(struct usb_serial *serial) * the device descriptors of the X/HX, HXD, EA, RA, SA, TA, TB */ if (le16_to_cpu(serial->dev->descriptor.bcdDevice) == 0x300) { - type = HX_TA; - type_str = "X/HX/TA"; + /* Check if the device is a clone */ + pl2303_vendor_read(0x9494, 0, serial, buf); + /* + * NOTE: Not sure if this read is really needed. + * The HX returns 0x00, the clone 0x02, but the Windows + * driver seems to ignore the value and continues. + */ + pl2303_vendor_write(0x0606, 0xaa, serial); + pl2303_vendor_read(0x8686, 0, serial, buf); + if (buf[0] != 0xaa) { + type = HX_CLONE; + type_str = "X/HX clone (limited functionality)"; + } else { + type = HX_TA; + type_str = "X/HX/TA"; + } + pl2303_vendor_write(0x0606, 0x00, serial); } else if (le16_to_cpu(serial->dev->descriptor.bcdDevice) == 0x400) { type = HXD_EA_RA_SA; @@ -305,8 +321,9 @@ static int pl2303_baudrate_encode_direct(int baud, enum pl2303_type type, { /* * NOTE: Only the values defined in baud_sup are supported ! - * => if unsupported values are set, the PL2303 seems to - * use 9600 baud (at least my PL2303X always does) + * => if unsupported values are set, the PL2303 uses 9600 baud instead + * => HX clones just don't work at unsupported baud rates < 115200 baud, + * for baud rates > 115200 they run at 115200 baud */ const int baud_sup[] = { 75, 150, 300, 600, 1200, 1800, 2400, 3600, 4800, 7200, 9600, 14400, 19200, 28800, 38400, @@ -316,14 +333,14 @@ static int pl2303_baudrate_encode_direct(int baud, enum pl2303_type type, * NOTE: With the exception of type_0/1 devices, the following * additional baud rates are supported (tested with HX rev. 3A only): * 110*, 56000*, 128000, 134400, 161280, 201600, 256000*, 268800, - * 403200, 806400. (*: not HX) + * 403200, 806400. (*: not HX and HX clones) * * Maximum values: HXD, TB: 12000000; HX, TA: 6000000; - * type_0+1: 1228800; RA: 921600; SA: 115200 + * type_0+1: 1228800; RA: 921600; HX clones, SA: 115200 * * As long as we are not using this encoding method for anything else - * than the type_0+1 and HX chips, there is no point in complicating - * the code to support them. + * than the type_0+1, HX and HX clone chips, there is no point in + * complicating the code to support them. */ int i; @@ -347,6 +364,8 @@ static int pl2303_baudrate_encode_direct(int baud, enum pl2303_type type, baud = min_t(int, baud, 6000000); else if (type == type_0 || type == type_1) baud = min_t(int, baud, 1228800); + else if (type == HX_CLONE) + baud = min_t(int, baud, 115200); /* Direct (standard) baud rate encoding method */ put_unaligned_le32(baud, buf); @@ -359,7 +378,8 @@ static int pl2303_baudrate_encode_divisor(int baud, enum pl2303_type type, /* * Divisor based baud rate encoding method * - * NOTE: it's not clear if the type_0/1 chips support this method + * NOTE: HX clones do NOT support this method. + * It's not clear if the type_0/1 chips support it. * * divisor = 12MHz * 32 / baudrate = 2^A * B * @@ -452,7 +472,7 @@ static void pl2303_encode_baudrate(struct tty_struct *tty, * 1) Direct method: encodes the baud rate value directly * => supported by all chip types * 2) Divisor based method: encodes a divisor to a base value (12MHz*32) - * => supported by HX chips (and likely not by type_0/1 chips) + * => not supported by HX clones (and likely type_0/1 chips) * * NOTE: Although the divisor based baud rate encoding method is much * more flexible, some of the standard baud rate values can not be @@ -460,7 +480,7 @@ static void pl2303_encode_baudrate(struct tty_struct *tty, * the device likely uses the same baud rate generator for both methods * so that there is likley no difference. */ - if (type == type_0 || type == type_1) + if (type == type_0 || type == type_1 || type == HX_CLONE) baud = pl2303_baudrate_encode_direct(baud, type, buf); else baud = pl2303_baudrate_encode_divisor(baud, type, buf); @@ -813,6 +833,7 @@ static void pl2303_break_ctl(struct tty_struct *tty, int break_state) result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), BREAK_REQUEST, BREAK_REQUEST_TYPE, state, 0, NULL, 0, 100); + /* NOTE: HX clones don't support sending breaks, -EPIPE is returned */ if (result) dev_err(&port->dev, "error sending break = %d\n", result); } diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index 4b79a1f2f901..592b31698fc8 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c @@ -461,7 +461,7 @@ static void tcm_vhost_release_cmd(struct se_cmd *se_cmd) u32 i; for (i = 0; i < tv_cmd->tvc_sgl_count; i++) put_page(sg_page(&tv_cmd->tvc_sgl[i])); - } + } tcm_vhost_put_inflight(tv_cmd->inflight); percpu_ida_free(&se_sess->sess_tag_pool, se_cmd->map_tag); @@ -1373,21 +1373,30 @@ static int vhost_scsi_set_features(struct vhost_scsi *vs, u64 features) return 0; } +static void vhost_scsi_free(struct vhost_scsi *vs) +{ + if (is_vmalloc_addr(vs)) + vfree(vs); + else + kfree(vs); +} + static int vhost_scsi_open(struct inode *inode, struct file *f) { struct vhost_scsi *vs; struct vhost_virtqueue **vqs; - int r, i; + int r = -ENOMEM, i; - vs = kzalloc(sizeof(*vs), GFP_KERNEL); - if (!vs) - return -ENOMEM; + vs = kzalloc(sizeof(*vs), GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT); + if (!vs) { + vs = vzalloc(sizeof(*vs)); + if (!vs) + goto err_vs; + } vqs = kmalloc(VHOST_SCSI_MAX_VQ * sizeof(*vqs), GFP_KERNEL); - if (!vqs) { - kfree(vs); - return -ENOMEM; - } + if (!vqs) + goto err_vqs; vhost_work_init(&vs->vs_completion_work, vhost_scsi_complete_cmd_work); vhost_work_init(&vs->vs_event_work, tcm_vhost_evt_work); @@ -1407,14 +1416,18 @@ static int vhost_scsi_open(struct inode *inode, struct file *f) tcm_vhost_init_inflight(vs, NULL); - if (r < 0) { - kfree(vqs); - kfree(vs); - return r; - } + if (r < 0) + goto err_init; f->private_data = vs; return 0; + +err_init: + kfree(vqs); +err_vqs: + vhost_scsi_free(vs); +err_vs: + return r; } static int vhost_scsi_release(struct inode *inode, struct file *f) @@ -1431,7 +1444,7 @@ static int vhost_scsi_release(struct inode *inode, struct file *f) /* Jobs can re-queue themselves in evt kick handler. Do extra flush. */ vhost_scsi_flush(vs); kfree(vs->dev.vqs); - kfree(vs); + vhost_scsi_free(vs); return 0; } diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 9a9502a4aa50..69068e0d8f31 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -161,9 +161,11 @@ void vhost_work_queue(struct vhost_dev *dev, struct vhost_work *work) if (list_empty(&work->node)) { list_add_tail(&work->node, &dev->work_list); work->queue_seq++; + spin_unlock_irqrestore(&dev->work_lock, flags); wake_up_process(dev->worker); + } else { + spin_unlock_irqrestore(&dev->work_lock, flags); } - spin_unlock_irqrestore(&dev->work_lock, flags); } EXPORT_SYMBOL_GPL(vhost_work_queue); diff --git a/drivers/video/mmp/hw/mmp_ctrl.c b/drivers/video/mmp/hw/mmp_ctrl.c index 75dca19bf214..6ac755270ab4 100644 --- a/drivers/video/mmp/hw/mmp_ctrl.c +++ b/drivers/video/mmp/hw/mmp_ctrl.c @@ -514,7 +514,7 @@ static int mmphw_probe(struct platform_device *pdev) if (IS_ERR(ctrl->clk)) { dev_err(ctrl->dev, "unable to get clk %s\n", mi->clk_name); ret = -ENOENT; - goto failed_get_clk; + goto failed; } clk_prepare_enable(ctrl->clk); @@ -551,21 +551,8 @@ failed_path_init: path_deinit(path_plat); } - if (ctrl->clk) { - devm_clk_put(ctrl->dev, ctrl->clk); - clk_disable_unprepare(ctrl->clk); - } -failed_get_clk: - devm_free_irq(ctrl->dev, ctrl->irq, ctrl); + clk_disable_unprepare(ctrl->clk); failed: - if (ctrl) { - if (ctrl->reg_base) - devm_iounmap(ctrl->dev, ctrl->reg_base); - devm_release_mem_region(ctrl->dev, res->start, - resource_size(res)); - devm_kfree(ctrl->dev, ctrl); - } - dev_err(&pdev->dev, "device init failed\n"); return ret; diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c index d250ed0f806d..27197a8048c0 100644 --- a/drivers/video/mxsfb.c +++ b/drivers/video/mxsfb.c @@ -620,6 +620,7 @@ static int mxsfb_restore_mode(struct mxsfb_info *host) break; case 3: bits_per_pixel = 32; + break; case 1: default: return -EINVAL; diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c index 7ef079c146e7..c172a5281f9e 100644 --- a/drivers/video/neofb.c +++ b/drivers/video/neofb.c @@ -2075,6 +2075,7 @@ static int neofb_probe(struct pci_dev *dev, const struct pci_device_id *id) if (!fb_find_mode(&info->var, info, mode_option, NULL, 0, info->monspecs.modedb, 16)) { printk(KERN_ERR "neofb: Unable to find usable video mode.\n"); + err = -EINVAL; goto err_map_video; } @@ -2097,7 +2098,8 @@ static int neofb_probe(struct pci_dev *dev, const struct pci_device_id *id) info->fix.smem_len >> 10, info->var.xres, info->var.yres, h_sync / 1000, h_sync % 1000, v_sync); - if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) + err = fb_alloc_cmap(&info->cmap, 256, 0); + if (err < 0) goto err_map_video; err = register_framebuffer(info); diff --git a/drivers/video/of_display_timing.c b/drivers/video/of_display_timing.c index 171821ddd78d..ba5b40f581f6 100644 --- a/drivers/video/of_display_timing.c +++ b/drivers/video/of_display_timing.c @@ -120,7 +120,7 @@ int of_get_display_timing(struct device_node *np, const char *name, return -EINVAL; } - timing_np = of_find_node_by_name(np, name); + timing_np = of_get_child_by_name(np, name); if (!timing_np) { pr_err("%s: could not find node '%s'\n", of_node_full_name(np), name); @@ -143,11 +143,11 @@ struct display_timings *of_get_display_timings(struct device_node *np) struct display_timings *disp; if (!np) { - pr_err("%s: no devicenode given\n", of_node_full_name(np)); + pr_err("%s: no device node given\n", of_node_full_name(np)); return NULL; } - timings_np = of_find_node_by_name(np, "display-timings"); + timings_np = of_get_child_by_name(np, "display-timings"); if (!timings_np) { pr_err("%s: could not find display-timings node\n", of_node_full_name(np)); diff --git a/drivers/video/omap2/displays-new/Kconfig b/drivers/video/omap2/displays-new/Kconfig index 6c90885b0940..10b25e7cd878 100644 --- a/drivers/video/omap2/displays-new/Kconfig +++ b/drivers/video/omap2/displays-new/Kconfig @@ -35,6 +35,7 @@ config DISPLAY_PANEL_DPI config DISPLAY_PANEL_DSI_CM tristate "Generic DSI Command Mode Panel" + depends on BACKLIGHT_CLASS_DEVICE help Driver for generic DSI command mode panels. diff --git a/drivers/video/omap2/displays-new/connector-analog-tv.c b/drivers/video/omap2/displays-new/connector-analog-tv.c index 1b60698f141e..ccd9073f706f 100644 --- a/drivers/video/omap2/displays-new/connector-analog-tv.c +++ b/drivers/video/omap2/displays-new/connector-analog-tv.c @@ -191,7 +191,7 @@ static int tvc_probe_pdata(struct platform_device *pdev) in = omap_dss_find_output(pdata->source); if (in == NULL) { dev_err(&pdev->dev, "Failed to find video source\n"); - return -ENODEV; + return -EPROBE_DEFER; } ddata->in = in; diff --git a/drivers/video/omap2/displays-new/connector-dvi.c b/drivers/video/omap2/displays-new/connector-dvi.c index bc5f8ceda371..63d88ee6dfe4 100644 --- a/drivers/video/omap2/displays-new/connector-dvi.c +++ b/drivers/video/omap2/displays-new/connector-dvi.c @@ -263,7 +263,7 @@ static int dvic_probe_pdata(struct platform_device *pdev) in = omap_dss_find_output(pdata->source); if (in == NULL) { dev_err(&pdev->dev, "Failed to find video source\n"); - return -ENODEV; + return -EPROBE_DEFER; } ddata->in = in; diff --git a/drivers/video/omap2/displays-new/connector-hdmi.c b/drivers/video/omap2/displays-new/connector-hdmi.c index c5826716d6ab..9abe2c039ae9 100644 --- a/drivers/video/omap2/displays-new/connector-hdmi.c +++ b/drivers/video/omap2/displays-new/connector-hdmi.c @@ -290,7 +290,7 @@ static int hdmic_probe_pdata(struct platform_device *pdev) in = omap_dss_find_output(pdata->source); if (in == NULL) { dev_err(&pdev->dev, "Failed to find video source\n"); - return -ENODEV; + return -EPROBE_DEFER; } ddata->in = in; diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 02a7340111df..477975009eee 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -3691,6 +3691,7 @@ static int __init omap_dispchw_probe(struct platform_device *pdev) } pm_runtime_enable(&pdev->dev); + pm_runtime_irq_safe(&pdev->dev); r = dispc_runtime_get(); if (r) diff --git a/drivers/video/s3fb.c b/drivers/video/s3fb.c index 47ca86c5c6c0..d838ba829459 100644 --- a/drivers/video/s3fb.c +++ b/drivers/video/s3fb.c @@ -1336,14 +1336,7 @@ static int s3_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) (info->var.bits_per_pixel * info->var.xres_virtual); if (info->var.yres_virtual < info->var.yres) { dev_err(info->device, "virtual vertical size smaller than real\n"); - goto err_find_mode; - } - - /* maximize virtual vertical size for fast scrolling */ - info->var.yres_virtual = info->fix.smem_len * 8 / - (info->var.bits_per_pixel * info->var.xres_virtual); - if (info->var.yres_virtual < info->var.yres) { - dev_err(info->device, "virtual vertical size smaller than real\n"); + rc = -EINVAL; goto err_find_mode; } diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index a50c6e3a7cc4..b232908a6192 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c @@ -398,8 +398,6 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp) if (nr_pages > ARRAY_SIZE(frame_list)) nr_pages = ARRAY_SIZE(frame_list); - scratch_page = get_balloon_scratch_page(); - for (i = 0; i < nr_pages; i++) { page = alloc_page(gfp); if (page == NULL) { @@ -413,6 +411,12 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp) scrub_page(page); + /* + * Ballooned out frames are effectively replaced with + * a scratch frame. Ensure direct mappings and the + * p2m are consistent. + */ + scratch_page = get_balloon_scratch_page(); #ifdef CONFIG_XEN_HAVE_PVMMU if (xen_pv_domain() && !PageHighMem(page)) { ret = HYPERVISOR_update_va_mapping( @@ -422,24 +426,19 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp) BUG_ON(ret); } #endif - } - - /* Ensure that ballooned highmem pages don't have kmaps. */ - kmap_flush_unused(); - flush_tlb_all(); - - /* No more mappings: invalidate P2M and add to balloon. */ - for (i = 0; i < nr_pages; i++) { - pfn = mfn_to_pfn(frame_list[i]); if (!xen_feature(XENFEAT_auto_translated_physmap)) { unsigned long p; p = page_to_pfn(scratch_page); __set_phys_to_machine(pfn, pfn_to_mfn(p)); } + put_balloon_scratch_page(); + balloon_append(pfn_to_page(pfn)); } - put_balloon_scratch_page(); + /* Ensure that ballooned highmem pages don't have kmaps. */ + kmap_flush_unused(); + flush_tlb_all(); set_xen_guest_handle(reservation.extent_start, frame_list); reservation.nr_extents = nr_pages; |