diff options
Diffstat (limited to 'drivers')
119 files changed, 2762 insertions, 504 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 25dbb76c02cc..5eef4cb4f70e 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
| @@ -58,10 +58,10 @@ config ACPI_CCA_REQUIRED | |||
| 58 | bool | 58 | bool |
| 59 | 59 | ||
| 60 | config ACPI_DEBUGGER | 60 | config ACPI_DEBUGGER |
| 61 | bool "In-kernel debugger (EXPERIMENTAL)" | 61 | bool "AML debugger interface (EXPERIMENTAL)" |
| 62 | select ACPI_DEBUG | 62 | select ACPI_DEBUG |
| 63 | help | 63 | help |
| 64 | Enable in-kernel debugging facilities: statistics, internal | 64 | Enable in-kernel debugging of AML facilities: statistics, internal |
| 65 | object dump, single step control method execution. | 65 | object dump, single step control method execution. |
| 66 | This is still under development, currently enabling this only | 66 | This is still under development, currently enabling this only |
| 67 | results in the compilation of the ACPICA debugger files. | 67 | results in the compilation of the ACPICA debugger files. |
diff --git a/drivers/acpi/nfit.c b/drivers/acpi/nfit.c index f7dab53b352a..e7ed39bab97d 100644 --- a/drivers/acpi/nfit.c +++ b/drivers/acpi/nfit.c | |||
| @@ -233,11 +233,12 @@ static bool add_spa(struct acpi_nfit_desc *acpi_desc, | |||
| 233 | struct nfit_table_prev *prev, | 233 | struct nfit_table_prev *prev, |
| 234 | struct acpi_nfit_system_address *spa) | 234 | struct acpi_nfit_system_address *spa) |
| 235 | { | 235 | { |
| 236 | size_t length = min_t(size_t, sizeof(*spa), spa->header.length); | ||
| 236 | struct device *dev = acpi_desc->dev; | 237 | struct device *dev = acpi_desc->dev; |
| 237 | struct nfit_spa *nfit_spa; | 238 | struct nfit_spa *nfit_spa; |
| 238 | 239 | ||
| 239 | list_for_each_entry(nfit_spa, &prev->spas, list) { | 240 | list_for_each_entry(nfit_spa, &prev->spas, list) { |
| 240 | if (memcmp(nfit_spa->spa, spa, sizeof(*spa)) == 0) { | 241 | if (memcmp(nfit_spa->spa, spa, length) == 0) { |
| 241 | list_move_tail(&nfit_spa->list, &acpi_desc->spas); | 242 | list_move_tail(&nfit_spa->list, &acpi_desc->spas); |
| 242 | return true; | 243 | return true; |
| 243 | } | 244 | } |
| @@ -259,11 +260,12 @@ static bool add_memdev(struct acpi_nfit_desc *acpi_desc, | |||
| 259 | struct nfit_table_prev *prev, | 260 | struct nfit_table_prev *prev, |
| 260 | struct acpi_nfit_memory_map *memdev) | 261 | struct acpi_nfit_memory_map *memdev) |
| 261 | { | 262 | { |
| 263 | size_t length = min_t(size_t, sizeof(*memdev), memdev->header.length); | ||
| 262 | struct device *dev = acpi_desc->dev; | 264 | struct device *dev = acpi_desc->dev; |
| 263 | struct nfit_memdev *nfit_memdev; | 265 | struct nfit_memdev *nfit_memdev; |
| 264 | 266 | ||
| 265 | list_for_each_entry(nfit_memdev, &prev->memdevs, list) | 267 | list_for_each_entry(nfit_memdev, &prev->memdevs, list) |
| 266 | if (memcmp(nfit_memdev->memdev, memdev, sizeof(*memdev)) == 0) { | 268 | if (memcmp(nfit_memdev->memdev, memdev, length) == 0) { |
| 267 | list_move_tail(&nfit_memdev->list, &acpi_desc->memdevs); | 269 | list_move_tail(&nfit_memdev->list, &acpi_desc->memdevs); |
| 268 | return true; | 270 | return true; |
| 269 | } | 271 | } |
| @@ -284,11 +286,12 @@ static bool add_dcr(struct acpi_nfit_desc *acpi_desc, | |||
| 284 | struct nfit_table_prev *prev, | 286 | struct nfit_table_prev *prev, |
| 285 | struct acpi_nfit_control_region *dcr) | 287 | struct acpi_nfit_control_region *dcr) |
| 286 | { | 288 | { |
| 289 | size_t length = min_t(size_t, sizeof(*dcr), dcr->header.length); | ||
| 287 | struct device *dev = acpi_desc->dev; | 290 | struct device *dev = acpi_desc->dev; |
| 288 | struct nfit_dcr *nfit_dcr; | 291 | struct nfit_dcr *nfit_dcr; |
| 289 | 292 | ||
| 290 | list_for_each_entry(nfit_dcr, &prev->dcrs, list) | 293 | list_for_each_entry(nfit_dcr, &prev->dcrs, list) |
| 291 | if (memcmp(nfit_dcr->dcr, dcr, sizeof(*dcr)) == 0) { | 294 | if (memcmp(nfit_dcr->dcr, dcr, length) == 0) { |
| 292 | list_move_tail(&nfit_dcr->list, &acpi_desc->dcrs); | 295 | list_move_tail(&nfit_dcr->list, &acpi_desc->dcrs); |
| 293 | return true; | 296 | return true; |
| 294 | } | 297 | } |
| @@ -308,11 +311,12 @@ static bool add_bdw(struct acpi_nfit_desc *acpi_desc, | |||
| 308 | struct nfit_table_prev *prev, | 311 | struct nfit_table_prev *prev, |
| 309 | struct acpi_nfit_data_region *bdw) | 312 | struct acpi_nfit_data_region *bdw) |
| 310 | { | 313 | { |
| 314 | size_t length = min_t(size_t, sizeof(*bdw), bdw->header.length); | ||
| 311 | struct device *dev = acpi_desc->dev; | 315 | struct device *dev = acpi_desc->dev; |
| 312 | struct nfit_bdw *nfit_bdw; | 316 | struct nfit_bdw *nfit_bdw; |
| 313 | 317 | ||
| 314 | list_for_each_entry(nfit_bdw, &prev->bdws, list) | 318 | list_for_each_entry(nfit_bdw, &prev->bdws, list) |
| 315 | if (memcmp(nfit_bdw->bdw, bdw, sizeof(*bdw)) == 0) { | 319 | if (memcmp(nfit_bdw->bdw, bdw, length) == 0) { |
| 316 | list_move_tail(&nfit_bdw->list, &acpi_desc->bdws); | 320 | list_move_tail(&nfit_bdw->list, &acpi_desc->bdws); |
| 317 | return true; | 321 | return true; |
| 318 | } | 322 | } |
| @@ -332,11 +336,12 @@ static bool add_idt(struct acpi_nfit_desc *acpi_desc, | |||
| 332 | struct nfit_table_prev *prev, | 336 | struct nfit_table_prev *prev, |
| 333 | struct acpi_nfit_interleave *idt) | 337 | struct acpi_nfit_interleave *idt) |
| 334 | { | 338 | { |
| 339 | size_t length = min_t(size_t, sizeof(*idt), idt->header.length); | ||
| 335 | struct device *dev = acpi_desc->dev; | 340 | struct device *dev = acpi_desc->dev; |
| 336 | struct nfit_idt *nfit_idt; | 341 | struct nfit_idt *nfit_idt; |
| 337 | 342 | ||
| 338 | list_for_each_entry(nfit_idt, &prev->idts, list) | 343 | list_for_each_entry(nfit_idt, &prev->idts, list) |
| 339 | if (memcmp(nfit_idt->idt, idt, sizeof(*idt)) == 0) { | 344 | if (memcmp(nfit_idt->idt, idt, length) == 0) { |
| 340 | list_move_tail(&nfit_idt->list, &acpi_desc->idts); | 345 | list_move_tail(&nfit_idt->list, &acpi_desc->idts); |
| 341 | return true; | 346 | return true; |
| 342 | } | 347 | } |
| @@ -356,11 +361,12 @@ static bool add_flush(struct acpi_nfit_desc *acpi_desc, | |||
| 356 | struct nfit_table_prev *prev, | 361 | struct nfit_table_prev *prev, |
| 357 | struct acpi_nfit_flush_address *flush) | 362 | struct acpi_nfit_flush_address *flush) |
| 358 | { | 363 | { |
| 364 | size_t length = min_t(size_t, sizeof(*flush), flush->header.length); | ||
| 359 | struct device *dev = acpi_desc->dev; | 365 | struct device *dev = acpi_desc->dev; |
| 360 | struct nfit_flush *nfit_flush; | 366 | struct nfit_flush *nfit_flush; |
| 361 | 367 | ||
| 362 | list_for_each_entry(nfit_flush, &prev->flushes, list) | 368 | list_for_each_entry(nfit_flush, &prev->flushes, list) |
| 363 | if (memcmp(nfit_flush->flush, flush, sizeof(*flush)) == 0) { | 369 | if (memcmp(nfit_flush->flush, flush, length) == 0) { |
| 364 | list_move_tail(&nfit_flush->list, &acpi_desc->flushes); | 370 | list_move_tail(&nfit_flush->list, &acpi_desc->flushes); |
| 365 | return true; | 371 | return true; |
| 366 | } | 372 | } |
| @@ -655,7 +661,7 @@ static ssize_t revision_show(struct device *dev, | |||
| 655 | struct nvdimm_bus_descriptor *nd_desc = to_nd_desc(nvdimm_bus); | 661 | struct nvdimm_bus_descriptor *nd_desc = to_nd_desc(nvdimm_bus); |
| 656 | struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc); | 662 | struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc); |
| 657 | 663 | ||
| 658 | return sprintf(buf, "%d\n", acpi_desc->nfit->header.revision); | 664 | return sprintf(buf, "%d\n", acpi_desc->acpi_header.revision); |
| 659 | } | 665 | } |
| 660 | static DEVICE_ATTR_RO(revision); | 666 | static DEVICE_ATTR_RO(revision); |
| 661 | 667 | ||
| @@ -1652,7 +1658,6 @@ int acpi_nfit_init(struct acpi_nfit_desc *acpi_desc, acpi_size sz) | |||
| 1652 | 1658 | ||
| 1653 | data = (u8 *) acpi_desc->nfit; | 1659 | data = (u8 *) acpi_desc->nfit; |
| 1654 | end = data + sz; | 1660 | end = data + sz; |
| 1655 | data += sizeof(struct acpi_table_nfit); | ||
| 1656 | while (!IS_ERR_OR_NULL(data)) | 1661 | while (!IS_ERR_OR_NULL(data)) |
| 1657 | data = add_table(acpi_desc, &prev, data, end); | 1662 | data = add_table(acpi_desc, &prev, data, end); |
| 1658 | 1663 | ||
| @@ -1748,13 +1753,29 @@ static int acpi_nfit_add(struct acpi_device *adev) | |||
| 1748 | return PTR_ERR(acpi_desc); | 1753 | return PTR_ERR(acpi_desc); |
| 1749 | } | 1754 | } |
| 1750 | 1755 | ||
| 1751 | acpi_desc->nfit = (struct acpi_table_nfit *) tbl; | 1756 | /* |
| 1757 | * Save the acpi header for later and then skip it, | ||
| 1758 | * making nfit point to the first nfit table header. | ||
| 1759 | */ | ||
| 1760 | acpi_desc->acpi_header = *tbl; | ||
| 1761 | acpi_desc->nfit = (void *) tbl + sizeof(struct acpi_table_nfit); | ||
| 1762 | sz -= sizeof(struct acpi_table_nfit); | ||
| 1752 | 1763 | ||
| 1753 | /* Evaluate _FIT and override with that if present */ | 1764 | /* Evaluate _FIT and override with that if present */ |
| 1754 | status = acpi_evaluate_object(adev->handle, "_FIT", NULL, &buf); | 1765 | status = acpi_evaluate_object(adev->handle, "_FIT", NULL, &buf); |
| 1755 | if (ACPI_SUCCESS(status) && buf.length > 0) { | 1766 | if (ACPI_SUCCESS(status) && buf.length > 0) { |
| 1756 | acpi_desc->nfit = (struct acpi_table_nfit *)buf.pointer; | 1767 | union acpi_object *obj; |
| 1757 | sz = buf.length; | 1768 | /* |
| 1769 | * Adjust for the acpi_object header of the _FIT | ||
| 1770 | */ | ||
| 1771 | obj = buf.pointer; | ||
| 1772 | if (obj->type == ACPI_TYPE_BUFFER) { | ||
| 1773 | acpi_desc->nfit = | ||
| 1774 | (struct acpi_nfit_header *)obj->buffer.pointer; | ||
| 1775 | sz = obj->buffer.length; | ||
| 1776 | } else | ||
| 1777 | dev_dbg(dev, "%s invalid type %d, ignoring _FIT\n", | ||
| 1778 | __func__, (int) obj->type); | ||
| 1758 | } | 1779 | } |
| 1759 | 1780 | ||
| 1760 | rc = acpi_nfit_init(acpi_desc, sz); | 1781 | rc = acpi_nfit_init(acpi_desc, sz); |
| @@ -1777,7 +1798,8 @@ static void acpi_nfit_notify(struct acpi_device *adev, u32 event) | |||
| 1777 | { | 1798 | { |
| 1778 | struct acpi_nfit_desc *acpi_desc = dev_get_drvdata(&adev->dev); | 1799 | struct acpi_nfit_desc *acpi_desc = dev_get_drvdata(&adev->dev); |
| 1779 | struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL }; | 1800 | struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL }; |
| 1780 | struct acpi_table_nfit *nfit_saved; | 1801 | struct acpi_nfit_header *nfit_saved; |
| 1802 | union acpi_object *obj; | ||
| 1781 | struct device *dev = &adev->dev; | 1803 | struct device *dev = &adev->dev; |
| 1782 | acpi_status status; | 1804 | acpi_status status; |
| 1783 | int ret; | 1805 | int ret; |
| @@ -1808,12 +1830,19 @@ static void acpi_nfit_notify(struct acpi_device *adev, u32 event) | |||
| 1808 | } | 1830 | } |
| 1809 | 1831 | ||
| 1810 | nfit_saved = acpi_desc->nfit; | 1832 | nfit_saved = acpi_desc->nfit; |
| 1811 | acpi_desc->nfit = (struct acpi_table_nfit *)buf.pointer; | 1833 | obj = buf.pointer; |
| 1812 | ret = acpi_nfit_init(acpi_desc, buf.length); | 1834 | if (obj->type == ACPI_TYPE_BUFFER) { |
| 1813 | if (!ret) { | 1835 | acpi_desc->nfit = |
| 1814 | /* Merge failed, restore old nfit, and exit */ | 1836 | (struct acpi_nfit_header *)obj->buffer.pointer; |
| 1815 | acpi_desc->nfit = nfit_saved; | 1837 | ret = acpi_nfit_init(acpi_desc, obj->buffer.length); |
| 1816 | dev_err(dev, "failed to merge updated NFIT\n"); | 1838 | if (ret) { |
| 1839 | /* Merge failed, restore old nfit, and exit */ | ||
| 1840 | acpi_desc->nfit = nfit_saved; | ||
| 1841 | dev_err(dev, "failed to merge updated NFIT\n"); | ||
| 1842 | } | ||
| 1843 | } else { | ||
| 1844 | /* Bad _FIT, restore old nfit */ | ||
| 1845 | dev_err(dev, "Invalid _FIT\n"); | ||
| 1817 | } | 1846 | } |
| 1818 | kfree(buf.pointer); | 1847 | kfree(buf.pointer); |
| 1819 | 1848 | ||
diff --git a/drivers/acpi/nfit.h b/drivers/acpi/nfit.h index 2ea5c0797c8f..3d549a383659 100644 --- a/drivers/acpi/nfit.h +++ b/drivers/acpi/nfit.h | |||
| @@ -96,7 +96,8 @@ struct nfit_mem { | |||
| 96 | 96 | ||
| 97 | struct acpi_nfit_desc { | 97 | struct acpi_nfit_desc { |
| 98 | struct nvdimm_bus_descriptor nd_desc; | 98 | struct nvdimm_bus_descriptor nd_desc; |
| 99 | struct acpi_table_nfit *nfit; | 99 | struct acpi_table_header acpi_header; |
| 100 | struct acpi_nfit_header *nfit; | ||
| 100 | struct mutex spa_map_mutex; | 101 | struct mutex spa_map_mutex; |
| 101 | struct mutex init_mutex; | 102 | struct mutex init_mutex; |
| 102 | struct list_head spa_maps; | 103 | struct list_head spa_maps; |
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 850d7bf0c873..ae3fe4e64203 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
| @@ -768,6 +768,13 @@ static void pci_acpi_root_add_resources(struct acpi_pci_root_info *info) | |||
| 768 | else | 768 | else |
| 769 | continue; | 769 | continue; |
| 770 | 770 | ||
| 771 | /* | ||
| 772 | * Some legacy x86 host bridge drivers use iomem_resource and | ||
| 773 | * ioport_resource as default resource pool, skip it. | ||
| 774 | */ | ||
| 775 | if (res == root) | ||
| 776 | continue; | ||
| 777 | |||
| 771 | conflict = insert_resource_conflict(root, res); | 778 | conflict = insert_resource_conflict(root, res); |
| 772 | if (conflict) { | 779 | if (conflict) { |
| 773 | dev_info(&info->bridge->dev, | 780 | dev_info(&info->bridge->dev, |
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index e03b1ad25a90..167418e73445 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c | |||
| @@ -1775,10 +1775,10 @@ int genpd_dev_pm_attach(struct device *dev) | |||
| 1775 | } | 1775 | } |
| 1776 | 1776 | ||
| 1777 | pd = of_genpd_get_from_provider(&pd_args); | 1777 | pd = of_genpd_get_from_provider(&pd_args); |
| 1778 | of_node_put(pd_args.np); | ||
| 1778 | if (IS_ERR(pd)) { | 1779 | if (IS_ERR(pd)) { |
| 1779 | dev_dbg(dev, "%s() failed to find PM domain: %ld\n", | 1780 | dev_dbg(dev, "%s() failed to find PM domain: %ld\n", |
| 1780 | __func__, PTR_ERR(pd)); | 1781 | __func__, PTR_ERR(pd)); |
| 1781 | of_node_put(dev->of_node); | ||
| 1782 | return -EPROBE_DEFER; | 1782 | return -EPROBE_DEFER; |
| 1783 | } | 1783 | } |
| 1784 | 1784 | ||
| @@ -1796,7 +1796,6 @@ int genpd_dev_pm_attach(struct device *dev) | |||
| 1796 | if (ret < 0) { | 1796 | if (ret < 0) { |
| 1797 | dev_err(dev, "failed to add to PM domain %s: %d", | 1797 | dev_err(dev, "failed to add to PM domain %s: %d", |
| 1798 | pd->name, ret); | 1798 | pd->name, ret); |
| 1799 | of_node_put(dev->of_node); | ||
| 1800 | goto out; | 1799 | goto out; |
| 1801 | } | 1800 | } |
| 1802 | 1801 | ||
diff --git a/drivers/base/power/domain_governor.c b/drivers/base/power/domain_governor.c index e60dd12e23aa..1e937ac5f456 100644 --- a/drivers/base/power/domain_governor.c +++ b/drivers/base/power/domain_governor.c | |||
| @@ -160,9 +160,6 @@ static bool default_power_down_ok(struct dev_pm_domain *pd) | |||
| 160 | struct gpd_timing_data *td; | 160 | struct gpd_timing_data *td; |
| 161 | s64 constraint_ns; | 161 | s64 constraint_ns; |
| 162 | 162 | ||
| 163 | if (!pdd->dev->driver) | ||
| 164 | continue; | ||
| 165 | |||
| 166 | /* | 163 | /* |
| 167 | * Check if the device is allowed to be off long enough for the | 164 | * Check if the device is allowed to be off long enough for the |
| 168 | * domain to turn off and on (that's how much time it will | 165 | * domain to turn off and on (that's how much time it will |
diff --git a/drivers/block/null_blk.c b/drivers/block/null_blk.c index 5c8ba5484d86..0c3940ec5e62 100644 --- a/drivers/block/null_blk.c +++ b/drivers/block/null_blk.c | |||
| @@ -18,6 +18,7 @@ struct nullb_cmd { | |||
| 18 | struct bio *bio; | 18 | struct bio *bio; |
| 19 | unsigned int tag; | 19 | unsigned int tag; |
| 20 | struct nullb_queue *nq; | 20 | struct nullb_queue *nq; |
| 21 | struct hrtimer timer; | ||
| 21 | }; | 22 | }; |
| 22 | 23 | ||
| 23 | struct nullb_queue { | 24 | struct nullb_queue { |
| @@ -49,17 +50,6 @@ static int null_major; | |||
| 49 | static int nullb_indexes; | 50 | static int nullb_indexes; |
| 50 | static struct kmem_cache *ppa_cache; | 51 | static struct kmem_cache *ppa_cache; |
| 51 | 52 | ||
| 52 | struct completion_queue { | ||
| 53 | struct llist_head list; | ||
| 54 | struct hrtimer timer; | ||
| 55 | }; | ||
| 56 | |||
| 57 | /* | ||
| 58 | * These are per-cpu for now, they will need to be configured by the | ||
| 59 | * complete_queues parameter and appropriately mapped. | ||
| 60 | */ | ||
| 61 | static DEFINE_PER_CPU(struct completion_queue, completion_queues); | ||
| 62 | |||
| 63 | enum { | 53 | enum { |
| 64 | NULL_IRQ_NONE = 0, | 54 | NULL_IRQ_NONE = 0, |
| 65 | NULL_IRQ_SOFTIRQ = 1, | 55 | NULL_IRQ_SOFTIRQ = 1, |
| @@ -142,8 +132,8 @@ static const struct kernel_param_ops null_irqmode_param_ops = { | |||
| 142 | device_param_cb(irqmode, &null_irqmode_param_ops, &irqmode, S_IRUGO); | 132 | device_param_cb(irqmode, &null_irqmode_param_ops, &irqmode, S_IRUGO); |
| 143 | MODULE_PARM_DESC(irqmode, "IRQ completion handler. 0-none, 1-softirq, 2-timer"); | 133 | MODULE_PARM_DESC(irqmode, "IRQ completion handler. 0-none, 1-softirq, 2-timer"); |
| 144 | 134 | ||
| 145 | static int completion_nsec = 10000; | 135 | static unsigned long completion_nsec = 10000; |
| 146 | module_param(completion_nsec, int, S_IRUGO); | 136 | module_param(completion_nsec, ulong, S_IRUGO); |
| 147 | MODULE_PARM_DESC(completion_nsec, "Time in ns to complete a request in hardware. Default: 10,000ns"); | 137 | MODULE_PARM_DESC(completion_nsec, "Time in ns to complete a request in hardware. Default: 10,000ns"); |
| 148 | 138 | ||
| 149 | static int hw_queue_depth = 64; | 139 | static int hw_queue_depth = 64; |
| @@ -180,6 +170,8 @@ static void free_cmd(struct nullb_cmd *cmd) | |||
| 180 | put_tag(cmd->nq, cmd->tag); | 170 | put_tag(cmd->nq, cmd->tag); |
| 181 | } | 171 | } |
| 182 | 172 | ||
| 173 | static enum hrtimer_restart null_cmd_timer_expired(struct hrtimer *timer); | ||
| 174 | |||
| 183 | static struct nullb_cmd *__alloc_cmd(struct nullb_queue *nq) | 175 | static struct nullb_cmd *__alloc_cmd(struct nullb_queue *nq) |
| 184 | { | 176 | { |
| 185 | struct nullb_cmd *cmd; | 177 | struct nullb_cmd *cmd; |
| @@ -190,6 +182,11 @@ static struct nullb_cmd *__alloc_cmd(struct nullb_queue *nq) | |||
| 190 | cmd = &nq->cmds[tag]; | 182 | cmd = &nq->cmds[tag]; |
| 191 | cmd->tag = tag; | 183 | cmd->tag = tag; |
| 192 | cmd->nq = nq; | 184 | cmd->nq = nq; |
| 185 | if (irqmode == NULL_IRQ_TIMER) { | ||
| 186 | hrtimer_init(&cmd->timer, CLOCK_MONOTONIC, | ||
| 187 | HRTIMER_MODE_REL); | ||
| 188 | cmd->timer.function = null_cmd_timer_expired; | ||
| 189 | } | ||
| 193 | return cmd; | 190 | return cmd; |
| 194 | } | 191 | } |
| 195 | 192 | ||
| @@ -220,6 +217,8 @@ static struct nullb_cmd *alloc_cmd(struct nullb_queue *nq, int can_wait) | |||
| 220 | 217 | ||
| 221 | static void end_cmd(struct nullb_cmd *cmd) | 218 | static void end_cmd(struct nullb_cmd *cmd) |
| 222 | { | 219 | { |
| 220 | struct request_queue *q = NULL; | ||
| 221 | |||
| 223 | switch (queue_mode) { | 222 | switch (queue_mode) { |
| 224 | case NULL_Q_MQ: | 223 | case NULL_Q_MQ: |
| 225 | blk_mq_end_request(cmd->rq, 0); | 224 | blk_mq_end_request(cmd->rq, 0); |
| @@ -230,55 +229,37 @@ static void end_cmd(struct nullb_cmd *cmd) | |||
| 230 | break; | 229 | break; |
| 231 | case NULL_Q_BIO: | 230 | case NULL_Q_BIO: |
| 232 | bio_endio(cmd->bio); | 231 | bio_endio(cmd->bio); |
| 233 | break; | 232 | goto free_cmd; |
| 234 | } | 233 | } |
| 235 | 234 | ||
| 235 | if (cmd->rq) | ||
| 236 | q = cmd->rq->q; | ||
| 237 | |||
| 238 | /* Restart queue if needed, as we are freeing a tag */ | ||
| 239 | if (q && !q->mq_ops && blk_queue_stopped(q)) { | ||
| 240 | unsigned long flags; | ||
| 241 | |||
| 242 | spin_lock_irqsave(q->queue_lock, flags); | ||
| 243 | if (blk_queue_stopped(q)) | ||
| 244 | blk_start_queue(q); | ||
| 245 | spin_unlock_irqrestore(q->queue_lock, flags); | ||
| 246 | } | ||
| 247 | free_cmd: | ||
| 236 | free_cmd(cmd); | 248 | free_cmd(cmd); |
| 237 | } | 249 | } |
| 238 | 250 | ||
| 239 | static enum hrtimer_restart null_cmd_timer_expired(struct hrtimer *timer) | 251 | static enum hrtimer_restart null_cmd_timer_expired(struct hrtimer *timer) |
| 240 | { | 252 | { |
| 241 | struct completion_queue *cq; | 253 | end_cmd(container_of(timer, struct nullb_cmd, timer)); |
| 242 | struct llist_node *entry; | ||
| 243 | struct nullb_cmd *cmd; | ||
| 244 | |||
| 245 | cq = &per_cpu(completion_queues, smp_processor_id()); | ||
| 246 | |||
| 247 | while ((entry = llist_del_all(&cq->list)) != NULL) { | ||
| 248 | entry = llist_reverse_order(entry); | ||
| 249 | do { | ||
| 250 | struct request_queue *q = NULL; | ||
| 251 | |||
| 252 | cmd = container_of(entry, struct nullb_cmd, ll_list); | ||
| 253 | entry = entry->next; | ||
| 254 | if (cmd->rq) | ||
| 255 | q = cmd->rq->q; | ||
| 256 | end_cmd(cmd); | ||
| 257 | |||
| 258 | if (q && !q->mq_ops && blk_queue_stopped(q)) { | ||
| 259 | spin_lock(q->queue_lock); | ||
| 260 | if (blk_queue_stopped(q)) | ||
| 261 | blk_start_queue(q); | ||
| 262 | spin_unlock(q->queue_lock); | ||
| 263 | } | ||
| 264 | } while (entry); | ||
| 265 | } | ||
| 266 | 254 | ||
| 267 | return HRTIMER_NORESTART; | 255 | return HRTIMER_NORESTART; |
| 268 | } | 256 | } |
| 269 | 257 | ||
| 270 | static void null_cmd_end_timer(struct nullb_cmd *cmd) | 258 | static void null_cmd_end_timer(struct nullb_cmd *cmd) |
| 271 | { | 259 | { |
| 272 | struct completion_queue *cq = &per_cpu(completion_queues, get_cpu()); | 260 | ktime_t kt = ktime_set(0, completion_nsec); |
| 273 | |||
| 274 | cmd->ll_list.next = NULL; | ||
| 275 | if (llist_add(&cmd->ll_list, &cq->list)) { | ||
| 276 | ktime_t kt = ktime_set(0, completion_nsec); | ||
| 277 | |||
| 278 | hrtimer_start(&cq->timer, kt, HRTIMER_MODE_REL_PINNED); | ||
| 279 | } | ||
| 280 | 261 | ||
| 281 | put_cpu(); | 262 | hrtimer_start(&cmd->timer, kt, HRTIMER_MODE_REL); |
| 282 | } | 263 | } |
| 283 | 264 | ||
| 284 | static void null_softirq_done_fn(struct request *rq) | 265 | static void null_softirq_done_fn(struct request *rq) |
| @@ -376,6 +357,10 @@ static int null_queue_rq(struct blk_mq_hw_ctx *hctx, | |||
| 376 | { | 357 | { |
| 377 | struct nullb_cmd *cmd = blk_mq_rq_to_pdu(bd->rq); | 358 | struct nullb_cmd *cmd = blk_mq_rq_to_pdu(bd->rq); |
| 378 | 359 | ||
| 360 | if (irqmode == NULL_IRQ_TIMER) { | ||
| 361 | hrtimer_init(&cmd->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | ||
| 362 | cmd->timer.function = null_cmd_timer_expired; | ||
| 363 | } | ||
| 379 | cmd->rq = bd->rq; | 364 | cmd->rq = bd->rq; |
| 380 | cmd->nq = hctx->driver_data; | 365 | cmd->nq = hctx->driver_data; |
| 381 | 366 | ||
| @@ -813,19 +798,6 @@ static int __init null_init(void) | |||
| 813 | 798 | ||
| 814 | mutex_init(&lock); | 799 | mutex_init(&lock); |
| 815 | 800 | ||
| 816 | /* Initialize a separate list for each CPU for issuing softirqs */ | ||
| 817 | for_each_possible_cpu(i) { | ||
| 818 | struct completion_queue *cq = &per_cpu(completion_queues, i); | ||
| 819 | |||
| 820 | init_llist_head(&cq->list); | ||
| 821 | |||
| 822 | if (irqmode != NULL_IRQ_TIMER) | ||
| 823 | continue; | ||
| 824 | |||
| 825 | hrtimer_init(&cq->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | ||
| 826 | cq->timer.function = null_cmd_timer_expired; | ||
| 827 | } | ||
| 828 | |||
| 829 | null_major = register_blkdev(0, "nullb"); | 801 | null_major = register_blkdev(0, "nullb"); |
| 830 | if (null_major < 0) | 802 | if (null_major < 0) |
| 831 | return null_major; | 803 | return null_major; |
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 235708c7c46e..81ea69fee7ca 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
| @@ -3442,6 +3442,7 @@ static void rbd_queue_workfn(struct work_struct *work) | |||
| 3442 | goto err_rq; | 3442 | goto err_rq; |
| 3443 | } | 3443 | } |
| 3444 | img_request->rq = rq; | 3444 | img_request->rq = rq; |
| 3445 | snapc = NULL; /* img_request consumes a ref */ | ||
| 3445 | 3446 | ||
| 3446 | if (op_type == OBJ_OP_DISCARD) | 3447 | if (op_type == OBJ_OP_DISCARD) |
| 3447 | result = rbd_img_request_fill(img_request, OBJ_REQUEST_NODATA, | 3448 | result = rbd_img_request_fill(img_request, OBJ_REQUEST_NODATA, |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index a83c995a62df..8412ce5f93a7 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
| @@ -976,10 +976,14 @@ static int cpufreq_init_policy(struct cpufreq_policy *policy) | |||
| 976 | 976 | ||
| 977 | new_policy.governor = gov; | 977 | new_policy.governor = gov; |
| 978 | 978 | ||
| 979 | /* Use the default policy if its valid. */ | 979 | /* Use the default policy if there is no last_policy. */ |
| 980 | if (cpufreq_driver->setpolicy) | 980 | if (cpufreq_driver->setpolicy) { |
| 981 | cpufreq_parse_governor(gov->name, &new_policy.policy, NULL); | 981 | if (policy->last_policy) |
| 982 | 982 | new_policy.policy = policy->last_policy; | |
| 983 | else | ||
| 984 | cpufreq_parse_governor(gov->name, &new_policy.policy, | ||
| 985 | NULL); | ||
| 986 | } | ||
| 983 | /* set default policy */ | 987 | /* set default policy */ |
| 984 | return cpufreq_set_policy(policy, &new_policy); | 988 | return cpufreq_set_policy(policy, &new_policy); |
| 985 | } | 989 | } |
| @@ -1330,6 +1334,8 @@ static void cpufreq_offline_prepare(unsigned int cpu) | |||
| 1330 | if (has_target()) | 1334 | if (has_target()) |
| 1331 | strncpy(policy->last_governor, policy->governor->name, | 1335 | strncpy(policy->last_governor, policy->governor->name, |
| 1332 | CPUFREQ_NAME_LEN); | 1336 | CPUFREQ_NAME_LEN); |
| 1337 | else | ||
| 1338 | policy->last_policy = policy->policy; | ||
| 1333 | } else if (cpu == policy->cpu) { | 1339 | } else if (cpu == policy->cpu) { |
| 1334 | /* Nominate new CPU */ | 1340 | /* Nominate new CPU */ |
| 1335 | policy->cpu = cpumask_any(policy->cpus); | 1341 | policy->cpu = cpumask_any(policy->cpus); |
diff --git a/drivers/crypto/nx/nx-aes-ccm.c b/drivers/crypto/nx/nx-aes-ccm.c index 73ef49922788..7038f364acb5 100644 --- a/drivers/crypto/nx/nx-aes-ccm.c +++ b/drivers/crypto/nx/nx-aes-ccm.c | |||
| @@ -409,7 +409,7 @@ static int ccm_nx_decrypt(struct aead_request *req, | |||
| 409 | processed += to_process; | 409 | processed += to_process; |
| 410 | } while (processed < nbytes); | 410 | } while (processed < nbytes); |
| 411 | 411 | ||
| 412 | rc = memcmp(csbcpb->cpb.aes_ccm.out_pat_or_mac, priv->oauth_tag, | 412 | rc = crypto_memneq(csbcpb->cpb.aes_ccm.out_pat_or_mac, priv->oauth_tag, |
| 413 | authsize) ? -EBADMSG : 0; | 413 | authsize) ? -EBADMSG : 0; |
| 414 | out: | 414 | out: |
| 415 | spin_unlock_irqrestore(&nx_ctx->lock, irq_flags); | 415 | spin_unlock_irqrestore(&nx_ctx->lock, irq_flags); |
diff --git a/drivers/crypto/nx/nx-aes-gcm.c b/drivers/crypto/nx/nx-aes-gcm.c index eee624f589b6..abd465f479c4 100644 --- a/drivers/crypto/nx/nx-aes-gcm.c +++ b/drivers/crypto/nx/nx-aes-gcm.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | 21 | ||
| 22 | #include <crypto/internal/aead.h> | 22 | #include <crypto/internal/aead.h> |
| 23 | #include <crypto/aes.h> | 23 | #include <crypto/aes.h> |
| 24 | #include <crypto/algapi.h> | ||
| 24 | #include <crypto/scatterwalk.h> | 25 | #include <crypto/scatterwalk.h> |
| 25 | #include <linux/module.h> | 26 | #include <linux/module.h> |
| 26 | #include <linux/types.h> | 27 | #include <linux/types.h> |
| @@ -418,7 +419,7 @@ mac: | |||
| 418 | itag, req->src, req->assoclen + nbytes, | 419 | itag, req->src, req->assoclen + nbytes, |
| 419 | crypto_aead_authsize(crypto_aead_reqtfm(req)), | 420 | crypto_aead_authsize(crypto_aead_reqtfm(req)), |
| 420 | SCATTERWALK_FROM_SG); | 421 | SCATTERWALK_FROM_SG); |
| 421 | rc = memcmp(itag, otag, | 422 | rc = crypto_memneq(itag, otag, |
| 422 | crypto_aead_authsize(crypto_aead_reqtfm(req))) ? | 423 | crypto_aead_authsize(crypto_aead_reqtfm(req))) ? |
| 423 | -EBADMSG : 0; | 424 | -EBADMSG : 0; |
| 424 | } | 425 | } |
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index 46f531e19ccf..b6f9f42e2985 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c | |||
| @@ -977,7 +977,7 @@ static void ipsec_esp_decrypt_swauth_done(struct device *dev, | |||
| 977 | } else | 977 | } else |
| 978 | oicv = (char *)&edesc->link_tbl[0]; | 978 | oicv = (char *)&edesc->link_tbl[0]; |
| 979 | 979 | ||
| 980 | err = memcmp(oicv, icv, authsize) ? -EBADMSG : 0; | 980 | err = crypto_memneq(oicv, icv, authsize) ? -EBADMSG : 0; |
| 981 | } | 981 | } |
| 982 | 982 | ||
| 983 | kfree(edesc); | 983 | kfree(edesc); |
diff --git a/drivers/gpio/gpio-74xx-mmio.c b/drivers/gpio/gpio-74xx-mmio.c index 6ed7c0fb3378..6b186829087c 100644 --- a/drivers/gpio/gpio-74xx-mmio.c +++ b/drivers/gpio/gpio-74xx-mmio.c | |||
| @@ -113,13 +113,16 @@ static int mmio_74xx_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) | |||
| 113 | 113 | ||
| 114 | static int mmio_74xx_gpio_probe(struct platform_device *pdev) | 114 | static int mmio_74xx_gpio_probe(struct platform_device *pdev) |
| 115 | { | 115 | { |
| 116 | const struct of_device_id *of_id = | 116 | const struct of_device_id *of_id; |
| 117 | of_match_device(mmio_74xx_gpio_ids, &pdev->dev); | ||
| 118 | struct mmio_74xx_gpio_priv *priv; | 117 | struct mmio_74xx_gpio_priv *priv; |
| 119 | struct resource *res; | 118 | struct resource *res; |
| 120 | void __iomem *dat; | 119 | void __iomem *dat; |
| 121 | int err; | 120 | int err; |
| 122 | 121 | ||
| 122 | of_id = of_match_device(mmio_74xx_gpio_ids, &pdev->dev); | ||
| 123 | if (!of_id) | ||
| 124 | return -ENODEV; | ||
| 125 | |||
| 123 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); | 126 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); |
| 124 | if (!priv) | 127 | if (!priv) |
| 125 | return -ENOMEM; | 128 | return -ENOMEM; |
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 56d2d026e62e..f7fbb46d5d79 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c | |||
| @@ -1122,8 +1122,6 @@ static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc) | |||
| 1122 | /* MPUIO is a bit different, reading IRQ status clears it */ | 1122 | /* MPUIO is a bit different, reading IRQ status clears it */ |
| 1123 | if (bank->is_mpuio) { | 1123 | if (bank->is_mpuio) { |
| 1124 | irqc->irq_ack = dummy_irq_chip.irq_ack; | 1124 | irqc->irq_ack = dummy_irq_chip.irq_ack; |
| 1125 | irqc->irq_mask = irq_gc_mask_set_bit; | ||
| 1126 | irqc->irq_unmask = irq_gc_mask_clr_bit; | ||
| 1127 | if (!bank->regs->wkup_en) | 1125 | if (!bank->regs->wkup_en) |
| 1128 | irqc->irq_set_wake = NULL; | 1126 | irqc->irq_set_wake = NULL; |
| 1129 | } | 1127 | } |
diff --git a/drivers/gpio/gpio-palmas.c b/drivers/gpio/gpio-palmas.c index 171a6389f9ce..52b447c071cb 100644 --- a/drivers/gpio/gpio-palmas.c +++ b/drivers/gpio/gpio-palmas.c | |||
| @@ -167,6 +167,8 @@ static int palmas_gpio_probe(struct platform_device *pdev) | |||
| 167 | const struct palmas_device_data *dev_data; | 167 | const struct palmas_device_data *dev_data; |
| 168 | 168 | ||
| 169 | match = of_match_device(of_palmas_gpio_match, &pdev->dev); | 169 | match = of_match_device(of_palmas_gpio_match, &pdev->dev); |
| 170 | if (!match) | ||
| 171 | return -ENODEV; | ||
| 170 | dev_data = match->data; | 172 | dev_data = match->data; |
| 171 | if (!dev_data) | 173 | if (!dev_data) |
| 172 | dev_data = &palmas_dev_data; | 174 | dev_data = &palmas_dev_data; |
diff --git a/drivers/gpio/gpio-syscon.c b/drivers/gpio/gpio-syscon.c index 045a952576c7..7b25fdf64802 100644 --- a/drivers/gpio/gpio-syscon.c +++ b/drivers/gpio/gpio-syscon.c | |||
| @@ -187,11 +187,15 @@ MODULE_DEVICE_TABLE(of, syscon_gpio_ids); | |||
| 187 | static int syscon_gpio_probe(struct platform_device *pdev) | 187 | static int syscon_gpio_probe(struct platform_device *pdev) |
| 188 | { | 188 | { |
| 189 | struct device *dev = &pdev->dev; | 189 | struct device *dev = &pdev->dev; |
| 190 | const struct of_device_id *of_id = of_match_device(syscon_gpio_ids, dev); | 190 | const struct of_device_id *of_id; |
| 191 | struct syscon_gpio_priv *priv; | 191 | struct syscon_gpio_priv *priv; |
| 192 | struct device_node *np = dev->of_node; | 192 | struct device_node *np = dev->of_node; |
| 193 | int ret; | 193 | int ret; |
| 194 | 194 | ||
| 195 | of_id = of_match_device(syscon_gpio_ids, dev); | ||
| 196 | if (!of_id) | ||
| 197 | return -ENODEV; | ||
| 198 | |||
| 195 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | 199 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); |
| 196 | if (!priv) | 200 | if (!priv) |
| 197 | return -ENOMEM; | 201 | return -ENOMEM; |
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index 027e5f47dd28..896bf29776b0 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c | |||
| @@ -375,6 +375,60 @@ static int tegra_gpio_irq_set_wake(struct irq_data *d, unsigned int enable) | |||
| 375 | } | 375 | } |
| 376 | #endif | 376 | #endif |
| 377 | 377 | ||
| 378 | #ifdef CONFIG_DEBUG_FS | ||
| 379 | |||
| 380 | #include <linux/debugfs.h> | ||
| 381 | #include <linux/seq_file.h> | ||
| 382 | |||
| 383 | static int dbg_gpio_show(struct seq_file *s, void *unused) | ||
| 384 | { | ||
| 385 | int i; | ||
| 386 | int j; | ||
| 387 | |||
| 388 | for (i = 0; i < tegra_gpio_bank_count; i++) { | ||
| 389 | for (j = 0; j < 4; j++) { | ||
| 390 | int gpio = tegra_gpio_compose(i, j, 0); | ||
| 391 | seq_printf(s, | ||
| 392 | "%d:%d %02x %02x %02x %02x %02x %02x %06x\n", | ||
| 393 | i, j, | ||
| 394 | tegra_gpio_readl(GPIO_CNF(gpio)), | ||
| 395 | tegra_gpio_readl(GPIO_OE(gpio)), | ||
| 396 | tegra_gpio_readl(GPIO_OUT(gpio)), | ||
| 397 | tegra_gpio_readl(GPIO_IN(gpio)), | ||
| 398 | tegra_gpio_readl(GPIO_INT_STA(gpio)), | ||
| 399 | tegra_gpio_readl(GPIO_INT_ENB(gpio)), | ||
| 400 | tegra_gpio_readl(GPIO_INT_LVL(gpio))); | ||
| 401 | } | ||
| 402 | } | ||
| 403 | return 0; | ||
| 404 | } | ||
| 405 | |||
| 406 | static int dbg_gpio_open(struct inode *inode, struct file *file) | ||
| 407 | { | ||
| 408 | return single_open(file, dbg_gpio_show, &inode->i_private); | ||
| 409 | } | ||
| 410 | |||
| 411 | static const struct file_operations debug_fops = { | ||
| 412 | .open = dbg_gpio_open, | ||
| 413 | .read = seq_read, | ||
| 414 | .llseek = seq_lseek, | ||
| 415 | .release = single_release, | ||
| 416 | }; | ||
| 417 | |||
| 418 | static void tegra_gpio_debuginit(void) | ||
| 419 | { | ||
| 420 | (void) debugfs_create_file("tegra_gpio", S_IRUGO, | ||
| 421 | NULL, NULL, &debug_fops); | ||
| 422 | } | ||
| 423 | |||
| 424 | #else | ||
| 425 | |||
| 426 | static inline void tegra_gpio_debuginit(void) | ||
| 427 | { | ||
| 428 | } | ||
| 429 | |||
| 430 | #endif | ||
| 431 | |||
| 378 | static struct irq_chip tegra_gpio_irq_chip = { | 432 | static struct irq_chip tegra_gpio_irq_chip = { |
| 379 | .name = "GPIO", | 433 | .name = "GPIO", |
| 380 | .irq_ack = tegra_gpio_irq_ack, | 434 | .irq_ack = tegra_gpio_irq_ack, |
| @@ -519,6 +573,8 @@ static int tegra_gpio_probe(struct platform_device *pdev) | |||
| 519 | spin_lock_init(&bank->lvl_lock[j]); | 573 | spin_lock_init(&bank->lvl_lock[j]); |
| 520 | } | 574 | } |
| 521 | 575 | ||
| 576 | tegra_gpio_debuginit(); | ||
| 577 | |||
| 522 | return 0; | 578 | return 0; |
| 523 | } | 579 | } |
| 524 | 580 | ||
| @@ -536,52 +592,3 @@ static int __init tegra_gpio_init(void) | |||
| 536 | return platform_driver_register(&tegra_gpio_driver); | 592 | return platform_driver_register(&tegra_gpio_driver); |
| 537 | } | 593 | } |
| 538 | postcore_initcall(tegra_gpio_init); | 594 | postcore_initcall(tegra_gpio_init); |
| 539 | |||
| 540 | #ifdef CONFIG_DEBUG_FS | ||
| 541 | |||
| 542 | #include <linux/debugfs.h> | ||
| 543 | #include <linux/seq_file.h> | ||
| 544 | |||
| 545 | static int dbg_gpio_show(struct seq_file *s, void *unused) | ||
| 546 | { | ||
| 547 | int i; | ||
| 548 | int j; | ||
| 549 | |||
| 550 | for (i = 0; i < tegra_gpio_bank_count; i++) { | ||
| 551 | for (j = 0; j < 4; j++) { | ||
| 552 | int gpio = tegra_gpio_compose(i, j, 0); | ||
| 553 | seq_printf(s, | ||
| 554 | "%d:%d %02x %02x %02x %02x %02x %02x %06x\n", | ||
| 555 | i, j, | ||
| 556 | tegra_gpio_readl(GPIO_CNF(gpio)), | ||
| 557 | tegra_gpio_readl(GPIO_OE(gpio)), | ||
| 558 | tegra_gpio_readl(GPIO_OUT(gpio)), | ||
| 559 | tegra_gpio_readl(GPIO_IN(gpio)), | ||
| 560 | tegra_gpio_readl(GPIO_INT_STA(gpio)), | ||
| 561 | tegra_gpio_readl(GPIO_INT_ENB(gpio)), | ||
| 562 | tegra_gpio_readl(GPIO_INT_LVL(gpio))); | ||
| 563 | } | ||
| 564 | } | ||
| 565 | return 0; | ||
| 566 | } | ||
| 567 | |||
| 568 | static int dbg_gpio_open(struct inode *inode, struct file *file) | ||
| 569 | { | ||
| 570 | return single_open(file, dbg_gpio_show, &inode->i_private); | ||
| 571 | } | ||
| 572 | |||
| 573 | static const struct file_operations debug_fops = { | ||
| 574 | .open = dbg_gpio_open, | ||
| 575 | .read = seq_read, | ||
| 576 | .llseek = seq_lseek, | ||
| 577 | .release = single_release, | ||
| 578 | }; | ||
| 579 | |||
| 580 | static int __init tegra_gpio_debuginit(void) | ||
| 581 | { | ||
| 582 | (void) debugfs_create_file("tegra_gpio", S_IRUGO, | ||
| 583 | NULL, NULL, &debug_fops); | ||
| 584 | return 0; | ||
| 585 | } | ||
| 586 | late_initcall(tegra_gpio_debuginit); | ||
| 587 | #endif | ||
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index a18f00fc1bb8..2a91f3287e3b 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
| @@ -233,7 +233,7 @@ static struct gpio_desc *gpio_name_to_desc(const char * const name) | |||
| 233 | for (i = 0; i != chip->ngpio; ++i) { | 233 | for (i = 0; i != chip->ngpio; ++i) { |
| 234 | struct gpio_desc *gpio = &chip->desc[i]; | 234 | struct gpio_desc *gpio = &chip->desc[i]; |
| 235 | 235 | ||
| 236 | if (!gpio->name) | 236 | if (!gpio->name || !name) |
| 237 | continue; | 237 | continue; |
| 238 | 238 | ||
| 239 | if (!strcmp(gpio->name, name)) { | 239 | if (!strcmp(gpio->name, name)) { |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index ac1feea51be3..9024a3de4032 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
| @@ -609,6 +609,7 @@ | |||
| 609 | #define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110 | 609 | #define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110 |
| 610 | #define USB_DEVICE_ID_LOGITECH_HARMONY_LAST 0xc14f | 610 | #define USB_DEVICE_ID_LOGITECH_HARMONY_LAST 0xc14f |
| 611 | #define USB_DEVICE_ID_LOGITECH_HARMONY_PS3 0x0306 | 611 | #define USB_DEVICE_ID_LOGITECH_HARMONY_PS3 0x0306 |
| 612 | #define USB_DEVICE_ID_LOGITECH_KEYBOARD_G710_PLUS 0xc24d | ||
| 612 | #define USB_DEVICE_ID_LOGITECH_MOUSE_C01A 0xc01a | 613 | #define USB_DEVICE_ID_LOGITECH_MOUSE_C01A 0xc01a |
| 613 | #define USB_DEVICE_ID_LOGITECH_MOUSE_C05A 0xc05a | 614 | #define USB_DEVICE_ID_LOGITECH_MOUSE_C05A 0xc05a |
| 614 | #define USB_DEVICE_ID_LOGITECH_MOUSE_C06A 0xc06a | 615 | #define USB_DEVICE_ID_LOGITECH_MOUSE_C06A 0xc06a |
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c index c20ac76c0a8c..c690fae02cf8 100644 --- a/drivers/hid/hid-lg.c +++ b/drivers/hid/hid-lg.c | |||
| @@ -665,8 +665,9 @@ static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
| 665 | struct lg_drv_data *drv_data; | 665 | struct lg_drv_data *drv_data; |
| 666 | int ret; | 666 | int ret; |
| 667 | 667 | ||
| 668 | /* Only work with the 1st interface (G29 presents multiple) */ | 668 | /* G29 only work with the 1st interface */ |
| 669 | if (iface_num != 0) { | 669 | if ((hdev->product == USB_DEVICE_ID_LOGITECH_G29_WHEEL) && |
| 670 | (iface_num != 0)) { | ||
| 670 | dbg_hid("%s: ignoring ifnum %d\n", __func__, iface_num); | 671 | dbg_hid("%s: ignoring ifnum %d\n", __func__, iface_num); |
| 671 | return -ENODEV; | 672 | return -ENODEV; |
| 672 | } | 673 | } |
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 94bb137abe32..2324520b006d 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c | |||
| @@ -84,6 +84,7 @@ static const struct hid_blacklist { | |||
| 84 | { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A, HID_QUIRK_ALWAYS_POLL }, | 84 | { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A, HID_QUIRK_ALWAYS_POLL }, |
| 85 | { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL }, | 85 | { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL }, |
| 86 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C077, HID_QUIRK_ALWAYS_POLL }, | 86 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C077, HID_QUIRK_ALWAYS_POLL }, |
| 87 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KEYBOARD_G710_PLUS, HID_QUIRK_NOGET }, | ||
| 87 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C01A, HID_QUIRK_ALWAYS_POLL }, | 88 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C01A, HID_QUIRK_ALWAYS_POLL }, |
| 88 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C05A, HID_QUIRK_ALWAYS_POLL }, | 89 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C05A, HID_QUIRK_ALWAYS_POLL }, |
| 89 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C06A, HID_QUIRK_ALWAYS_POLL }, | 90 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C06A, HID_QUIRK_ALWAYS_POLL }, |
diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c index b33f53b3ca93..bf04d2a3cf4a 100644 --- a/drivers/isdn/hisax/config.c +++ b/drivers/isdn/hisax/config.c | |||
| @@ -1896,7 +1896,7 @@ static void EChannel_proc_rcv(struct hisax_d_if *d_if) | |||
| 1896 | ptr--; | 1896 | ptr--; |
| 1897 | *ptr++ = '\n'; | 1897 | *ptr++ = '\n'; |
| 1898 | *ptr = 0; | 1898 | *ptr = 0; |
| 1899 | HiSax_putstatus(cs, NULL, "%s", cs->dlog); | 1899 | HiSax_putstatus(cs, NULL, cs->dlog); |
| 1900 | } else | 1900 | } else |
| 1901 | HiSax_putstatus(cs, "LogEcho: ", | 1901 | HiSax_putstatus(cs, "LogEcho: ", |
| 1902 | "warning Frame too big (%d)", | 1902 | "warning Frame too big (%d)", |
diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c index 4a4825528188..90449e1e91e5 100644 --- a/drivers/isdn/hisax/hfc_pci.c +++ b/drivers/isdn/hisax/hfc_pci.c | |||
| @@ -901,7 +901,7 @@ Begin: | |||
| 901 | ptr--; | 901 | ptr--; |
| 902 | *ptr++ = '\n'; | 902 | *ptr++ = '\n'; |
| 903 | *ptr = 0; | 903 | *ptr = 0; |
| 904 | HiSax_putstatus(cs, NULL, "%s", cs->dlog); | 904 | HiSax_putstatus(cs, NULL, cs->dlog); |
| 905 | } else | 905 | } else |
| 906 | HiSax_putstatus(cs, "LogEcho: ", "warning Frame too big (%d)", total - 3); | 906 | HiSax_putstatus(cs, "LogEcho: ", "warning Frame too big (%d)", total - 3); |
| 907 | } | 907 | } |
diff --git a/drivers/isdn/hisax/hfc_sx.c b/drivers/isdn/hisax/hfc_sx.c index b1fad81f0722..13b2151c10f5 100644 --- a/drivers/isdn/hisax/hfc_sx.c +++ b/drivers/isdn/hisax/hfc_sx.c | |||
| @@ -674,7 +674,7 @@ receive_emsg(struct IsdnCardState *cs) | |||
| 674 | ptr--; | 674 | ptr--; |
| 675 | *ptr++ = '\n'; | 675 | *ptr++ = '\n'; |
| 676 | *ptr = 0; | 676 | *ptr = 0; |
| 677 | HiSax_putstatus(cs, NULL, "%s", cs->dlog); | 677 | HiSax_putstatus(cs, NULL, cs->dlog); |
| 678 | } else | 678 | } else |
| 679 | HiSax_putstatus(cs, "LogEcho: ", "warning Frame too big (%d)", skb->len); | 679 | HiSax_putstatus(cs, "LogEcho: ", "warning Frame too big (%d)", skb->len); |
| 680 | } | 680 | } |
diff --git a/drivers/isdn/hisax/q931.c b/drivers/isdn/hisax/q931.c index b420f8bd862e..ba4beb25d872 100644 --- a/drivers/isdn/hisax/q931.c +++ b/drivers/isdn/hisax/q931.c | |||
| @@ -1179,7 +1179,7 @@ LogFrame(struct IsdnCardState *cs, u_char *buf, int size) | |||
| 1179 | dp--; | 1179 | dp--; |
| 1180 | *dp++ = '\n'; | 1180 | *dp++ = '\n'; |
| 1181 | *dp = 0; | 1181 | *dp = 0; |
| 1182 | HiSax_putstatus(cs, NULL, "%s", cs->dlog); | 1182 | HiSax_putstatus(cs, NULL, cs->dlog); |
| 1183 | } else | 1183 | } else |
| 1184 | HiSax_putstatus(cs, "LogFrame: ", "warning Frame too big (%d)", size); | 1184 | HiSax_putstatus(cs, "LogFrame: ", "warning Frame too big (%d)", size); |
| 1185 | } | 1185 | } |
| @@ -1246,7 +1246,7 @@ dlogframe(struct IsdnCardState *cs, struct sk_buff *skb, int dir) | |||
| 1246 | } | 1246 | } |
| 1247 | if (finish) { | 1247 | if (finish) { |
| 1248 | *dp = 0; | 1248 | *dp = 0; |
| 1249 | HiSax_putstatus(cs, NULL, "%s", cs->dlog); | 1249 | HiSax_putstatus(cs, NULL, cs->dlog); |
| 1250 | return; | 1250 | return; |
| 1251 | } | 1251 | } |
| 1252 | if ((0xfe & buf[0]) == PROTO_DIS_N0) { /* 1TR6 */ | 1252 | if ((0xfe & buf[0]) == PROTO_DIS_N0) { /* 1TR6 */ |
| @@ -1509,5 +1509,5 @@ dlogframe(struct IsdnCardState *cs, struct sk_buff *skb, int dir) | |||
| 1509 | dp += sprintf(dp, "Unknown protocol %x!", buf[0]); | 1509 | dp += sprintf(dp, "Unknown protocol %x!", buf[0]); |
| 1510 | } | 1510 | } |
| 1511 | *dp = 0; | 1511 | *dp = 0; |
| 1512 | HiSax_putstatus(cs, NULL, "%s", cs->dlog); | 1512 | HiSax_putstatus(cs, NULL, cs->dlog); |
| 1513 | } | 1513 | } |
diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c index 5178645ac42b..86ce887b2ed6 100644 --- a/drivers/lightnvm/core.c +++ b/drivers/lightnvm/core.c | |||
| @@ -123,6 +123,26 @@ void nvm_unregister_mgr(struct nvmm_type *mt) | |||
| 123 | } | 123 | } |
| 124 | EXPORT_SYMBOL(nvm_unregister_mgr); | 124 | EXPORT_SYMBOL(nvm_unregister_mgr); |
| 125 | 125 | ||
| 126 | /* register with device with a supported manager */ | ||
| 127 | static int register_mgr(struct nvm_dev *dev) | ||
| 128 | { | ||
| 129 | struct nvmm_type *mt; | ||
| 130 | int ret = 0; | ||
| 131 | |||
| 132 | list_for_each_entry(mt, &nvm_mgrs, list) { | ||
| 133 | ret = mt->register_mgr(dev); | ||
| 134 | if (ret > 0) { | ||
| 135 | dev->mt = mt; | ||
| 136 | break; /* successfully initialized */ | ||
| 137 | } | ||
| 138 | } | ||
| 139 | |||
| 140 | if (!ret) | ||
| 141 | pr_info("nvm: no compatible nvm manager found.\n"); | ||
| 142 | |||
| 143 | return ret; | ||
| 144 | } | ||
| 145 | |||
| 126 | static struct nvm_dev *nvm_find_nvm_dev(const char *name) | 146 | static struct nvm_dev *nvm_find_nvm_dev(const char *name) |
| 127 | { | 147 | { |
| 128 | struct nvm_dev *dev; | 148 | struct nvm_dev *dev; |
| @@ -221,7 +241,6 @@ static void nvm_free(struct nvm_dev *dev) | |||
| 221 | 241 | ||
| 222 | static int nvm_init(struct nvm_dev *dev) | 242 | static int nvm_init(struct nvm_dev *dev) |
| 223 | { | 243 | { |
| 224 | struct nvmm_type *mt; | ||
| 225 | int ret = -EINVAL; | 244 | int ret = -EINVAL; |
| 226 | 245 | ||
| 227 | if (!dev->q || !dev->ops) | 246 | if (!dev->q || !dev->ops) |
| @@ -252,21 +271,13 @@ static int nvm_init(struct nvm_dev *dev) | |||
| 252 | goto err; | 271 | goto err; |
| 253 | } | 272 | } |
| 254 | 273 | ||
| 255 | /* register with device with a supported manager */ | 274 | down_write(&nvm_lock); |
| 256 | list_for_each_entry(mt, &nvm_mgrs, list) { | 275 | ret = register_mgr(dev); |
| 257 | ret = mt->register_mgr(dev); | 276 | up_write(&nvm_lock); |
| 258 | if (ret < 0) | 277 | if (ret < 0) |
| 259 | goto err; /* initialization failed */ | 278 | goto err; |
| 260 | if (ret > 0) { | 279 | if (!ret) |
| 261 | dev->mt = mt; | ||
| 262 | break; /* successfully initialized */ | ||
| 263 | } | ||
| 264 | } | ||
| 265 | |||
| 266 | if (!ret) { | ||
| 267 | pr_info("nvm: no compatible manager found.\n"); | ||
| 268 | return 0; | 280 | return 0; |
| 269 | } | ||
| 270 | 281 | ||
| 271 | pr_info("nvm: registered %s [%u/%u/%u/%u/%u/%u]\n", | 282 | pr_info("nvm: registered %s [%u/%u/%u/%u/%u/%u]\n", |
| 272 | dev->name, dev->sec_per_pg, dev->nr_planes, | 283 | dev->name, dev->sec_per_pg, dev->nr_planes, |
| @@ -308,6 +319,12 @@ int nvm_register(struct request_queue *q, char *disk_name, | |||
| 308 | if (ret) | 319 | if (ret) |
| 309 | goto err_init; | 320 | goto err_init; |
| 310 | 321 | ||
| 322 | if (dev->ops->max_phys_sect > 256) { | ||
| 323 | pr_info("nvm: max sectors supported is 256.\n"); | ||
| 324 | ret = -EINVAL; | ||
| 325 | goto err_init; | ||
| 326 | } | ||
| 327 | |||
| 311 | if (dev->ops->max_phys_sect > 1) { | 328 | if (dev->ops->max_phys_sect > 1) { |
| 312 | dev->ppalist_pool = dev->ops->create_dma_pool(dev->q, | 329 | dev->ppalist_pool = dev->ops->create_dma_pool(dev->q, |
| 313 | "ppalist"); | 330 | "ppalist"); |
| @@ -316,10 +333,6 @@ int nvm_register(struct request_queue *q, char *disk_name, | |||
| 316 | ret = -ENOMEM; | 333 | ret = -ENOMEM; |
| 317 | goto err_init; | 334 | goto err_init; |
| 318 | } | 335 | } |
| 319 | } else if (dev->ops->max_phys_sect > 256) { | ||
| 320 | pr_info("nvm: max sectors supported is 256.\n"); | ||
| 321 | ret = -EINVAL; | ||
| 322 | goto err_init; | ||
| 323 | } | 336 | } |
| 324 | 337 | ||
| 325 | down_write(&nvm_lock); | 338 | down_write(&nvm_lock); |
| @@ -335,15 +348,17 @@ EXPORT_SYMBOL(nvm_register); | |||
| 335 | 348 | ||
| 336 | void nvm_unregister(char *disk_name) | 349 | void nvm_unregister(char *disk_name) |
| 337 | { | 350 | { |
| 338 | struct nvm_dev *dev = nvm_find_nvm_dev(disk_name); | 351 | struct nvm_dev *dev; |
| 339 | 352 | ||
| 353 | down_write(&nvm_lock); | ||
| 354 | dev = nvm_find_nvm_dev(disk_name); | ||
| 340 | if (!dev) { | 355 | if (!dev) { |
| 341 | pr_err("nvm: could not find device %s to unregister\n", | 356 | pr_err("nvm: could not find device %s to unregister\n", |
| 342 | disk_name); | 357 | disk_name); |
| 358 | up_write(&nvm_lock); | ||
| 343 | return; | 359 | return; |
| 344 | } | 360 | } |
| 345 | 361 | ||
| 346 | down_write(&nvm_lock); | ||
| 347 | list_del(&dev->devices); | 362 | list_del(&dev->devices); |
| 348 | up_write(&nvm_lock); | 363 | up_write(&nvm_lock); |
| 349 | 364 | ||
| @@ -361,38 +376,30 @@ static int nvm_create_target(struct nvm_dev *dev, | |||
| 361 | { | 376 | { |
| 362 | struct nvm_ioctl_create_simple *s = &create->conf.s; | 377 | struct nvm_ioctl_create_simple *s = &create->conf.s; |
| 363 | struct request_queue *tqueue; | 378 | struct request_queue *tqueue; |
| 364 | struct nvmm_type *mt; | ||
| 365 | struct gendisk *tdisk; | 379 | struct gendisk *tdisk; |
| 366 | struct nvm_tgt_type *tt; | 380 | struct nvm_tgt_type *tt; |
| 367 | struct nvm_target *t; | 381 | struct nvm_target *t; |
| 368 | void *targetdata; | 382 | void *targetdata; |
| 369 | int ret = 0; | 383 | int ret = 0; |
| 370 | 384 | ||
| 385 | down_write(&nvm_lock); | ||
| 371 | if (!dev->mt) { | 386 | if (!dev->mt) { |
| 372 | /* register with device with a supported NVM manager */ | 387 | ret = register_mgr(dev); |
| 373 | list_for_each_entry(mt, &nvm_mgrs, list) { | 388 | if (!ret) |
| 374 | ret = mt->register_mgr(dev); | 389 | ret = -ENODEV; |
| 375 | if (ret < 0) | 390 | if (ret < 0) { |
| 376 | return ret; /* initialization failed */ | 391 | up_write(&nvm_lock); |
| 377 | if (ret > 0) { | 392 | return ret; |
| 378 | dev->mt = mt; | ||
| 379 | break; /* successfully initialized */ | ||
| 380 | } | ||
| 381 | } | ||
| 382 | |||
| 383 | if (!ret) { | ||
| 384 | pr_info("nvm: no compatible nvm manager found.\n"); | ||
| 385 | return -ENODEV; | ||
| 386 | } | 393 | } |
| 387 | } | 394 | } |
| 388 | 395 | ||
| 389 | tt = nvm_find_target_type(create->tgttype); | 396 | tt = nvm_find_target_type(create->tgttype); |
| 390 | if (!tt) { | 397 | if (!tt) { |
| 391 | pr_err("nvm: target type %s not found\n", create->tgttype); | 398 | pr_err("nvm: target type %s not found\n", create->tgttype); |
| 399 | up_write(&nvm_lock); | ||
| 392 | return -EINVAL; | 400 | return -EINVAL; |
| 393 | } | 401 | } |
| 394 | 402 | ||
| 395 | down_write(&nvm_lock); | ||
| 396 | list_for_each_entry(t, &dev->online_targets, list) { | 403 | list_for_each_entry(t, &dev->online_targets, list) { |
| 397 | if (!strcmp(create->tgtname, t->disk->disk_name)) { | 404 | if (!strcmp(create->tgtname, t->disk->disk_name)) { |
| 398 | pr_err("nvm: target name already exists.\n"); | 405 | pr_err("nvm: target name already exists.\n"); |
| @@ -476,7 +483,9 @@ static int __nvm_configure_create(struct nvm_ioctl_create *create) | |||
| 476 | struct nvm_dev *dev; | 483 | struct nvm_dev *dev; |
| 477 | struct nvm_ioctl_create_simple *s; | 484 | struct nvm_ioctl_create_simple *s; |
| 478 | 485 | ||
| 486 | down_write(&nvm_lock); | ||
| 479 | dev = nvm_find_nvm_dev(create->dev); | 487 | dev = nvm_find_nvm_dev(create->dev); |
| 488 | up_write(&nvm_lock); | ||
| 480 | if (!dev) { | 489 | if (!dev) { |
| 481 | pr_err("nvm: device not found\n"); | 490 | pr_err("nvm: device not found\n"); |
| 482 | return -EINVAL; | 491 | return -EINVAL; |
| @@ -535,7 +544,9 @@ static int nvm_configure_show(const char *val) | |||
| 535 | return -EINVAL; | 544 | return -EINVAL; |
| 536 | } | 545 | } |
| 537 | 546 | ||
| 547 | down_write(&nvm_lock); | ||
| 538 | dev = nvm_find_nvm_dev(devname); | 548 | dev = nvm_find_nvm_dev(devname); |
| 549 | up_write(&nvm_lock); | ||
| 539 | if (!dev) { | 550 | if (!dev) { |
| 540 | pr_err("nvm: device not found\n"); | 551 | pr_err("nvm: device not found\n"); |
| 541 | return -EINVAL; | 552 | return -EINVAL; |
| @@ -680,8 +691,10 @@ static long nvm_ioctl_info(struct file *file, void __user *arg) | |||
| 680 | info->tgtsize = tgt_iter; | 691 | info->tgtsize = tgt_iter; |
| 681 | up_write(&nvm_lock); | 692 | up_write(&nvm_lock); |
| 682 | 693 | ||
| 683 | if (copy_to_user(arg, info, sizeof(struct nvm_ioctl_info))) | 694 | if (copy_to_user(arg, info, sizeof(struct nvm_ioctl_info))) { |
| 695 | kfree(info); | ||
| 684 | return -EFAULT; | 696 | return -EFAULT; |
| 697 | } | ||
| 685 | 698 | ||
| 686 | kfree(info); | 699 | kfree(info); |
| 687 | return 0; | 700 | return 0; |
| @@ -724,8 +737,11 @@ static long nvm_ioctl_get_devices(struct file *file, void __user *arg) | |||
| 724 | 737 | ||
| 725 | devices->nr_devices = i; | 738 | devices->nr_devices = i; |
| 726 | 739 | ||
| 727 | if (copy_to_user(arg, devices, sizeof(struct nvm_ioctl_get_devices))) | 740 | if (copy_to_user(arg, devices, |
| 741 | sizeof(struct nvm_ioctl_get_devices))) { | ||
| 742 | kfree(devices); | ||
| 728 | return -EFAULT; | 743 | return -EFAULT; |
| 744 | } | ||
| 729 | 745 | ||
| 730 | kfree(devices); | 746 | kfree(devices); |
| 731 | return 0; | 747 | return 0; |
diff --git a/drivers/lightnvm/gennvm.c b/drivers/lightnvm/gennvm.c index e20e74ec6b91..35dde84b71e9 100644 --- a/drivers/lightnvm/gennvm.c +++ b/drivers/lightnvm/gennvm.c | |||
| @@ -75,7 +75,6 @@ static int gennvm_block_bb(struct ppa_addr ppa, int nr_blocks, u8 *blks, | |||
| 75 | struct nvm_block *blk; | 75 | struct nvm_block *blk; |
| 76 | int i; | 76 | int i; |
| 77 | 77 | ||
| 78 | ppa = dev_to_generic_addr(gn->dev, ppa); | ||
| 79 | lun = &gn->luns[(dev->nr_luns * ppa.g.ch) + ppa.g.lun]; | 78 | lun = &gn->luns[(dev->nr_luns * ppa.g.ch) + ppa.g.lun]; |
| 80 | 79 | ||
| 81 | for (i = 0; i < nr_blocks; i++) { | 80 | for (i = 0; i < nr_blocks; i++) { |
| @@ -187,7 +186,7 @@ static int gennvm_blocks_init(struct nvm_dev *dev, struct gen_nvm *gn) | |||
| 187 | ppa.g.lun = lun->vlun.id; | 186 | ppa.g.lun = lun->vlun.id; |
| 188 | ppa = generic_to_dev_addr(dev, ppa); | 187 | ppa = generic_to_dev_addr(dev, ppa); |
| 189 | 188 | ||
| 190 | ret = dev->ops->get_bb_tbl(dev->q, ppa, | 189 | ret = dev->ops->get_bb_tbl(dev, ppa, |
| 191 | dev->blks_per_lun, | 190 | dev->blks_per_lun, |
| 192 | gennvm_block_bb, gn); | 191 | gennvm_block_bb, gn); |
| 193 | if (ret) | 192 | if (ret) |
| @@ -207,6 +206,14 @@ static int gennvm_blocks_init(struct nvm_dev *dev, struct gen_nvm *gn) | |||
| 207 | return 0; | 206 | return 0; |
| 208 | } | 207 | } |
| 209 | 208 | ||
| 209 | static void gennvm_free(struct nvm_dev *dev) | ||
| 210 | { | ||
| 211 | gennvm_blocks_free(dev); | ||
| 212 | gennvm_luns_free(dev); | ||
| 213 | kfree(dev->mp); | ||
| 214 | dev->mp = NULL; | ||
| 215 | } | ||
| 216 | |||
| 210 | static int gennvm_register(struct nvm_dev *dev) | 217 | static int gennvm_register(struct nvm_dev *dev) |
| 211 | { | 218 | { |
| 212 | struct gen_nvm *gn; | 219 | struct gen_nvm *gn; |
| @@ -234,16 +241,13 @@ static int gennvm_register(struct nvm_dev *dev) | |||
| 234 | 241 | ||
| 235 | return 1; | 242 | return 1; |
| 236 | err: | 243 | err: |
| 237 | kfree(gn); | 244 | gennvm_free(dev); |
| 238 | return ret; | 245 | return ret; |
| 239 | } | 246 | } |
| 240 | 247 | ||
| 241 | static void gennvm_unregister(struct nvm_dev *dev) | 248 | static void gennvm_unregister(struct nvm_dev *dev) |
| 242 | { | 249 | { |
| 243 | gennvm_blocks_free(dev); | 250 | gennvm_free(dev); |
| 244 | gennvm_luns_free(dev); | ||
| 245 | kfree(dev->mp); | ||
| 246 | dev->mp = NULL; | ||
| 247 | } | 251 | } |
| 248 | 252 | ||
| 249 | static struct nvm_block *gennvm_get_blk(struct nvm_dev *dev, | 253 | static struct nvm_block *gennvm_get_blk(struct nvm_dev *dev, |
diff --git a/drivers/net/can/bfin_can.c b/drivers/net/can/bfin_can.c index 57dadd52b428..1deb8ff90a89 100644 --- a/drivers/net/can/bfin_can.c +++ b/drivers/net/can/bfin_can.c | |||
| @@ -501,8 +501,6 @@ static int bfin_can_err(struct net_device *dev, u16 isrc, u16 status) | |||
| 501 | cf->data[2] |= CAN_ERR_PROT_FORM; | 501 | cf->data[2] |= CAN_ERR_PROT_FORM; |
| 502 | else if (status & SER) | 502 | else if (status & SER) |
| 503 | cf->data[2] |= CAN_ERR_PROT_STUFF; | 503 | cf->data[2] |= CAN_ERR_PROT_STUFF; |
| 504 | else | ||
| 505 | cf->data[2] |= CAN_ERR_PROT_UNSPEC; | ||
| 506 | } | 504 | } |
| 507 | 505 | ||
| 508 | priv->can.state = state; | 506 | priv->can.state = state; |
diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index 5d214d135332..f91b094288da 100644 --- a/drivers/net/can/c_can/c_can.c +++ b/drivers/net/can/c_can/c_can.c | |||
| @@ -962,7 +962,6 @@ static int c_can_handle_bus_err(struct net_device *dev, | |||
| 962 | * type of the last error to occur on the CAN bus | 962 | * type of the last error to occur on the CAN bus |
| 963 | */ | 963 | */ |
| 964 | cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; | 964 | cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; |
| 965 | cf->data[2] |= CAN_ERR_PROT_UNSPEC; | ||
| 966 | 965 | ||
| 967 | switch (lec_type) { | 966 | switch (lec_type) { |
| 968 | case LEC_STUFF_ERROR: | 967 | case LEC_STUFF_ERROR: |
| @@ -975,8 +974,7 @@ static int c_can_handle_bus_err(struct net_device *dev, | |||
| 975 | break; | 974 | break; |
| 976 | case LEC_ACK_ERROR: | 975 | case LEC_ACK_ERROR: |
| 977 | netdev_dbg(dev, "ack error\n"); | 976 | netdev_dbg(dev, "ack error\n"); |
| 978 | cf->data[3] |= (CAN_ERR_PROT_LOC_ACK | | 977 | cf->data[3] = CAN_ERR_PROT_LOC_ACK; |
| 979 | CAN_ERR_PROT_LOC_ACK_DEL); | ||
| 980 | break; | 978 | break; |
| 981 | case LEC_BIT1_ERROR: | 979 | case LEC_BIT1_ERROR: |
| 982 | netdev_dbg(dev, "bit1 error\n"); | 980 | netdev_dbg(dev, "bit1 error\n"); |
| @@ -988,8 +986,7 @@ static int c_can_handle_bus_err(struct net_device *dev, | |||
| 988 | break; | 986 | break; |
| 989 | case LEC_CRC_ERROR: | 987 | case LEC_CRC_ERROR: |
| 990 | netdev_dbg(dev, "CRC error\n"); | 988 | netdev_dbg(dev, "CRC error\n"); |
| 991 | cf->data[3] |= (CAN_ERR_PROT_LOC_CRC_SEQ | | 989 | cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ; |
| 992 | CAN_ERR_PROT_LOC_CRC_DEL); | ||
| 993 | break; | 990 | break; |
| 994 | default: | 991 | default: |
| 995 | break; | 992 | break; |
diff --git a/drivers/net/can/cc770/cc770.c b/drivers/net/can/cc770/cc770.c index 70a8cbb29e75..1e37313054f3 100644 --- a/drivers/net/can/cc770/cc770.c +++ b/drivers/net/can/cc770/cc770.c | |||
| @@ -578,7 +578,7 @@ static int cc770_err(struct net_device *dev, u8 status) | |||
| 578 | cf->data[2] |= CAN_ERR_PROT_BIT0; | 578 | cf->data[2] |= CAN_ERR_PROT_BIT0; |
| 579 | break; | 579 | break; |
| 580 | case STAT_LEC_CRC: | 580 | case STAT_LEC_CRC: |
| 581 | cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ; | 581 | cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ; |
| 582 | break; | 582 | break; |
| 583 | } | 583 | } |
| 584 | } | 584 | } |
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 868fe945e35a..41c0fc9f3b14 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c | |||
| @@ -535,13 +535,13 @@ static void do_bus_err(struct net_device *dev, | |||
| 535 | if (reg_esr & FLEXCAN_ESR_ACK_ERR) { | 535 | if (reg_esr & FLEXCAN_ESR_ACK_ERR) { |
| 536 | netdev_dbg(dev, "ACK_ERR irq\n"); | 536 | netdev_dbg(dev, "ACK_ERR irq\n"); |
| 537 | cf->can_id |= CAN_ERR_ACK; | 537 | cf->can_id |= CAN_ERR_ACK; |
| 538 | cf->data[3] |= CAN_ERR_PROT_LOC_ACK; | 538 | cf->data[3] = CAN_ERR_PROT_LOC_ACK; |
| 539 | tx_errors = 1; | 539 | tx_errors = 1; |
| 540 | } | 540 | } |
| 541 | if (reg_esr & FLEXCAN_ESR_CRC_ERR) { | 541 | if (reg_esr & FLEXCAN_ESR_CRC_ERR) { |
| 542 | netdev_dbg(dev, "CRC_ERR irq\n"); | 542 | netdev_dbg(dev, "CRC_ERR irq\n"); |
| 543 | cf->data[2] |= CAN_ERR_PROT_BIT; | 543 | cf->data[2] |= CAN_ERR_PROT_BIT; |
| 544 | cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ; | 544 | cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ; |
| 545 | rx_errors = 1; | 545 | rx_errors = 1; |
| 546 | } | 546 | } |
| 547 | if (reg_esr & FLEXCAN_ESR_FRM_ERR) { | 547 | if (reg_esr & FLEXCAN_ESR_FRM_ERR) { |
diff --git a/drivers/net/can/janz-ican3.c b/drivers/net/can/janz-ican3.c index c1e85368a198..5d04f5464faf 100644 --- a/drivers/net/can/janz-ican3.c +++ b/drivers/net/can/janz-ican3.c | |||
| @@ -1096,7 +1096,6 @@ static int ican3_handle_cevtind(struct ican3_dev *mod, struct ican3_msg *msg) | |||
| 1096 | cf->data[2] |= CAN_ERR_PROT_STUFF; | 1096 | cf->data[2] |= CAN_ERR_PROT_STUFF; |
| 1097 | break; | 1097 | break; |
| 1098 | default: | 1098 | default: |
| 1099 | cf->data[2] |= CAN_ERR_PROT_UNSPEC; | ||
| 1100 | cf->data[3] = ecc & ECC_SEG; | 1099 | cf->data[3] = ecc & ECC_SEG; |
| 1101 | break; | 1100 | break; |
| 1102 | } | 1101 | } |
diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index ef655177bb5e..39cf911f7a1e 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c | |||
| @@ -487,7 +487,6 @@ static int m_can_handle_lec_err(struct net_device *dev, | |||
| 487 | * type of the last error to occur on the CAN bus | 487 | * type of the last error to occur on the CAN bus |
| 488 | */ | 488 | */ |
| 489 | cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; | 489 | cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; |
| 490 | cf->data[2] |= CAN_ERR_PROT_UNSPEC; | ||
| 491 | 490 | ||
| 492 | switch (lec_type) { | 491 | switch (lec_type) { |
| 493 | case LEC_STUFF_ERROR: | 492 | case LEC_STUFF_ERROR: |
| @@ -500,8 +499,7 @@ static int m_can_handle_lec_err(struct net_device *dev, | |||
| 500 | break; | 499 | break; |
| 501 | case LEC_ACK_ERROR: | 500 | case LEC_ACK_ERROR: |
| 502 | netdev_dbg(dev, "ack error\n"); | 501 | netdev_dbg(dev, "ack error\n"); |
| 503 | cf->data[3] |= (CAN_ERR_PROT_LOC_ACK | | 502 | cf->data[3] = CAN_ERR_PROT_LOC_ACK; |
| 504 | CAN_ERR_PROT_LOC_ACK_DEL); | ||
| 505 | break; | 503 | break; |
| 506 | case LEC_BIT1_ERROR: | 504 | case LEC_BIT1_ERROR: |
| 507 | netdev_dbg(dev, "bit1 error\n"); | 505 | netdev_dbg(dev, "bit1 error\n"); |
| @@ -513,8 +511,7 @@ static int m_can_handle_lec_err(struct net_device *dev, | |||
| 513 | break; | 511 | break; |
| 514 | case LEC_CRC_ERROR: | 512 | case LEC_CRC_ERROR: |
| 515 | netdev_dbg(dev, "CRC error\n"); | 513 | netdev_dbg(dev, "CRC error\n"); |
| 516 | cf->data[3] |= (CAN_ERR_PROT_LOC_CRC_SEQ | | 514 | cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ; |
| 517 | CAN_ERR_PROT_LOC_CRC_DEL); | ||
| 518 | break; | 515 | break; |
| 519 | default: | 516 | default: |
| 520 | break; | 517 | break; |
diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index e187ca783da0..c1317889d3d8 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c | |||
| @@ -559,8 +559,7 @@ static void pch_can_error(struct net_device *ndev, u32 status) | |||
| 559 | stats->rx_errors++; | 559 | stats->rx_errors++; |
| 560 | break; | 560 | break; |
| 561 | case PCH_CRC_ERR: | 561 | case PCH_CRC_ERR: |
| 562 | cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ | | 562 | cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ; |
| 563 | CAN_ERR_PROT_LOC_CRC_DEL; | ||
| 564 | priv->can.can_stats.bus_error++; | 563 | priv->can.can_stats.bus_error++; |
| 565 | stats->rx_errors++; | 564 | stats->rx_errors++; |
| 566 | break; | 565 | break; |
diff --git a/drivers/net/can/rcar_can.c b/drivers/net/can/rcar_can.c index 7bd54191f962..bc46be39549d 100644 --- a/drivers/net/can/rcar_can.c +++ b/drivers/net/can/rcar_can.c | |||
| @@ -241,17 +241,16 @@ static void rcar_can_error(struct net_device *ndev) | |||
| 241 | u8 ecsr; | 241 | u8 ecsr; |
| 242 | 242 | ||
| 243 | netdev_dbg(priv->ndev, "Bus error interrupt:\n"); | 243 | netdev_dbg(priv->ndev, "Bus error interrupt:\n"); |
| 244 | if (skb) { | 244 | if (skb) |
| 245 | cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_PROT; | 245 | cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_PROT; |
| 246 | cf->data[2] = CAN_ERR_PROT_UNSPEC; | 246 | |
| 247 | } | ||
| 248 | ecsr = readb(&priv->regs->ecsr); | 247 | ecsr = readb(&priv->regs->ecsr); |
| 249 | if (ecsr & RCAR_CAN_ECSR_ADEF) { | 248 | if (ecsr & RCAR_CAN_ECSR_ADEF) { |
| 250 | netdev_dbg(priv->ndev, "ACK Delimiter Error\n"); | 249 | netdev_dbg(priv->ndev, "ACK Delimiter Error\n"); |
| 251 | tx_errors++; | 250 | tx_errors++; |
| 252 | writeb(~RCAR_CAN_ECSR_ADEF, &priv->regs->ecsr); | 251 | writeb(~RCAR_CAN_ECSR_ADEF, &priv->regs->ecsr); |
| 253 | if (skb) | 252 | if (skb) |
| 254 | cf->data[3] |= CAN_ERR_PROT_LOC_ACK_DEL; | 253 | cf->data[3] = CAN_ERR_PROT_LOC_ACK_DEL; |
| 255 | } | 254 | } |
| 256 | if (ecsr & RCAR_CAN_ECSR_BE0F) { | 255 | if (ecsr & RCAR_CAN_ECSR_BE0F) { |
| 257 | netdev_dbg(priv->ndev, "Bit Error (dominant)\n"); | 256 | netdev_dbg(priv->ndev, "Bit Error (dominant)\n"); |
| @@ -272,7 +271,7 @@ static void rcar_can_error(struct net_device *ndev) | |||
| 272 | rx_errors++; | 271 | rx_errors++; |
| 273 | writeb(~RCAR_CAN_ECSR_CEF, &priv->regs->ecsr); | 272 | writeb(~RCAR_CAN_ECSR_CEF, &priv->regs->ecsr); |
| 274 | if (skb) | 273 | if (skb) |
| 275 | cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ; | 274 | cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ; |
| 276 | } | 275 | } |
| 277 | if (ecsr & RCAR_CAN_ECSR_AEF) { | 276 | if (ecsr & RCAR_CAN_ECSR_AEF) { |
| 278 | netdev_dbg(priv->ndev, "ACK Error\n"); | 277 | netdev_dbg(priv->ndev, "ACK Error\n"); |
| @@ -280,7 +279,7 @@ static void rcar_can_error(struct net_device *ndev) | |||
| 280 | writeb(~RCAR_CAN_ECSR_AEF, &priv->regs->ecsr); | 279 | writeb(~RCAR_CAN_ECSR_AEF, &priv->regs->ecsr); |
| 281 | if (skb) { | 280 | if (skb) { |
| 282 | cf->can_id |= CAN_ERR_ACK; | 281 | cf->can_id |= CAN_ERR_ACK; |
| 283 | cf->data[3] |= CAN_ERR_PROT_LOC_ACK; | 282 | cf->data[3] = CAN_ERR_PROT_LOC_ACK; |
| 284 | } | 283 | } |
| 285 | } | 284 | } |
| 286 | if (ecsr & RCAR_CAN_ECSR_FEF) { | 285 | if (ecsr & RCAR_CAN_ECSR_FEF) { |
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c index 7b92e911a616..8dda3b703d39 100644 --- a/drivers/net/can/sja1000/sja1000.c +++ b/drivers/net/can/sja1000/sja1000.c | |||
| @@ -218,6 +218,9 @@ static void sja1000_start(struct net_device *dev) | |||
| 218 | priv->write_reg(priv, SJA1000_RXERR, 0x0); | 218 | priv->write_reg(priv, SJA1000_RXERR, 0x0); |
| 219 | priv->read_reg(priv, SJA1000_ECC); | 219 | priv->read_reg(priv, SJA1000_ECC); |
| 220 | 220 | ||
| 221 | /* clear interrupt flags */ | ||
| 222 | priv->read_reg(priv, SJA1000_IR); | ||
| 223 | |||
| 221 | /* leave reset mode */ | 224 | /* leave reset mode */ |
| 222 | set_normal_mode(dev); | 225 | set_normal_mode(dev); |
| 223 | } | 226 | } |
| @@ -446,7 +449,6 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) | |||
| 446 | cf->data[2] |= CAN_ERR_PROT_STUFF; | 449 | cf->data[2] |= CAN_ERR_PROT_STUFF; |
| 447 | break; | 450 | break; |
| 448 | default: | 451 | default: |
| 449 | cf->data[2] |= CAN_ERR_PROT_UNSPEC; | ||
| 450 | cf->data[3] = ecc & ECC_SEG; | 452 | cf->data[3] = ecc & ECC_SEG; |
| 451 | break; | 453 | break; |
| 452 | } | 454 | } |
diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c index d9a42c646783..68ef0a4cd821 100644 --- a/drivers/net/can/sun4i_can.c +++ b/drivers/net/can/sun4i_can.c | |||
| @@ -575,7 +575,6 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status) | |||
| 575 | cf->data[2] |= CAN_ERR_PROT_STUFF; | 575 | cf->data[2] |= CAN_ERR_PROT_STUFF; |
| 576 | break; | 576 | break; |
| 577 | default: | 577 | default: |
| 578 | cf->data[2] |= CAN_ERR_PROT_UNSPEC; | ||
| 579 | cf->data[3] = (ecc & SUN4I_STA_ERR_SEG_CODE) | 578 | cf->data[3] = (ecc & SUN4I_STA_ERR_SEG_CODE) |
| 580 | >> 16; | 579 | >> 16; |
| 581 | break; | 580 | break; |
diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c index cf345cbfe819..680d1ff07a55 100644 --- a/drivers/net/can/ti_hecc.c +++ b/drivers/net/can/ti_hecc.c | |||
| @@ -722,7 +722,6 @@ static int ti_hecc_error(struct net_device *ndev, int int_status, | |||
| 722 | if (err_status & HECC_BUS_ERROR) { | 722 | if (err_status & HECC_BUS_ERROR) { |
| 723 | ++priv->can.can_stats.bus_error; | 723 | ++priv->can.can_stats.bus_error; |
| 724 | cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_PROT; | 724 | cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_PROT; |
| 725 | cf->data[2] |= CAN_ERR_PROT_UNSPEC; | ||
| 726 | if (err_status & HECC_CANES_FE) { | 725 | if (err_status & HECC_CANES_FE) { |
| 727 | hecc_set_bit(priv, HECC_CANES, HECC_CANES_FE); | 726 | hecc_set_bit(priv, HECC_CANES, HECC_CANES_FE); |
| 728 | cf->data[2] |= CAN_ERR_PROT_FORM; | 727 | cf->data[2] |= CAN_ERR_PROT_FORM; |
| @@ -737,13 +736,11 @@ static int ti_hecc_error(struct net_device *ndev, int int_status, | |||
| 737 | } | 736 | } |
| 738 | if (err_status & HECC_CANES_CRCE) { | 737 | if (err_status & HECC_CANES_CRCE) { |
| 739 | hecc_set_bit(priv, HECC_CANES, HECC_CANES_CRCE); | 738 | hecc_set_bit(priv, HECC_CANES, HECC_CANES_CRCE); |
| 740 | cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ | | 739 | cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ; |
| 741 | CAN_ERR_PROT_LOC_CRC_DEL; | ||
| 742 | } | 740 | } |
| 743 | if (err_status & HECC_CANES_ACKE) { | 741 | if (err_status & HECC_CANES_ACKE) { |
| 744 | hecc_set_bit(priv, HECC_CANES, HECC_CANES_ACKE); | 742 | hecc_set_bit(priv, HECC_CANES, HECC_CANES_ACKE); |
| 745 | cf->data[3] |= CAN_ERR_PROT_LOC_ACK | | 743 | cf->data[3] = CAN_ERR_PROT_LOC_ACK; |
| 746 | CAN_ERR_PROT_LOC_ACK_DEL; | ||
| 747 | } | 744 | } |
| 748 | } | 745 | } |
| 749 | 746 | ||
diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c index 2d390384ef3b..fc5b75675cd8 100644 --- a/drivers/net/can/usb/ems_usb.c +++ b/drivers/net/can/usb/ems_usb.c | |||
| @@ -377,7 +377,6 @@ static void ems_usb_rx_err(struct ems_usb *dev, struct ems_cpc_msg *msg) | |||
| 377 | cf->data[2] |= CAN_ERR_PROT_STUFF; | 377 | cf->data[2] |= CAN_ERR_PROT_STUFF; |
| 378 | break; | 378 | break; |
| 379 | default: | 379 | default: |
| 380 | cf->data[2] |= CAN_ERR_PROT_UNSPEC; | ||
| 381 | cf->data[3] = ecc & SJA1000_ECC_SEG; | 380 | cf->data[3] = ecc & SJA1000_ECC_SEG; |
| 382 | break; | 381 | break; |
| 383 | } | 382 | } |
diff --git a/drivers/net/can/usb/esd_usb2.c b/drivers/net/can/usb/esd_usb2.c index 0e5a4493ba4f..113e64fcd73b 100644 --- a/drivers/net/can/usb/esd_usb2.c +++ b/drivers/net/can/usb/esd_usb2.c | |||
| @@ -282,7 +282,6 @@ static void esd_usb2_rx_event(struct esd_usb2_net_priv *priv, | |||
| 282 | cf->data[2] |= CAN_ERR_PROT_STUFF; | 282 | cf->data[2] |= CAN_ERR_PROT_STUFF; |
| 283 | break; | 283 | break; |
| 284 | default: | 284 | default: |
| 285 | cf->data[2] |= CAN_ERR_PROT_UNSPEC; | ||
| 286 | cf->data[3] = ecc & SJA1000_ECC_SEG; | 285 | cf->data[3] = ecc & SJA1000_ECC_SEG; |
| 287 | break; | 286 | break; |
| 288 | } | 287 | } |
diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c index 8b17a9065b0b..022bfa13ebfa 100644 --- a/drivers/net/can/usb/kvaser_usb.c +++ b/drivers/net/can/usb/kvaser_usb.c | |||
| @@ -944,10 +944,9 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev, | |||
| 944 | cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_PROT; | 944 | cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_PROT; |
| 945 | 945 | ||
| 946 | if (es->leaf.error_factor & M16C_EF_ACKE) | 946 | if (es->leaf.error_factor & M16C_EF_ACKE) |
| 947 | cf->data[3] |= (CAN_ERR_PROT_LOC_ACK); | 947 | cf->data[3] = CAN_ERR_PROT_LOC_ACK; |
| 948 | if (es->leaf.error_factor & M16C_EF_CRCE) | 948 | if (es->leaf.error_factor & M16C_EF_CRCE) |
| 949 | cf->data[3] |= (CAN_ERR_PROT_LOC_CRC_SEQ | | 949 | cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ; |
| 950 | CAN_ERR_PROT_LOC_CRC_DEL); | ||
| 951 | if (es->leaf.error_factor & M16C_EF_FORME) | 950 | if (es->leaf.error_factor & M16C_EF_FORME) |
| 952 | cf->data[2] |= CAN_ERR_PROT_FORM; | 951 | cf->data[2] |= CAN_ERR_PROT_FORM; |
| 953 | if (es->leaf.error_factor & M16C_EF_STFE) | 952 | if (es->leaf.error_factor & M16C_EF_STFE) |
diff --git a/drivers/net/can/usb/usb_8dev.c b/drivers/net/can/usb/usb_8dev.c index de95b1ccba3e..a731720f1d13 100644 --- a/drivers/net/can/usb/usb_8dev.c +++ b/drivers/net/can/usb/usb_8dev.c | |||
| @@ -401,9 +401,7 @@ static void usb_8dev_rx_err_msg(struct usb_8dev_priv *priv, | |||
| 401 | tx_errors = 1; | 401 | tx_errors = 1; |
| 402 | break; | 402 | break; |
| 403 | case USB_8DEV_STATUSMSG_CRC: | 403 | case USB_8DEV_STATUSMSG_CRC: |
| 404 | cf->data[2] |= CAN_ERR_PROT_UNSPEC; | 404 | cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ; |
| 405 | cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ | | ||
| 406 | CAN_ERR_PROT_LOC_CRC_DEL; | ||
| 407 | rx_errors = 1; | 405 | rx_errors = 1; |
| 408 | break; | 406 | break; |
| 409 | case USB_8DEV_STATUSMSG_BIT0: | 407 | case USB_8DEV_STATUSMSG_BIT0: |
diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c index fc55e8e0351d..51670b322409 100644 --- a/drivers/net/can/xilinx_can.c +++ b/drivers/net/can/xilinx_can.c | |||
| @@ -608,17 +608,15 @@ static void xcan_err_interrupt(struct net_device *ndev, u32 isr) | |||
| 608 | 608 | ||
| 609 | /* Check for error interrupt */ | 609 | /* Check for error interrupt */ |
| 610 | if (isr & XCAN_IXR_ERROR_MASK) { | 610 | if (isr & XCAN_IXR_ERROR_MASK) { |
| 611 | if (skb) { | 611 | if (skb) |
| 612 | cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; | 612 | cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; |
| 613 | cf->data[2] |= CAN_ERR_PROT_UNSPEC; | ||
| 614 | } | ||
| 615 | 613 | ||
| 616 | /* Check for Ack error interrupt */ | 614 | /* Check for Ack error interrupt */ |
| 617 | if (err_status & XCAN_ESR_ACKER_MASK) { | 615 | if (err_status & XCAN_ESR_ACKER_MASK) { |
| 618 | stats->tx_errors++; | 616 | stats->tx_errors++; |
| 619 | if (skb) { | 617 | if (skb) { |
| 620 | cf->can_id |= CAN_ERR_ACK; | 618 | cf->can_id |= CAN_ERR_ACK; |
| 621 | cf->data[3] |= CAN_ERR_PROT_LOC_ACK; | 619 | cf->data[3] = CAN_ERR_PROT_LOC_ACK; |
| 622 | } | 620 | } |
| 623 | } | 621 | } |
| 624 | 622 | ||
| @@ -654,8 +652,7 @@ static void xcan_err_interrupt(struct net_device *ndev, u32 isr) | |||
| 654 | stats->rx_errors++; | 652 | stats->rx_errors++; |
| 655 | if (skb) { | 653 | if (skb) { |
| 656 | cf->can_id |= CAN_ERR_PROT; | 654 | cf->can_id |= CAN_ERR_PROT; |
| 657 | cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ | | 655 | cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ; |
| 658 | CAN_ERR_PROT_LOC_CRC_DEL; | ||
| 659 | } | 656 | } |
| 660 | } | 657 | } |
| 661 | priv->can.can_stats.bus_error++; | 658 | priv->can.can_stats.bus_error++; |
diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig index 955d06b9cdba..31c5e476fd64 100644 --- a/drivers/net/ethernet/Kconfig +++ b/drivers/net/ethernet/Kconfig | |||
| @@ -29,6 +29,7 @@ source "drivers/net/ethernet/apm/Kconfig" | |||
| 29 | source "drivers/net/ethernet/apple/Kconfig" | 29 | source "drivers/net/ethernet/apple/Kconfig" |
| 30 | source "drivers/net/ethernet/arc/Kconfig" | 30 | source "drivers/net/ethernet/arc/Kconfig" |
| 31 | source "drivers/net/ethernet/atheros/Kconfig" | 31 | source "drivers/net/ethernet/atheros/Kconfig" |
| 32 | source "drivers/net/ethernet/aurora/Kconfig" | ||
| 32 | source "drivers/net/ethernet/cadence/Kconfig" | 33 | source "drivers/net/ethernet/cadence/Kconfig" |
| 33 | source "drivers/net/ethernet/adi/Kconfig" | 34 | source "drivers/net/ethernet/adi/Kconfig" |
| 34 | source "drivers/net/ethernet/broadcom/Kconfig" | 35 | source "drivers/net/ethernet/broadcom/Kconfig" |
diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile index 4a2ee98738f0..071f84eb6f3f 100644 --- a/drivers/net/ethernet/Makefile +++ b/drivers/net/ethernet/Makefile | |||
| @@ -15,6 +15,7 @@ obj-$(CONFIG_NET_XGENE) += apm/ | |||
| 15 | obj-$(CONFIG_NET_VENDOR_APPLE) += apple/ | 15 | obj-$(CONFIG_NET_VENDOR_APPLE) += apple/ |
| 16 | obj-$(CONFIG_NET_VENDOR_ARC) += arc/ | 16 | obj-$(CONFIG_NET_VENDOR_ARC) += arc/ |
| 17 | obj-$(CONFIG_NET_VENDOR_ATHEROS) += atheros/ | 17 | obj-$(CONFIG_NET_VENDOR_ATHEROS) += atheros/ |
| 18 | obj-$(CONFIG_NET_VENDOR_AURORA) += aurora/ | ||
| 18 | obj-$(CONFIG_NET_CADENCE) += cadence/ | 19 | obj-$(CONFIG_NET_CADENCE) += cadence/ |
| 19 | obj-$(CONFIG_NET_BFIN) += adi/ | 20 | obj-$(CONFIG_NET_BFIN) += adi/ |
| 20 | obj-$(CONFIG_NET_VENDOR_BROADCOM) += broadcom/ | 21 | obj-$(CONFIG_NET_VENDOR_BROADCOM) += broadcom/ |
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c index 991412ce6f48..9147a0107c44 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c | |||
| @@ -450,12 +450,12 @@ static netdev_tx_t xgene_enet_start_xmit(struct sk_buff *skb, | |||
| 450 | return NETDEV_TX_OK; | 450 | return NETDEV_TX_OK; |
| 451 | } | 451 | } |
| 452 | 452 | ||
| 453 | pdata->ring_ops->wr_cmd(tx_ring, count); | ||
| 454 | skb_tx_timestamp(skb); | 453 | skb_tx_timestamp(skb); |
| 455 | 454 | ||
| 456 | pdata->stats.tx_packets++; | 455 | pdata->stats.tx_packets++; |
| 457 | pdata->stats.tx_bytes += skb->len; | 456 | pdata->stats.tx_bytes += skb->len; |
| 458 | 457 | ||
| 458 | pdata->ring_ops->wr_cmd(tx_ring, count); | ||
| 459 | return NETDEV_TX_OK; | 459 | return NETDEV_TX_OK; |
| 460 | } | 460 | } |
| 461 | 461 | ||
| @@ -688,10 +688,10 @@ static int xgene_enet_open(struct net_device *ndev) | |||
| 688 | mac_ops->tx_enable(pdata); | 688 | mac_ops->tx_enable(pdata); |
| 689 | mac_ops->rx_enable(pdata); | 689 | mac_ops->rx_enable(pdata); |
| 690 | 690 | ||
| 691 | xgene_enet_napi_enable(pdata); | ||
| 691 | ret = xgene_enet_register_irq(ndev); | 692 | ret = xgene_enet_register_irq(ndev); |
| 692 | if (ret) | 693 | if (ret) |
| 693 | return ret; | 694 | return ret; |
| 694 | xgene_enet_napi_enable(pdata); | ||
| 695 | 695 | ||
| 696 | if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII) | 696 | if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII) |
| 697 | phy_start(pdata->phy_dev); | 697 | phy_start(pdata->phy_dev); |
| @@ -715,13 +715,13 @@ static int xgene_enet_close(struct net_device *ndev) | |||
| 715 | else | 715 | else |
| 716 | cancel_delayed_work_sync(&pdata->link_work); | 716 | cancel_delayed_work_sync(&pdata->link_work); |
| 717 | 717 | ||
| 718 | xgene_enet_napi_disable(pdata); | ||
| 719 | xgene_enet_free_irq(ndev); | ||
| 720 | xgene_enet_process_ring(pdata->rx_ring, -1); | ||
| 721 | |||
| 722 | mac_ops->tx_disable(pdata); | 718 | mac_ops->tx_disable(pdata); |
| 723 | mac_ops->rx_disable(pdata); | 719 | mac_ops->rx_disable(pdata); |
| 724 | 720 | ||
| 721 | xgene_enet_free_irq(ndev); | ||
| 722 | xgene_enet_napi_disable(pdata); | ||
| 723 | xgene_enet_process_ring(pdata->rx_ring, -1); | ||
| 724 | |||
| 725 | return 0; | 725 | return 0; |
| 726 | } | 726 | } |
| 727 | 727 | ||
| @@ -1474,15 +1474,15 @@ static int xgene_enet_probe(struct platform_device *pdev) | |||
| 1474 | } | 1474 | } |
| 1475 | ndev->hw_features = ndev->features; | 1475 | ndev->hw_features = ndev->features; |
| 1476 | 1476 | ||
| 1477 | ret = register_netdev(ndev); | 1477 | ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(64)); |
| 1478 | if (ret) { | 1478 | if (ret) { |
| 1479 | netdev_err(ndev, "Failed to register netdev\n"); | 1479 | netdev_err(ndev, "No usable DMA configuration\n"); |
| 1480 | goto err; | 1480 | goto err; |
| 1481 | } | 1481 | } |
| 1482 | 1482 | ||
| 1483 | ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(64)); | 1483 | ret = register_netdev(ndev); |
| 1484 | if (ret) { | 1484 | if (ret) { |
| 1485 | netdev_err(ndev, "No usable DMA configuration\n"); | 1485 | netdev_err(ndev, "Failed to register netdev\n"); |
| 1486 | goto err; | 1486 | goto err; |
| 1487 | } | 1487 | } |
| 1488 | 1488 | ||
| @@ -1490,14 +1490,17 @@ static int xgene_enet_probe(struct platform_device *pdev) | |||
| 1490 | if (ret) | 1490 | if (ret) |
| 1491 | goto err; | 1491 | goto err; |
| 1492 | 1492 | ||
| 1493 | xgene_enet_napi_add(pdata); | ||
| 1494 | mac_ops = pdata->mac_ops; | 1493 | mac_ops = pdata->mac_ops; |
| 1495 | if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII) | 1494 | if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII) { |
| 1496 | ret = xgene_enet_mdio_config(pdata); | 1495 | ret = xgene_enet_mdio_config(pdata); |
| 1497 | else | 1496 | if (ret) |
| 1497 | goto err; | ||
| 1498 | } else { | ||
| 1498 | INIT_DELAYED_WORK(&pdata->link_work, mac_ops->link_state); | 1499 | INIT_DELAYED_WORK(&pdata->link_work, mac_ops->link_state); |
| 1500 | } | ||
| 1499 | 1501 | ||
| 1500 | return ret; | 1502 | xgene_enet_napi_add(pdata); |
| 1503 | return 0; | ||
| 1501 | err: | 1504 | err: |
| 1502 | unregister_netdev(ndev); | 1505 | unregister_netdev(ndev); |
| 1503 | free_netdev(ndev); | 1506 | free_netdev(ndev); |
diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c index c8af3ce3ea38..bd377a6b067d 100644 --- a/drivers/net/ethernet/atheros/alx/main.c +++ b/drivers/net/ethernet/atheros/alx/main.c | |||
| @@ -1534,6 +1534,8 @@ static const struct pci_device_id alx_pci_tbl[] = { | |||
| 1534 | .driver_data = ALX_DEV_QUIRK_MSI_INTX_DISABLE_BUG }, | 1534 | .driver_data = ALX_DEV_QUIRK_MSI_INTX_DISABLE_BUG }, |
| 1535 | { PCI_VDEVICE(ATTANSIC, ALX_DEV_ID_E2200), | 1535 | { PCI_VDEVICE(ATTANSIC, ALX_DEV_ID_E2200), |
| 1536 | .driver_data = ALX_DEV_QUIRK_MSI_INTX_DISABLE_BUG }, | 1536 | .driver_data = ALX_DEV_QUIRK_MSI_INTX_DISABLE_BUG }, |
| 1537 | { PCI_VDEVICE(ATTANSIC, ALX_DEV_ID_E2400), | ||
| 1538 | .driver_data = ALX_DEV_QUIRK_MSI_INTX_DISABLE_BUG }, | ||
| 1537 | { PCI_VDEVICE(ATTANSIC, ALX_DEV_ID_AR8162), | 1539 | { PCI_VDEVICE(ATTANSIC, ALX_DEV_ID_AR8162), |
| 1538 | .driver_data = ALX_DEV_QUIRK_MSI_INTX_DISABLE_BUG }, | 1540 | .driver_data = ALX_DEV_QUIRK_MSI_INTX_DISABLE_BUG }, |
| 1539 | { PCI_VDEVICE(ATTANSIC, ALX_DEV_ID_AR8171) }, | 1541 | { PCI_VDEVICE(ATTANSIC, ALX_DEV_ID_AR8171) }, |
diff --git a/drivers/net/ethernet/atheros/alx/reg.h b/drivers/net/ethernet/atheros/alx/reg.h index af006b44b2a6..0959e6824cb6 100644 --- a/drivers/net/ethernet/atheros/alx/reg.h +++ b/drivers/net/ethernet/atheros/alx/reg.h | |||
| @@ -37,6 +37,7 @@ | |||
| 37 | 37 | ||
| 38 | #define ALX_DEV_ID_AR8161 0x1091 | 38 | #define ALX_DEV_ID_AR8161 0x1091 |
| 39 | #define ALX_DEV_ID_E2200 0xe091 | 39 | #define ALX_DEV_ID_E2200 0xe091 |
| 40 | #define ALX_DEV_ID_E2400 0xe0a1 | ||
| 40 | #define ALX_DEV_ID_AR8162 0x1090 | 41 | #define ALX_DEV_ID_AR8162 0x1090 |
| 41 | #define ALX_DEV_ID_AR8171 0x10A1 | 42 | #define ALX_DEV_ID_AR8171 0x10A1 |
| 42 | #define ALX_DEV_ID_AR8172 0x10A0 | 43 | #define ALX_DEV_ID_AR8172 0x10A0 |
diff --git a/drivers/net/ethernet/aurora/Kconfig b/drivers/net/ethernet/aurora/Kconfig new file mode 100644 index 000000000000..a3c7106fdf85 --- /dev/null +++ b/drivers/net/ethernet/aurora/Kconfig | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | config NET_VENDOR_AURORA | ||
| 2 | bool "Aurora VLSI devices" | ||
| 3 | help | ||
| 4 | If you have a network (Ethernet) device belonging to this class, | ||
| 5 | say Y. | ||
| 6 | |||
| 7 | Note that the answer to this question doesn't directly affect the | ||
| 8 | kernel: saying N will just cause the configurator to skip all | ||
| 9 | questions about Aurora devices. If you say Y, you will be asked | ||
| 10 | for your specific device in the following questions. | ||
| 11 | |||
| 12 | if NET_VENDOR_AURORA | ||
| 13 | |||
| 14 | config AURORA_NB8800 | ||
| 15 | tristate "Aurora AU-NB8800 support" | ||
| 16 | select PHYLIB | ||
| 17 | help | ||
| 18 | Support for the AU-NB8800 gigabit Ethernet controller. | ||
| 19 | |||
| 20 | endif | ||
diff --git a/drivers/net/ethernet/aurora/Makefile b/drivers/net/ethernet/aurora/Makefile new file mode 100644 index 000000000000..6cb528a2fc26 --- /dev/null +++ b/drivers/net/ethernet/aurora/Makefile | |||
| @@ -0,0 +1 @@ | |||
| obj-$(CONFIG_AURORA_NB8800) += nb8800.o | |||
diff --git a/drivers/net/ethernet/aurora/nb8800.c b/drivers/net/ethernet/aurora/nb8800.c new file mode 100644 index 000000000000..ecc4a334c507 --- /dev/null +++ b/drivers/net/ethernet/aurora/nb8800.c | |||
| @@ -0,0 +1,1552 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2015 Mans Rullgard <mans@mansr.com> | ||
| 3 | * | ||
| 4 | * Mostly rewritten, based on driver from Sigma Designs. Original | ||
| 5 | * copyright notice below. | ||
| 6 | * | ||
| 7 | * | ||
| 8 | * Driver for tangox SMP864x/SMP865x/SMP867x/SMP868x builtin Ethernet Mac. | ||
| 9 | * | ||
| 10 | * Copyright (C) 2005 Maxime Bizon <mbizon@freebox.fr> | ||
| 11 | * | ||
| 12 | * This program is free software; you can redistribute it and/or modify | ||
| 13 | * it under the terms of the GNU General Public License as published by | ||
| 14 | * the Free Software Foundation; either version 2 of the License, or | ||
| 15 | * (at your option) any later version. | ||
| 16 | * | ||
| 17 | * This program is distributed in the hope that it will be useful, | ||
| 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 20 | * GNU General Public License for more details. | ||
| 21 | */ | ||
| 22 | |||
| 23 | #include <linux/module.h> | ||
| 24 | #include <linux/etherdevice.h> | ||
| 25 | #include <linux/delay.h> | ||
| 26 | #include <linux/ethtool.h> | ||
| 27 | #include <linux/interrupt.h> | ||
| 28 | #include <linux/platform_device.h> | ||
| 29 | #include <linux/of_device.h> | ||
| 30 | #include <linux/of_mdio.h> | ||
| 31 | #include <linux/of_net.h> | ||
| 32 | #include <linux/dma-mapping.h> | ||
| 33 | #include <linux/phy.h> | ||
| 34 | #include <linux/cache.h> | ||
| 35 | #include <linux/jiffies.h> | ||
| 36 | #include <linux/io.h> | ||
| 37 | #include <linux/iopoll.h> | ||
| 38 | #include <asm/barrier.h> | ||
| 39 | |||
| 40 | #include "nb8800.h" | ||
| 41 | |||
| 42 | static void nb8800_tx_done(struct net_device *dev); | ||
| 43 | static int nb8800_dma_stop(struct net_device *dev); | ||
| 44 | |||
| 45 | static inline u8 nb8800_readb(struct nb8800_priv *priv, int reg) | ||
| 46 | { | ||
| 47 | return readb_relaxed(priv->base + reg); | ||
| 48 | } | ||
| 49 | |||
| 50 | static inline u32 nb8800_readl(struct nb8800_priv *priv, int reg) | ||
| 51 | { | ||
| 52 | return readl_relaxed(priv->base + reg); | ||
| 53 | } | ||
| 54 | |||
| 55 | static inline void nb8800_writeb(struct nb8800_priv *priv, int reg, u8 val) | ||
| 56 | { | ||
| 57 | writeb_relaxed(val, priv->base + reg); | ||
| 58 | } | ||
| 59 | |||
| 60 | static inline void nb8800_writew(struct nb8800_priv *priv, int reg, u16 val) | ||
| 61 | { | ||
| 62 | writew_relaxed(val, priv->base + reg); | ||
| 63 | } | ||
| 64 | |||
| 65 | static inline void nb8800_writel(struct nb8800_priv *priv, int reg, u32 val) | ||
| 66 | { | ||
| 67 | writel_relaxed(val, priv->base + reg); | ||
| 68 | } | ||
| 69 | |||
| 70 | static inline void nb8800_maskb(struct nb8800_priv *priv, int reg, | ||
| 71 | u32 mask, u32 val) | ||
| 72 | { | ||
| 73 | u32 old = nb8800_readb(priv, reg); | ||
| 74 | u32 new = (old & ~mask) | (val & mask); | ||
| 75 | |||
| 76 | if (new != old) | ||
| 77 | nb8800_writeb(priv, reg, new); | ||
| 78 | } | ||
| 79 | |||
| 80 | static inline void nb8800_maskl(struct nb8800_priv *priv, int reg, | ||
| 81 | u32 mask, u32 val) | ||
| 82 | { | ||
| 83 | u32 old = nb8800_readl(priv, reg); | ||
| 84 | u32 new = (old & ~mask) | (val & mask); | ||
| 85 | |||
| 86 | if (new != old) | ||
| 87 | nb8800_writel(priv, reg, new); | ||
| 88 | } | ||
| 89 | |||
| 90 | static inline void nb8800_modb(struct nb8800_priv *priv, int reg, u8 bits, | ||
| 91 | bool set) | ||
| 92 | { | ||
| 93 | nb8800_maskb(priv, reg, bits, set ? bits : 0); | ||
| 94 | } | ||
| 95 | |||
| 96 | static inline void nb8800_setb(struct nb8800_priv *priv, int reg, u8 bits) | ||
| 97 | { | ||
| 98 | nb8800_maskb(priv, reg, bits, bits); | ||
| 99 | } | ||
| 100 | |||
| 101 | static inline void nb8800_clearb(struct nb8800_priv *priv, int reg, u8 bits) | ||
| 102 | { | ||
| 103 | nb8800_maskb(priv, reg, bits, 0); | ||
| 104 | } | ||
| 105 | |||
| 106 | static inline void nb8800_modl(struct nb8800_priv *priv, int reg, u32 bits, | ||
| 107 | bool set) | ||
| 108 | { | ||
| 109 | nb8800_maskl(priv, reg, bits, set ? bits : 0); | ||
| 110 | } | ||
| 111 | |||
| 112 | static inline void nb8800_setl(struct nb8800_priv *priv, int reg, u32 bits) | ||
| 113 | { | ||
| 114 | nb8800_maskl(priv, reg, bits, bits); | ||
| 115 | } | ||
| 116 | |||
| 117 | static inline void nb8800_clearl(struct nb8800_priv *priv, int reg, u32 bits) | ||
| 118 | { | ||
| 119 | nb8800_maskl(priv, reg, bits, 0); | ||
| 120 | } | ||
| 121 | |||
| 122 | static int nb8800_mdio_wait(struct mii_bus *bus) | ||
| 123 | { | ||
| 124 | struct nb8800_priv *priv = bus->priv; | ||
| 125 | u32 val; | ||
| 126 | |||
| 127 | return readl_poll_timeout_atomic(priv->base + NB8800_MDIO_CMD, | ||
| 128 | val, !(val & MDIO_CMD_GO), 1, 1000); | ||
| 129 | } | ||
| 130 | |||
| 131 | static int nb8800_mdio_cmd(struct mii_bus *bus, u32 cmd) | ||
| 132 | { | ||
| 133 | struct nb8800_priv *priv = bus->priv; | ||
| 134 | int err; | ||
| 135 | |||
| 136 | err = nb8800_mdio_wait(bus); | ||
| 137 | if (err) | ||
| 138 | return err; | ||
| 139 | |||
| 140 | nb8800_writel(priv, NB8800_MDIO_CMD, cmd); | ||
| 141 | udelay(10); | ||
| 142 | nb8800_writel(priv, NB8800_MDIO_CMD, cmd | MDIO_CMD_GO); | ||
| 143 | |||
| 144 | return nb8800_mdio_wait(bus); | ||
| 145 | } | ||
| 146 | |||
| 147 | static int nb8800_mdio_read(struct mii_bus *bus, int phy_id, int reg) | ||
| 148 | { | ||
| 149 | struct nb8800_priv *priv = bus->priv; | ||
| 150 | u32 val; | ||
| 151 | int err; | ||
| 152 | |||
| 153 | err = nb8800_mdio_cmd(bus, MDIO_CMD_ADDR(phy_id) | MDIO_CMD_REG(reg)); | ||
| 154 | if (err) | ||
| 155 | return err; | ||
| 156 | |||
| 157 | val = nb8800_readl(priv, NB8800_MDIO_STS); | ||
| 158 | if (val & MDIO_STS_ERR) | ||
| 159 | return 0xffff; | ||
| 160 | |||
| 161 | return val & 0xffff; | ||
| 162 | } | ||
| 163 | |||
| 164 | static int nb8800_mdio_write(struct mii_bus *bus, int phy_id, int reg, u16 val) | ||
| 165 | { | ||
| 166 | u32 cmd = MDIO_CMD_ADDR(phy_id) | MDIO_CMD_REG(reg) | | ||
| 167 | MDIO_CMD_DATA(val) | MDIO_CMD_WR; | ||
| 168 | |||
| 169 | return nb8800_mdio_cmd(bus, cmd); | ||
| 170 | } | ||
| 171 | |||
| 172 | static void nb8800_mac_tx(struct net_device *dev, bool enable) | ||
| 173 | { | ||
| 174 | struct nb8800_priv *priv = netdev_priv(dev); | ||
| 175 | |||
| 176 | while (nb8800_readl(priv, NB8800_TXC_CR) & TCR_EN) | ||
| 177 | cpu_relax(); | ||
| 178 | |||
| 179 | nb8800_modb(priv, NB8800_TX_CTL1, TX_EN, enable); | ||
| 180 | } | ||
| 181 | |||
| 182 | static void nb8800_mac_rx(struct net_device *dev, bool enable) | ||
| 183 | { | ||
| 184 | nb8800_modb(netdev_priv(dev), NB8800_RX_CTL, RX_EN, enable); | ||
| 185 | } | ||
| 186 | |||
| 187 | static void nb8800_mac_af(struct net_device *dev, bool enable) | ||
| 188 | { | ||
| 189 | nb8800_modb(netdev_priv(dev), NB8800_RX_CTL, RX_AF_EN, enable); | ||
| 190 | } | ||
| 191 | |||
| 192 | static void nb8800_start_rx(struct net_device *dev) | ||
| 193 | { | ||
| 194 | nb8800_setl(netdev_priv(dev), NB8800_RXC_CR, RCR_EN); | ||
| 195 | } | ||
| 196 | |||
| 197 | static int nb8800_alloc_rx(struct net_device *dev, unsigned int i, bool napi) | ||
| 198 | { | ||
| 199 | struct nb8800_priv *priv = netdev_priv(dev); | ||
| 200 | struct nb8800_rx_desc *rxd = &priv->rx_descs[i]; | ||
| 201 | struct nb8800_rx_buf *rxb = &priv->rx_bufs[i]; | ||
| 202 | int size = L1_CACHE_ALIGN(RX_BUF_SIZE); | ||
| 203 | dma_addr_t dma_addr; | ||
| 204 | struct page *page; | ||
| 205 | unsigned long offset; | ||
| 206 | void *data; | ||
| 207 | |||
| 208 | data = napi ? napi_alloc_frag(size) : netdev_alloc_frag(size); | ||
| 209 | if (!data) | ||
| 210 | return -ENOMEM; | ||
| 211 | |||
| 212 | page = virt_to_head_page(data); | ||
| 213 | offset = data - page_address(page); | ||
| 214 | |||
| 215 | dma_addr = dma_map_page(&dev->dev, page, offset, RX_BUF_SIZE, | ||
| 216 | DMA_FROM_DEVICE); | ||
| 217 | |||
| 218 | if (dma_mapping_error(&dev->dev, dma_addr)) { | ||
| 219 | skb_free_frag(data); | ||
| 220 | return -ENOMEM; | ||
| 221 | } | ||
| 222 | |||
| 223 | rxb->page = page; | ||
| 224 | rxb->offset = offset; | ||
| 225 | rxd->desc.s_addr = dma_addr; | ||
| 226 | |||
| 227 | return 0; | ||
| 228 | } | ||
| 229 | |||
| 230 | static void nb8800_receive(struct net_device *dev, unsigned int i, | ||
| 231 | unsigned int len) | ||
| 232 | { | ||
| 233 | struct nb8800_priv *priv = netdev_priv(dev); | ||
| 234 | struct nb8800_rx_desc *rxd = &priv->rx_descs[i]; | ||
| 235 | struct page *page = priv->rx_bufs[i].page; | ||
| 236 | int offset = priv->rx_bufs[i].offset; | ||
| 237 | void *data = page_address(page) + offset; | ||
| 238 | dma_addr_t dma = rxd->desc.s_addr; | ||
| 239 | struct sk_buff *skb; | ||
| 240 | unsigned int size; | ||
| 241 | int err; | ||
| 242 | |||
| 243 | size = len <= RX_COPYBREAK ? len : RX_COPYHDR; | ||
| 244 | |||
| 245 | skb = napi_alloc_skb(&priv->napi, size); | ||
| 246 | if (!skb) { | ||
| 247 | netdev_err(dev, "rx skb allocation failed\n"); | ||
| 248 | dev->stats.rx_dropped++; | ||
| 249 | return; | ||
| 250 | } | ||
| 251 | |||
| 252 | if (len <= RX_COPYBREAK) { | ||
| 253 | dma_sync_single_for_cpu(&dev->dev, dma, len, DMA_FROM_DEVICE); | ||
| 254 | memcpy(skb_put(skb, len), data, len); | ||
| 255 | dma_sync_single_for_device(&dev->dev, dma, len, | ||
| 256 | DMA_FROM_DEVICE); | ||
| 257 | } else { | ||
| 258 | err = nb8800_alloc_rx(dev, i, true); | ||
| 259 | if (err) { | ||
| 260 | netdev_err(dev, "rx buffer allocation failed\n"); | ||
| 261 | dev->stats.rx_dropped++; | ||
| 262 | return; | ||
| 263 | } | ||
| 264 | |||
| 265 | dma_unmap_page(&dev->dev, dma, RX_BUF_SIZE, DMA_FROM_DEVICE); | ||
| 266 | memcpy(skb_put(skb, RX_COPYHDR), data, RX_COPYHDR); | ||
| 267 | skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, | ||
| 268 | offset + RX_COPYHDR, len - RX_COPYHDR, | ||
| 269 | RX_BUF_SIZE); | ||
| 270 | } | ||
| 271 | |||
| 272 | skb->protocol = eth_type_trans(skb, dev); | ||
| 273 | napi_gro_receive(&priv->napi, skb); | ||
| 274 | } | ||
| 275 | |||
| 276 | static void nb8800_rx_error(struct net_device *dev, u32 report) | ||
| 277 | { | ||
| 278 | if (report & RX_LENGTH_ERR) | ||
| 279 | dev->stats.rx_length_errors++; | ||
| 280 | |||
| 281 | if (report & RX_FCS_ERR) | ||
| 282 | dev->stats.rx_crc_errors++; | ||
| 283 | |||
| 284 | if (report & RX_FIFO_OVERRUN) | ||
| 285 | dev->stats.rx_fifo_errors++; | ||
| 286 | |||
| 287 | if (report & RX_ALIGNMENT_ERROR) | ||
| 288 | dev->stats.rx_frame_errors++; | ||
| 289 | |||
| 290 | dev->stats.rx_errors++; | ||
| 291 | } | ||
| 292 | |||
| 293 | static int nb8800_poll(struct napi_struct *napi, int budget) | ||
| 294 | { | ||
| 295 | struct net_device *dev = napi->dev; | ||
| 296 | struct nb8800_priv *priv = netdev_priv(dev); | ||
| 297 | struct nb8800_rx_desc *rxd; | ||
| 298 | unsigned int last = priv->rx_eoc; | ||
| 299 | unsigned int next; | ||
| 300 | int work = 0; | ||
| 301 | |||
| 302 | nb8800_tx_done(dev); | ||
| 303 | |||
| 304 | again: | ||
| 305 | while (work < budget) { | ||
| 306 | struct nb8800_rx_buf *rxb; | ||
| 307 | unsigned int len; | ||
| 308 | |||
| 309 | next = (last + 1) % RX_DESC_COUNT; | ||
| 310 | |||
| 311 | rxb = &priv->rx_bufs[next]; | ||
| 312 | rxd = &priv->rx_descs[next]; | ||
| 313 | |||
| 314 | if (!rxd->report) | ||
| 315 | break; | ||
| 316 | |||
| 317 | len = RX_BYTES_TRANSFERRED(rxd->report); | ||
| 318 | |||
| 319 | if (IS_RX_ERROR(rxd->report)) | ||
| 320 | nb8800_rx_error(dev, rxd->report); | ||
| 321 | else | ||
| 322 | nb8800_receive(dev, next, len); | ||
| 323 | |||
| 324 | dev->stats.rx_packets++; | ||
| 325 | dev->stats.rx_bytes += len; | ||
| 326 | |||
| 327 | if (rxd->report & RX_MULTICAST_PKT) | ||
| 328 | dev->stats.multicast++; | ||
| 329 | |||
| 330 | rxd->report = 0; | ||
| 331 | last = next; | ||
| 332 | work++; | ||
| 333 | } | ||
| 334 | |||
| 335 | if (work) { | ||
| 336 | priv->rx_descs[last].desc.config |= DESC_EOC; | ||
| 337 | wmb(); /* ensure new EOC is written before clearing old */ | ||
| 338 | priv->rx_descs[priv->rx_eoc].desc.config &= ~DESC_EOC; | ||
| 339 | priv->rx_eoc = last; | ||
| 340 | nb8800_start_rx(dev); | ||
| 341 | } | ||
| 342 | |||
| 343 | if (work < budget) { | ||
| 344 | nb8800_writel(priv, NB8800_RX_ITR, priv->rx_itr_irq); | ||
| 345 | |||
| 346 | /* If a packet arrived after we last checked but | ||
| 347 | * before writing RX_ITR, the interrupt will be | ||
| 348 | * delayed, so we retrieve it now. | ||
| 349 | */ | ||
| 350 | if (priv->rx_descs[next].report) | ||
| 351 | goto again; | ||
| 352 | |||
| 353 | napi_complete_done(napi, work); | ||
| 354 | } | ||
| 355 | |||
| 356 | return work; | ||
| 357 | } | ||
| 358 | |||
| 359 | static void __nb8800_tx_dma_start(struct net_device *dev) | ||
| 360 | { | ||
| 361 | struct nb8800_priv *priv = netdev_priv(dev); | ||
| 362 | struct nb8800_tx_buf *txb; | ||
| 363 | u32 txc_cr; | ||
| 364 | |||
| 365 | txb = &priv->tx_bufs[priv->tx_queue]; | ||
| 366 | if (!txb->ready) | ||
| 367 | return; | ||
| 368 | |||
| 369 | txc_cr = nb8800_readl(priv, NB8800_TXC_CR); | ||
| 370 | if (txc_cr & TCR_EN) | ||
| 371 | return; | ||
| 372 | |||
| 373 | nb8800_writel(priv, NB8800_TX_DESC_ADDR, txb->dma_desc); | ||
| 374 | wmb(); /* ensure desc addr is written before starting DMA */ | ||
| 375 | nb8800_writel(priv, NB8800_TXC_CR, txc_cr | TCR_EN); | ||
| 376 | |||
| 377 | priv->tx_queue = (priv->tx_queue + txb->chain_len) % TX_DESC_COUNT; | ||
| 378 | } | ||
| 379 | |||
| 380 | static void nb8800_tx_dma_start(struct net_device *dev) | ||
| 381 | { | ||
| 382 | struct nb8800_priv *priv = netdev_priv(dev); | ||
| 383 | |||
| 384 | spin_lock_irq(&priv->tx_lock); | ||
| 385 | __nb8800_tx_dma_start(dev); | ||
| 386 | spin_unlock_irq(&priv->tx_lock); | ||
| 387 | } | ||
| 388 | |||
| 389 | static void nb8800_tx_dma_start_irq(struct net_device *dev) | ||
| 390 | { | ||
| 391 | struct nb8800_priv *priv = netdev_priv(dev); | ||
| 392 | |||
| 393 | spin_lock(&priv->tx_lock); | ||
| 394 | __nb8800_tx_dma_start(dev); | ||
| 395 | spin_unlock(&priv->tx_lock); | ||
| 396 | } | ||
| 397 | |||
| 398 | static int nb8800_xmit(struct sk_buff *skb, struct net_device *dev) | ||
| 399 | { | ||
| 400 | struct nb8800_priv *priv = netdev_priv(dev); | ||
| 401 | struct nb8800_tx_desc *txd; | ||
| 402 | struct nb8800_tx_buf *txb; | ||
| 403 | struct nb8800_dma_desc *desc; | ||
| 404 | dma_addr_t dma_addr; | ||
| 405 | unsigned int dma_len; | ||
| 406 | unsigned int align; | ||
| 407 | unsigned int next; | ||
| 408 | |||
| 409 | if (atomic_read(&priv->tx_free) <= NB8800_DESC_LOW) { | ||
| 410 | netif_stop_queue(dev); | ||
| 411 | return NETDEV_TX_BUSY; | ||
| 412 | } | ||
| 413 | |||
| 414 | align = (8 - (uintptr_t)skb->data) & 7; | ||
| 415 | |||
| 416 | dma_len = skb->len - align; | ||
| 417 | dma_addr = dma_map_single(&dev->dev, skb->data + align, | ||
| 418 | dma_len, DMA_TO_DEVICE); | ||
| 419 | |||
| 420 | if (dma_mapping_error(&dev->dev, dma_addr)) { | ||
| 421 | netdev_err(dev, "tx dma mapping error\n"); | ||
| 422 | kfree_skb(skb); | ||
| 423 | dev->stats.tx_dropped++; | ||
| 424 | return NETDEV_TX_OK; | ||
| 425 | } | ||
| 426 | |||
| 427 | if (atomic_dec_return(&priv->tx_free) <= NB8800_DESC_LOW) { | ||
| 428 | netif_stop_queue(dev); | ||
| 429 | skb->xmit_more = 0; | ||
| 430 | } | ||
| 431 | |||
| 432 | next = priv->tx_next; | ||
| 433 | txb = &priv->tx_bufs[next]; | ||
| 434 | txd = &priv->tx_descs[next]; | ||
| 435 | desc = &txd->desc[0]; | ||
| 436 | |||
| 437 | next = (next + 1) % TX_DESC_COUNT; | ||
| 438 | |||
| 439 | if (align) { | ||
| 440 | memcpy(txd->buf, skb->data, align); | ||
| 441 | |||
| 442 | desc->s_addr = | ||
| 443 | txb->dma_desc + offsetof(struct nb8800_tx_desc, buf); | ||
| 444 | desc->n_addr = txb->dma_desc + sizeof(txd->desc[0]); | ||
| 445 | desc->config = DESC_BTS(2) | DESC_DS | align; | ||
| 446 | |||
| 447 | desc++; | ||
| 448 | } | ||
| 449 | |||
| 450 | desc->s_addr = dma_addr; | ||
| 451 | desc->n_addr = priv->tx_bufs[next].dma_desc; | ||
| 452 | desc->config = DESC_BTS(2) | DESC_DS | DESC_EOF | dma_len; | ||
| 453 | |||
| 454 | if (!skb->xmit_more) | ||
| 455 | desc->config |= DESC_EOC; | ||
| 456 | |||
| 457 | txb->skb = skb; | ||
| 458 | txb->dma_addr = dma_addr; | ||
| 459 | txb->dma_len = dma_len; | ||
| 460 | |||
| 461 | if (!priv->tx_chain) { | ||
| 462 | txb->chain_len = 1; | ||
| 463 | priv->tx_chain = txb; | ||
| 464 | } else { | ||
| 465 | priv->tx_chain->chain_len++; | ||
| 466 | } | ||
| 467 | |||
| 468 | netdev_sent_queue(dev, skb->len); | ||
| 469 | |||
| 470 | priv->tx_next = next; | ||
| 471 | |||
| 472 | if (!skb->xmit_more) { | ||
| 473 | smp_wmb(); | ||
| 474 | priv->tx_chain->ready = true; | ||
| 475 | priv->tx_chain = NULL; | ||
| 476 | nb8800_tx_dma_start(dev); | ||
| 477 | } | ||
| 478 | |||
| 479 | return NETDEV_TX_OK; | ||
| 480 | } | ||
| 481 | |||
| 482 | static void nb8800_tx_error(struct net_device *dev, u32 report) | ||
| 483 | { | ||
| 484 | if (report & TX_LATE_COLLISION) | ||
| 485 | dev->stats.collisions++; | ||
| 486 | |||
| 487 | if (report & TX_PACKET_DROPPED) | ||
| 488 | dev->stats.tx_dropped++; | ||
| 489 | |||
| 490 | if (report & TX_FIFO_UNDERRUN) | ||
| 491 | dev->stats.tx_fifo_errors++; | ||
| 492 | |||
| 493 | dev->stats.tx_errors++; | ||
| 494 | } | ||
| 495 | |||
| 496 | static void nb8800_tx_done(struct net_device *dev) | ||
| 497 | { | ||
| 498 | struct nb8800_priv *priv = netdev_priv(dev); | ||
| 499 | unsigned int limit = priv->tx_next; | ||
| 500 | unsigned int done = priv->tx_done; | ||
| 501 | unsigned int packets = 0; | ||
| 502 | unsigned int len = 0; | ||
| 503 | |||
| 504 | while (done != limit) { | ||
| 505 | struct nb8800_tx_desc *txd = &priv->tx_descs[done]; | ||
| 506 | struct nb8800_tx_buf *txb = &priv->tx_bufs[done]; | ||
| 507 | struct sk_buff *skb; | ||
| 508 | |||
| 509 | if (!txd->report) | ||
| 510 | break; | ||
| 511 | |||
| 512 | skb = txb->skb; | ||
| 513 | len += skb->len; | ||
| 514 | |||
| 515 | dma_unmap_single(&dev->dev, txb->dma_addr, txb->dma_len, | ||
| 516 | DMA_TO_DEVICE); | ||
| 517 | |||
| 518 | if (IS_TX_ERROR(txd->report)) { | ||
| 519 | nb8800_tx_error(dev, txd->report); | ||
| 520 | kfree_skb(skb); | ||
| 521 | } else { | ||
| 522 | consume_skb(skb); | ||
| 523 | } | ||
| 524 | |||
| 525 | dev->stats.tx_packets++; | ||
| 526 | dev->stats.tx_bytes += TX_BYTES_TRANSFERRED(txd->report); | ||
| 527 | dev->stats.collisions += TX_EARLY_COLLISIONS(txd->report); | ||
| 528 | |||
| 529 | txb->skb = NULL; | ||
| 530 | txb->ready = false; | ||
| 531 | txd->report = 0; | ||
| 532 | |||
| 533 | done = (done + 1) % TX_DESC_COUNT; | ||
| 534 | packets++; | ||
| 535 | } | ||
| 536 | |||
| 537 | if (packets) { | ||
| 538 | smp_mb__before_atomic(); | ||
| 539 | atomic_add(packets, &priv->tx_free); | ||
| 540 | netdev_completed_queue(dev, packets, len); | ||
| 541 | netif_wake_queue(dev); | ||
| 542 | priv->tx_done = done; | ||
| 543 | } | ||
| 544 | } | ||
| 545 | |||
| 546 | static irqreturn_t nb8800_irq(int irq, void *dev_id) | ||
| 547 | { | ||
| 548 | struct net_device *dev = dev_id; | ||
| 549 | struct nb8800_priv *priv = netdev_priv(dev); | ||
| 550 | irqreturn_t ret = IRQ_NONE; | ||
| 551 | u32 val; | ||
| 552 | |||
| 553 | /* tx interrupt */ | ||
| 554 | val = nb8800_readl(priv, NB8800_TXC_SR); | ||
| 555 | if (val) { | ||
| 556 | nb8800_writel(priv, NB8800_TXC_SR, val); | ||
| 557 | |||
| 558 | if (val & TSR_DI) | ||
| 559 | nb8800_tx_dma_start_irq(dev); | ||
| 560 | |||
| 561 | if (val & TSR_TI) | ||
| 562 | napi_schedule_irqoff(&priv->napi); | ||
| 563 | |||
| 564 | if (unlikely(val & TSR_DE)) | ||
| 565 | netdev_err(dev, "TX DMA error\n"); | ||
| 566 | |||
| 567 | /* should never happen with automatic status retrieval */ | ||
| 568 | if (unlikely(val & TSR_TO)) | ||
| 569 | netdev_err(dev, "TX Status FIFO overflow\n"); | ||
| 570 | |||
| 571 | ret = IRQ_HANDLED; | ||
| 572 | } | ||
| 573 | |||
| 574 | /* rx interrupt */ | ||
| 575 | val = nb8800_readl(priv, NB8800_RXC_SR); | ||
| 576 | if (val) { | ||
| 577 | nb8800_writel(priv, NB8800_RXC_SR, val); | ||
| 578 | |||
| 579 | if (likely(val & (RSR_RI | RSR_DI))) { | ||
| 580 | nb8800_writel(priv, NB8800_RX_ITR, priv->rx_itr_poll); | ||
| 581 | napi_schedule_irqoff(&priv->napi); | ||
| 582 | } | ||
| 583 | |||
| 584 | if (unlikely(val & RSR_DE)) | ||
| 585 | netdev_err(dev, "RX DMA error\n"); | ||
| 586 | |||
| 587 | /* should never happen with automatic status retrieval */ | ||
| 588 | if (unlikely(val & RSR_RO)) | ||
| 589 | netdev_err(dev, "RX Status FIFO overflow\n"); | ||
| 590 | |||
| 591 | ret = IRQ_HANDLED; | ||
| 592 | } | ||
| 593 | |||
| 594 | return ret; | ||
| 595 | } | ||
| 596 | |||
| 597 | static void nb8800_mac_config(struct net_device *dev) | ||
| 598 | { | ||
| 599 | struct nb8800_priv *priv = netdev_priv(dev); | ||
| 600 | bool gigabit = priv->speed == SPEED_1000; | ||
| 601 | u32 mac_mode_mask = RGMII_MODE | HALF_DUPLEX | GMAC_MODE; | ||
| 602 | u32 mac_mode = 0; | ||
| 603 | u32 slot_time; | ||
| 604 | u32 phy_clk; | ||
| 605 | u32 ict; | ||
| 606 | |||
| 607 | if (!priv->duplex) | ||
| 608 | mac_mode |= HALF_DUPLEX; | ||
| 609 | |||
| 610 | if (gigabit) { | ||
| 611 | if (priv->phy_mode == PHY_INTERFACE_MODE_RGMII) | ||
| 612 | mac_mode |= RGMII_MODE; | ||
| 613 | |||
| 614 | mac_mode |= GMAC_MODE; | ||
| 615 | phy_clk = 125000000; | ||
| 616 | |||
| 617 | /* Should be 512 but register is only 8 bits */ | ||
| 618 | slot_time = 255; | ||
| 619 | } else { | ||
| 620 | phy_clk = 25000000; | ||
| 621 | slot_time = 128; | ||
| 622 | } | ||
| 623 | |||
| 624 | ict = DIV_ROUND_UP(phy_clk, clk_get_rate(priv->clk)); | ||
| 625 | |||
| 626 | nb8800_writeb(priv, NB8800_IC_THRESHOLD, ict); | ||
| 627 | nb8800_writeb(priv, NB8800_SLOT_TIME, slot_time); | ||
| 628 | nb8800_maskb(priv, NB8800_MAC_MODE, mac_mode_mask, mac_mode); | ||
| 629 | } | ||
| 630 | |||
| 631 | static void nb8800_pause_config(struct net_device *dev) | ||
| 632 | { | ||
| 633 | struct nb8800_priv *priv = netdev_priv(dev); | ||
| 634 | struct phy_device *phydev = priv->phydev; | ||
| 635 | u32 rxcr; | ||
| 636 | |||
| 637 | if (priv->pause_aneg) { | ||
| 638 | if (!phydev || !phydev->link) | ||
| 639 | return; | ||
| 640 | |||
| 641 | priv->pause_rx = phydev->pause; | ||
| 642 | priv->pause_tx = phydev->pause ^ phydev->asym_pause; | ||
| 643 | } | ||
| 644 | |||
| 645 | nb8800_modb(priv, NB8800_RX_CTL, RX_PAUSE_EN, priv->pause_rx); | ||
| 646 | |||
| 647 | rxcr = nb8800_readl(priv, NB8800_RXC_CR); | ||
| 648 | if (!!(rxcr & RCR_FL) == priv->pause_tx) | ||
| 649 | return; | ||
| 650 | |||
| 651 | if (netif_running(dev)) { | ||
| 652 | napi_disable(&priv->napi); | ||
| 653 | netif_tx_lock_bh(dev); | ||
| 654 | nb8800_dma_stop(dev); | ||
| 655 | nb8800_modl(priv, NB8800_RXC_CR, RCR_FL, priv->pause_tx); | ||
| 656 | nb8800_start_rx(dev); | ||
| 657 | netif_tx_unlock_bh(dev); | ||
| 658 | napi_enable(&priv->napi); | ||
| 659 | } else { | ||
| 660 | nb8800_modl(priv, NB8800_RXC_CR, RCR_FL, priv->pause_tx); | ||
| 661 | } | ||
| 662 | } | ||
| 663 | |||
| 664 | static void nb8800_link_reconfigure(struct net_device *dev) | ||
| 665 | { | ||
| 666 | struct nb8800_priv *priv = netdev_priv(dev); | ||
| 667 | struct phy_device *phydev = priv->phydev; | ||
| 668 | int change = 0; | ||
| 669 | |||
| 670 | if (phydev->link) { | ||
| 671 | if (phydev->speed != priv->speed) { | ||
| 672 | priv->speed = phydev->speed; | ||
| 673 | change = 1; | ||
| 674 | } | ||
| 675 | |||
| 676 | if (phydev->duplex != priv->duplex) { | ||
| 677 | priv->duplex = phydev->duplex; | ||
| 678 | change = 1; | ||
| 679 | } | ||
| 680 | |||
| 681 | if (change) | ||
| 682 | nb8800_mac_config(dev); | ||
| 683 | |||
| 684 | nb8800_pause_config(dev); | ||
| 685 | } | ||
| 686 | |||
| 687 | if (phydev->link != priv->link) { | ||
| 688 | priv->link = phydev->link; | ||
| 689 | change = 1; | ||
| 690 | } | ||
| 691 | |||
| 692 | if (change) | ||
| 693 | phy_print_status(priv->phydev); | ||
| 694 | } | ||
| 695 | |||
| 696 | static void nb8800_update_mac_addr(struct net_device *dev) | ||
| 697 | { | ||
| 698 | struct nb8800_priv *priv = netdev_priv(dev); | ||
| 699 | int i; | ||
| 700 | |||
| 701 | for (i = 0; i < ETH_ALEN; i++) | ||
| 702 | nb8800_writeb(priv, NB8800_SRC_ADDR(i), dev->dev_addr[i]); | ||
| 703 | |||
| 704 | for (i = 0; i < ETH_ALEN; i++) | ||
| 705 | nb8800_writeb(priv, NB8800_UC_ADDR(i), dev->dev_addr[i]); | ||
| 706 | } | ||
| 707 | |||
| 708 | static int nb8800_set_mac_address(struct net_device *dev, void *addr) | ||
| 709 | { | ||
| 710 | struct sockaddr *sock = addr; | ||
| 711 | |||
| 712 | if (netif_running(dev)) | ||
| 713 | return -EBUSY; | ||
| 714 | |||
| 715 | ether_addr_copy(dev->dev_addr, sock->sa_data); | ||
| 716 | nb8800_update_mac_addr(dev); | ||
| 717 | |||
| 718 | return 0; | ||
| 719 | } | ||
| 720 | |||
| 721 | static void nb8800_mc_init(struct net_device *dev, int val) | ||
| 722 | { | ||
| 723 | struct nb8800_priv *priv = netdev_priv(dev); | ||
| 724 | |||
| 725 | nb8800_writeb(priv, NB8800_MC_INIT, val); | ||
| 726 | readb_poll_timeout_atomic(priv->base + NB8800_MC_INIT, val, !val, | ||
| 727 | 1, 1000); | ||
| 728 | } | ||
| 729 | |||
| 730 | static void nb8800_set_rx_mode(struct net_device *dev) | ||
| 731 | { | ||
| 732 | struct nb8800_priv *priv = netdev_priv(dev); | ||
| 733 | struct netdev_hw_addr *ha; | ||
| 734 | int i; | ||
| 735 | |||
| 736 | if (dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) { | ||
| 737 | nb8800_mac_af(dev, false); | ||
| 738 | return; | ||
| 739 | } | ||
| 740 | |||
| 741 | nb8800_mac_af(dev, true); | ||
| 742 | nb8800_mc_init(dev, 0); | ||
| 743 | |||
| 744 | netdev_for_each_mc_addr(ha, dev) { | ||
| 745 | for (i = 0; i < ETH_ALEN; i++) | ||
| 746 | nb8800_writeb(priv, NB8800_MC_ADDR(i), ha->addr[i]); | ||
| 747 | |||
| 748 | nb8800_mc_init(dev, 0xff); | ||
| 749 | } | ||
| 750 | } | ||
| 751 | |||
| 752 | #define RX_DESC_SIZE (RX_DESC_COUNT * sizeof(struct nb8800_rx_desc)) | ||
| 753 | #define TX_DESC_SIZE (TX_DESC_COUNT * sizeof(struct nb8800_tx_desc)) | ||
| 754 | |||
| 755 | static void nb8800_dma_free(struct net_device *dev) | ||
| 756 | { | ||
| 757 | struct nb8800_priv *priv = netdev_priv(dev); | ||
| 758 | unsigned int i; | ||
| 759 | |||
| 760 | if (priv->rx_bufs) { | ||
| 761 | for (i = 0; i < RX_DESC_COUNT; i++) | ||
| 762 | if (priv->rx_bufs[i].page) | ||
| 763 | put_page(priv->rx_bufs[i].page); | ||
| 764 | |||
| 765 | kfree(priv->rx_bufs); | ||
| 766 | priv->rx_bufs = NULL; | ||
| 767 | } | ||
| 768 | |||
| 769 | if (priv->tx_bufs) { | ||
| 770 | for (i = 0; i < TX_DESC_COUNT; i++) | ||
| 771 | kfree_skb(priv->tx_bufs[i].skb); | ||
| 772 | |||
| 773 | kfree(priv->tx_bufs); | ||
| 774 | priv->tx_bufs = NULL; | ||
| 775 | } | ||
| 776 | |||
| 777 | if (priv->rx_descs) { | ||
| 778 | dma_free_coherent(dev->dev.parent, RX_DESC_SIZE, priv->rx_descs, | ||
| 779 | priv->rx_desc_dma); | ||
| 780 | priv->rx_descs = NULL; | ||
| 781 | } | ||
| 782 | |||
| 783 | if (priv->tx_descs) { | ||
| 784 | dma_free_coherent(dev->dev.parent, TX_DESC_SIZE, priv->tx_descs, | ||
| 785 | priv->tx_desc_dma); | ||
| 786 | priv->tx_descs = NULL; | ||
| 787 | } | ||
| 788 | } | ||
| 789 | |||
| 790 | static void nb8800_dma_reset(struct net_device *dev) | ||
| 791 | { | ||
| 792 | struct nb8800_priv *priv = netdev_priv(dev); | ||
| 793 | struct nb8800_rx_desc *rxd; | ||
| 794 | struct nb8800_tx_desc *txd; | ||
| 795 | unsigned int i; | ||
| 796 | |||
| 797 | for (i = 0; i < RX_DESC_COUNT; i++) { | ||
| 798 | dma_addr_t rx_dma = priv->rx_desc_dma + i * sizeof(*rxd); | ||
| 799 | |||
| 800 | rxd = &priv->rx_descs[i]; | ||
| 801 | rxd->desc.n_addr = rx_dma + sizeof(*rxd); | ||
| 802 | rxd->desc.r_addr = | ||
| 803 | rx_dma + offsetof(struct nb8800_rx_desc, report); | ||
| 804 | rxd->desc.config = priv->rx_dma_config; | ||
| 805 | rxd->report = 0; | ||
| 806 | } | ||
| 807 | |||
| 808 | rxd->desc.n_addr = priv->rx_desc_dma; | ||
| 809 | rxd->desc.config |= DESC_EOC; | ||
| 810 | |||
| 811 | priv->rx_eoc = RX_DESC_COUNT - 1; | ||
| 812 | |||
| 813 | for (i = 0; i < TX_DESC_COUNT; i++) { | ||
| 814 | struct nb8800_tx_buf *txb = &priv->tx_bufs[i]; | ||
| 815 | dma_addr_t r_dma = txb->dma_desc + | ||
| 816 | offsetof(struct nb8800_tx_desc, report); | ||
| 817 | |||
| 818 | txd = &priv->tx_descs[i]; | ||
| 819 | txd->desc[0].r_addr = r_dma; | ||
| 820 | txd->desc[1].r_addr = r_dma; | ||
| 821 | txd->report = 0; | ||
| 822 | } | ||
| 823 | |||
| 824 | priv->tx_next = 0; | ||
| 825 | priv->tx_queue = 0; | ||
| 826 | priv->tx_done = 0; | ||
| 827 | atomic_set(&priv->tx_free, TX_DESC_COUNT); | ||
| 828 | |||
| 829 | nb8800_writel(priv, NB8800_RX_DESC_ADDR, priv->rx_desc_dma); | ||
| 830 | |||
| 831 | wmb(); /* ensure all setup is written before starting */ | ||
| 832 | } | ||
| 833 | |||
| 834 | static int nb8800_dma_init(struct net_device *dev) | ||
| 835 | { | ||
| 836 | struct nb8800_priv *priv = netdev_priv(dev); | ||
| 837 | unsigned int n_rx = RX_DESC_COUNT; | ||
| 838 | unsigned int n_tx = TX_DESC_COUNT; | ||
| 839 | unsigned int i; | ||
| 840 | int err; | ||
| 841 | |||
| 842 | priv->rx_descs = dma_alloc_coherent(dev->dev.parent, RX_DESC_SIZE, | ||
| 843 | &priv->rx_desc_dma, GFP_KERNEL); | ||
| 844 | if (!priv->rx_descs) | ||
| 845 | goto err_out; | ||
| 846 | |||
| 847 | priv->rx_bufs = kcalloc(n_rx, sizeof(*priv->rx_bufs), GFP_KERNEL); | ||
| 848 | if (!priv->rx_bufs) | ||
| 849 | goto err_out; | ||
| 850 | |||
| 851 | for (i = 0; i < n_rx; i++) { | ||
| 852 | err = nb8800_alloc_rx(dev, i, false); | ||
| 853 | if (err) | ||
| 854 | goto err_out; | ||
| 855 | } | ||
| 856 | |||
| 857 | priv->tx_descs = dma_alloc_coherent(dev->dev.parent, TX_DESC_SIZE, | ||
| 858 | &priv->tx_desc_dma, GFP_KERNEL); | ||
| 859 | if (!priv->tx_descs) | ||
| 860 | goto err_out; | ||
| 861 | |||
| 862 | priv->tx_bufs = kcalloc(n_tx, sizeof(*priv->tx_bufs), GFP_KERNEL); | ||
| 863 | if (!priv->tx_bufs) | ||
| 864 | goto err_out; | ||
| 865 | |||
| 866 | for (i = 0; i < n_tx; i++) | ||
| 867 | priv->tx_bufs[i].dma_desc = | ||
| 868 | priv->tx_desc_dma + i * sizeof(struct nb8800_tx_desc); | ||
| 869 | |||
| 870 | nb8800_dma_reset(dev); | ||
| 871 | |||
| 872 | return 0; | ||
| 873 | |||
| 874 | err_out: | ||
| 875 | nb8800_dma_free(dev); | ||
| 876 | |||
| 877 | return -ENOMEM; | ||
| 878 | } | ||
| 879 | |||
| 880 | static int nb8800_dma_stop(struct net_device *dev) | ||
| 881 | { | ||
| 882 | struct nb8800_priv *priv = netdev_priv(dev); | ||
| 883 | struct nb8800_tx_buf *txb = &priv->tx_bufs[0]; | ||
| 884 | struct nb8800_tx_desc *txd = &priv->tx_descs[0]; | ||
| 885 | int retry = 5; | ||
| 886 | u32 txcr; | ||
| 887 | u32 rxcr; | ||
| 888 | int err; | ||
| 889 | unsigned int i; | ||
| 890 | |||
| 891 | /* wait for tx to finish */ | ||
| 892 | err = readl_poll_timeout_atomic(priv->base + NB8800_TXC_CR, txcr, | ||
| 893 | !(txcr & TCR_EN) && | ||
| 894 | priv->tx_done == priv->tx_next, | ||
| 895 | 1000, 1000000); | ||
| 896 | if (err) | ||
| 897 | return err; | ||
| 898 | |||
| 899 | /* The rx DMA only stops if it reaches the end of chain. | ||
| 900 | * To make this happen, we set the EOC flag on all rx | ||
| 901 | * descriptors, put the device in loopback mode, and send | ||
| 902 | * a few dummy frames. The interrupt handler will ignore | ||
| 903 | * these since NAPI is disabled and no real frames are in | ||
| 904 | * the tx queue. | ||
| 905 | */ | ||
| 906 | |||
| 907 | for (i = 0; i < RX_DESC_COUNT; i++) | ||
| 908 | priv->rx_descs[i].desc.config |= DESC_EOC; | ||
| 909 | |||
| 910 | txd->desc[0].s_addr = | ||
| 911 | txb->dma_desc + offsetof(struct nb8800_tx_desc, buf); | ||
| 912 | txd->desc[0].config = DESC_BTS(2) | DESC_DS | DESC_EOF | DESC_EOC | 8; | ||
| 913 | memset(txd->buf, 0, sizeof(txd->buf)); | ||
| 914 | |||
| 915 | nb8800_mac_af(dev, false); | ||
| 916 | nb8800_setb(priv, NB8800_MAC_MODE, LOOPBACK_EN); | ||
| 917 | |||
| 918 | do { | ||
| 919 | nb8800_writel(priv, NB8800_TX_DESC_ADDR, txb->dma_desc); | ||
| 920 | wmb(); | ||
| 921 | nb8800_writel(priv, NB8800_TXC_CR, txcr | TCR_EN); | ||
| 922 | |||
| 923 | err = readl_poll_timeout_atomic(priv->base + NB8800_RXC_CR, | ||
| 924 | rxcr, !(rxcr & RCR_EN), | ||
| 925 | 1000, 100000); | ||
| 926 | } while (err && --retry); | ||
| 927 | |||
| 928 | nb8800_mac_af(dev, true); | ||
| 929 | nb8800_clearb(priv, NB8800_MAC_MODE, LOOPBACK_EN); | ||
| 930 | nb8800_dma_reset(dev); | ||
| 931 | |||
| 932 | return retry ? 0 : -ETIMEDOUT; | ||
| 933 | } | ||
| 934 | |||
| 935 | static void nb8800_pause_adv(struct net_device *dev) | ||
| 936 | { | ||
| 937 | struct nb8800_priv *priv = netdev_priv(dev); | ||
| 938 | u32 adv = 0; | ||
| 939 | |||
| 940 | if (!priv->phydev) | ||
| 941 | return; | ||
| 942 | |||
| 943 | if (priv->pause_rx) | ||
| 944 | adv |= ADVERTISED_Pause | ADVERTISED_Asym_Pause; | ||
| 945 | if (priv->pause_tx) | ||
| 946 | adv ^= ADVERTISED_Asym_Pause; | ||
| 947 | |||
| 948 | priv->phydev->supported |= adv; | ||
| 949 | priv->phydev->advertising |= adv; | ||
| 950 | } | ||
| 951 | |||
| 952 | static int nb8800_open(struct net_device *dev) | ||
| 953 | { | ||
| 954 | struct nb8800_priv *priv = netdev_priv(dev); | ||
| 955 | int err; | ||
| 956 | |||
| 957 | /* clear any pending interrupts */ | ||
| 958 | nb8800_writel(priv, NB8800_RXC_SR, 0xf); | ||
| 959 | nb8800_writel(priv, NB8800_TXC_SR, 0xf); | ||
| 960 | |||
| 961 | err = nb8800_dma_init(dev); | ||
| 962 | if (err) | ||
| 963 | return err; | ||
| 964 | |||
| 965 | err = request_irq(dev->irq, nb8800_irq, 0, dev_name(&dev->dev), dev); | ||
| 966 | if (err) | ||
| 967 | goto err_free_dma; | ||
| 968 | |||
| 969 | nb8800_mac_rx(dev, true); | ||
| 970 | nb8800_mac_tx(dev, true); | ||
| 971 | |||
| 972 | priv->phydev = of_phy_connect(dev, priv->phy_node, | ||
| 973 | nb8800_link_reconfigure, 0, | ||
| 974 | priv->phy_mode); | ||
| 975 | if (!priv->phydev) | ||
| 976 | goto err_free_irq; | ||
| 977 | |||
| 978 | nb8800_pause_adv(dev); | ||
| 979 | |||
| 980 | netdev_reset_queue(dev); | ||
| 981 | napi_enable(&priv->napi); | ||
| 982 | netif_start_queue(dev); | ||
| 983 | |||
| 984 | nb8800_start_rx(dev); | ||
| 985 | phy_start(priv->phydev); | ||
| 986 | |||
| 987 | return 0; | ||
| 988 | |||
| 989 | err_free_irq: | ||
| 990 | free_irq(dev->irq, dev); | ||
| 991 | err_free_dma: | ||
| 992 | nb8800_dma_free(dev); | ||
| 993 | |||
| 994 | return err; | ||
| 995 | } | ||
| 996 | |||
| 997 | static int nb8800_stop(struct net_device *dev) | ||
| 998 | { | ||
| 999 | struct nb8800_priv *priv = netdev_priv(dev); | ||
| 1000 | |||
| 1001 | phy_stop(priv->phydev); | ||
| 1002 | |||
| 1003 | netif_stop_queue(dev); | ||
| 1004 | napi_disable(&priv->napi); | ||
| 1005 | |||
| 1006 | nb8800_dma_stop(dev); | ||
| 1007 | nb8800_mac_rx(dev, false); | ||
| 1008 | nb8800_mac_tx(dev, false); | ||
| 1009 | |||
| 1010 | phy_disconnect(priv->phydev); | ||
| 1011 | priv->phydev = NULL; | ||
| 1012 | |||
| 1013 | free_irq(dev->irq, dev); | ||
| 1014 | |||
| 1015 | nb8800_dma_free(dev); | ||
| 1016 | |||
| 1017 | return 0; | ||
| 1018 | } | ||
| 1019 | |||
| 1020 | static int nb8800_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | ||
| 1021 | { | ||
| 1022 | struct nb8800_priv *priv = netdev_priv(dev); | ||
| 1023 | |||
| 1024 | return phy_mii_ioctl(priv->phydev, rq, cmd); | ||
| 1025 | } | ||
| 1026 | |||
| 1027 | static const struct net_device_ops nb8800_netdev_ops = { | ||
| 1028 | .ndo_open = nb8800_open, | ||
| 1029 | .ndo_stop = nb8800_stop, | ||
| 1030 | .ndo_start_xmit = nb8800_xmit, | ||
| 1031 | .ndo_set_mac_address = nb8800_set_mac_address, | ||
| 1032 | .ndo_set_rx_mode = nb8800_set_rx_mode, | ||
| 1033 | .ndo_do_ioctl = nb8800_ioctl, | ||
| 1034 | .ndo_change_mtu = eth_change_mtu, | ||
| 1035 | .ndo_validate_addr = eth_validate_addr, | ||
| 1036 | }; | ||
| 1037 | |||
| 1038 | static int nb8800_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
| 1039 | { | ||
| 1040 | struct nb8800_priv *priv = netdev_priv(dev); | ||
| 1041 | |||
| 1042 | if (!priv->phydev) | ||
| 1043 | return -ENODEV; | ||
| 1044 | |||
| 1045 | return phy_ethtool_gset(priv->phydev, cmd); | ||
| 1046 | } | ||
| 1047 | |||
| 1048 | static int nb8800_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
| 1049 | { | ||
| 1050 | struct nb8800_priv *priv = netdev_priv(dev); | ||
| 1051 | |||
| 1052 | if (!priv->phydev) | ||
| 1053 | return -ENODEV; | ||
| 1054 | |||
| 1055 | return phy_ethtool_sset(priv->phydev, cmd); | ||
| 1056 | } | ||
| 1057 | |||
| 1058 | static int nb8800_nway_reset(struct net_device *dev) | ||
| 1059 | { | ||
| 1060 | struct nb8800_priv *priv = netdev_priv(dev); | ||
| 1061 | |||
| 1062 | if (!priv->phydev) | ||
| 1063 | return -ENODEV; | ||
| 1064 | |||
| 1065 | return genphy_restart_aneg(priv->phydev); | ||
| 1066 | } | ||
| 1067 | |||
| 1068 | static void nb8800_get_pauseparam(struct net_device *dev, | ||
| 1069 | struct ethtool_pauseparam *pp) | ||
| 1070 | { | ||
| 1071 | struct nb8800_priv *priv = netdev_priv(dev); | ||
| 1072 | |||
| 1073 | pp->autoneg = priv->pause_aneg; | ||
| 1074 | pp->rx_pause = priv->pause_rx; | ||
| 1075 | pp->tx_pause = priv->pause_tx; | ||
| 1076 | } | ||
| 1077 | |||
| 1078 | static int nb8800_set_pauseparam(struct net_device *dev, | ||
| 1079 | struct ethtool_pauseparam *pp) | ||
| 1080 | { | ||
| 1081 | struct nb8800_priv *priv = netdev_priv(dev); | ||
| 1082 | |||
| 1083 | priv->pause_aneg = pp->autoneg; | ||
| 1084 | priv->pause_rx = pp->rx_pause; | ||
| 1085 | priv->pause_tx = pp->tx_pause; | ||
| 1086 | |||
| 1087 | nb8800_pause_adv(dev); | ||
| 1088 | |||
| 1089 | if (!priv->pause_aneg) | ||
| 1090 | nb8800_pause_config(dev); | ||
| 1091 | else if (priv->phydev) | ||
| 1092 | phy_start_aneg(priv->phydev); | ||
| 1093 | |||
| 1094 | return 0; | ||
| 1095 | } | ||
| 1096 | |||
| 1097 | static const char nb8800_stats_names[][ETH_GSTRING_LEN] = { | ||
| 1098 | "rx_bytes_ok", | ||
| 1099 | "rx_frames_ok", | ||
| 1100 | "rx_undersize_frames", | ||
| 1101 | "rx_fragment_frames", | ||
| 1102 | "rx_64_byte_frames", | ||
| 1103 | "rx_127_byte_frames", | ||
| 1104 | "rx_255_byte_frames", | ||
| 1105 | "rx_511_byte_frames", | ||
| 1106 | "rx_1023_byte_frames", | ||
| 1107 | "rx_max_size_frames", | ||
| 1108 | "rx_oversize_frames", | ||
| 1109 | "rx_bad_fcs_frames", | ||
| 1110 | "rx_broadcast_frames", | ||
| 1111 | "rx_multicast_frames", | ||
| 1112 | "rx_control_frames", | ||
| 1113 | "rx_pause_frames", | ||
| 1114 | "rx_unsup_control_frames", | ||
| 1115 | "rx_align_error_frames", | ||
| 1116 | "rx_overrun_frames", | ||
| 1117 | "rx_jabber_frames", | ||
| 1118 | "rx_bytes", | ||
| 1119 | "rx_frames", | ||
| 1120 | |||
| 1121 | "tx_bytes_ok", | ||
| 1122 | "tx_frames_ok", | ||
| 1123 | "tx_64_byte_frames", | ||
| 1124 | "tx_127_byte_frames", | ||
| 1125 | "tx_255_byte_frames", | ||
| 1126 | "tx_511_byte_frames", | ||
| 1127 | "tx_1023_byte_frames", | ||
| 1128 | "tx_max_size_frames", | ||
| 1129 | "tx_oversize_frames", | ||
| 1130 | "tx_broadcast_frames", | ||
| 1131 | "tx_multicast_frames", | ||
| 1132 | "tx_control_frames", | ||
| 1133 | "tx_pause_frames", | ||
| 1134 | "tx_underrun_frames", | ||
| 1135 | "tx_single_collision_frames", | ||
| 1136 | "tx_multi_collision_frames", | ||
| 1137 | "tx_deferred_collision_frames", | ||
| 1138 | "tx_late_collision_frames", | ||
| 1139 | "tx_excessive_collision_frames", | ||
| 1140 | "tx_bytes", | ||
| 1141 | "tx_frames", | ||
| 1142 | "tx_collisions", | ||
| 1143 | }; | ||
| 1144 | |||
| 1145 | #define NB8800_NUM_STATS ARRAY_SIZE(nb8800_stats_names) | ||
| 1146 | |||
| 1147 | static int nb8800_get_sset_count(struct net_device *dev, int sset) | ||
| 1148 | { | ||
| 1149 | if (sset == ETH_SS_STATS) | ||
| 1150 | return NB8800_NUM_STATS; | ||
| 1151 | |||
| 1152 | return -EOPNOTSUPP; | ||
| 1153 | } | ||
| 1154 | |||
| 1155 | static void nb8800_get_strings(struct net_device *dev, u32 sset, u8 *buf) | ||
| 1156 | { | ||
| 1157 | if (sset == ETH_SS_STATS) | ||
| 1158 | memcpy(buf, &nb8800_stats_names, sizeof(nb8800_stats_names)); | ||
| 1159 | } | ||
| 1160 | |||
| 1161 | static u32 nb8800_read_stat(struct net_device *dev, int index) | ||
| 1162 | { | ||
| 1163 | struct nb8800_priv *priv = netdev_priv(dev); | ||
| 1164 | |||
| 1165 | nb8800_writeb(priv, NB8800_STAT_INDEX, index); | ||
| 1166 | |||
| 1167 | return nb8800_readl(priv, NB8800_STAT_DATA); | ||
| 1168 | } | ||
| 1169 | |||
| 1170 | static void nb8800_get_ethtool_stats(struct net_device *dev, | ||
| 1171 | struct ethtool_stats *estats, u64 *st) | ||
| 1172 | { | ||
| 1173 | unsigned int i; | ||
| 1174 | u32 rx, tx; | ||
| 1175 | |||
| 1176 | for (i = 0; i < NB8800_NUM_STATS / 2; i++) { | ||
| 1177 | rx = nb8800_read_stat(dev, i); | ||
| 1178 | tx = nb8800_read_stat(dev, i | 0x80); | ||
| 1179 | st[i] = rx; | ||
| 1180 | st[i + NB8800_NUM_STATS / 2] = tx; | ||
| 1181 | } | ||
| 1182 | } | ||
| 1183 | |||
| 1184 | static const struct ethtool_ops nb8800_ethtool_ops = { | ||
| 1185 | .get_settings = nb8800_get_settings, | ||
| 1186 | .set_settings = nb8800_set_settings, | ||
| 1187 | .nway_reset = nb8800_nway_reset, | ||
| 1188 | .get_link = ethtool_op_get_link, | ||
| 1189 | .get_pauseparam = nb8800_get_pauseparam, | ||
| 1190 | .set_pauseparam = nb8800_set_pauseparam, | ||
| 1191 | .get_sset_count = nb8800_get_sset_count, | ||
| 1192 | .get_strings = nb8800_get_strings, | ||
| 1193 | .get_ethtool_stats = nb8800_get_ethtool_stats, | ||
| 1194 | }; | ||
| 1195 | |||
| 1196 | static int nb8800_hw_init(struct net_device *dev) | ||
| 1197 | { | ||
| 1198 | struct nb8800_priv *priv = netdev_priv(dev); | ||
| 1199 | u32 val; | ||
| 1200 | |||
| 1201 | val = TX_RETRY_EN | TX_PAD_EN | TX_APPEND_FCS; | ||
| 1202 | nb8800_writeb(priv, NB8800_TX_CTL1, val); | ||
| 1203 | |||
| 1204 | /* Collision retry count */ | ||
| 1205 | nb8800_writeb(priv, NB8800_TX_CTL2, 5); | ||
| 1206 | |||
| 1207 | val = RX_PAD_STRIP | RX_AF_EN; | ||
| 1208 | nb8800_writeb(priv, NB8800_RX_CTL, val); | ||
| 1209 | |||
| 1210 | /* Chosen by fair dice roll */ | ||
| 1211 | nb8800_writeb(priv, NB8800_RANDOM_SEED, 4); | ||
| 1212 | |||
| 1213 | /* TX cycles per deferral period */ | ||
| 1214 | nb8800_writeb(priv, NB8800_TX_SDP, 12); | ||
| 1215 | |||
| 1216 | /* The following three threshold values have been | ||
| 1217 | * experimentally determined for good results. | ||
| 1218 | */ | ||
| 1219 | |||
| 1220 | /* RX/TX FIFO threshold for partial empty (64-bit entries) */ | ||
| 1221 | nb8800_writeb(priv, NB8800_PE_THRESHOLD, 0); | ||
| 1222 | |||
| 1223 | /* RX/TX FIFO threshold for partial full (64-bit entries) */ | ||
| 1224 | nb8800_writeb(priv, NB8800_PF_THRESHOLD, 255); | ||
| 1225 | |||
| 1226 | /* Buffer size for transmit (64-bit entries) */ | ||
| 1227 | nb8800_writeb(priv, NB8800_TX_BUFSIZE, 64); | ||
| 1228 | |||
| 1229 | /* Configure tx DMA */ | ||
| 1230 | |||
| 1231 | val = nb8800_readl(priv, NB8800_TXC_CR); | ||
| 1232 | val &= TCR_LE; /* keep endian setting */ | ||
| 1233 | val |= TCR_DM; /* DMA descriptor mode */ | ||
| 1234 | val |= TCR_RS; /* automatically store tx status */ | ||
| 1235 | val |= TCR_DIE; /* interrupt on DMA chain completion */ | ||
| 1236 | val |= TCR_TFI(7); /* interrupt after 7 frames transmitted */ | ||
| 1237 | val |= TCR_BTS(2); /* 32-byte bus transaction size */ | ||
| 1238 | nb8800_writel(priv, NB8800_TXC_CR, val); | ||
| 1239 | |||
| 1240 | /* TX complete interrupt after 10 ms or 7 frames (see above) */ | ||
| 1241 | val = clk_get_rate(priv->clk) / 100; | ||
| 1242 | nb8800_writel(priv, NB8800_TX_ITR, val); | ||
| 1243 | |||
| 1244 | /* Configure rx DMA */ | ||
| 1245 | |||
| 1246 | val = nb8800_readl(priv, NB8800_RXC_CR); | ||
| 1247 | val &= RCR_LE; /* keep endian setting */ | ||
| 1248 | val |= RCR_DM; /* DMA descriptor mode */ | ||
| 1249 | val |= RCR_RS; /* automatically store rx status */ | ||
| 1250 | val |= RCR_DIE; /* interrupt at end of DMA chain */ | ||
| 1251 | val |= RCR_RFI(7); /* interrupt after 7 frames received */ | ||
| 1252 | val |= RCR_BTS(2); /* 32-byte bus transaction size */ | ||
| 1253 | nb8800_writel(priv, NB8800_RXC_CR, val); | ||
| 1254 | |||
| 1255 | /* The rx interrupt can fire before the DMA has completed | ||
| 1256 | * unless a small delay is added. 50 us is hopefully enough. | ||
| 1257 | */ | ||
| 1258 | priv->rx_itr_irq = clk_get_rate(priv->clk) / 20000; | ||
| 1259 | |||
| 1260 | /* In NAPI poll mode we want to disable interrupts, but the | ||
| 1261 | * hardware does not permit this. Delay 10 ms instead. | ||
| 1262 | */ | ||
| 1263 | priv->rx_itr_poll = clk_get_rate(priv->clk) / 100; | ||
| 1264 | |||
| 1265 | nb8800_writel(priv, NB8800_RX_ITR, priv->rx_itr_irq); | ||
| 1266 | |||
| 1267 | priv->rx_dma_config = RX_BUF_SIZE | DESC_BTS(2) | DESC_DS | DESC_EOF; | ||
| 1268 | |||
| 1269 | /* Flow control settings */ | ||
| 1270 | |||
| 1271 | /* Pause time of 0.1 ms */ | ||
| 1272 | val = 100000 / 512; | ||
| 1273 | nb8800_writeb(priv, NB8800_PQ1, val >> 8); | ||
| 1274 | nb8800_writeb(priv, NB8800_PQ2, val & 0xff); | ||
| 1275 | |||
| 1276 | /* Auto-negotiate by default */ | ||
| 1277 | priv->pause_aneg = true; | ||
| 1278 | priv->pause_rx = true; | ||
| 1279 | priv->pause_tx = true; | ||
| 1280 | |||
| 1281 | nb8800_mc_init(dev, 0); | ||
| 1282 | |||
| 1283 | return 0; | ||
| 1284 | } | ||
| 1285 | |||
| 1286 | static int nb8800_tangox_init(struct net_device *dev) | ||
| 1287 | { | ||
| 1288 | struct nb8800_priv *priv = netdev_priv(dev); | ||
| 1289 | u32 pad_mode = PAD_MODE_MII; | ||
| 1290 | |||
| 1291 | switch (priv->phy_mode) { | ||
| 1292 | case PHY_INTERFACE_MODE_MII: | ||
| 1293 | case PHY_INTERFACE_MODE_GMII: | ||
| 1294 | pad_mode = PAD_MODE_MII; | ||
| 1295 | break; | ||
| 1296 | |||
| 1297 | case PHY_INTERFACE_MODE_RGMII: | ||
| 1298 | pad_mode = PAD_MODE_RGMII; | ||
| 1299 | break; | ||
| 1300 | |||
| 1301 | case PHY_INTERFACE_MODE_RGMII_TXID: | ||
| 1302 | pad_mode = PAD_MODE_RGMII | PAD_MODE_GTX_CLK_DELAY; | ||
| 1303 | break; | ||
| 1304 | |||
| 1305 | default: | ||
| 1306 | dev_err(dev->dev.parent, "unsupported phy mode %s\n", | ||
| 1307 | phy_modes(priv->phy_mode)); | ||
| 1308 | return -EINVAL; | ||
| 1309 | } | ||
| 1310 | |||
| 1311 | nb8800_writeb(priv, NB8800_TANGOX_PAD_MODE, pad_mode); | ||
| 1312 | |||
| 1313 | return 0; | ||
| 1314 | } | ||
| 1315 | |||
| 1316 | static int nb8800_tangox_reset(struct net_device *dev) | ||
| 1317 | { | ||
| 1318 | struct nb8800_priv *priv = netdev_priv(dev); | ||
| 1319 | int clk_div; | ||
| 1320 | |||
| 1321 | nb8800_writeb(priv, NB8800_TANGOX_RESET, 0); | ||
| 1322 | usleep_range(1000, 10000); | ||
| 1323 | nb8800_writeb(priv, NB8800_TANGOX_RESET, 1); | ||
| 1324 | |||
| 1325 | wmb(); /* ensure reset is cleared before proceeding */ | ||
| 1326 | |||
| 1327 | clk_div = DIV_ROUND_UP(clk_get_rate(priv->clk), 2 * MAX_MDC_CLOCK); | ||
| 1328 | nb8800_writew(priv, NB8800_TANGOX_MDIO_CLKDIV, clk_div); | ||
| 1329 | |||
| 1330 | return 0; | ||
| 1331 | } | ||
| 1332 | |||
| 1333 | static const struct nb8800_ops nb8800_tangox_ops = { | ||
| 1334 | .init = nb8800_tangox_init, | ||
| 1335 | .reset = nb8800_tangox_reset, | ||
| 1336 | }; | ||
| 1337 | |||
| 1338 | static int nb8800_tango4_init(struct net_device *dev) | ||
| 1339 | { | ||
| 1340 | struct nb8800_priv *priv = netdev_priv(dev); | ||
| 1341 | int err; | ||
| 1342 | |||
| 1343 | err = nb8800_tangox_init(dev); | ||
| 1344 | if (err) | ||
| 1345 | return err; | ||
| 1346 | |||
| 1347 | /* On tango4 interrupt on DMA completion per frame works and gives | ||
| 1348 | * better performance despite generating more rx interrupts. | ||
| 1349 | */ | ||
| 1350 | |||
| 1351 | /* Disable unnecessary interrupt on rx completion */ | ||
| 1352 | nb8800_clearl(priv, NB8800_RXC_CR, RCR_RFI(7)); | ||
| 1353 | |||
| 1354 | /* Request interrupt on descriptor DMA completion */ | ||
| 1355 | priv->rx_dma_config |= DESC_ID; | ||
| 1356 | |||
| 1357 | return 0; | ||
| 1358 | } | ||
| 1359 | |||
| 1360 | static const struct nb8800_ops nb8800_tango4_ops = { | ||
| 1361 | .init = nb8800_tango4_init, | ||
| 1362 | .reset = nb8800_tangox_reset, | ||
| 1363 | }; | ||
| 1364 | |||
| 1365 | static const struct of_device_id nb8800_dt_ids[] = { | ||
| 1366 | { | ||
| 1367 | .compatible = "aurora,nb8800", | ||
| 1368 | }, | ||
| 1369 | { | ||
| 1370 | .compatible = "sigma,smp8642-ethernet", | ||
| 1371 | .data = &nb8800_tangox_ops, | ||
| 1372 | }, | ||
| 1373 | { | ||
| 1374 | .compatible = "sigma,smp8734-ethernet", | ||
| 1375 | .data = &nb8800_tango4_ops, | ||
| 1376 | }, | ||
| 1377 | { } | ||
| 1378 | }; | ||
| 1379 | |||
| 1380 | static int nb8800_probe(struct platform_device *pdev) | ||
| 1381 | { | ||
| 1382 | const struct of_device_id *match; | ||
| 1383 | const struct nb8800_ops *ops = NULL; | ||
| 1384 | struct nb8800_priv *priv; | ||
| 1385 | struct resource *res; | ||
| 1386 | struct net_device *dev; | ||
| 1387 | struct mii_bus *bus; | ||
| 1388 | const unsigned char *mac; | ||
| 1389 | void __iomem *base; | ||
| 1390 | int irq; | ||
| 1391 | int ret; | ||
| 1392 | |||
| 1393 | match = of_match_device(nb8800_dt_ids, &pdev->dev); | ||
| 1394 | if (match) | ||
| 1395 | ops = match->data; | ||
| 1396 | |||
| 1397 | irq = platform_get_irq(pdev, 0); | ||
| 1398 | if (irq <= 0) { | ||
| 1399 | dev_err(&pdev->dev, "No IRQ\n"); | ||
| 1400 | return -EINVAL; | ||
| 1401 | } | ||
| 1402 | |||
| 1403 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 1404 | base = devm_ioremap_resource(&pdev->dev, res); | ||
| 1405 | if (IS_ERR(base)) | ||
| 1406 | return PTR_ERR(base); | ||
| 1407 | |||
| 1408 | dev_dbg(&pdev->dev, "AU-NB8800 Ethernet at %pa\n", &res->start); | ||
| 1409 | |||
| 1410 | dev = alloc_etherdev(sizeof(*priv)); | ||
| 1411 | if (!dev) | ||
| 1412 | return -ENOMEM; | ||
| 1413 | |||
| 1414 | platform_set_drvdata(pdev, dev); | ||
| 1415 | SET_NETDEV_DEV(dev, &pdev->dev); | ||
| 1416 | |||
| 1417 | priv = netdev_priv(dev); | ||
| 1418 | priv->base = base; | ||
| 1419 | |||
| 1420 | priv->phy_mode = of_get_phy_mode(pdev->dev.of_node); | ||
| 1421 | if (priv->phy_mode < 0) | ||
| 1422 | priv->phy_mode = PHY_INTERFACE_MODE_RGMII; | ||
| 1423 | |||
| 1424 | priv->clk = devm_clk_get(&pdev->dev, NULL); | ||
| 1425 | if (IS_ERR(priv->clk)) { | ||
| 1426 | dev_err(&pdev->dev, "failed to get clock\n"); | ||
| 1427 | ret = PTR_ERR(priv->clk); | ||
| 1428 | goto err_free_dev; | ||
| 1429 | } | ||
| 1430 | |||
| 1431 | ret = clk_prepare_enable(priv->clk); | ||
| 1432 | if (ret) | ||
| 1433 | goto err_free_dev; | ||
| 1434 | |||
| 1435 | spin_lock_init(&priv->tx_lock); | ||
| 1436 | |||
| 1437 | if (ops && ops->reset) { | ||
| 1438 | ret = ops->reset(dev); | ||
| 1439 | if (ret) | ||
| 1440 | goto err_free_dev; | ||
| 1441 | } | ||
| 1442 | |||
| 1443 | bus = devm_mdiobus_alloc(&pdev->dev); | ||
| 1444 | if (!bus) { | ||
| 1445 | ret = -ENOMEM; | ||
| 1446 | goto err_disable_clk; | ||
| 1447 | } | ||
| 1448 | |||
| 1449 | bus->name = "nb8800-mii"; | ||
| 1450 | bus->read = nb8800_mdio_read; | ||
| 1451 | bus->write = nb8800_mdio_write; | ||
| 1452 | bus->parent = &pdev->dev; | ||
| 1453 | snprintf(bus->id, MII_BUS_ID_SIZE, "%lx.nb8800-mii", | ||
| 1454 | (unsigned long)res->start); | ||
| 1455 | bus->priv = priv; | ||
| 1456 | |||
| 1457 | ret = of_mdiobus_register(bus, pdev->dev.of_node); | ||
| 1458 | if (ret) { | ||
| 1459 | dev_err(&pdev->dev, "failed to register MII bus\n"); | ||
| 1460 | goto err_disable_clk; | ||
| 1461 | } | ||
| 1462 | |||
| 1463 | priv->phy_node = of_parse_phandle(pdev->dev.of_node, "phy-handle", 0); | ||
| 1464 | if (!priv->phy_node) { | ||
| 1465 | dev_err(&pdev->dev, "no PHY specified\n"); | ||
| 1466 | ret = -ENODEV; | ||
| 1467 | goto err_free_bus; | ||
| 1468 | } | ||
| 1469 | |||
| 1470 | priv->mii_bus = bus; | ||
| 1471 | |||
| 1472 | ret = nb8800_hw_init(dev); | ||
| 1473 | if (ret) | ||
| 1474 | goto err_free_bus; | ||
| 1475 | |||
| 1476 | if (ops && ops->init) { | ||
| 1477 | ret = ops->init(dev); | ||
| 1478 | if (ret) | ||
| 1479 | goto err_free_bus; | ||
| 1480 | } | ||
| 1481 | |||
| 1482 | dev->netdev_ops = &nb8800_netdev_ops; | ||
| 1483 | dev->ethtool_ops = &nb8800_ethtool_ops; | ||
| 1484 | dev->flags |= IFF_MULTICAST; | ||
| 1485 | dev->irq = irq; | ||
| 1486 | |||
| 1487 | mac = of_get_mac_address(pdev->dev.of_node); | ||
| 1488 | if (mac) | ||
| 1489 | ether_addr_copy(dev->dev_addr, mac); | ||
| 1490 | |||
| 1491 | if (!is_valid_ether_addr(dev->dev_addr)) | ||
| 1492 | eth_hw_addr_random(dev); | ||
| 1493 | |||
| 1494 | nb8800_update_mac_addr(dev); | ||
| 1495 | |||
| 1496 | netif_carrier_off(dev); | ||
| 1497 | |||
| 1498 | ret = register_netdev(dev); | ||
| 1499 | if (ret) { | ||
| 1500 | netdev_err(dev, "failed to register netdev\n"); | ||
| 1501 | goto err_free_dma; | ||
| 1502 | } | ||
| 1503 | |||
| 1504 | netif_napi_add(dev, &priv->napi, nb8800_poll, NAPI_POLL_WEIGHT); | ||
| 1505 | |||
| 1506 | netdev_info(dev, "MAC address %pM\n", dev->dev_addr); | ||
| 1507 | |||
| 1508 | return 0; | ||
| 1509 | |||
| 1510 | err_free_dma: | ||
| 1511 | nb8800_dma_free(dev); | ||
| 1512 | err_free_bus: | ||
| 1513 | mdiobus_unregister(bus); | ||
| 1514 | err_disable_clk: | ||
| 1515 | clk_disable_unprepare(priv->clk); | ||
| 1516 | err_free_dev: | ||
| 1517 | free_netdev(dev); | ||
| 1518 | |||
| 1519 | return ret; | ||
| 1520 | } | ||
| 1521 | |||
| 1522 | static int nb8800_remove(struct platform_device *pdev) | ||
| 1523 | { | ||
| 1524 | struct net_device *ndev = platform_get_drvdata(pdev); | ||
| 1525 | struct nb8800_priv *priv = netdev_priv(ndev); | ||
| 1526 | |||
| 1527 | unregister_netdev(ndev); | ||
| 1528 | |||
| 1529 | mdiobus_unregister(priv->mii_bus); | ||
| 1530 | |||
| 1531 | clk_disable_unprepare(priv->clk); | ||
| 1532 | |||
| 1533 | nb8800_dma_free(ndev); | ||
| 1534 | free_netdev(ndev); | ||
| 1535 | |||
| 1536 | return 0; | ||
| 1537 | } | ||
| 1538 | |||
| 1539 | static struct platform_driver nb8800_driver = { | ||
| 1540 | .driver = { | ||
| 1541 | .name = "nb8800", | ||
| 1542 | .of_match_table = nb8800_dt_ids, | ||
| 1543 | }, | ||
| 1544 | .probe = nb8800_probe, | ||
| 1545 | .remove = nb8800_remove, | ||
| 1546 | }; | ||
| 1547 | |||
| 1548 | module_platform_driver(nb8800_driver); | ||
| 1549 | |||
| 1550 | MODULE_DESCRIPTION("Aurora AU-NB8800 Ethernet driver"); | ||
| 1551 | MODULE_AUTHOR("Mans Rullgard <mans@mansr.com>"); | ||
| 1552 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/net/ethernet/aurora/nb8800.h b/drivers/net/ethernet/aurora/nb8800.h new file mode 100644 index 000000000000..e5adbc2aac9f --- /dev/null +++ b/drivers/net/ethernet/aurora/nb8800.h | |||
| @@ -0,0 +1,316 @@ | |||
| 1 | #ifndef _NB8800_H_ | ||
| 2 | #define _NB8800_H_ | ||
| 3 | |||
| 4 | #include <linux/types.h> | ||
| 5 | #include <linux/skbuff.h> | ||
| 6 | #include <linux/phy.h> | ||
| 7 | #include <linux/clk.h> | ||
| 8 | #include <linux/bitops.h> | ||
| 9 | |||
| 10 | #define RX_DESC_COUNT 256 | ||
| 11 | #define TX_DESC_COUNT 256 | ||
| 12 | |||
| 13 | #define NB8800_DESC_LOW 4 | ||
| 14 | |||
| 15 | #define RX_BUF_SIZE 1552 | ||
| 16 | |||
| 17 | #define RX_COPYBREAK 256 | ||
| 18 | #define RX_COPYHDR 128 | ||
| 19 | |||
| 20 | #define MAX_MDC_CLOCK 2500000 | ||
| 21 | |||
| 22 | /* Stargate Solutions SSN8800 core registers */ | ||
| 23 | #define NB8800_TX_CTL1 0x000 | ||
| 24 | #define TX_TPD BIT(5) | ||
| 25 | #define TX_APPEND_FCS BIT(4) | ||
| 26 | #define TX_PAD_EN BIT(3) | ||
| 27 | #define TX_RETRY_EN BIT(2) | ||
| 28 | #define TX_EN BIT(0) | ||
| 29 | |||
| 30 | #define NB8800_TX_CTL2 0x001 | ||
| 31 | |||
| 32 | #define NB8800_RX_CTL 0x004 | ||
| 33 | #define RX_BC_DISABLE BIT(7) | ||
| 34 | #define RX_RUNT BIT(6) | ||
| 35 | #define RX_AF_EN BIT(5) | ||
| 36 | #define RX_PAUSE_EN BIT(3) | ||
| 37 | #define RX_SEND_CRC BIT(2) | ||
| 38 | #define RX_PAD_STRIP BIT(1) | ||
| 39 | #define RX_EN BIT(0) | ||
| 40 | |||
| 41 | #define NB8800_RANDOM_SEED 0x008 | ||
| 42 | #define NB8800_TX_SDP 0x14 | ||
| 43 | #define NB8800_TX_TPDP1 0x18 | ||
| 44 | #define NB8800_TX_TPDP2 0x19 | ||
| 45 | #define NB8800_SLOT_TIME 0x1c | ||
| 46 | |||
| 47 | #define NB8800_MDIO_CMD 0x020 | ||
| 48 | #define MDIO_CMD_GO BIT(31) | ||
| 49 | #define MDIO_CMD_WR BIT(26) | ||
| 50 | #define MDIO_CMD_ADDR(x) ((x) << 21) | ||
| 51 | #define MDIO_CMD_REG(x) ((x) << 16) | ||
| 52 | #define MDIO_CMD_DATA(x) ((x) << 0) | ||
| 53 | |||
| 54 | #define NB8800_MDIO_STS 0x024 | ||
| 55 | #define MDIO_STS_ERR BIT(31) | ||
| 56 | |||
| 57 | #define NB8800_MC_ADDR(i) (0x028 + (i)) | ||
| 58 | #define NB8800_MC_INIT 0x02e | ||
| 59 | #define NB8800_UC_ADDR(i) (0x03c + (i)) | ||
| 60 | |||
| 61 | #define NB8800_MAC_MODE 0x044 | ||
| 62 | #define RGMII_MODE BIT(7) | ||
| 63 | #define HALF_DUPLEX BIT(4) | ||
| 64 | #define BURST_EN BIT(3) | ||
| 65 | #define LOOPBACK_EN BIT(2) | ||
| 66 | #define GMAC_MODE BIT(0) | ||
| 67 | |||
| 68 | #define NB8800_IC_THRESHOLD 0x050 | ||
| 69 | #define NB8800_PE_THRESHOLD 0x051 | ||
| 70 | #define NB8800_PF_THRESHOLD 0x052 | ||
| 71 | #define NB8800_TX_BUFSIZE 0x054 | ||
| 72 | #define NB8800_FIFO_CTL 0x056 | ||
| 73 | #define NB8800_PQ1 0x060 | ||
| 74 | #define NB8800_PQ2 0x061 | ||
| 75 | #define NB8800_SRC_ADDR(i) (0x06a + (i)) | ||
| 76 | #define NB8800_STAT_DATA 0x078 | ||
| 77 | #define NB8800_STAT_INDEX 0x07c | ||
| 78 | #define NB8800_STAT_CLEAR 0x07d | ||
| 79 | |||
| 80 | #define NB8800_SLEEP_MODE 0x07e | ||
| 81 | #define SLEEP_MODE BIT(0) | ||
| 82 | |||
| 83 | #define NB8800_WAKEUP 0x07f | ||
| 84 | #define WAKEUP BIT(0) | ||
| 85 | |||
| 86 | /* Aurora NB8800 host interface registers */ | ||
| 87 | #define NB8800_TXC_CR 0x100 | ||
| 88 | #define TCR_LK BIT(12) | ||
| 89 | #define TCR_DS BIT(11) | ||
| 90 | #define TCR_BTS(x) (((x) & 0x7) << 8) | ||
| 91 | #define TCR_DIE BIT(7) | ||
| 92 | #define TCR_TFI(x) (((x) & 0x7) << 4) | ||
| 93 | #define TCR_LE BIT(3) | ||
| 94 | #define TCR_RS BIT(2) | ||
| 95 | #define TCR_DM BIT(1) | ||
| 96 | #define TCR_EN BIT(0) | ||
| 97 | |||
| 98 | #define NB8800_TXC_SR 0x104 | ||
| 99 | #define TSR_DE BIT(3) | ||
| 100 | #define TSR_DI BIT(2) | ||
| 101 | #define TSR_TO BIT(1) | ||
| 102 | #define TSR_TI BIT(0) | ||
| 103 | |||
| 104 | #define NB8800_TX_SAR 0x108 | ||
| 105 | #define NB8800_TX_DESC_ADDR 0x10c | ||
| 106 | |||
| 107 | #define NB8800_TX_REPORT_ADDR 0x110 | ||
| 108 | #define TX_BYTES_TRANSFERRED(x) (((x) >> 16) & 0xffff) | ||
| 109 | #define TX_FIRST_DEFERRAL BIT(7) | ||
| 110 | #define TX_EARLY_COLLISIONS(x) (((x) >> 3) & 0xf) | ||
| 111 | #define TX_LATE_COLLISION BIT(2) | ||
| 112 | #define TX_PACKET_DROPPED BIT(1) | ||
| 113 | #define TX_FIFO_UNDERRUN BIT(0) | ||
| 114 | #define IS_TX_ERROR(r) ((r) & 0x07) | ||
| 115 | |||
| 116 | #define NB8800_TX_FIFO_SR 0x114 | ||
| 117 | #define NB8800_TX_ITR 0x118 | ||
| 118 | |||
| 119 | #define NB8800_RXC_CR 0x200 | ||
| 120 | #define RCR_FL BIT(13) | ||
| 121 | #define RCR_LK BIT(12) | ||
| 122 | #define RCR_DS BIT(11) | ||
| 123 | #define RCR_BTS(x) (((x) & 7) << 8) | ||
| 124 | #define RCR_DIE BIT(7) | ||
| 125 | #define RCR_RFI(x) (((x) & 7) << 4) | ||
| 126 | #define RCR_LE BIT(3) | ||
| 127 | #define RCR_RS BIT(2) | ||
| 128 | #define RCR_DM BIT(1) | ||
| 129 | #define RCR_EN BIT(0) | ||
| 130 | |||
| 131 | #define NB8800_RXC_SR 0x204 | ||
| 132 | #define RSR_DE BIT(3) | ||
| 133 | #define RSR_DI BIT(2) | ||
| 134 | #define RSR_RO BIT(1) | ||
| 135 | #define RSR_RI BIT(0) | ||
| 136 | |||
| 137 | #define NB8800_RX_SAR 0x208 | ||
| 138 | #define NB8800_RX_DESC_ADDR 0x20c | ||
| 139 | |||
| 140 | #define NB8800_RX_REPORT_ADDR 0x210 | ||
| 141 | #define RX_BYTES_TRANSFERRED(x) (((x) >> 16) & 0xFFFF) | ||
| 142 | #define RX_MULTICAST_PKT BIT(9) | ||
| 143 | #define RX_BROADCAST_PKT BIT(8) | ||
| 144 | #define RX_LENGTH_ERR BIT(7) | ||
| 145 | #define RX_FCS_ERR BIT(6) | ||
| 146 | #define RX_RUNT_PKT BIT(5) | ||
| 147 | #define RX_FIFO_OVERRUN BIT(4) | ||
| 148 | #define RX_LATE_COLLISION BIT(3) | ||
| 149 | #define RX_ALIGNMENT_ERROR BIT(2) | ||
| 150 | #define RX_ERROR_MASK 0xfc | ||
| 151 | #define IS_RX_ERROR(r) ((r) & RX_ERROR_MASK) | ||
| 152 | |||
| 153 | #define NB8800_RX_FIFO_SR 0x214 | ||
| 154 | #define NB8800_RX_ITR 0x218 | ||
| 155 | |||
| 156 | /* Sigma Designs SMP86xx additional registers */ | ||
| 157 | #define NB8800_TANGOX_PAD_MODE 0x400 | ||
| 158 | #define PAD_MODE_MASK 0x7 | ||
| 159 | #define PAD_MODE_MII 0x0 | ||
| 160 | #define PAD_MODE_RGMII 0x1 | ||
| 161 | #define PAD_MODE_GTX_CLK_INV BIT(3) | ||
| 162 | #define PAD_MODE_GTX_CLK_DELAY BIT(4) | ||
| 163 | |||
| 164 | #define NB8800_TANGOX_MDIO_CLKDIV 0x420 | ||
| 165 | #define NB8800_TANGOX_RESET 0x424 | ||
| 166 | |||
| 167 | /* Hardware DMA descriptor */ | ||
| 168 | struct nb8800_dma_desc { | ||
| 169 | u32 s_addr; /* start address */ | ||
| 170 | u32 n_addr; /* next descriptor address */ | ||
| 171 | u32 r_addr; /* report address */ | ||
| 172 | u32 config; | ||
| 173 | } __aligned(8); | ||
| 174 | |||
| 175 | #define DESC_ID BIT(23) | ||
| 176 | #define DESC_EOC BIT(22) | ||
| 177 | #define DESC_EOF BIT(21) | ||
| 178 | #define DESC_LK BIT(20) | ||
| 179 | #define DESC_DS BIT(19) | ||
| 180 | #define DESC_BTS(x) (((x) & 0x7) << 16) | ||
| 181 | |||
| 182 | /* DMA descriptor and associated data for rx. | ||
| 183 | * Allocated from coherent memory. | ||
| 184 | */ | ||
| 185 | struct nb8800_rx_desc { | ||
| 186 | /* DMA descriptor */ | ||
| 187 | struct nb8800_dma_desc desc; | ||
| 188 | |||
| 189 | /* Status report filled in by hardware */ | ||
| 190 | u32 report; | ||
| 191 | }; | ||
| 192 | |||
| 193 | /* Address of buffer on rx ring */ | ||
| 194 | struct nb8800_rx_buf { | ||
| 195 | struct page *page; | ||
| 196 | unsigned long offset; | ||
| 197 | }; | ||
| 198 | |||
| 199 | /* DMA descriptors and associated data for tx. | ||
| 200 | * Allocated from coherent memory. | ||
| 201 | */ | ||
| 202 | struct nb8800_tx_desc { | ||
| 203 | /* DMA descriptor. The second descriptor is used if packet | ||
| 204 | * data is unaligned. | ||
| 205 | */ | ||
| 206 | struct nb8800_dma_desc desc[2]; | ||
| 207 | |||
| 208 | /* Status report filled in by hardware */ | ||
| 209 | u32 report; | ||
| 210 | |||
| 211 | /* Bounce buffer for initial unaligned part of packet */ | ||
| 212 | u8 buf[8] __aligned(8); | ||
| 213 | }; | ||
| 214 | |||
| 215 | /* Packet in tx queue */ | ||
| 216 | struct nb8800_tx_buf { | ||
| 217 | /* Currently queued skb */ | ||
| 218 | struct sk_buff *skb; | ||
| 219 | |||
| 220 | /* DMA address of the first descriptor */ | ||
| 221 | dma_addr_t dma_desc; | ||
| 222 | |||
| 223 | /* DMA address of packet data */ | ||
| 224 | dma_addr_t dma_addr; | ||
| 225 | |||
| 226 | /* Length of DMA mapping, less than skb->len if alignment | ||
| 227 | * buffer is used. | ||
| 228 | */ | ||
| 229 | unsigned int dma_len; | ||
| 230 | |||
| 231 | /* Number of packets in chain starting here */ | ||
| 232 | unsigned int chain_len; | ||
| 233 | |||
| 234 | /* Packet chain ready to be submitted to hardware */ | ||
| 235 | bool ready; | ||
| 236 | }; | ||
| 237 | |||
| 238 | struct nb8800_priv { | ||
| 239 | struct napi_struct napi; | ||
| 240 | |||
| 241 | void __iomem *base; | ||
| 242 | |||
| 243 | /* RX DMA descriptors */ | ||
| 244 | struct nb8800_rx_desc *rx_descs; | ||
| 245 | |||
| 246 | /* RX buffers referenced by DMA descriptors */ | ||
| 247 | struct nb8800_rx_buf *rx_bufs; | ||
| 248 | |||
| 249 | /* Current end of chain */ | ||
| 250 | u32 rx_eoc; | ||
| 251 | |||
| 252 | /* Value for rx interrupt time register in NAPI interrupt mode */ | ||
| 253 | u32 rx_itr_irq; | ||
| 254 | |||
| 255 | /* Value for rx interrupt time register in NAPI poll mode */ | ||
| 256 | u32 rx_itr_poll; | ||
| 257 | |||
| 258 | /* Value for config field of rx DMA descriptors */ | ||
| 259 | u32 rx_dma_config; | ||
| 260 | |||
| 261 | /* TX DMA descriptors */ | ||
| 262 | struct nb8800_tx_desc *tx_descs; | ||
| 263 | |||
| 264 | /* TX packet queue */ | ||
| 265 | struct nb8800_tx_buf *tx_bufs; | ||
| 266 | |||
| 267 | /* Number of free tx queue entries */ | ||
| 268 | atomic_t tx_free; | ||
| 269 | |||
| 270 | /* First free tx queue entry */ | ||
| 271 | u32 tx_next; | ||
| 272 | |||
| 273 | /* Next buffer to transmit */ | ||
| 274 | u32 tx_queue; | ||
| 275 | |||
| 276 | /* Start of current packet chain */ | ||
| 277 | struct nb8800_tx_buf *tx_chain; | ||
| 278 | |||
| 279 | /* Next buffer to reclaim */ | ||
| 280 | u32 tx_done; | ||
| 281 | |||
| 282 | /* Lock for DMA activation */ | ||
| 283 | spinlock_t tx_lock; | ||
| 284 | |||
| 285 | struct mii_bus *mii_bus; | ||
| 286 | struct device_node *phy_node; | ||
| 287 | struct phy_device *phydev; | ||
| 288 | |||
| 289 | /* PHY connection type from DT */ | ||
| 290 | int phy_mode; | ||
| 291 | |||
| 292 | /* Current link status */ | ||
| 293 | int speed; | ||
| 294 | int duplex; | ||
| 295 | int link; | ||
| 296 | |||
| 297 | /* Pause settings */ | ||
| 298 | bool pause_aneg; | ||
| 299 | bool pause_rx; | ||
| 300 | bool pause_tx; | ||
| 301 | |||
| 302 | /* DMA base address of rx descriptors, see rx_descs above */ | ||
| 303 | dma_addr_t rx_desc_dma; | ||
| 304 | |||
| 305 | /* DMA base address of tx descriptors, see tx_descs above */ | ||
| 306 | dma_addr_t tx_desc_dma; | ||
| 307 | |||
| 308 | struct clk *clk; | ||
| 309 | }; | ||
| 310 | |||
| 311 | struct nb8800_ops { | ||
| 312 | int (*init)(struct net_device *dev); | ||
| 313 | int (*reset)(struct net_device *dev); | ||
| 314 | }; | ||
| 315 | |||
| 316 | #endif /* _NB8800_H_ */ | ||
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index c9b036789184..2e611dc5f162 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | |||
| @@ -10139,8 +10139,8 @@ static void __bnx2x_del_vxlan_port(struct bnx2x *bp, u16 port) | |||
| 10139 | DP(BNX2X_MSG_SP, "Invalid vxlan port\n"); | 10139 | DP(BNX2X_MSG_SP, "Invalid vxlan port\n"); |
| 10140 | return; | 10140 | return; |
| 10141 | } | 10141 | } |
| 10142 | bp->vxlan_dst_port--; | 10142 | bp->vxlan_dst_port_count--; |
| 10143 | if (bp->vxlan_dst_port) | 10143 | if (bp->vxlan_dst_port_count) |
| 10144 | return; | 10144 | return; |
| 10145 | 10145 | ||
| 10146 | if (netif_running(bp->dev)) { | 10146 | if (netif_running(bp->dev)) { |
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index db15c5ee09c5..bdf094fb6ef9 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c | |||
| @@ -3625,6 +3625,7 @@ static int bnxt_hwrm_func_qcaps(struct bnxt *bp) | |||
| 3625 | pf->fw_fid = le16_to_cpu(resp->fid); | 3625 | pf->fw_fid = le16_to_cpu(resp->fid); |
| 3626 | pf->port_id = le16_to_cpu(resp->port_id); | 3626 | pf->port_id = le16_to_cpu(resp->port_id); |
| 3627 | memcpy(pf->mac_addr, resp->perm_mac_address, ETH_ALEN); | 3627 | memcpy(pf->mac_addr, resp->perm_mac_address, ETH_ALEN); |
| 3628 | memcpy(bp->dev->dev_addr, pf->mac_addr, ETH_ALEN); | ||
| 3628 | pf->max_rsscos_ctxs = le16_to_cpu(resp->max_rsscos_ctx); | 3629 | pf->max_rsscos_ctxs = le16_to_cpu(resp->max_rsscos_ctx); |
| 3629 | pf->max_cp_rings = le16_to_cpu(resp->max_cmpl_rings); | 3630 | pf->max_cp_rings = le16_to_cpu(resp->max_cmpl_rings); |
| 3630 | pf->max_tx_rings = le16_to_cpu(resp->max_tx_rings); | 3631 | pf->max_tx_rings = le16_to_cpu(resp->max_tx_rings); |
| @@ -3648,8 +3649,11 @@ static int bnxt_hwrm_func_qcaps(struct bnxt *bp) | |||
| 3648 | 3649 | ||
| 3649 | vf->fw_fid = le16_to_cpu(resp->fid); | 3650 | vf->fw_fid = le16_to_cpu(resp->fid); |
| 3650 | memcpy(vf->mac_addr, resp->perm_mac_address, ETH_ALEN); | 3651 | memcpy(vf->mac_addr, resp->perm_mac_address, ETH_ALEN); |
| 3651 | if (!is_valid_ether_addr(vf->mac_addr)) | 3652 | if (is_valid_ether_addr(vf->mac_addr)) |
| 3652 | random_ether_addr(vf->mac_addr); | 3653 | /* overwrite netdev dev_adr with admin VF MAC */ |
| 3654 | memcpy(bp->dev->dev_addr, vf->mac_addr, ETH_ALEN); | ||
| 3655 | else | ||
| 3656 | random_ether_addr(bp->dev->dev_addr); | ||
| 3653 | 3657 | ||
| 3654 | vf->max_rsscos_ctxs = le16_to_cpu(resp->max_rsscos_ctx); | 3658 | vf->max_rsscos_ctxs = le16_to_cpu(resp->max_rsscos_ctx); |
| 3655 | vf->max_cp_rings = le16_to_cpu(resp->max_cmpl_rings); | 3659 | vf->max_cp_rings = le16_to_cpu(resp->max_cmpl_rings); |
| @@ -3880,6 +3884,8 @@ static int bnxt_alloc_rfs_vnics(struct bnxt *bp) | |||
| 3880 | #endif | 3884 | #endif |
| 3881 | } | 3885 | } |
| 3882 | 3886 | ||
| 3887 | static int bnxt_cfg_rx_mode(struct bnxt *); | ||
| 3888 | |||
| 3883 | static int bnxt_init_chip(struct bnxt *bp, bool irq_re_init) | 3889 | static int bnxt_init_chip(struct bnxt *bp, bool irq_re_init) |
| 3884 | { | 3890 | { |
| 3885 | int rc = 0; | 3891 | int rc = 0; |
| @@ -3946,11 +3952,9 @@ static int bnxt_init_chip(struct bnxt *bp, bool irq_re_init) | |||
| 3946 | bp->vnic_info[0].rx_mask |= | 3952 | bp->vnic_info[0].rx_mask |= |
| 3947 | CFA_L2_SET_RX_MASK_REQ_MASK_PROMISCUOUS; | 3953 | CFA_L2_SET_RX_MASK_REQ_MASK_PROMISCUOUS; |
| 3948 | 3954 | ||
| 3949 | rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, 0); | 3955 | rc = bnxt_cfg_rx_mode(bp); |
| 3950 | if (rc) { | 3956 | if (rc) |
| 3951 | netdev_err(bp->dev, "HWRM cfa l2 rx mask failure rc: %x\n", rc); | ||
| 3952 | goto err_out; | 3957 | goto err_out; |
| 3953 | } | ||
| 3954 | 3958 | ||
| 3955 | rc = bnxt_hwrm_set_coal(bp); | 3959 | rc = bnxt_hwrm_set_coal(bp); |
| 3956 | if (rc) | 3960 | if (rc) |
| @@ -4865,7 +4869,7 @@ static void bnxt_set_rx_mode(struct net_device *dev) | |||
| 4865 | } | 4869 | } |
| 4866 | } | 4870 | } |
| 4867 | 4871 | ||
| 4868 | static void bnxt_cfg_rx_mode(struct bnxt *bp) | 4872 | static int bnxt_cfg_rx_mode(struct bnxt *bp) |
| 4869 | { | 4873 | { |
| 4870 | struct net_device *dev = bp->dev; | 4874 | struct net_device *dev = bp->dev; |
| 4871 | struct bnxt_vnic_info *vnic = &bp->vnic_info[0]; | 4875 | struct bnxt_vnic_info *vnic = &bp->vnic_info[0]; |
| @@ -4914,6 +4918,7 @@ static void bnxt_cfg_rx_mode(struct bnxt *bp) | |||
| 4914 | netdev_err(bp->dev, "HWRM vnic filter failure rc: %x\n", | 4918 | netdev_err(bp->dev, "HWRM vnic filter failure rc: %x\n", |
| 4915 | rc); | 4919 | rc); |
| 4916 | vnic->uc_filter_count = i; | 4920 | vnic->uc_filter_count = i; |
| 4921 | return rc; | ||
| 4917 | } | 4922 | } |
| 4918 | } | 4923 | } |
| 4919 | 4924 | ||
| @@ -4922,6 +4927,8 @@ skip_uc: | |||
| 4922 | if (rc) | 4927 | if (rc) |
| 4923 | netdev_err(bp->dev, "HWRM cfa l2 rx mask failure rc: %x\n", | 4928 | netdev_err(bp->dev, "HWRM cfa l2 rx mask failure rc: %x\n", |
| 4924 | rc); | 4929 | rc); |
| 4930 | |||
| 4931 | return rc; | ||
| 4925 | } | 4932 | } |
| 4926 | 4933 | ||
| 4927 | static netdev_features_t bnxt_fix_features(struct net_device *dev, | 4934 | static netdev_features_t bnxt_fix_features(struct net_device *dev, |
| @@ -5212,13 +5219,27 @@ init_err: | |||
| 5212 | static int bnxt_change_mac_addr(struct net_device *dev, void *p) | 5219 | static int bnxt_change_mac_addr(struct net_device *dev, void *p) |
| 5213 | { | 5220 | { |
| 5214 | struct sockaddr *addr = p; | 5221 | struct sockaddr *addr = p; |
| 5222 | struct bnxt *bp = netdev_priv(dev); | ||
| 5223 | int rc = 0; | ||
| 5215 | 5224 | ||
| 5216 | if (!is_valid_ether_addr(addr->sa_data)) | 5225 | if (!is_valid_ether_addr(addr->sa_data)) |
| 5217 | return -EADDRNOTAVAIL; | 5226 | return -EADDRNOTAVAIL; |
| 5218 | 5227 | ||
| 5228 | #ifdef CONFIG_BNXT_SRIOV | ||
| 5229 | if (BNXT_VF(bp) && is_valid_ether_addr(bp->vf.mac_addr)) | ||
| 5230 | return -EADDRNOTAVAIL; | ||
| 5231 | #endif | ||
| 5232 | |||
| 5233 | if (ether_addr_equal(addr->sa_data, dev->dev_addr)) | ||
| 5234 | return 0; | ||
| 5235 | |||
| 5219 | memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); | 5236 | memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); |
| 5237 | if (netif_running(dev)) { | ||
| 5238 | bnxt_close_nic(bp, false, false); | ||
| 5239 | rc = bnxt_open_nic(bp, false, false); | ||
| 5240 | } | ||
| 5220 | 5241 | ||
| 5221 | return 0; | 5242 | return rc; |
| 5222 | } | 5243 | } |
| 5223 | 5244 | ||
| 5224 | /* rtnl_lock held */ | 5245 | /* rtnl_lock held */ |
| @@ -5686,15 +5707,12 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 5686 | bnxt_set_tpa_flags(bp); | 5707 | bnxt_set_tpa_flags(bp); |
| 5687 | bnxt_set_ring_params(bp); | 5708 | bnxt_set_ring_params(bp); |
| 5688 | dflt_rings = netif_get_num_default_rss_queues(); | 5709 | dflt_rings = netif_get_num_default_rss_queues(); |
| 5689 | if (BNXT_PF(bp)) { | 5710 | if (BNXT_PF(bp)) |
| 5690 | memcpy(dev->dev_addr, bp->pf.mac_addr, ETH_ALEN); | ||
| 5691 | bp->pf.max_irqs = max_irqs; | 5711 | bp->pf.max_irqs = max_irqs; |
| 5692 | } else { | ||
| 5693 | #if defined(CONFIG_BNXT_SRIOV) | 5712 | #if defined(CONFIG_BNXT_SRIOV) |
| 5694 | memcpy(dev->dev_addr, bp->vf.mac_addr, ETH_ALEN); | 5713 | else |
| 5695 | bp->vf.max_irqs = max_irqs; | 5714 | bp->vf.max_irqs = max_irqs; |
| 5696 | #endif | 5715 | #endif |
| 5697 | } | ||
| 5698 | bnxt_get_max_rings(bp, &max_rx_rings, &max_tx_rings); | 5716 | bnxt_get_max_rings(bp, &max_rx_rings, &max_tx_rings); |
| 5699 | bp->rx_nr_rings = min_t(int, dflt_rings, max_rx_rings); | 5717 | bp->rx_nr_rings = min_t(int, dflt_rings, max_rx_rings); |
| 5700 | bp->tx_nr_rings_per_tc = min_t(int, dflt_rings, max_tx_rings); | 5718 | bp->tx_nr_rings_per_tc = min_t(int, dflt_rings, max_tx_rings); |
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c index f4cf68861069..7a9af2887d8e 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c | |||
| @@ -804,10 +804,9 @@ void bnxt_update_vf_mac(struct bnxt *bp) | |||
| 804 | if (!is_valid_ether_addr(resp->perm_mac_address)) | 804 | if (!is_valid_ether_addr(resp->perm_mac_address)) |
| 805 | goto update_vf_mac_exit; | 805 | goto update_vf_mac_exit; |
| 806 | 806 | ||
| 807 | if (ether_addr_equal(resp->perm_mac_address, bp->vf.mac_addr)) | 807 | if (!ether_addr_equal(resp->perm_mac_address, bp->vf.mac_addr)) |
| 808 | goto update_vf_mac_exit; | 808 | memcpy(bp->vf.mac_addr, resp->perm_mac_address, ETH_ALEN); |
| 809 | 809 | /* overwrite netdev dev_adr with admin VF MAC */ | |
| 810 | memcpy(bp->vf.mac_addr, resp->perm_mac_address, ETH_ALEN); | ||
| 811 | memcpy(bp->dev->dev_addr, bp->vf.mac_addr, ETH_ALEN); | 810 | memcpy(bp->dev->dev_addr, bp->vf.mac_addr, ETH_ALEN); |
| 812 | update_vf_mac_exit: | 811 | update_vf_mac_exit: |
| 813 | mutex_unlock(&bp->hwrm_cmd_lock); | 812 | mutex_unlock(&bp->hwrm_cmd_lock); |
diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index 88c1e1a834f8..169059c92f80 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c | |||
| @@ -1682,6 +1682,8 @@ static void macb_init_hw(struct macb *bp) | |||
| 1682 | macb_set_hwaddr(bp); | 1682 | macb_set_hwaddr(bp); |
| 1683 | 1683 | ||
| 1684 | config = macb_mdc_clk_div(bp); | 1684 | config = macb_mdc_clk_div(bp); |
| 1685 | if (bp->phy_interface == PHY_INTERFACE_MODE_SGMII) | ||
| 1686 | config |= GEM_BIT(SGMIIEN) | GEM_BIT(PCSSEL); | ||
| 1685 | config |= MACB_BF(RBOF, NET_IP_ALIGN); /* Make eth data aligned */ | 1687 | config |= MACB_BF(RBOF, NET_IP_ALIGN); /* Make eth data aligned */ |
| 1686 | config |= MACB_BIT(PAE); /* PAuse Enable */ | 1688 | config |= MACB_BIT(PAE); /* PAuse Enable */ |
| 1687 | config |= MACB_BIT(DRFCS); /* Discard Rx FCS */ | 1689 | config |= MACB_BIT(DRFCS); /* Discard Rx FCS */ |
| @@ -2416,6 +2418,8 @@ static int macb_init(struct platform_device *pdev) | |||
| 2416 | /* Set MII management clock divider */ | 2418 | /* Set MII management clock divider */ |
| 2417 | val = macb_mdc_clk_div(bp); | 2419 | val = macb_mdc_clk_div(bp); |
| 2418 | val |= macb_dbw(bp); | 2420 | val |= macb_dbw(bp); |
| 2421 | if (bp->phy_interface == PHY_INTERFACE_MODE_SGMII) | ||
| 2422 | val |= GEM_BIT(SGMIIEN) | GEM_BIT(PCSSEL); | ||
| 2419 | macb_writel(bp, NCFGR, val); | 2423 | macb_writel(bp, NCFGR, val); |
| 2420 | 2424 | ||
| 2421 | return 0; | 2425 | return 0; |
diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h index 6e1faea00ca8..d83b0db77821 100644 --- a/drivers/net/ethernet/cadence/macb.h +++ b/drivers/net/ethernet/cadence/macb.h | |||
| @@ -215,12 +215,17 @@ | |||
| 215 | /* GEM specific NCFGR bitfields. */ | 215 | /* GEM specific NCFGR bitfields. */ |
| 216 | #define GEM_GBE_OFFSET 10 /* Gigabit mode enable */ | 216 | #define GEM_GBE_OFFSET 10 /* Gigabit mode enable */ |
| 217 | #define GEM_GBE_SIZE 1 | 217 | #define GEM_GBE_SIZE 1 |
| 218 | #define GEM_PCSSEL_OFFSET 11 | ||
| 219 | #define GEM_PCSSEL_SIZE 1 | ||
| 218 | #define GEM_CLK_OFFSET 18 /* MDC clock division */ | 220 | #define GEM_CLK_OFFSET 18 /* MDC clock division */ |
| 219 | #define GEM_CLK_SIZE 3 | 221 | #define GEM_CLK_SIZE 3 |
| 220 | #define GEM_DBW_OFFSET 21 /* Data bus width */ | 222 | #define GEM_DBW_OFFSET 21 /* Data bus width */ |
| 221 | #define GEM_DBW_SIZE 2 | 223 | #define GEM_DBW_SIZE 2 |
| 222 | #define GEM_RXCOEN_OFFSET 24 | 224 | #define GEM_RXCOEN_OFFSET 24 |
| 223 | #define GEM_RXCOEN_SIZE 1 | 225 | #define GEM_RXCOEN_SIZE 1 |
| 226 | #define GEM_SGMIIEN_OFFSET 27 | ||
| 227 | #define GEM_SGMIIEN_SIZE 1 | ||
| 228 | |||
| 224 | 229 | ||
| 225 | /* Constants for data bus width. */ | 230 | /* Constants for data bus width. */ |
| 226 | #define GEM_DBW32 0 /* 32 bit AMBA AHB data bus width */ | 231 | #define GEM_DBW32 0 /* 32 bit AMBA AHB data bus width */ |
diff --git a/drivers/net/ethernet/cavium/thunder/nic.h b/drivers/net/ethernet/cavium/thunder/nic.h index d3950b20feb9..39ca6744a4e6 100644 --- a/drivers/net/ethernet/cavium/thunder/nic.h +++ b/drivers/net/ethernet/cavium/thunder/nic.h | |||
| @@ -120,10 +120,9 @@ | |||
| 120 | * Calculated for SCLK of 700Mhz | 120 | * Calculated for SCLK of 700Mhz |
| 121 | * value written should be a 1/16th of what is expected | 121 | * value written should be a 1/16th of what is expected |
| 122 | * | 122 | * |
| 123 | * 1 tick per 0.05usec = value of 2.2 | 123 | * 1 tick per 0.025usec |
| 124 | * This 10% would be covered in CQ timer thresh value | ||
| 125 | */ | 124 | */ |
| 126 | #define NICPF_CLK_PER_INT_TICK 2 | 125 | #define NICPF_CLK_PER_INT_TICK 1 |
| 127 | 126 | ||
| 128 | /* Time to wait before we decide that a SQ is stuck. | 127 | /* Time to wait before we decide that a SQ is stuck. |
| 129 | * | 128 | * |
diff --git a/drivers/net/ethernet/cavium/thunder/nic_main.c b/drivers/net/ethernet/cavium/thunder/nic_main.c index c561fdcb79a7..4b7fd63ae57c 100644 --- a/drivers/net/ethernet/cavium/thunder/nic_main.c +++ b/drivers/net/ethernet/cavium/thunder/nic_main.c | |||
| @@ -37,6 +37,7 @@ struct nicpf { | |||
| 37 | #define NIC_GET_BGX_FROM_VF_LMAC_MAP(map) ((map >> 4) & 0xF) | 37 | #define NIC_GET_BGX_FROM_VF_LMAC_MAP(map) ((map >> 4) & 0xF) |
| 38 | #define NIC_GET_LMAC_FROM_VF_LMAC_MAP(map) (map & 0xF) | 38 | #define NIC_GET_LMAC_FROM_VF_LMAC_MAP(map) (map & 0xF) |
| 39 | u8 vf_lmac_map[MAX_LMAC]; | 39 | u8 vf_lmac_map[MAX_LMAC]; |
| 40 | u8 lmac_cnt; | ||
| 40 | struct delayed_work dwork; | 41 | struct delayed_work dwork; |
| 41 | struct workqueue_struct *check_link; | 42 | struct workqueue_struct *check_link; |
| 42 | u8 link[MAX_LMAC]; | 43 | u8 link[MAX_LMAC]; |
| @@ -279,6 +280,7 @@ static void nic_set_lmac_vf_mapping(struct nicpf *nic) | |||
| 279 | u64 lmac_credit; | 280 | u64 lmac_credit; |
| 280 | 281 | ||
| 281 | nic->num_vf_en = 0; | 282 | nic->num_vf_en = 0; |
| 283 | nic->lmac_cnt = 0; | ||
| 282 | 284 | ||
| 283 | for (bgx = 0; bgx < NIC_MAX_BGX; bgx++) { | 285 | for (bgx = 0; bgx < NIC_MAX_BGX; bgx++) { |
| 284 | if (!(bgx_map & (1 << bgx))) | 286 | if (!(bgx_map & (1 << bgx))) |
| @@ -288,6 +290,7 @@ static void nic_set_lmac_vf_mapping(struct nicpf *nic) | |||
| 288 | nic->vf_lmac_map[next_bgx_lmac++] = | 290 | nic->vf_lmac_map[next_bgx_lmac++] = |
| 289 | NIC_SET_VF_LMAC_MAP(bgx, lmac); | 291 | NIC_SET_VF_LMAC_MAP(bgx, lmac); |
| 290 | nic->num_vf_en += lmac_cnt; | 292 | nic->num_vf_en += lmac_cnt; |
| 293 | nic->lmac_cnt += lmac_cnt; | ||
| 291 | 294 | ||
| 292 | /* Program LMAC credits */ | 295 | /* Program LMAC credits */ |
| 293 | lmac_credit = (1ull << 1); /* channel credit enable */ | 296 | lmac_credit = (1ull << 1); /* channel credit enable */ |
| @@ -715,6 +718,13 @@ static void nic_handle_mbx_intr(struct nicpf *nic, int vf) | |||
| 715 | case NIC_MBOX_MSG_CFG_DONE: | 718 | case NIC_MBOX_MSG_CFG_DONE: |
| 716 | /* Last message of VF config msg sequence */ | 719 | /* Last message of VF config msg sequence */ |
| 717 | nic->vf_enabled[vf] = true; | 720 | nic->vf_enabled[vf] = true; |
| 721 | if (vf >= nic->lmac_cnt) | ||
| 722 | goto unlock; | ||
| 723 | |||
| 724 | bgx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]); | ||
| 725 | lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]); | ||
| 726 | |||
| 727 | bgx_lmac_rx_tx_enable(nic->node, bgx, lmac, true); | ||
| 718 | goto unlock; | 728 | goto unlock; |
| 719 | case NIC_MBOX_MSG_SHUTDOWN: | 729 | case NIC_MBOX_MSG_SHUTDOWN: |
| 720 | /* First msg in VF teardown sequence */ | 730 | /* First msg in VF teardown sequence */ |
| @@ -722,6 +732,14 @@ static void nic_handle_mbx_intr(struct nicpf *nic, int vf) | |||
| 722 | if (vf >= nic->num_vf_en) | 732 | if (vf >= nic->num_vf_en) |
| 723 | nic->sqs_used[vf - nic->num_vf_en] = false; | 733 | nic->sqs_used[vf - nic->num_vf_en] = false; |
| 724 | nic->pqs_vf[vf] = 0; | 734 | nic->pqs_vf[vf] = 0; |
| 735 | |||
| 736 | if (vf >= nic->lmac_cnt) | ||
| 737 | break; | ||
| 738 | |||
| 739 | bgx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]); | ||
| 740 | lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]); | ||
| 741 | |||
| 742 | bgx_lmac_rx_tx_enable(nic->node, bgx, lmac, false); | ||
| 725 | break; | 743 | break; |
| 726 | case NIC_MBOX_MSG_ALLOC_SQS: | 744 | case NIC_MBOX_MSG_ALLOC_SQS: |
| 727 | nic_alloc_sqs(nic, &mbx.sqs_alloc); | 745 | nic_alloc_sqs(nic, &mbx.sqs_alloc); |
| @@ -940,7 +958,7 @@ static void nic_poll_for_link(struct work_struct *work) | |||
| 940 | 958 | ||
| 941 | mbx.link_status.msg = NIC_MBOX_MSG_BGX_LINK_CHANGE; | 959 | mbx.link_status.msg = NIC_MBOX_MSG_BGX_LINK_CHANGE; |
| 942 | 960 | ||
| 943 | for (vf = 0; vf < nic->num_vf_en; vf++) { | 961 | for (vf = 0; vf < nic->lmac_cnt; vf++) { |
| 944 | /* Poll only if VF is UP */ | 962 | /* Poll only if VF is UP */ |
| 945 | if (!nic->vf_enabled[vf]) | 963 | if (!nic->vf_enabled[vf]) |
| 946 | continue; | 964 | continue; |
| @@ -1074,8 +1092,7 @@ static void nic_remove(struct pci_dev *pdev) | |||
| 1074 | 1092 | ||
| 1075 | if (nic->check_link) { | 1093 | if (nic->check_link) { |
| 1076 | /* Destroy work Queue */ | 1094 | /* Destroy work Queue */ |
| 1077 | cancel_delayed_work(&nic->dwork); | 1095 | cancel_delayed_work_sync(&nic->dwork); |
| 1078 | flush_workqueue(nic->check_link); | ||
| 1079 | destroy_workqueue(nic->check_link); | 1096 | destroy_workqueue(nic->check_link); |
| 1080 | } | 1097 | } |
| 1081 | 1098 | ||
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c b/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c index af54c10945c2..a12b2e38cf61 100644 --- a/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c +++ b/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c | |||
| @@ -112,6 +112,13 @@ static int nicvf_get_settings(struct net_device *netdev, | |||
| 112 | 112 | ||
| 113 | cmd->supported = 0; | 113 | cmd->supported = 0; |
| 114 | cmd->transceiver = XCVR_EXTERNAL; | 114 | cmd->transceiver = XCVR_EXTERNAL; |
| 115 | |||
| 116 | if (!nic->link_up) { | ||
| 117 | cmd->duplex = DUPLEX_UNKNOWN; | ||
| 118 | ethtool_cmd_speed_set(cmd, SPEED_UNKNOWN); | ||
| 119 | return 0; | ||
| 120 | } | ||
| 121 | |||
| 115 | if (nic->speed <= 1000) { | 122 | if (nic->speed <= 1000) { |
| 116 | cmd->port = PORT_MII; | 123 | cmd->port = PORT_MII; |
| 117 | cmd->autoneg = AUTONEG_ENABLE; | 124 | cmd->autoneg = AUTONEG_ENABLE; |
| @@ -125,6 +132,13 @@ static int nicvf_get_settings(struct net_device *netdev, | |||
| 125 | return 0; | 132 | return 0; |
| 126 | } | 133 | } |
| 127 | 134 | ||
| 135 | static u32 nicvf_get_link(struct net_device *netdev) | ||
| 136 | { | ||
| 137 | struct nicvf *nic = netdev_priv(netdev); | ||
| 138 | |||
| 139 | return nic->link_up; | ||
| 140 | } | ||
| 141 | |||
| 128 | static void nicvf_get_drvinfo(struct net_device *netdev, | 142 | static void nicvf_get_drvinfo(struct net_device *netdev, |
| 129 | struct ethtool_drvinfo *info) | 143 | struct ethtool_drvinfo *info) |
| 130 | { | 144 | { |
| @@ -660,7 +674,7 @@ static int nicvf_set_channels(struct net_device *dev, | |||
| 660 | 674 | ||
| 661 | static const struct ethtool_ops nicvf_ethtool_ops = { | 675 | static const struct ethtool_ops nicvf_ethtool_ops = { |
| 662 | .get_settings = nicvf_get_settings, | 676 | .get_settings = nicvf_get_settings, |
| 663 | .get_link = ethtool_op_get_link, | 677 | .get_link = nicvf_get_link, |
| 664 | .get_drvinfo = nicvf_get_drvinfo, | 678 | .get_drvinfo = nicvf_get_drvinfo, |
| 665 | .get_msglevel = nicvf_get_msglevel, | 679 | .get_msglevel = nicvf_get_msglevel, |
| 666 | .set_msglevel = nicvf_set_msglevel, | 680 | .set_msglevel = nicvf_set_msglevel, |
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c index 7f709cbdcd87..dde8dc720cd3 100644 --- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c +++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c | |||
| @@ -1057,6 +1057,7 @@ int nicvf_stop(struct net_device *netdev) | |||
| 1057 | 1057 | ||
| 1058 | netif_carrier_off(netdev); | 1058 | netif_carrier_off(netdev); |
| 1059 | netif_tx_stop_all_queues(nic->netdev); | 1059 | netif_tx_stop_all_queues(nic->netdev); |
| 1060 | nic->link_up = false; | ||
| 1060 | 1061 | ||
| 1061 | /* Teardown secondary qsets first */ | 1062 | /* Teardown secondary qsets first */ |
| 1062 | if (!nic->sqs_mode) { | 1063 | if (!nic->sqs_mode) { |
| @@ -1211,9 +1212,6 @@ int nicvf_open(struct net_device *netdev) | |||
| 1211 | nic->drv_stats.txq_stop = 0; | 1212 | nic->drv_stats.txq_stop = 0; |
| 1212 | nic->drv_stats.txq_wake = 0; | 1213 | nic->drv_stats.txq_wake = 0; |
| 1213 | 1214 | ||
| 1214 | netif_carrier_on(netdev); | ||
| 1215 | netif_tx_start_all_queues(netdev); | ||
| 1216 | |||
| 1217 | return 0; | 1215 | return 0; |
| 1218 | cleanup: | 1216 | cleanup: |
| 1219 | nicvf_disable_intr(nic, NICVF_INTR_MBOX, 0); | 1217 | nicvf_disable_intr(nic, NICVF_INTR_MBOX, 0); |
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c index e404ea837727..206b6a71a545 100644 --- a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c +++ b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c | |||
| @@ -592,7 +592,7 @@ void nicvf_cmp_queue_config(struct nicvf *nic, struct queue_set *qs, | |||
| 592 | /* Set threshold value for interrupt generation */ | 592 | /* Set threshold value for interrupt generation */ |
| 593 | nicvf_queue_reg_write(nic, NIC_QSET_CQ_0_7_THRESH, qidx, cq->thresh); | 593 | nicvf_queue_reg_write(nic, NIC_QSET_CQ_0_7_THRESH, qidx, cq->thresh); |
| 594 | nicvf_queue_reg_write(nic, NIC_QSET_CQ_0_7_CFG2, | 594 | nicvf_queue_reg_write(nic, NIC_QSET_CQ_0_7_CFG2, |
| 595 | qidx, nic->cq_coalesce_usecs); | 595 | qidx, CMP_QUEUE_TIMER_THRESH); |
| 596 | } | 596 | } |
| 597 | 597 | ||
| 598 | /* Configures transmit queue */ | 598 | /* Configures transmit queue */ |
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_queues.h b/drivers/net/ethernet/cavium/thunder/nicvf_queues.h index fb4957d09914..033e8306e91c 100644 --- a/drivers/net/ethernet/cavium/thunder/nicvf_queues.h +++ b/drivers/net/ethernet/cavium/thunder/nicvf_queues.h | |||
| @@ -76,7 +76,7 @@ | |||
| 76 | #define CMP_QSIZE CMP_QUEUE_SIZE2 | 76 | #define CMP_QSIZE CMP_QUEUE_SIZE2 |
| 77 | #define CMP_QUEUE_LEN (1ULL << (CMP_QSIZE + 10)) | 77 | #define CMP_QUEUE_LEN (1ULL << (CMP_QSIZE + 10)) |
| 78 | #define CMP_QUEUE_CQE_THRESH 0 | 78 | #define CMP_QUEUE_CQE_THRESH 0 |
| 79 | #define CMP_QUEUE_TIMER_THRESH 220 /* 10usec */ | 79 | #define CMP_QUEUE_TIMER_THRESH 80 /* ~2usec */ |
| 80 | 80 | ||
| 81 | #define RBDR_SIZE RBDR_SIZE0 | 81 | #define RBDR_SIZE RBDR_SIZE0 |
| 82 | #define RCV_BUF_COUNT (1ULL << (RBDR_SIZE + 13)) | 82 | #define RCV_BUF_COUNT (1ULL << (RBDR_SIZE + 13)) |
diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c index 180aa9fabf48..9df26c2263bc 100644 --- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c +++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c | |||
| @@ -186,6 +186,23 @@ void bgx_set_lmac_mac(int node, int bgx_idx, int lmacid, const u8 *mac) | |||
| 186 | } | 186 | } |
| 187 | EXPORT_SYMBOL(bgx_set_lmac_mac); | 187 | EXPORT_SYMBOL(bgx_set_lmac_mac); |
| 188 | 188 | ||
| 189 | void bgx_lmac_rx_tx_enable(int node, int bgx_idx, int lmacid, bool enable) | ||
| 190 | { | ||
| 191 | struct bgx *bgx = bgx_vnic[(node * MAX_BGX_PER_CN88XX) + bgx_idx]; | ||
| 192 | u64 cfg; | ||
| 193 | |||
| 194 | if (!bgx) | ||
| 195 | return; | ||
| 196 | |||
| 197 | cfg = bgx_reg_read(bgx, lmacid, BGX_CMRX_CFG); | ||
| 198 | if (enable) | ||
| 199 | cfg |= CMR_PKT_RX_EN | CMR_PKT_TX_EN; | ||
| 200 | else | ||
| 201 | cfg &= ~(CMR_PKT_RX_EN | CMR_PKT_TX_EN); | ||
| 202 | bgx_reg_write(bgx, lmacid, BGX_CMRX_CFG, cfg); | ||
| 203 | } | ||
| 204 | EXPORT_SYMBOL(bgx_lmac_rx_tx_enable); | ||
| 205 | |||
| 189 | static void bgx_sgmii_change_link_state(struct lmac *lmac) | 206 | static void bgx_sgmii_change_link_state(struct lmac *lmac) |
| 190 | { | 207 | { |
| 191 | struct bgx *bgx = lmac->bgx; | 208 | struct bgx *bgx = lmac->bgx; |
| @@ -612,6 +629,8 @@ static void bgx_poll_for_link(struct work_struct *work) | |||
| 612 | lmac->last_duplex = 1; | 629 | lmac->last_duplex = 1; |
| 613 | } else { | 630 | } else { |
| 614 | lmac->link_up = 0; | 631 | lmac->link_up = 0; |
| 632 | lmac->last_speed = SPEED_UNKNOWN; | ||
| 633 | lmac->last_duplex = DUPLEX_UNKNOWN; | ||
| 615 | } | 634 | } |
| 616 | 635 | ||
| 617 | if (lmac->last_link != lmac->link_up) { | 636 | if (lmac->last_link != lmac->link_up) { |
| @@ -654,8 +673,7 @@ static int bgx_lmac_enable(struct bgx *bgx, u8 lmacid) | |||
| 654 | } | 673 | } |
| 655 | 674 | ||
| 656 | /* Enable lmac */ | 675 | /* Enable lmac */ |
| 657 | bgx_reg_modify(bgx, lmacid, BGX_CMRX_CFG, | 676 | bgx_reg_modify(bgx, lmacid, BGX_CMRX_CFG, CMR_EN); |
| 658 | CMR_EN | CMR_PKT_RX_EN | CMR_PKT_TX_EN); | ||
| 659 | 677 | ||
| 660 | /* Restore default cfg, incase low level firmware changed it */ | 678 | /* Restore default cfg, incase low level firmware changed it */ |
| 661 | bgx_reg_write(bgx, lmacid, BGX_CMRX_RX_DMAC_CTL, 0x03); | 679 | bgx_reg_write(bgx, lmacid, BGX_CMRX_RX_DMAC_CTL, 0x03); |
| @@ -695,8 +713,7 @@ static void bgx_lmac_disable(struct bgx *bgx, u8 lmacid) | |||
| 695 | lmac = &bgx->lmac[lmacid]; | 713 | lmac = &bgx->lmac[lmacid]; |
| 696 | if (lmac->check_link) { | 714 | if (lmac->check_link) { |
| 697 | /* Destroy work queue */ | 715 | /* Destroy work queue */ |
| 698 | cancel_delayed_work(&lmac->dwork); | 716 | cancel_delayed_work_sync(&lmac->dwork); |
| 699 | flush_workqueue(lmac->check_link); | ||
| 700 | destroy_workqueue(lmac->check_link); | 717 | destroy_workqueue(lmac->check_link); |
| 701 | } | 718 | } |
| 702 | 719 | ||
| @@ -1009,6 +1026,9 @@ static int bgx_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 1009 | struct bgx *bgx = NULL; | 1026 | struct bgx *bgx = NULL; |
| 1010 | u8 lmac; | 1027 | u8 lmac; |
| 1011 | 1028 | ||
| 1029 | /* Load octeon mdio driver */ | ||
| 1030 | octeon_mdiobus_force_mod_depencency(); | ||
| 1031 | |||
| 1012 | bgx = devm_kzalloc(dev, sizeof(*bgx), GFP_KERNEL); | 1032 | bgx = devm_kzalloc(dev, sizeof(*bgx), GFP_KERNEL); |
| 1013 | if (!bgx) | 1033 | if (!bgx) |
| 1014 | return -ENOMEM; | 1034 | return -ENOMEM; |
diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.h b/drivers/net/ethernet/cavium/thunder/thunder_bgx.h index 07b7ec66c60d..149e179363a1 100644 --- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.h +++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.h | |||
| @@ -182,6 +182,8 @@ enum MCAST_MODE { | |||
| 182 | #define BCAST_ACCEPT 1 | 182 | #define BCAST_ACCEPT 1 |
| 183 | #define CAM_ACCEPT 1 | 183 | #define CAM_ACCEPT 1 |
| 184 | 184 | ||
| 185 | void octeon_mdiobus_force_mod_depencency(void); | ||
| 186 | void bgx_lmac_rx_tx_enable(int node, int bgx_idx, int lmacid, bool enable); | ||
| 185 | void bgx_add_dmac_addr(u64 dmac, int node, int bgx_idx, int lmac); | 187 | void bgx_add_dmac_addr(u64 dmac, int node, int bgx_idx, int lmac); |
| 186 | unsigned bgx_get_map(int node); | 188 | unsigned bgx_get_map(int node); |
| 187 | int bgx_get_lmac_count(int node, int bgx); | 189 | int bgx_get_lmac_count(int node, int bgx); |
diff --git a/drivers/net/ethernet/dec/tulip/tulip_core.c b/drivers/net/ethernet/dec/tulip/tulip_core.c index ed41559bae77..b553409e04ad 100644 --- a/drivers/net/ethernet/dec/tulip/tulip_core.c +++ b/drivers/net/ethernet/dec/tulip/tulip_core.c | |||
| @@ -98,8 +98,7 @@ static int csr0 = 0x01A00000 | 0x4800; | |||
| 98 | #elif defined(__mips__) | 98 | #elif defined(__mips__) |
| 99 | static int csr0 = 0x00200000 | 0x4000; | 99 | static int csr0 = 0x00200000 | 0x4000; |
| 100 | #else | 100 | #else |
| 101 | #warning Processor architecture undefined! | 101 | static int csr0; |
| 102 | static int csr0 = 0x00A00000 | 0x4800; | ||
| 103 | #endif | 102 | #endif |
| 104 | 103 | ||
| 105 | /* Operational parameters that usually are not changed. */ | 104 | /* Operational parameters that usually are not changed. */ |
| @@ -1982,6 +1981,12 @@ static int __init tulip_init (void) | |||
| 1982 | pr_info("%s", version); | 1981 | pr_info("%s", version); |
| 1983 | #endif | 1982 | #endif |
| 1984 | 1983 | ||
| 1984 | if (!csr0) { | ||
| 1985 | pr_warn("tulip: unknown CPU architecture, using default csr0\n"); | ||
| 1986 | /* default to 8 longword cache line alignment */ | ||
| 1987 | csr0 = 0x00A00000 | 0x4800; | ||
| 1988 | } | ||
| 1989 | |||
| 1985 | /* copy module parms into globals */ | 1990 | /* copy module parms into globals */ |
| 1986 | tulip_rx_copybreak = rx_copybreak; | 1991 | tulip_rx_copybreak = rx_copybreak; |
| 1987 | tulip_max_interrupt_work = max_interrupt_work; | 1992 | tulip_max_interrupt_work = max_interrupt_work; |
diff --git a/drivers/net/ethernet/dec/tulip/winbond-840.c b/drivers/net/ethernet/dec/tulip/winbond-840.c index 9beb3d34d4ba..3c0e4d5c5fef 100644 --- a/drivers/net/ethernet/dec/tulip/winbond-840.c +++ b/drivers/net/ethernet/dec/tulip/winbond-840.c | |||
| @@ -907,7 +907,7 @@ static void init_registers(struct net_device *dev) | |||
| 907 | #elif defined(CONFIG_SPARC) || defined (CONFIG_PARISC) || defined(CONFIG_ARM) | 907 | #elif defined(CONFIG_SPARC) || defined (CONFIG_PARISC) || defined(CONFIG_ARM) |
| 908 | i |= 0x4800; | 908 | i |= 0x4800; |
| 909 | #else | 909 | #else |
| 910 | #warning Processor architecture undefined | 910 | dev_warn(&dev->dev, "unknown CPU architecture, using default csr0 setting\n"); |
| 911 | i |= 0x4800; | 911 | i |= 0x4800; |
| 912 | #endif | 912 | #endif |
| 913 | iowrite32(i, ioaddr + PCIBusCfg); | 913 | iowrite32(i, ioaddr + PCIBusCfg); |
diff --git a/drivers/net/ethernet/freescale/Kconfig b/drivers/net/ethernet/freescale/Kconfig index ff76d4e9dc1b..bee32a9d9876 100644 --- a/drivers/net/ethernet/freescale/Kconfig +++ b/drivers/net/ethernet/freescale/Kconfig | |||
| @@ -7,7 +7,8 @@ config NET_VENDOR_FREESCALE | |||
| 7 | default y | 7 | default y |
| 8 | depends on FSL_SOC || QUICC_ENGINE || CPM1 || CPM2 || PPC_MPC512x || \ | 8 | depends on FSL_SOC || QUICC_ENGINE || CPM1 || CPM2 || PPC_MPC512x || \ |
| 9 | M523x || M527x || M5272 || M528x || M520x || M532x || \ | 9 | M523x || M527x || M5272 || M528x || M520x || M532x || \ |
| 10 | ARCH_MXC || ARCH_MXS || (PPC_MPC52xx && PPC_BESTCOMM) | 10 | ARCH_MXC || ARCH_MXS || (PPC_MPC52xx && PPC_BESTCOMM) || \ |
| 11 | ARCH_LAYERSCAPE | ||
| 11 | ---help--- | 12 | ---help--- |
| 12 | If you have a network (Ethernet) card belonging to this class, say Y. | 13 | If you have a network (Ethernet) card belonging to this class, say Y. |
| 13 | 14 | ||
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 3e6b9b437497..7cf898455e60 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c | |||
| @@ -647,9 +647,9 @@ static int gfar_parse_group(struct device_node *np, | |||
| 647 | if (model && strcasecmp(model, "FEC")) { | 647 | if (model && strcasecmp(model, "FEC")) { |
| 648 | gfar_irq(grp, RX)->irq = irq_of_parse_and_map(np, 1); | 648 | gfar_irq(grp, RX)->irq = irq_of_parse_and_map(np, 1); |
| 649 | gfar_irq(grp, ER)->irq = irq_of_parse_and_map(np, 2); | 649 | gfar_irq(grp, ER)->irq = irq_of_parse_and_map(np, 2); |
| 650 | if (gfar_irq(grp, TX)->irq == NO_IRQ || | 650 | if (!gfar_irq(grp, TX)->irq || |
| 651 | gfar_irq(grp, RX)->irq == NO_IRQ || | 651 | !gfar_irq(grp, RX)->irq || |
| 652 | gfar_irq(grp, ER)->irq == NO_IRQ) | 652 | !gfar_irq(grp, ER)->irq) |
| 653 | return -EINVAL; | 653 | return -EINVAL; |
| 654 | } | 654 | } |
| 655 | 655 | ||
diff --git a/drivers/net/ethernet/freescale/gianfar_ptp.c b/drivers/net/ethernet/freescale/gianfar_ptp.c index 664d0c261269..b40fba929d65 100644 --- a/drivers/net/ethernet/freescale/gianfar_ptp.c +++ b/drivers/net/ethernet/freescale/gianfar_ptp.c | |||
| @@ -467,7 +467,7 @@ static int gianfar_ptp_probe(struct platform_device *dev) | |||
| 467 | 467 | ||
| 468 | etsects->irq = platform_get_irq(dev, 0); | 468 | etsects->irq = platform_get_irq(dev, 0); |
| 469 | 469 | ||
| 470 | if (etsects->irq == NO_IRQ) { | 470 | if (etsects->irq < 0) { |
| 471 | pr_err("irq not in device tree\n"); | 471 | pr_err("irq not in device tree\n"); |
| 472 | goto no_node; | 472 | goto no_node; |
| 473 | } | 473 | } |
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c index 639263d5e833..7781e80896a6 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c | |||
| @@ -627,8 +627,10 @@ static netdev_tx_t fm10k_xmit_frame(struct sk_buff *skb, struct net_device *dev) | |||
| 627 | 627 | ||
| 628 | /* verify the skb head is not shared */ | 628 | /* verify the skb head is not shared */ |
| 629 | err = skb_cow_head(skb, 0); | 629 | err = skb_cow_head(skb, 0); |
| 630 | if (err) | 630 | if (err) { |
| 631 | dev_kfree_skb(skb); | ||
| 631 | return NETDEV_TX_OK; | 632 | return NETDEV_TX_OK; |
| 633 | } | ||
| 632 | 634 | ||
| 633 | /* locate vlan header */ | 635 | /* locate vlan header */ |
| 634 | vhdr = (struct vlan_hdr *)(skb->data + ETH_HLEN); | 636 | vhdr = (struct vlan_hdr *)(skb->data + ETH_HLEN); |
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index e84c7f2634d3..ed622fa29dfa 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c | |||
| @@ -36,7 +36,7 @@ | |||
| 36 | 36 | ||
| 37 | /* Registers */ | 37 | /* Registers */ |
| 38 | #define MVNETA_RXQ_CONFIG_REG(q) (0x1400 + ((q) << 2)) | 38 | #define MVNETA_RXQ_CONFIG_REG(q) (0x1400 + ((q) << 2)) |
| 39 | #define MVNETA_RXQ_HW_BUF_ALLOC BIT(1) | 39 | #define MVNETA_RXQ_HW_BUF_ALLOC BIT(0) |
| 40 | #define MVNETA_RXQ_PKT_OFFSET_ALL_MASK (0xf << 8) | 40 | #define MVNETA_RXQ_PKT_OFFSET_ALL_MASK (0xf << 8) |
| 41 | #define MVNETA_RXQ_PKT_OFFSET_MASK(offs) ((offs) << 8) | 41 | #define MVNETA_RXQ_PKT_OFFSET_MASK(offs) ((offs) << 8) |
| 42 | #define MVNETA_RXQ_THRESHOLD_REG(q) (0x14c0 + ((q) << 2)) | 42 | #define MVNETA_RXQ_THRESHOLD_REG(q) (0x14c0 + ((q) << 2)) |
| @@ -62,6 +62,7 @@ | |||
| 62 | #define MVNETA_WIN_SIZE(w) (0x2204 + ((w) << 3)) | 62 | #define MVNETA_WIN_SIZE(w) (0x2204 + ((w) << 3)) |
| 63 | #define MVNETA_WIN_REMAP(w) (0x2280 + ((w) << 2)) | 63 | #define MVNETA_WIN_REMAP(w) (0x2280 + ((w) << 2)) |
| 64 | #define MVNETA_BASE_ADDR_ENABLE 0x2290 | 64 | #define MVNETA_BASE_ADDR_ENABLE 0x2290 |
| 65 | #define MVNETA_ACCESS_PROTECT_ENABLE 0x2294 | ||
| 65 | #define MVNETA_PORT_CONFIG 0x2400 | 66 | #define MVNETA_PORT_CONFIG 0x2400 |
| 66 | #define MVNETA_UNI_PROMISC_MODE BIT(0) | 67 | #define MVNETA_UNI_PROMISC_MODE BIT(0) |
| 67 | #define MVNETA_DEF_RXQ(q) ((q) << 1) | 68 | #define MVNETA_DEF_RXQ(q) ((q) << 1) |
| @@ -159,7 +160,7 @@ | |||
| 159 | 160 | ||
| 160 | #define MVNETA_INTR_ENABLE 0x25b8 | 161 | #define MVNETA_INTR_ENABLE 0x25b8 |
| 161 | #define MVNETA_TXQ_INTR_ENABLE_ALL_MASK 0x0000ff00 | 162 | #define MVNETA_TXQ_INTR_ENABLE_ALL_MASK 0x0000ff00 |
| 162 | #define MVNETA_RXQ_INTR_ENABLE_ALL_MASK 0xff000000 // note: neta says it's 0x000000FF | 163 | #define MVNETA_RXQ_INTR_ENABLE_ALL_MASK 0x000000ff |
| 163 | 164 | ||
| 164 | #define MVNETA_RXQ_CMD 0x2680 | 165 | #define MVNETA_RXQ_CMD 0x2680 |
| 165 | #define MVNETA_RXQ_DISABLE_SHIFT 8 | 166 | #define MVNETA_RXQ_DISABLE_SHIFT 8 |
| @@ -242,6 +243,7 @@ | |||
| 242 | #define MVNETA_VLAN_TAG_LEN 4 | 243 | #define MVNETA_VLAN_TAG_LEN 4 |
| 243 | 244 | ||
| 244 | #define MVNETA_CPU_D_CACHE_LINE_SIZE 32 | 245 | #define MVNETA_CPU_D_CACHE_LINE_SIZE 32 |
| 246 | #define MVNETA_TX_CSUM_DEF_SIZE 1600 | ||
| 245 | #define MVNETA_TX_CSUM_MAX_SIZE 9800 | 247 | #define MVNETA_TX_CSUM_MAX_SIZE 9800 |
| 246 | #define MVNETA_ACC_MODE_EXT 1 | 248 | #define MVNETA_ACC_MODE_EXT 1 |
| 247 | 249 | ||
| @@ -1579,12 +1581,16 @@ static int mvneta_rx(struct mvneta_port *pp, int rx_todo, | |||
| 1579 | } | 1581 | } |
| 1580 | 1582 | ||
| 1581 | skb = build_skb(data, pp->frag_size > PAGE_SIZE ? 0 : pp->frag_size); | 1583 | skb = build_skb(data, pp->frag_size > PAGE_SIZE ? 0 : pp->frag_size); |
| 1582 | if (!skb) | ||
| 1583 | goto err_drop_frame; | ||
| 1584 | 1584 | ||
| 1585 | /* After refill old buffer has to be unmapped regardless | ||
| 1586 | * the skb is successfully built or not. | ||
| 1587 | */ | ||
| 1585 | dma_unmap_single(dev->dev.parent, phys_addr, | 1588 | dma_unmap_single(dev->dev.parent, phys_addr, |
| 1586 | MVNETA_RX_BUF_SIZE(pp->pkt_size), DMA_FROM_DEVICE); | 1589 | MVNETA_RX_BUF_SIZE(pp->pkt_size), DMA_FROM_DEVICE); |
| 1587 | 1590 | ||
| 1591 | if (!skb) | ||
| 1592 | goto err_drop_frame; | ||
| 1593 | |||
| 1588 | rcvd_pkts++; | 1594 | rcvd_pkts++; |
| 1589 | rcvd_bytes += rx_bytes; | 1595 | rcvd_bytes += rx_bytes; |
| 1590 | 1596 | ||
| @@ -3191,6 +3197,7 @@ static void mvneta_conf_mbus_windows(struct mvneta_port *pp, | |||
| 3191 | } | 3197 | } |
| 3192 | 3198 | ||
| 3193 | mvreg_write(pp, MVNETA_BASE_ADDR_ENABLE, win_enable); | 3199 | mvreg_write(pp, MVNETA_BASE_ADDR_ENABLE, win_enable); |
| 3200 | mvreg_write(pp, MVNETA_ACCESS_PROTECT_ENABLE, win_protect); | ||
| 3194 | } | 3201 | } |
| 3195 | 3202 | ||
| 3196 | /* Power up the port */ | 3203 | /* Power up the port */ |
| @@ -3250,6 +3257,7 @@ static int mvneta_probe(struct platform_device *pdev) | |||
| 3250 | char hw_mac_addr[ETH_ALEN]; | 3257 | char hw_mac_addr[ETH_ALEN]; |
| 3251 | const char *mac_from; | 3258 | const char *mac_from; |
| 3252 | const char *managed; | 3259 | const char *managed; |
| 3260 | int tx_csum_limit; | ||
| 3253 | int phy_mode; | 3261 | int phy_mode; |
| 3254 | int err; | 3262 | int err; |
| 3255 | int cpu; | 3263 | int cpu; |
| @@ -3350,8 +3358,21 @@ static int mvneta_probe(struct platform_device *pdev) | |||
| 3350 | } | 3358 | } |
| 3351 | } | 3359 | } |
| 3352 | 3360 | ||
| 3353 | if (of_device_is_compatible(dn, "marvell,armada-370-neta")) | 3361 | if (!of_property_read_u32(dn, "tx-csum-limit", &tx_csum_limit)) { |
| 3354 | pp->tx_csum_limit = 1600; | 3362 | if (tx_csum_limit < 0 || |
| 3363 | tx_csum_limit > MVNETA_TX_CSUM_MAX_SIZE) { | ||
| 3364 | tx_csum_limit = MVNETA_TX_CSUM_DEF_SIZE; | ||
| 3365 | dev_info(&pdev->dev, | ||
| 3366 | "Wrong TX csum limit in DT, set to %dB\n", | ||
| 3367 | MVNETA_TX_CSUM_DEF_SIZE); | ||
| 3368 | } | ||
| 3369 | } else if (of_device_is_compatible(dn, "marvell,armada-370-neta")) { | ||
| 3370 | tx_csum_limit = MVNETA_TX_CSUM_DEF_SIZE; | ||
| 3371 | } else { | ||
| 3372 | tx_csum_limit = MVNETA_TX_CSUM_MAX_SIZE; | ||
| 3373 | } | ||
| 3374 | |||
| 3375 | pp->tx_csum_limit = tx_csum_limit; | ||
| 3355 | 3376 | ||
| 3356 | pp->tx_ring_size = MVNETA_MAX_TXD; | 3377 | pp->tx_ring_size = MVNETA_MAX_TXD; |
| 3357 | pp->rx_ring_size = MVNETA_MAX_RXD; | 3378 | pp->rx_ring_size = MVNETA_MAX_RXD; |
diff --git a/drivers/net/ethernet/nxp/lpc_eth.c b/drivers/net/ethernet/nxp/lpc_eth.c index b159ef8303cc..057665180f13 100644 --- a/drivers/net/ethernet/nxp/lpc_eth.c +++ b/drivers/net/ethernet/nxp/lpc_eth.c | |||
| @@ -1326,7 +1326,7 @@ static int lpc_eth_drv_probe(struct platform_device *pdev) | |||
| 1326 | /* Get platform resources */ | 1326 | /* Get platform resources */ |
| 1327 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1327 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 1328 | irq = platform_get_irq(pdev, 0); | 1328 | irq = platform_get_irq(pdev, 0); |
| 1329 | if ((!res) || (irq < 0) || (irq >= NR_IRQS)) { | 1329 | if (!res || irq < 0) { |
| 1330 | dev_err(&pdev->dev, "error getting resources.\n"); | 1330 | dev_err(&pdev->dev, "error getting resources.\n"); |
| 1331 | ret = -ENXIO; | 1331 | ret = -ENXIO; |
| 1332 | goto err_exit; | 1332 | goto err_exit; |
diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c index ee8d1ec61fab..ed5da4d47668 100644 --- a/drivers/net/ethernet/renesas/ravb_main.c +++ b/drivers/net/ethernet/renesas/ravb_main.c | |||
| @@ -1225,7 +1225,7 @@ static int ravb_open(struct net_device *ndev) | |||
| 1225 | /* Device init */ | 1225 | /* Device init */ |
| 1226 | error = ravb_dmac_init(ndev); | 1226 | error = ravb_dmac_init(ndev); |
| 1227 | if (error) | 1227 | if (error) |
| 1228 | goto out_free_irq; | 1228 | goto out_free_irq2; |
| 1229 | ravb_emac_init(ndev); | 1229 | ravb_emac_init(ndev); |
| 1230 | 1230 | ||
| 1231 | /* Initialise PTP Clock driver */ | 1231 | /* Initialise PTP Clock driver */ |
| @@ -1243,9 +1243,11 @@ static int ravb_open(struct net_device *ndev) | |||
| 1243 | out_ptp_stop: | 1243 | out_ptp_stop: |
| 1244 | /* Stop PTP Clock driver */ | 1244 | /* Stop PTP Clock driver */ |
| 1245 | ravb_ptp_stop(ndev); | 1245 | ravb_ptp_stop(ndev); |
| 1246 | out_free_irq2: | ||
| 1247 | if (priv->chip_id == RCAR_GEN3) | ||
| 1248 | free_irq(priv->emac_irq, ndev); | ||
| 1246 | out_free_irq: | 1249 | out_free_irq: |
| 1247 | free_irq(ndev->irq, ndev); | 1250 | free_irq(ndev->irq, ndev); |
| 1248 | free_irq(priv->emac_irq, ndev); | ||
| 1249 | out_napi_off: | 1251 | out_napi_off: |
| 1250 | napi_disable(&priv->napi[RAVB_NC]); | 1252 | napi_disable(&priv->napi[RAVB_NC]); |
| 1251 | napi_disable(&priv->napi[RAVB_BE]); | 1253 | napi_disable(&priv->napi[RAVB_BE]); |
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c index 7f6f4a4fcc70..58c05acc2aab 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c | |||
| @@ -299,16 +299,17 @@ static int sti_dwmac_parse_data(struct sti_dwmac *dwmac, | |||
| 299 | if (IS_PHY_IF_MODE_GBIT(dwmac->interface)) { | 299 | if (IS_PHY_IF_MODE_GBIT(dwmac->interface)) { |
| 300 | const char *rs; | 300 | const char *rs; |
| 301 | 301 | ||
| 302 | dwmac->tx_retime_src = TX_RETIME_SRC_CLKGEN; | ||
| 303 | |||
| 302 | err = of_property_read_string(np, "st,tx-retime-src", &rs); | 304 | err = of_property_read_string(np, "st,tx-retime-src", &rs); |
| 303 | if (err < 0) { | 305 | if (err < 0) { |
| 304 | dev_warn(dev, "Use internal clock source\n"); | 306 | dev_warn(dev, "Use internal clock source\n"); |
| 305 | dwmac->tx_retime_src = TX_RETIME_SRC_CLKGEN; | 307 | } else { |
| 306 | } else if (!strcasecmp(rs, "clk_125")) { | 308 | if (!strcasecmp(rs, "clk_125")) |
| 307 | dwmac->tx_retime_src = TX_RETIME_SRC_CLK_125; | 309 | dwmac->tx_retime_src = TX_RETIME_SRC_CLK_125; |
| 308 | } else if (!strcasecmp(rs, "txclk")) { | 310 | else if (!strcasecmp(rs, "txclk")) |
| 309 | dwmac->tx_retime_src = TX_RETIME_SRC_TXCLK; | 311 | dwmac->tx_retime_src = TX_RETIME_SRC_TXCLK; |
| 310 | } | 312 | } |
| 311 | |||
| 312 | dwmac->speed = SPEED_1000; | 313 | dwmac->speed = SPEED_1000; |
| 313 | } | 314 | } |
| 314 | 315 | ||
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 64d8aa4e0cad..3c6549aee11d 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | |||
| @@ -185,7 +185,7 @@ static void stmmac_clk_csr_set(struct stmmac_priv *priv) | |||
| 185 | priv->clk_csr = STMMAC_CSR_100_150M; | 185 | priv->clk_csr = STMMAC_CSR_100_150M; |
| 186 | else if ((clk_rate >= CSR_F_150M) && (clk_rate < CSR_F_250M)) | 186 | else if ((clk_rate >= CSR_F_150M) && (clk_rate < CSR_F_250M)) |
| 187 | priv->clk_csr = STMMAC_CSR_150_250M; | 187 | priv->clk_csr = STMMAC_CSR_150_250M; |
| 188 | else if ((clk_rate >= CSR_F_250M) && (clk_rate < CSR_F_300M)) | 188 | else if ((clk_rate >= CSR_F_250M) && (clk_rate <= CSR_F_300M)) |
| 189 | priv->clk_csr = STMMAC_CSR_250_300M; | 189 | priv->clk_csr = STMMAC_CSR_250_300M; |
| 190 | } | 190 | } |
| 191 | } | 191 | } |
| @@ -2232,6 +2232,12 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit) | |||
| 2232 | 2232 | ||
| 2233 | frame_len = priv->hw->desc->get_rx_frame_len(p, coe); | 2233 | frame_len = priv->hw->desc->get_rx_frame_len(p, coe); |
| 2234 | 2234 | ||
| 2235 | /* check if frame_len fits the preallocated memory */ | ||
| 2236 | if (frame_len > priv->dma_buf_sz) { | ||
| 2237 | priv->dev->stats.rx_length_errors++; | ||
| 2238 | break; | ||
| 2239 | } | ||
| 2240 | |||
| 2235 | /* ACS is set; GMAC core strips PAD/FCS for IEEE 802.3 | 2241 | /* ACS is set; GMAC core strips PAD/FCS for IEEE 802.3 |
| 2236 | * Type frames (LLC/LLC-SNAP) | 2242 | * Type frames (LLC/LLC-SNAP) |
| 2237 | */ | 2243 | */ |
| @@ -3102,6 +3108,7 @@ int stmmac_resume(struct net_device *ndev) | |||
| 3102 | init_dma_desc_rings(ndev, GFP_ATOMIC); | 3108 | init_dma_desc_rings(ndev, GFP_ATOMIC); |
| 3103 | stmmac_hw_setup(ndev, false); | 3109 | stmmac_hw_setup(ndev, false); |
| 3104 | stmmac_init_tx_coalesce(priv); | 3110 | stmmac_init_tx_coalesce(priv); |
| 3111 | stmmac_set_rx_mode(ndev); | ||
| 3105 | 3112 | ||
| 3106 | napi_enable(&priv->napi); | 3113 | napi_enable(&priv->napi); |
| 3107 | 3114 | ||
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c index ebf6abc4853f..bba670c42e37 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c | |||
| @@ -138,7 +138,6 @@ int stmmac_mdio_reset(struct mii_bus *bus) | |||
| 138 | 138 | ||
| 139 | #ifdef CONFIG_OF | 139 | #ifdef CONFIG_OF |
| 140 | if (priv->device->of_node) { | 140 | if (priv->device->of_node) { |
| 141 | int reset_gpio, active_low; | ||
| 142 | 141 | ||
| 143 | if (data->reset_gpio < 0) { | 142 | if (data->reset_gpio < 0) { |
| 144 | struct device_node *np = priv->device->of_node; | 143 | struct device_node *np = priv->device->of_node; |
| @@ -154,24 +153,23 @@ int stmmac_mdio_reset(struct mii_bus *bus) | |||
| 154 | "snps,reset-active-low"); | 153 | "snps,reset-active-low"); |
| 155 | of_property_read_u32_array(np, | 154 | of_property_read_u32_array(np, |
| 156 | "snps,reset-delays-us", data->delays, 3); | 155 | "snps,reset-delays-us", data->delays, 3); |
| 157 | } | ||
| 158 | 156 | ||
| 159 | reset_gpio = data->reset_gpio; | 157 | if (gpio_request(data->reset_gpio, "mdio-reset")) |
| 160 | active_low = data->active_low; | 158 | return 0; |
| 159 | } | ||
| 161 | 160 | ||
| 162 | if (!gpio_request(reset_gpio, "mdio-reset")) { | 161 | gpio_direction_output(data->reset_gpio, |
| 163 | gpio_direction_output(reset_gpio, active_low ? 1 : 0); | 162 | data->active_low ? 1 : 0); |
| 164 | if (data->delays[0]) | 163 | if (data->delays[0]) |
| 165 | msleep(DIV_ROUND_UP(data->delays[0], 1000)); | 164 | msleep(DIV_ROUND_UP(data->delays[0], 1000)); |
| 166 | 165 | ||
| 167 | gpio_set_value(reset_gpio, active_low ? 0 : 1); | 166 | gpio_set_value(data->reset_gpio, data->active_low ? 0 : 1); |
| 168 | if (data->delays[1]) | 167 | if (data->delays[1]) |
| 169 | msleep(DIV_ROUND_UP(data->delays[1], 1000)); | 168 | msleep(DIV_ROUND_UP(data->delays[1], 1000)); |
| 170 | 169 | ||
| 171 | gpio_set_value(reset_gpio, active_low ? 1 : 0); | 170 | gpio_set_value(data->reset_gpio, data->active_low ? 1 : 0); |
| 172 | if (data->delays[2]) | 171 | if (data->delays[2]) |
| 173 | msleep(DIV_ROUND_UP(data->delays[2], 1000)); | 172 | msleep(DIV_ROUND_UP(data->delays[2], 1000)); |
| 174 | } | ||
| 175 | } | 173 | } |
| 176 | #endif | 174 | #endif |
| 177 | 175 | ||
diff --git a/drivers/net/ethernet/ti/cpsw-common.c b/drivers/net/ethernet/ti/cpsw-common.c index c08be62bceba..1562ab4151e1 100644 --- a/drivers/net/ethernet/ti/cpsw-common.c +++ b/drivers/net/ethernet/ti/cpsw-common.c | |||
| @@ -78,6 +78,9 @@ static int cpsw_am33xx_cm_get_macid(struct device *dev, u16 offset, int slave, | |||
| 78 | 78 | ||
| 79 | int ti_cm_get_macid(struct device *dev, int slave, u8 *mac_addr) | 79 | int ti_cm_get_macid(struct device *dev, int slave, u8 *mac_addr) |
| 80 | { | 80 | { |
| 81 | if (of_machine_is_compatible("ti,dm8148")) | ||
| 82 | return cpsw_am33xx_cm_get_macid(dev, 0x630, slave, mac_addr); | ||
| 83 | |||
| 81 | if (of_machine_is_compatible("ti,am33xx")) | 84 | if (of_machine_is_compatible("ti,am33xx")) |
| 82 | return cpsw_am33xx_cm_get_macid(dev, 0x630, slave, mac_addr); | 85 | return cpsw_am33xx_cm_get_macid(dev, 0x630, slave, mac_addr); |
| 83 | 86 | ||
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 54036ae0a388..0fc521941c71 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c | |||
| @@ -498,7 +498,7 @@ static void macvtap_sock_write_space(struct sock *sk) | |||
| 498 | wait_queue_head_t *wqueue; | 498 | wait_queue_head_t *wqueue; |
| 499 | 499 | ||
| 500 | if (!sock_writeable(sk) || | 500 | if (!sock_writeable(sk) || |
| 501 | !test_and_clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags)) | 501 | !test_and_clear_bit(SOCKWQ_ASYNC_NOSPACE, &sk->sk_socket->flags)) |
| 502 | return; | 502 | return; |
| 503 | 503 | ||
| 504 | wqueue = sk_sleep(sk); | 504 | wqueue = sk_sleep(sk); |
| @@ -585,7 +585,7 @@ static unsigned int macvtap_poll(struct file *file, poll_table * wait) | |||
| 585 | mask |= POLLIN | POLLRDNORM; | 585 | mask |= POLLIN | POLLRDNORM; |
| 586 | 586 | ||
| 587 | if (sock_writeable(&q->sk) || | 587 | if (sock_writeable(&q->sk) || |
| 588 | (!test_and_set_bit(SOCK_ASYNC_NOSPACE, &q->sock.flags) && | 588 | (!test_and_set_bit(SOCKWQ_ASYNC_NOSPACE, &q->sock.flags) && |
| 589 | sock_writeable(&q->sk))) | 589 | sock_writeable(&q->sk))) |
| 590 | mask |= POLLOUT | POLLWRNORM; | 590 | mask |= POLLOUT | POLLWRNORM; |
| 591 | 591 | ||
diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c index 07a6119121c3..3ce5d9514623 100644 --- a/drivers/net/phy/broadcom.c +++ b/drivers/net/phy/broadcom.c | |||
| @@ -614,7 +614,7 @@ static struct mdio_device_id __maybe_unused broadcom_tbl[] = { | |||
| 614 | { PHY_ID_BCM5461, 0xfffffff0 }, | 614 | { PHY_ID_BCM5461, 0xfffffff0 }, |
| 615 | { PHY_ID_BCM54616S, 0xfffffff0 }, | 615 | { PHY_ID_BCM54616S, 0xfffffff0 }, |
| 616 | { PHY_ID_BCM5464, 0xfffffff0 }, | 616 | { PHY_ID_BCM5464, 0xfffffff0 }, |
| 617 | { PHY_ID_BCM5482, 0xfffffff0 }, | 617 | { PHY_ID_BCM5481, 0xfffffff0 }, |
| 618 | { PHY_ID_BCM5482, 0xfffffff0 }, | 618 | { PHY_ID_BCM5482, 0xfffffff0 }, |
| 619 | { PHY_ID_BCM50610, 0xfffffff0 }, | 619 | { PHY_ID_BCM50610, 0xfffffff0 }, |
| 620 | { PHY_ID_BCM50610M, 0xfffffff0 }, | 620 | { PHY_ID_BCM50610M, 0xfffffff0 }, |
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 48ce6ef400fe..47cd306dbb3c 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c | |||
| @@ -448,7 +448,8 @@ int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd) | |||
| 448 | mdiobus_write(phydev->bus, mii_data->phy_id, | 448 | mdiobus_write(phydev->bus, mii_data->phy_id, |
| 449 | mii_data->reg_num, val); | 449 | mii_data->reg_num, val); |
| 450 | 450 | ||
| 451 | if (mii_data->reg_num == MII_BMCR && | 451 | if (mii_data->phy_id == phydev->addr && |
| 452 | mii_data->reg_num == MII_BMCR && | ||
| 452 | val & BMCR_RESET) | 453 | val & BMCR_RESET) |
| 453 | return phy_init_hw(phydev); | 454 | return phy_init_hw(phydev); |
| 454 | 455 | ||
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index b1878faea397..f0db770e8b2f 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
| @@ -1040,7 +1040,7 @@ static unsigned int tun_chr_poll(struct file *file, poll_table *wait) | |||
| 1040 | mask |= POLLIN | POLLRDNORM; | 1040 | mask |= POLLIN | POLLRDNORM; |
| 1041 | 1041 | ||
| 1042 | if (sock_writeable(sk) || | 1042 | if (sock_writeable(sk) || |
| 1043 | (!test_and_set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags) && | 1043 | (!test_and_set_bit(SOCKWQ_ASYNC_NOSPACE, &sk->sk_socket->flags) && |
| 1044 | sock_writeable(sk))) | 1044 | sock_writeable(sk))) |
| 1045 | mask |= POLLOUT | POLLWRNORM; | 1045 | mask |= POLLOUT | POLLWRNORM; |
| 1046 | 1046 | ||
| @@ -1488,7 +1488,7 @@ static void tun_sock_write_space(struct sock *sk) | |||
| 1488 | if (!sock_writeable(sk)) | 1488 | if (!sock_writeable(sk)) |
| 1489 | return; | 1489 | return; |
| 1490 | 1490 | ||
| 1491 | if (!test_and_clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags)) | 1491 | if (!test_and_clear_bit(SOCKWQ_ASYNC_NOSPACE, &sk->sk_socket->flags)) |
| 1492 | return; | 1492 | return; |
| 1493 | 1493 | ||
| 1494 | wqueue = sk_sleep(sk); | 1494 | wqueue = sk_sleep(sk); |
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index a187f08113ec..3b1ba8237768 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c | |||
| @@ -691,7 +691,6 @@ static void cdc_ncm_free(struct cdc_ncm_ctx *ctx) | |||
| 691 | 691 | ||
| 692 | int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_altsetting, int drvflags) | 692 | int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_altsetting, int drvflags) |
| 693 | { | 693 | { |
| 694 | const struct usb_cdc_union_desc *union_desc = NULL; | ||
| 695 | struct cdc_ncm_ctx *ctx; | 694 | struct cdc_ncm_ctx *ctx; |
| 696 | struct usb_driver *driver; | 695 | struct usb_driver *driver; |
| 697 | u8 *buf; | 696 | u8 *buf; |
| @@ -725,15 +724,16 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_ | |||
| 725 | /* parse through descriptors associated with control interface */ | 724 | /* parse through descriptors associated with control interface */ |
| 726 | cdc_parse_cdc_header(&hdr, intf, buf, len); | 725 | cdc_parse_cdc_header(&hdr, intf, buf, len); |
| 727 | 726 | ||
| 728 | ctx->data = usb_ifnum_to_if(dev->udev, | 727 | if (hdr.usb_cdc_union_desc) |
| 729 | hdr.usb_cdc_union_desc->bSlaveInterface0); | 728 | ctx->data = usb_ifnum_to_if(dev->udev, |
| 729 | hdr.usb_cdc_union_desc->bSlaveInterface0); | ||
| 730 | ctx->ether_desc = hdr.usb_cdc_ether_desc; | 730 | ctx->ether_desc = hdr.usb_cdc_ether_desc; |
| 731 | ctx->func_desc = hdr.usb_cdc_ncm_desc; | 731 | ctx->func_desc = hdr.usb_cdc_ncm_desc; |
| 732 | ctx->mbim_desc = hdr.usb_cdc_mbim_desc; | 732 | ctx->mbim_desc = hdr.usb_cdc_mbim_desc; |
| 733 | ctx->mbim_extended_desc = hdr.usb_cdc_mbim_extended_desc; | 733 | ctx->mbim_extended_desc = hdr.usb_cdc_mbim_extended_desc; |
| 734 | 734 | ||
| 735 | /* some buggy devices have an IAD but no CDC Union */ | 735 | /* some buggy devices have an IAD but no CDC Union */ |
| 736 | if (!union_desc && intf->intf_assoc && intf->intf_assoc->bInterfaceCount == 2) { | 736 | if (!hdr.usb_cdc_union_desc && intf->intf_assoc && intf->intf_assoc->bInterfaceCount == 2) { |
| 737 | ctx->data = usb_ifnum_to_if(dev->udev, intf->cur_altsetting->desc.bInterfaceNumber + 1); | 737 | ctx->data = usb_ifnum_to_if(dev->udev, intf->cur_altsetting->desc.bInterfaceNumber + 1); |
| 738 | dev_dbg(&intf->dev, "CDC Union missing - got slave from IAD\n"); | 738 | dev_dbg(&intf->dev, "CDC Union missing - got slave from IAD\n"); |
| 739 | } | 739 | } |
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 34799eaace41..9a5be8b85186 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c | |||
| @@ -725,6 +725,7 @@ static const struct usb_device_id products[] = { | |||
| 725 | {QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */ | 725 | {QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */ |
| 726 | {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */ | 726 | {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */ |
| 727 | {QMI_FIXED_INTF(0x1bc7, 0x1201, 2)}, /* Telit LE920 */ | 727 | {QMI_FIXED_INTF(0x1bc7, 0x1201, 2)}, /* Telit LE920 */ |
| 728 | {QMI_FIXED_INTF(0x1c9e, 0x9b01, 3)}, /* XS Stick W100-2 from 4G Systems */ | ||
| 728 | {QMI_FIXED_INTF(0x0b3c, 0xc000, 4)}, /* Olivetti Olicard 100 */ | 729 | {QMI_FIXED_INTF(0x0b3c, 0xc000, 4)}, /* Olivetti Olicard 100 */ |
| 729 | {QMI_FIXED_INTF(0x0b3c, 0xc001, 4)}, /* Olivetti Olicard 120 */ | 730 | {QMI_FIXED_INTF(0x0b3c, 0xc001, 4)}, /* Olivetti Olicard 120 */ |
| 730 | {QMI_FIXED_INTF(0x0b3c, 0xc002, 4)}, /* Olivetti Olicard 140 */ | 731 | {QMI_FIXED_INTF(0x0b3c, 0xc002, 4)}, /* Olivetti Olicard 140 */ |
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 899ea4288197..417903715437 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c | |||
| @@ -587,6 +587,12 @@ vmxnet3_rq_alloc_rx_buf(struct vmxnet3_rx_queue *rq, u32 ring_idx, | |||
| 587 | &adapter->pdev->dev, | 587 | &adapter->pdev->dev, |
| 588 | rbi->skb->data, rbi->len, | 588 | rbi->skb->data, rbi->len, |
| 589 | PCI_DMA_FROMDEVICE); | 589 | PCI_DMA_FROMDEVICE); |
| 590 | if (dma_mapping_error(&adapter->pdev->dev, | ||
| 591 | rbi->dma_addr)) { | ||
| 592 | dev_kfree_skb_any(rbi->skb); | ||
| 593 | rq->stats.rx_buf_alloc_failure++; | ||
| 594 | break; | ||
| 595 | } | ||
| 590 | } else { | 596 | } else { |
| 591 | /* rx buffer skipped by the device */ | 597 | /* rx buffer skipped by the device */ |
| 592 | } | 598 | } |
| @@ -605,13 +611,18 @@ vmxnet3_rq_alloc_rx_buf(struct vmxnet3_rx_queue *rq, u32 ring_idx, | |||
| 605 | &adapter->pdev->dev, | 611 | &adapter->pdev->dev, |
| 606 | rbi->page, 0, PAGE_SIZE, | 612 | rbi->page, 0, PAGE_SIZE, |
| 607 | PCI_DMA_FROMDEVICE); | 613 | PCI_DMA_FROMDEVICE); |
| 614 | if (dma_mapping_error(&adapter->pdev->dev, | ||
| 615 | rbi->dma_addr)) { | ||
| 616 | put_page(rbi->page); | ||
| 617 | rq->stats.rx_buf_alloc_failure++; | ||
| 618 | break; | ||
| 619 | } | ||
| 608 | } else { | 620 | } else { |
| 609 | /* rx buffers skipped by the device */ | 621 | /* rx buffers skipped by the device */ |
| 610 | } | 622 | } |
| 611 | val = VMXNET3_RXD_BTYPE_BODY << VMXNET3_RXD_BTYPE_SHIFT; | 623 | val = VMXNET3_RXD_BTYPE_BODY << VMXNET3_RXD_BTYPE_SHIFT; |
| 612 | } | 624 | } |
| 613 | 625 | ||
| 614 | BUG_ON(rbi->dma_addr == 0); | ||
| 615 | gd->rxd.addr = cpu_to_le64(rbi->dma_addr); | 626 | gd->rxd.addr = cpu_to_le64(rbi->dma_addr); |
| 616 | gd->dword[2] = cpu_to_le32((!ring->gen << VMXNET3_RXD_GEN_SHIFT) | 627 | gd->dword[2] = cpu_to_le32((!ring->gen << VMXNET3_RXD_GEN_SHIFT) |
| 617 | | val | rbi->len); | 628 | | val | rbi->len); |
| @@ -655,7 +666,7 @@ vmxnet3_append_frag(struct sk_buff *skb, struct Vmxnet3_RxCompDesc *rcd, | |||
| 655 | } | 666 | } |
| 656 | 667 | ||
| 657 | 668 | ||
| 658 | static void | 669 | static int |
| 659 | vmxnet3_map_pkt(struct sk_buff *skb, struct vmxnet3_tx_ctx *ctx, | 670 | vmxnet3_map_pkt(struct sk_buff *skb, struct vmxnet3_tx_ctx *ctx, |
| 660 | struct vmxnet3_tx_queue *tq, struct pci_dev *pdev, | 671 | struct vmxnet3_tx_queue *tq, struct pci_dev *pdev, |
| 661 | struct vmxnet3_adapter *adapter) | 672 | struct vmxnet3_adapter *adapter) |
| @@ -715,6 +726,8 @@ vmxnet3_map_pkt(struct sk_buff *skb, struct vmxnet3_tx_ctx *ctx, | |||
| 715 | tbi->dma_addr = dma_map_single(&adapter->pdev->dev, | 726 | tbi->dma_addr = dma_map_single(&adapter->pdev->dev, |
| 716 | skb->data + buf_offset, buf_size, | 727 | skb->data + buf_offset, buf_size, |
| 717 | PCI_DMA_TODEVICE); | 728 | PCI_DMA_TODEVICE); |
| 729 | if (dma_mapping_error(&adapter->pdev->dev, tbi->dma_addr)) | ||
| 730 | return -EFAULT; | ||
| 718 | 731 | ||
| 719 | tbi->len = buf_size; | 732 | tbi->len = buf_size; |
| 720 | 733 | ||
| @@ -755,6 +768,8 @@ vmxnet3_map_pkt(struct sk_buff *skb, struct vmxnet3_tx_ctx *ctx, | |||
| 755 | tbi->dma_addr = skb_frag_dma_map(&adapter->pdev->dev, frag, | 768 | tbi->dma_addr = skb_frag_dma_map(&adapter->pdev->dev, frag, |
| 756 | buf_offset, buf_size, | 769 | buf_offset, buf_size, |
| 757 | DMA_TO_DEVICE); | 770 | DMA_TO_DEVICE); |
| 771 | if (dma_mapping_error(&adapter->pdev->dev, tbi->dma_addr)) | ||
| 772 | return -EFAULT; | ||
| 758 | 773 | ||
| 759 | tbi->len = buf_size; | 774 | tbi->len = buf_size; |
| 760 | 775 | ||
| @@ -782,6 +797,8 @@ vmxnet3_map_pkt(struct sk_buff *skb, struct vmxnet3_tx_ctx *ctx, | |||
| 782 | /* set the last buf_info for the pkt */ | 797 | /* set the last buf_info for the pkt */ |
| 783 | tbi->skb = skb; | 798 | tbi->skb = skb; |
| 784 | tbi->sop_idx = ctx->sop_txd - tq->tx_ring.base; | 799 | tbi->sop_idx = ctx->sop_txd - tq->tx_ring.base; |
| 800 | |||
| 801 | return 0; | ||
| 785 | } | 802 | } |
| 786 | 803 | ||
| 787 | 804 | ||
| @@ -1020,7 +1037,8 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, | |||
| 1020 | } | 1037 | } |
| 1021 | 1038 | ||
| 1022 | /* fill tx descs related to addr & len */ | 1039 | /* fill tx descs related to addr & len */ |
| 1023 | vmxnet3_map_pkt(skb, &ctx, tq, adapter->pdev, adapter); | 1040 | if (vmxnet3_map_pkt(skb, &ctx, tq, adapter->pdev, adapter)) |
| 1041 | goto unlock_drop_pkt; | ||
| 1024 | 1042 | ||
| 1025 | /* setup the EOP desc */ | 1043 | /* setup the EOP desc */ |
| 1026 | ctx.eop_txd->dword[3] = cpu_to_le32(VMXNET3_TXD_CQ | VMXNET3_TXD_EOP); | 1044 | ctx.eop_txd->dword[3] = cpu_to_le32(VMXNET3_TXD_CQ | VMXNET3_TXD_EOP); |
| @@ -1231,6 +1249,7 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq, | |||
| 1231 | struct vmxnet3_rx_buf_info *rbi; | 1249 | struct vmxnet3_rx_buf_info *rbi; |
| 1232 | struct sk_buff *skb, *new_skb = NULL; | 1250 | struct sk_buff *skb, *new_skb = NULL; |
| 1233 | struct page *new_page = NULL; | 1251 | struct page *new_page = NULL; |
| 1252 | dma_addr_t new_dma_addr; | ||
| 1234 | int num_to_alloc; | 1253 | int num_to_alloc; |
| 1235 | struct Vmxnet3_RxDesc *rxd; | 1254 | struct Vmxnet3_RxDesc *rxd; |
| 1236 | u32 idx, ring_idx; | 1255 | u32 idx, ring_idx; |
| @@ -1287,6 +1306,21 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq, | |||
| 1287 | skip_page_frags = true; | 1306 | skip_page_frags = true; |
| 1288 | goto rcd_done; | 1307 | goto rcd_done; |
| 1289 | } | 1308 | } |
| 1309 | new_dma_addr = dma_map_single(&adapter->pdev->dev, | ||
| 1310 | new_skb->data, rbi->len, | ||
| 1311 | PCI_DMA_FROMDEVICE); | ||
| 1312 | if (dma_mapping_error(&adapter->pdev->dev, | ||
| 1313 | new_dma_addr)) { | ||
| 1314 | dev_kfree_skb(new_skb); | ||
| 1315 | /* Skb allocation failed, do not handover this | ||
| 1316 | * skb to stack. Reuse it. Drop the existing pkt | ||
| 1317 | */ | ||
| 1318 | rq->stats.rx_buf_alloc_failure++; | ||
| 1319 | ctx->skb = NULL; | ||
| 1320 | rq->stats.drop_total++; | ||
| 1321 | skip_page_frags = true; | ||
| 1322 | goto rcd_done; | ||
| 1323 | } | ||
| 1290 | 1324 | ||
| 1291 | dma_unmap_single(&adapter->pdev->dev, rbi->dma_addr, | 1325 | dma_unmap_single(&adapter->pdev->dev, rbi->dma_addr, |
| 1292 | rbi->len, | 1326 | rbi->len, |
| @@ -1303,9 +1337,7 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq, | |||
| 1303 | 1337 | ||
| 1304 | /* Immediate refill */ | 1338 | /* Immediate refill */ |
| 1305 | rbi->skb = new_skb; | 1339 | rbi->skb = new_skb; |
| 1306 | rbi->dma_addr = dma_map_single(&adapter->pdev->dev, | 1340 | rbi->dma_addr = new_dma_addr; |
| 1307 | rbi->skb->data, rbi->len, | ||
| 1308 | PCI_DMA_FROMDEVICE); | ||
| 1309 | rxd->addr = cpu_to_le64(rbi->dma_addr); | 1341 | rxd->addr = cpu_to_le64(rbi->dma_addr); |
| 1310 | rxd->len = rbi->len; | 1342 | rxd->len = rbi->len; |
| 1311 | if (adapter->version == 2 && | 1343 | if (adapter->version == 2 && |
| @@ -1348,6 +1380,19 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq, | |||
| 1348 | skip_page_frags = true; | 1380 | skip_page_frags = true; |
| 1349 | goto rcd_done; | 1381 | goto rcd_done; |
| 1350 | } | 1382 | } |
| 1383 | new_dma_addr = dma_map_page(&adapter->pdev->dev | ||
| 1384 | , rbi->page, | ||
| 1385 | 0, PAGE_SIZE, | ||
| 1386 | PCI_DMA_FROMDEVICE); | ||
| 1387 | if (dma_mapping_error(&adapter->pdev->dev, | ||
| 1388 | new_dma_addr)) { | ||
| 1389 | put_page(new_page); | ||
| 1390 | rq->stats.rx_buf_alloc_failure++; | ||
| 1391 | dev_kfree_skb(ctx->skb); | ||
| 1392 | ctx->skb = NULL; | ||
| 1393 | skip_page_frags = true; | ||
| 1394 | goto rcd_done; | ||
| 1395 | } | ||
| 1351 | 1396 | ||
| 1352 | dma_unmap_page(&adapter->pdev->dev, | 1397 | dma_unmap_page(&adapter->pdev->dev, |
| 1353 | rbi->dma_addr, rbi->len, | 1398 | rbi->dma_addr, rbi->len, |
| @@ -1357,10 +1402,7 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq, | |||
| 1357 | 1402 | ||
| 1358 | /* Immediate refill */ | 1403 | /* Immediate refill */ |
| 1359 | rbi->page = new_page; | 1404 | rbi->page = new_page; |
| 1360 | rbi->dma_addr = dma_map_page(&adapter->pdev->dev | 1405 | rbi->dma_addr = new_dma_addr; |
| 1361 | , rbi->page, | ||
| 1362 | 0, PAGE_SIZE, | ||
| 1363 | PCI_DMA_FROMDEVICE); | ||
| 1364 | rxd->addr = cpu_to_le64(rbi->dma_addr); | 1406 | rxd->addr = cpu_to_le64(rbi->dma_addr); |
| 1365 | rxd->len = rbi->len; | 1407 | rxd->len = rbi->len; |
| 1366 | } | 1408 | } |
| @@ -2167,7 +2209,8 @@ vmxnet3_set_mc(struct net_device *netdev) | |||
| 2167 | PCI_DMA_TODEVICE); | 2209 | PCI_DMA_TODEVICE); |
| 2168 | } | 2210 | } |
| 2169 | 2211 | ||
| 2170 | if (new_table_pa) { | 2212 | if (!dma_mapping_error(&adapter->pdev->dev, |
| 2213 | new_table_pa)) { | ||
| 2171 | new_mode |= VMXNET3_RXM_MCAST; | 2214 | new_mode |= VMXNET3_RXM_MCAST; |
| 2172 | rxConf->mfTablePA = cpu_to_le64(new_table_pa); | 2215 | rxConf->mfTablePA = cpu_to_le64(new_table_pa); |
| 2173 | } else { | 2216 | } else { |
| @@ -3075,6 +3118,11 @@ vmxnet3_probe_device(struct pci_dev *pdev, | |||
| 3075 | adapter->adapter_pa = dma_map_single(&adapter->pdev->dev, adapter, | 3118 | adapter->adapter_pa = dma_map_single(&adapter->pdev->dev, adapter, |
| 3076 | sizeof(struct vmxnet3_adapter), | 3119 | sizeof(struct vmxnet3_adapter), |
| 3077 | PCI_DMA_TODEVICE); | 3120 | PCI_DMA_TODEVICE); |
| 3121 | if (dma_mapping_error(&adapter->pdev->dev, adapter->adapter_pa)) { | ||
| 3122 | dev_err(&pdev->dev, "Failed to map dma\n"); | ||
| 3123 | err = -EFAULT; | ||
| 3124 | goto err_dma_map; | ||
| 3125 | } | ||
| 3078 | adapter->shared = dma_alloc_coherent( | 3126 | adapter->shared = dma_alloc_coherent( |
| 3079 | &adapter->pdev->dev, | 3127 | &adapter->pdev->dev, |
| 3080 | sizeof(struct Vmxnet3_DriverShared), | 3128 | sizeof(struct Vmxnet3_DriverShared), |
| @@ -3233,6 +3281,7 @@ err_alloc_queue_desc: | |||
| 3233 | err_alloc_shared: | 3281 | err_alloc_shared: |
| 3234 | dma_unmap_single(&adapter->pdev->dev, adapter->adapter_pa, | 3282 | dma_unmap_single(&adapter->pdev->dev, adapter->adapter_pa, |
| 3235 | sizeof(struct vmxnet3_adapter), PCI_DMA_TODEVICE); | 3283 | sizeof(struct vmxnet3_adapter), PCI_DMA_TODEVICE); |
| 3284 | err_dma_map: | ||
| 3236 | free_netdev(netdev); | 3285 | free_netdev(netdev); |
| 3237 | return err; | 3286 | return err; |
| 3238 | } | 3287 | } |
diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c index 92fa3e1ea65c..4f9748457f5a 100644 --- a/drivers/net/vrf.c +++ b/drivers/net/vrf.c | |||
| @@ -907,7 +907,6 @@ static int vrf_newlink(struct net *src_net, struct net_device *dev, | |||
| 907 | struct nlattr *tb[], struct nlattr *data[]) | 907 | struct nlattr *tb[], struct nlattr *data[]) |
| 908 | { | 908 | { |
| 909 | struct net_vrf *vrf = netdev_priv(dev); | 909 | struct net_vrf *vrf = netdev_priv(dev); |
| 910 | int err; | ||
| 911 | 910 | ||
| 912 | if (!data || !data[IFLA_VRF_TABLE]) | 911 | if (!data || !data[IFLA_VRF_TABLE]) |
| 913 | return -EINVAL; | 912 | return -EINVAL; |
| @@ -916,15 +915,7 @@ static int vrf_newlink(struct net *src_net, struct net_device *dev, | |||
| 916 | 915 | ||
| 917 | dev->priv_flags |= IFF_L3MDEV_MASTER; | 916 | dev->priv_flags |= IFF_L3MDEV_MASTER; |
| 918 | 917 | ||
| 919 | err = register_netdevice(dev); | 918 | return register_netdevice(dev); |
| 920 | if (err < 0) | ||
| 921 | goto out_fail; | ||
| 922 | |||
| 923 | return 0; | ||
| 924 | |||
| 925 | out_fail: | ||
| 926 | free_netdev(dev); | ||
| 927 | return err; | ||
| 928 | } | 919 | } |
| 929 | 920 | ||
| 930 | static size_t vrf_nl_getsize(const struct net_device *dev) | 921 | static size_t vrf_nl_getsize(const struct net_device *dev) |
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c index e92aaf615901..89541cc90e87 100644 --- a/drivers/net/wan/hdlc_fr.c +++ b/drivers/net/wan/hdlc_fr.c | |||
| @@ -1075,11 +1075,10 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type) | |||
| 1075 | 1075 | ||
| 1076 | used = pvc_is_used(pvc); | 1076 | used = pvc_is_used(pvc); |
| 1077 | 1077 | ||
| 1078 | if (type == ARPHRD_ETHER) { | 1078 | if (type == ARPHRD_ETHER) |
| 1079 | dev = alloc_netdev(0, "pvceth%d", NET_NAME_UNKNOWN, | 1079 | dev = alloc_netdev(0, "pvceth%d", NET_NAME_UNKNOWN, |
| 1080 | ether_setup); | 1080 | ether_setup); |
| 1081 | dev->priv_flags &= ~IFF_TX_SKB_SHARING; | 1081 | else |
| 1082 | } else | ||
| 1083 | dev = alloc_netdev(0, "pvc%d", NET_NAME_UNKNOWN, pvc_setup); | 1082 | dev = alloc_netdev(0, "pvc%d", NET_NAME_UNKNOWN, pvc_setup); |
| 1084 | 1083 | ||
| 1085 | if (!dev) { | 1084 | if (!dev) { |
| @@ -1088,9 +1087,10 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type) | |||
| 1088 | return -ENOBUFS; | 1087 | return -ENOBUFS; |
| 1089 | } | 1088 | } |
| 1090 | 1089 | ||
| 1091 | if (type == ARPHRD_ETHER) | 1090 | if (type == ARPHRD_ETHER) { |
| 1091 | dev->priv_flags &= ~IFF_TX_SKB_SHARING; | ||
| 1092 | eth_hw_addr_random(dev); | 1092 | eth_hw_addr_random(dev); |
| 1093 | else { | 1093 | } else { |
| 1094 | *(__be16*)dev->dev_addr = htons(dlci); | 1094 | *(__be16*)dev->dev_addr = htons(dlci); |
| 1095 | dlci_to_q922(dev->broadcast, dlci); | 1095 | dlci_to_q922(dev->broadcast, dlci); |
| 1096 | } | 1096 | } |
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c index 5c47b011a9d7..cd39025d2abf 100644 --- a/drivers/net/wan/x25_asy.c +++ b/drivers/net/wan/x25_asy.c | |||
| @@ -549,16 +549,12 @@ static void x25_asy_receive_buf(struct tty_struct *tty, | |||
| 549 | 549 | ||
| 550 | static int x25_asy_open_tty(struct tty_struct *tty) | 550 | static int x25_asy_open_tty(struct tty_struct *tty) |
| 551 | { | 551 | { |
| 552 | struct x25_asy *sl = tty->disc_data; | 552 | struct x25_asy *sl; |
| 553 | int err; | 553 | int err; |
| 554 | 554 | ||
| 555 | if (tty->ops->write == NULL) | 555 | if (tty->ops->write == NULL) |
| 556 | return -EOPNOTSUPP; | 556 | return -EOPNOTSUPP; |
| 557 | 557 | ||
| 558 | /* First make sure we're not already connected. */ | ||
| 559 | if (sl && sl->magic == X25_ASY_MAGIC) | ||
| 560 | return -EEXIST; | ||
| 561 | |||
| 562 | /* OK. Find a free X.25 channel to use. */ | 558 | /* OK. Find a free X.25 channel to use. */ |
| 563 | sl = x25_asy_alloc(); | 559 | sl = x25_asy_alloc(); |
| 564 | if (sl == NULL) | 560 | if (sl == NULL) |
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index aa9bd92ac4ed..0947cc271e69 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c | |||
| @@ -51,6 +51,7 @@ MODULE_PARM_DESC(rawmode, "Use raw 802.11 frame datapath"); | |||
| 51 | static const struct ath10k_hw_params ath10k_hw_params_list[] = { | 51 | static const struct ath10k_hw_params ath10k_hw_params_list[] = { |
| 52 | { | 52 | { |
| 53 | .id = QCA988X_HW_2_0_VERSION, | 53 | .id = QCA988X_HW_2_0_VERSION, |
| 54 | .dev_id = QCA988X_2_0_DEVICE_ID, | ||
| 54 | .name = "qca988x hw2.0", | 55 | .name = "qca988x hw2.0", |
| 55 | .patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR, | 56 | .patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR, |
| 56 | .uart_pin = 7, | 57 | .uart_pin = 7, |
| @@ -69,6 +70,25 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { | |||
| 69 | }, | 70 | }, |
| 70 | { | 71 | { |
| 71 | .id = QCA6174_HW_2_1_VERSION, | 72 | .id = QCA6174_HW_2_1_VERSION, |
| 73 | .dev_id = QCA6164_2_1_DEVICE_ID, | ||
| 74 | .name = "qca6164 hw2.1", | ||
| 75 | .patch_load_addr = QCA6174_HW_2_1_PATCH_LOAD_ADDR, | ||
| 76 | .uart_pin = 6, | ||
| 77 | .otp_exe_param = 0, | ||
| 78 | .channel_counters_freq_hz = 88000, | ||
| 79 | .max_probe_resp_desc_thres = 0, | ||
| 80 | .fw = { | ||
| 81 | .dir = QCA6174_HW_2_1_FW_DIR, | ||
| 82 | .fw = QCA6174_HW_2_1_FW_FILE, | ||
| 83 | .otp = QCA6174_HW_2_1_OTP_FILE, | ||
| 84 | .board = QCA6174_HW_2_1_BOARD_DATA_FILE, | ||
| 85 | .board_size = QCA6174_BOARD_DATA_SZ, | ||
| 86 | .board_ext_size = QCA6174_BOARD_EXT_DATA_SZ, | ||
| 87 | }, | ||
| 88 | }, | ||
| 89 | { | ||
| 90 | .id = QCA6174_HW_2_1_VERSION, | ||
| 91 | .dev_id = QCA6174_2_1_DEVICE_ID, | ||
| 72 | .name = "qca6174 hw2.1", | 92 | .name = "qca6174 hw2.1", |
| 73 | .patch_load_addr = QCA6174_HW_2_1_PATCH_LOAD_ADDR, | 93 | .patch_load_addr = QCA6174_HW_2_1_PATCH_LOAD_ADDR, |
| 74 | .uart_pin = 6, | 94 | .uart_pin = 6, |
| @@ -86,6 +106,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { | |||
| 86 | }, | 106 | }, |
| 87 | { | 107 | { |
| 88 | .id = QCA6174_HW_3_0_VERSION, | 108 | .id = QCA6174_HW_3_0_VERSION, |
| 109 | .dev_id = QCA6174_2_1_DEVICE_ID, | ||
| 89 | .name = "qca6174 hw3.0", | 110 | .name = "qca6174 hw3.0", |
| 90 | .patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR, | 111 | .patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR, |
| 91 | .uart_pin = 6, | 112 | .uart_pin = 6, |
| @@ -103,6 +124,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { | |||
| 103 | }, | 124 | }, |
| 104 | { | 125 | { |
| 105 | .id = QCA6174_HW_3_2_VERSION, | 126 | .id = QCA6174_HW_3_2_VERSION, |
| 127 | .dev_id = QCA6174_2_1_DEVICE_ID, | ||
| 106 | .name = "qca6174 hw3.2", | 128 | .name = "qca6174 hw3.2", |
| 107 | .patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR, | 129 | .patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR, |
| 108 | .uart_pin = 6, | 130 | .uart_pin = 6, |
| @@ -121,6 +143,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { | |||
| 121 | }, | 143 | }, |
| 122 | { | 144 | { |
| 123 | .id = QCA99X0_HW_2_0_DEV_VERSION, | 145 | .id = QCA99X0_HW_2_0_DEV_VERSION, |
| 146 | .dev_id = QCA99X0_2_0_DEVICE_ID, | ||
| 124 | .name = "qca99x0 hw2.0", | 147 | .name = "qca99x0 hw2.0", |
| 125 | .patch_load_addr = QCA99X0_HW_2_0_PATCH_LOAD_ADDR, | 148 | .patch_load_addr = QCA99X0_HW_2_0_PATCH_LOAD_ADDR, |
| 126 | .uart_pin = 7, | 149 | .uart_pin = 7, |
| @@ -139,10 +162,31 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { | |||
| 139 | }, | 162 | }, |
| 140 | { | 163 | { |
| 141 | .id = QCA9377_HW_1_0_DEV_VERSION, | 164 | .id = QCA9377_HW_1_0_DEV_VERSION, |
| 165 | .dev_id = QCA9377_1_0_DEVICE_ID, | ||
| 142 | .name = "qca9377 hw1.0", | 166 | .name = "qca9377 hw1.0", |
| 143 | .patch_load_addr = QCA9377_HW_1_0_PATCH_LOAD_ADDR, | 167 | .patch_load_addr = QCA9377_HW_1_0_PATCH_LOAD_ADDR, |
| 144 | .uart_pin = 7, | 168 | .uart_pin = 6, |
| 145 | .otp_exe_param = 0, | 169 | .otp_exe_param = 0, |
| 170 | .channel_counters_freq_hz = 88000, | ||
| 171 | .max_probe_resp_desc_thres = 0, | ||
| 172 | .fw = { | ||
| 173 | .dir = QCA9377_HW_1_0_FW_DIR, | ||
| 174 | .fw = QCA9377_HW_1_0_FW_FILE, | ||
| 175 | .otp = QCA9377_HW_1_0_OTP_FILE, | ||
| 176 | .board = QCA9377_HW_1_0_BOARD_DATA_FILE, | ||
| 177 | .board_size = QCA9377_BOARD_DATA_SZ, | ||
| 178 | .board_ext_size = QCA9377_BOARD_EXT_DATA_SZ, | ||
| 179 | }, | ||
| 180 | }, | ||
| 181 | { | ||
| 182 | .id = QCA9377_HW_1_1_DEV_VERSION, | ||
| 183 | .dev_id = QCA9377_1_0_DEVICE_ID, | ||
| 184 | .name = "qca9377 hw1.1", | ||
| 185 | .patch_load_addr = QCA9377_HW_1_0_PATCH_LOAD_ADDR, | ||
| 186 | .uart_pin = 6, | ||
| 187 | .otp_exe_param = 0, | ||
| 188 | .channel_counters_freq_hz = 88000, | ||
| 189 | .max_probe_resp_desc_thres = 0, | ||
| 146 | .fw = { | 190 | .fw = { |
| 147 | .dir = QCA9377_HW_1_0_FW_DIR, | 191 | .dir = QCA9377_HW_1_0_FW_DIR, |
| 148 | .fw = QCA9377_HW_1_0_FW_FILE, | 192 | .fw = QCA9377_HW_1_0_FW_FILE, |
| @@ -1263,7 +1307,8 @@ static int ath10k_init_hw_params(struct ath10k *ar) | |||
| 1263 | for (i = 0; i < ARRAY_SIZE(ath10k_hw_params_list); i++) { | 1307 | for (i = 0; i < ARRAY_SIZE(ath10k_hw_params_list); i++) { |
| 1264 | hw_params = &ath10k_hw_params_list[i]; | 1308 | hw_params = &ath10k_hw_params_list[i]; |
| 1265 | 1309 | ||
| 1266 | if (hw_params->id == ar->target_version) | 1310 | if (hw_params->id == ar->target_version && |
| 1311 | hw_params->dev_id == ar->dev_id) | ||
| 1267 | break; | 1312 | break; |
| 1268 | } | 1313 | } |
| 1269 | 1314 | ||
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 018c64f4fd25..858d75f49a9f 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h | |||
| @@ -636,6 +636,7 @@ struct ath10k { | |||
| 636 | 636 | ||
| 637 | struct ath10k_hw_params { | 637 | struct ath10k_hw_params { |
| 638 | u32 id; | 638 | u32 id; |
| 639 | u16 dev_id; | ||
| 639 | const char *name; | 640 | const char *name; |
| 640 | u32 patch_load_addr; | 641 | u32 patch_load_addr; |
| 641 | int uart_pin; | 642 | int uart_pin; |
diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h index 39966a05c1cc..713c2bcea178 100644 --- a/drivers/net/wireless/ath/ath10k/hw.h +++ b/drivers/net/wireless/ath/ath10k/hw.h | |||
| @@ -22,6 +22,12 @@ | |||
| 22 | 22 | ||
| 23 | #define ATH10K_FW_DIR "ath10k" | 23 | #define ATH10K_FW_DIR "ath10k" |
| 24 | 24 | ||
| 25 | #define QCA988X_2_0_DEVICE_ID (0x003c) | ||
| 26 | #define QCA6164_2_1_DEVICE_ID (0x0041) | ||
| 27 | #define QCA6174_2_1_DEVICE_ID (0x003e) | ||
| 28 | #define QCA99X0_2_0_DEVICE_ID (0x0040) | ||
| 29 | #define QCA9377_1_0_DEVICE_ID (0x0042) | ||
| 30 | |||
| 25 | /* QCA988X 1.0 definitions (unsupported) */ | 31 | /* QCA988X 1.0 definitions (unsupported) */ |
| 26 | #define QCA988X_HW_1_0_CHIP_ID_REV 0x0 | 32 | #define QCA988X_HW_1_0_CHIP_ID_REV 0x0 |
| 27 | 33 | ||
| @@ -42,6 +48,10 @@ | |||
| 42 | #define QCA6174_HW_3_0_VERSION 0x05020000 | 48 | #define QCA6174_HW_3_0_VERSION 0x05020000 |
| 43 | #define QCA6174_HW_3_2_VERSION 0x05030000 | 49 | #define QCA6174_HW_3_2_VERSION 0x05030000 |
| 44 | 50 | ||
| 51 | /* QCA9377 target BMI version signatures */ | ||
| 52 | #define QCA9377_HW_1_0_DEV_VERSION 0x05020000 | ||
| 53 | #define QCA9377_HW_1_1_DEV_VERSION 0x05020001 | ||
| 54 | |||
| 45 | enum qca6174_pci_rev { | 55 | enum qca6174_pci_rev { |
| 46 | QCA6174_PCI_REV_1_1 = 0x11, | 56 | QCA6174_PCI_REV_1_1 = 0x11, |
| 47 | QCA6174_PCI_REV_1_3 = 0x13, | 57 | QCA6174_PCI_REV_1_3 = 0x13, |
| @@ -60,6 +70,11 @@ enum qca6174_chip_id_rev { | |||
| 60 | QCA6174_HW_3_2_CHIP_ID_REV = 10, | 70 | QCA6174_HW_3_2_CHIP_ID_REV = 10, |
| 61 | }; | 71 | }; |
| 62 | 72 | ||
| 73 | enum qca9377_chip_id_rev { | ||
| 74 | QCA9377_HW_1_0_CHIP_ID_REV = 0x0, | ||
| 75 | QCA9377_HW_1_1_CHIP_ID_REV = 0x1, | ||
| 76 | }; | ||
| 77 | |||
| 63 | #define QCA6174_HW_2_1_FW_DIR "ath10k/QCA6174/hw2.1" | 78 | #define QCA6174_HW_2_1_FW_DIR "ath10k/QCA6174/hw2.1" |
| 64 | #define QCA6174_HW_2_1_FW_FILE "firmware.bin" | 79 | #define QCA6174_HW_2_1_FW_FILE "firmware.bin" |
| 65 | #define QCA6174_HW_2_1_OTP_FILE "otp.bin" | 80 | #define QCA6174_HW_2_1_OTP_FILE "otp.bin" |
| @@ -85,8 +100,6 @@ enum qca6174_chip_id_rev { | |||
| 85 | #define QCA99X0_HW_2_0_PATCH_LOAD_ADDR 0x1234 | 100 | #define QCA99X0_HW_2_0_PATCH_LOAD_ADDR 0x1234 |
| 86 | 101 | ||
| 87 | /* QCA9377 1.0 definitions */ | 102 | /* QCA9377 1.0 definitions */ |
| 88 | #define QCA9377_HW_1_0_DEV_VERSION 0x05020001 | ||
| 89 | #define QCA9377_HW_1_0_CHIP_ID_REV 0x1 | ||
| 90 | #define QCA9377_HW_1_0_FW_DIR ATH10K_FW_DIR "/QCA9377/hw1.0" | 103 | #define QCA9377_HW_1_0_FW_DIR ATH10K_FW_DIR "/QCA9377/hw1.0" |
| 91 | #define QCA9377_HW_1_0_FW_FILE "firmware.bin" | 104 | #define QCA9377_HW_1_0_FW_FILE "firmware.bin" |
| 92 | #define QCA9377_HW_1_0_OTP_FILE "otp.bin" | 105 | #define QCA9377_HW_1_0_OTP_FILE "otp.bin" |
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index a7411fe90cc4..95a55405ebf0 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c | |||
| @@ -4225,7 +4225,7 @@ static int ath10k_config(struct ieee80211_hw *hw, u32 changed) | |||
| 4225 | 4225 | ||
| 4226 | static u32 get_nss_from_chainmask(u16 chain_mask) | 4226 | static u32 get_nss_from_chainmask(u16 chain_mask) |
| 4227 | { | 4227 | { |
| 4228 | if ((chain_mask & 0x15) == 0x15) | 4228 | if ((chain_mask & 0xf) == 0xf) |
| 4229 | return 4; | 4229 | return 4; |
| 4230 | else if ((chain_mask & 0x7) == 0x7) | 4230 | else if ((chain_mask & 0x7) == 0x7) |
| 4231 | return 3; | 4231 | return 3; |
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 3fca200b986c..930785a724e1 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c | |||
| @@ -57,12 +57,6 @@ MODULE_PARM_DESC(reset_mode, "0: auto, 1: warm only (default: 0)"); | |||
| 57 | #define ATH10K_PCI_TARGET_WAIT 3000 | 57 | #define ATH10K_PCI_TARGET_WAIT 3000 |
| 58 | #define ATH10K_PCI_NUM_WARM_RESET_ATTEMPTS 3 | 58 | #define ATH10K_PCI_NUM_WARM_RESET_ATTEMPTS 3 |
| 59 | 59 | ||
| 60 | #define QCA988X_2_0_DEVICE_ID (0x003c) | ||
| 61 | #define QCA6164_2_1_DEVICE_ID (0x0041) | ||
| 62 | #define QCA6174_2_1_DEVICE_ID (0x003e) | ||
| 63 | #define QCA99X0_2_0_DEVICE_ID (0x0040) | ||
| 64 | #define QCA9377_1_0_DEVICE_ID (0x0042) | ||
| 65 | |||
| 66 | static const struct pci_device_id ath10k_pci_id_table[] = { | 60 | static const struct pci_device_id ath10k_pci_id_table[] = { |
| 67 | { PCI_VDEVICE(ATHEROS, QCA988X_2_0_DEVICE_ID) }, /* PCI-E QCA988X V2 */ | 61 | { PCI_VDEVICE(ATHEROS, QCA988X_2_0_DEVICE_ID) }, /* PCI-E QCA988X V2 */ |
| 68 | { PCI_VDEVICE(ATHEROS, QCA6164_2_1_DEVICE_ID) }, /* PCI-E QCA6164 V2.1 */ | 62 | { PCI_VDEVICE(ATHEROS, QCA6164_2_1_DEVICE_ID) }, /* PCI-E QCA6164 V2.1 */ |
| @@ -92,7 +86,9 @@ static const struct ath10k_pci_supp_chip ath10k_pci_supp_chips[] = { | |||
| 92 | { QCA6174_2_1_DEVICE_ID, QCA6174_HW_3_2_CHIP_ID_REV }, | 86 | { QCA6174_2_1_DEVICE_ID, QCA6174_HW_3_2_CHIP_ID_REV }, |
| 93 | 87 | ||
| 94 | { QCA99X0_2_0_DEVICE_ID, QCA99X0_HW_2_0_CHIP_ID_REV }, | 88 | { QCA99X0_2_0_DEVICE_ID, QCA99X0_HW_2_0_CHIP_ID_REV }, |
| 89 | |||
| 95 | { QCA9377_1_0_DEVICE_ID, QCA9377_HW_1_0_CHIP_ID_REV }, | 90 | { QCA9377_1_0_DEVICE_ID, QCA9377_HW_1_0_CHIP_ID_REV }, |
| 91 | { QCA9377_1_0_DEVICE_ID, QCA9377_HW_1_1_CHIP_ID_REV }, | ||
| 96 | }; | 92 | }; |
| 97 | 93 | ||
| 98 | static void ath10k_pci_buffer_cleanup(struct ath10k *ar); | 94 | static void ath10k_pci_buffer_cleanup(struct ath10k *ar); |
| @@ -111,8 +107,9 @@ static void ath10k_pci_htc_tx_cb(struct ath10k_ce_pipe *ce_state); | |||
| 111 | static void ath10k_pci_htc_rx_cb(struct ath10k_ce_pipe *ce_state); | 107 | static void ath10k_pci_htc_rx_cb(struct ath10k_ce_pipe *ce_state); |
| 112 | static void ath10k_pci_htt_tx_cb(struct ath10k_ce_pipe *ce_state); | 108 | static void ath10k_pci_htt_tx_cb(struct ath10k_ce_pipe *ce_state); |
| 113 | static void ath10k_pci_htt_rx_cb(struct ath10k_ce_pipe *ce_state); | 109 | static void ath10k_pci_htt_rx_cb(struct ath10k_ce_pipe *ce_state); |
| 110 | static void ath10k_pci_htt_htc_rx_cb(struct ath10k_ce_pipe *ce_state); | ||
| 114 | 111 | ||
| 115 | static const struct ce_attr host_ce_config_wlan[] = { | 112 | static struct ce_attr host_ce_config_wlan[] = { |
| 116 | /* CE0: host->target HTC control and raw streams */ | 113 | /* CE0: host->target HTC control and raw streams */ |
| 117 | { | 114 | { |
| 118 | .flags = CE_ATTR_FLAGS, | 115 | .flags = CE_ATTR_FLAGS, |
| @@ -128,7 +125,7 @@ static const struct ce_attr host_ce_config_wlan[] = { | |||
| 128 | .src_nentries = 0, | 125 | .src_nentries = 0, |
| 129 | .src_sz_max = 2048, | 126 | .src_sz_max = 2048, |
| 130 | .dest_nentries = 512, | 127 | .dest_nentries = 512, |
| 131 | .recv_cb = ath10k_pci_htc_rx_cb, | 128 | .recv_cb = ath10k_pci_htt_htc_rx_cb, |
| 132 | }, | 129 | }, |
| 133 | 130 | ||
| 134 | /* CE2: target->host WMI */ | 131 | /* CE2: target->host WMI */ |
| @@ -217,7 +214,7 @@ static const struct ce_attr host_ce_config_wlan[] = { | |||
| 217 | }; | 214 | }; |
| 218 | 215 | ||
| 219 | /* Target firmware's Copy Engine configuration. */ | 216 | /* Target firmware's Copy Engine configuration. */ |
| 220 | static const struct ce_pipe_config target_ce_config_wlan[] = { | 217 | static struct ce_pipe_config target_ce_config_wlan[] = { |
| 221 | /* CE0: host->target HTC control and raw streams */ | 218 | /* CE0: host->target HTC control and raw streams */ |
| 222 | { | 219 | { |
| 223 | .pipenum = __cpu_to_le32(0), | 220 | .pipenum = __cpu_to_le32(0), |
| @@ -330,7 +327,7 @@ static const struct ce_pipe_config target_ce_config_wlan[] = { | |||
| 330 | * This table is derived from the CE_PCI TABLE, above. | 327 | * This table is derived from the CE_PCI TABLE, above. |
| 331 | * It is passed to the Target at startup for use by firmware. | 328 | * It is passed to the Target at startup for use by firmware. |
| 332 | */ | 329 | */ |
| 333 | static const struct service_to_pipe target_service_to_ce_map_wlan[] = { | 330 | static struct service_to_pipe target_service_to_ce_map_wlan[] = { |
| 334 | { | 331 | { |
| 335 | __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VO), | 332 | __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VO), |
| 336 | __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ | 333 | __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ |
| @@ -1208,6 +1205,16 @@ static void ath10k_pci_htc_rx_cb(struct ath10k_ce_pipe *ce_state) | |||
| 1208 | ath10k_pci_process_rx_cb(ce_state, ath10k_htc_rx_completion_handler); | 1205 | ath10k_pci_process_rx_cb(ce_state, ath10k_htc_rx_completion_handler); |
| 1209 | } | 1206 | } |
| 1210 | 1207 | ||
| 1208 | static void ath10k_pci_htt_htc_rx_cb(struct ath10k_ce_pipe *ce_state) | ||
| 1209 | { | ||
| 1210 | /* CE4 polling needs to be done whenever CE pipe which transports | ||
| 1211 | * HTT Rx (target->host) is processed. | ||
| 1212 | */ | ||
| 1213 | ath10k_ce_per_engine_service(ce_state->ar, 4); | ||
| 1214 | |||
| 1215 | ath10k_pci_process_rx_cb(ce_state, ath10k_htc_rx_completion_handler); | ||
| 1216 | } | ||
| 1217 | |||
| 1211 | /* Called by lower (CE) layer when a send to HTT Target completes. */ | 1218 | /* Called by lower (CE) layer when a send to HTT Target completes. */ |
| 1212 | static void ath10k_pci_htt_tx_cb(struct ath10k_ce_pipe *ce_state) | 1219 | static void ath10k_pci_htt_tx_cb(struct ath10k_ce_pipe *ce_state) |
| 1213 | { | 1220 | { |
| @@ -2027,6 +2034,29 @@ static int ath10k_pci_init_config(struct ath10k *ar) | |||
| 2027 | return 0; | 2034 | return 0; |
| 2028 | } | 2035 | } |
| 2029 | 2036 | ||
| 2037 | static void ath10k_pci_override_ce_config(struct ath10k *ar) | ||
| 2038 | { | ||
| 2039 | struct ce_attr *attr; | ||
| 2040 | struct ce_pipe_config *config; | ||
| 2041 | |||
| 2042 | /* For QCA6174 we're overriding the Copy Engine 5 configuration, | ||
| 2043 | * since it is currently used for other feature. | ||
| 2044 | */ | ||
| 2045 | |||
| 2046 | /* Override Host's Copy Engine 5 configuration */ | ||
| 2047 | attr = &host_ce_config_wlan[5]; | ||
| 2048 | attr->src_sz_max = 0; | ||
| 2049 | attr->dest_nentries = 0; | ||
| 2050 | |||
| 2051 | /* Override Target firmware's Copy Engine configuration */ | ||
| 2052 | config = &target_ce_config_wlan[5]; | ||
| 2053 | config->pipedir = __cpu_to_le32(PIPEDIR_OUT); | ||
| 2054 | config->nbytes_max = __cpu_to_le32(2048); | ||
| 2055 | |||
| 2056 | /* Map from service/endpoint to Copy Engine */ | ||
| 2057 | target_service_to_ce_map_wlan[15].pipenum = __cpu_to_le32(1); | ||
| 2058 | } | ||
| 2059 | |||
| 2030 | static int ath10k_pci_alloc_pipes(struct ath10k *ar) | 2060 | static int ath10k_pci_alloc_pipes(struct ath10k *ar) |
| 2031 | { | 2061 | { |
| 2032 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | 2062 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); |
| @@ -3020,6 +3050,9 @@ static int ath10k_pci_probe(struct pci_dev *pdev, | |||
| 3020 | goto err_core_destroy; | 3050 | goto err_core_destroy; |
| 3021 | } | 3051 | } |
| 3022 | 3052 | ||
| 3053 | if (QCA_REV_6174(ar)) | ||
| 3054 | ath10k_pci_override_ce_config(ar); | ||
| 3055 | |||
| 3023 | ret = ath10k_pci_alloc_pipes(ar); | 3056 | ret = ath10k_pci_alloc_pipes(ar); |
| 3024 | if (ret) { | 3057 | if (ret) { |
| 3025 | ath10k_err(ar, "failed to allocate copy engine pipes: %d\n", | 3058 | ath10k_err(ar, "failed to allocate copy engine pipes: %d\n", |
diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c index 1a73c7a1da77..bf88ec3a65fa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-7000.c +++ b/drivers/net/wireless/iwlwifi/iwl-7000.c | |||
| @@ -69,7 +69,7 @@ | |||
| 69 | #include "iwl-agn-hw.h" | 69 | #include "iwl-agn-hw.h" |
| 70 | 70 | ||
| 71 | /* Highest firmware API version supported */ | 71 | /* Highest firmware API version supported */ |
| 72 | #define IWL7260_UCODE_API_MAX 17 | 72 | #define IWL7260_UCODE_API_MAX 19 |
| 73 | 73 | ||
| 74 | /* Oldest version we won't warn about */ | 74 | /* Oldest version we won't warn about */ |
| 75 | #define IWL7260_UCODE_API_OK 13 | 75 | #define IWL7260_UCODE_API_OK 13 |
diff --git a/drivers/net/wireless/iwlwifi/iwl-8000.c b/drivers/net/wireless/iwlwifi/iwl-8000.c index 0116e5a4c393..9bcc0bf937d8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-8000.c +++ b/drivers/net/wireless/iwlwifi/iwl-8000.c | |||
| @@ -69,7 +69,7 @@ | |||
| 69 | #include "iwl-agn-hw.h" | 69 | #include "iwl-agn-hw.h" |
| 70 | 70 | ||
| 71 | /* Highest firmware API version supported */ | 71 | /* Highest firmware API version supported */ |
| 72 | #define IWL8000_UCODE_API_MAX 17 | 72 | #define IWL8000_UCODE_API_MAX 19 |
| 73 | 73 | ||
| 74 | /* Oldest version we won't warn about */ | 74 | /* Oldest version we won't warn about */ |
| 75 | #define IWL8000_UCODE_API_OK 13 | 75 | #define IWL8000_UCODE_API_OK 13 |
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c index 85ae902df7c0..29ae58ebf223 100644 --- a/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/iwlwifi/mvm/d3.c | |||
| @@ -309,9 +309,9 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw, | |||
| 309 | * to transmit packets to the AP, i.e. the PTK. | 309 | * to transmit packets to the AP, i.e. the PTK. |
| 310 | */ | 310 | */ |
| 311 | if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { | 311 | if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { |
| 312 | key->hw_key_idx = 0; | ||
| 313 | mvm->ptk_ivlen = key->iv_len; | 312 | mvm->ptk_ivlen = key->iv_len; |
| 314 | mvm->ptk_icvlen = key->icv_len; | 313 | mvm->ptk_icvlen = key->icv_len; |
| 314 | ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, 0); | ||
| 315 | } else { | 315 | } else { |
| 316 | /* | 316 | /* |
| 317 | * firmware only supports TSC/RSC for a single key, | 317 | * firmware only supports TSC/RSC for a single key, |
| @@ -319,12 +319,11 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw, | |||
| 319 | * with new ones -- this relies on mac80211 doing | 319 | * with new ones -- this relies on mac80211 doing |
| 320 | * list_add_tail(). | 320 | * list_add_tail(). |
| 321 | */ | 321 | */ |
| 322 | key->hw_key_idx = 1; | ||
| 323 | mvm->gtk_ivlen = key->iv_len; | 322 | mvm->gtk_ivlen = key->iv_len; |
| 324 | mvm->gtk_icvlen = key->icv_len; | 323 | mvm->gtk_icvlen = key->icv_len; |
| 324 | ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, 1); | ||
| 325 | } | 325 | } |
| 326 | 326 | ||
| 327 | ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, true); | ||
| 328 | data->error = ret != 0; | 327 | data->error = ret != 0; |
| 329 | out_unlock: | 328 | out_unlock: |
| 330 | mutex_unlock(&mvm->mutex); | 329 | mutex_unlock(&mvm->mutex); |
| @@ -772,9 +771,6 @@ static int iwl_mvm_switch_to_d3(struct iwl_mvm *mvm) | |||
| 772 | */ | 771 | */ |
| 773 | set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status); | 772 | set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status); |
| 774 | 773 | ||
| 775 | /* We reprogram keys and shouldn't allocate new key indices */ | ||
| 776 | memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table)); | ||
| 777 | |||
| 778 | mvm->ptk_ivlen = 0; | 774 | mvm->ptk_ivlen = 0; |
| 779 | mvm->ptk_icvlen = 0; | 775 | mvm->ptk_icvlen = 0; |
| 780 | mvm->ptk_ivlen = 0; | 776 | mvm->ptk_ivlen = 0; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 1fb684693040..e88afac51c5d 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c | |||
| @@ -2941,6 +2941,7 @@ static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw, | |||
| 2941 | { | 2941 | { |
| 2942 | struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); | 2942 | struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); |
| 2943 | int ret; | 2943 | int ret; |
| 2944 | u8 key_offset; | ||
| 2944 | 2945 | ||
| 2945 | if (iwlwifi_mod_params.sw_crypto) { | 2946 | if (iwlwifi_mod_params.sw_crypto) { |
| 2946 | IWL_DEBUG_MAC80211(mvm, "leave - hwcrypto disabled\n"); | 2947 | IWL_DEBUG_MAC80211(mvm, "leave - hwcrypto disabled\n"); |
| @@ -3006,10 +3007,14 @@ static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw, | |||
| 3006 | break; | 3007 | break; |
| 3007 | } | 3008 | } |
| 3008 | 3009 | ||
| 3010 | /* in HW restart reuse the index, otherwise request a new one */ | ||
| 3011 | if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) | ||
| 3012 | key_offset = key->hw_key_idx; | ||
| 3013 | else | ||
| 3014 | key_offset = STA_KEY_IDX_INVALID; | ||
| 3015 | |||
| 3009 | IWL_DEBUG_MAC80211(mvm, "set hwcrypto key\n"); | 3016 | IWL_DEBUG_MAC80211(mvm, "set hwcrypto key\n"); |
| 3010 | ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, | 3017 | ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, key_offset); |
| 3011 | test_bit(IWL_MVM_STATUS_IN_HW_RESTART, | ||
| 3012 | &mvm->status)); | ||
| 3013 | if (ret) { | 3018 | if (ret) { |
| 3014 | IWL_WARN(mvm, "set key failed\n"); | 3019 | IWL_WARN(mvm, "set key failed\n"); |
| 3015 | /* | 3020 | /* |
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index 300a249486e4..354acbde088e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c | |||
| @@ -1201,7 +1201,8 @@ static int iwl_mvm_set_fw_key_idx(struct iwl_mvm *mvm) | |||
| 1201 | return max_offs; | 1201 | return max_offs; |
| 1202 | } | 1202 | } |
| 1203 | 1203 | ||
| 1204 | static u8 iwl_mvm_get_key_sta_id(struct ieee80211_vif *vif, | 1204 | static u8 iwl_mvm_get_key_sta_id(struct iwl_mvm *mvm, |
| 1205 | struct ieee80211_vif *vif, | ||
| 1205 | struct ieee80211_sta *sta) | 1206 | struct ieee80211_sta *sta) |
| 1206 | { | 1207 | { |
| 1207 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 1208 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
| @@ -1218,8 +1219,21 @@ static u8 iwl_mvm_get_key_sta_id(struct ieee80211_vif *vif, | |||
| 1218 | * station ID, then use AP's station ID. | 1219 | * station ID, then use AP's station ID. |
| 1219 | */ | 1220 | */ |
| 1220 | if (vif->type == NL80211_IFTYPE_STATION && | 1221 | if (vif->type == NL80211_IFTYPE_STATION && |
| 1221 | mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) | 1222 | mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) { |
| 1222 | return mvmvif->ap_sta_id; | 1223 | u8 sta_id = mvmvif->ap_sta_id; |
| 1224 | |||
| 1225 | sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id], | ||
| 1226 | lockdep_is_held(&mvm->mutex)); | ||
| 1227 | /* | ||
| 1228 | * It is possible that the 'sta' parameter is NULL, | ||
| 1229 | * for example when a GTK is removed - the sta_id will then | ||
| 1230 | * be the AP ID, and no station was passed by mac80211. | ||
| 1231 | */ | ||
| 1232 | if (IS_ERR_OR_NULL(sta)) | ||
| 1233 | return IWL_MVM_STATION_COUNT; | ||
| 1234 | |||
| 1235 | return sta_id; | ||
| 1236 | } | ||
| 1223 | 1237 | ||
| 1224 | return IWL_MVM_STATION_COUNT; | 1238 | return IWL_MVM_STATION_COUNT; |
| 1225 | } | 1239 | } |
| @@ -1227,7 +1241,8 @@ static u8 iwl_mvm_get_key_sta_id(struct ieee80211_vif *vif, | |||
| 1227 | static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm, | 1241 | static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm, |
| 1228 | struct iwl_mvm_sta *mvm_sta, | 1242 | struct iwl_mvm_sta *mvm_sta, |
| 1229 | struct ieee80211_key_conf *keyconf, bool mcast, | 1243 | struct ieee80211_key_conf *keyconf, bool mcast, |
| 1230 | u32 tkip_iv32, u16 *tkip_p1k, u32 cmd_flags) | 1244 | u32 tkip_iv32, u16 *tkip_p1k, u32 cmd_flags, |
| 1245 | u8 key_offset) | ||
| 1231 | { | 1246 | { |
| 1232 | struct iwl_mvm_add_sta_key_cmd cmd = {}; | 1247 | struct iwl_mvm_add_sta_key_cmd cmd = {}; |
| 1233 | __le16 key_flags; | 1248 | __le16 key_flags; |
| @@ -1269,7 +1284,7 @@ static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm, | |||
| 1269 | if (mcast) | 1284 | if (mcast) |
| 1270 | key_flags |= cpu_to_le16(STA_KEY_MULTICAST); | 1285 | key_flags |= cpu_to_le16(STA_KEY_MULTICAST); |
| 1271 | 1286 | ||
| 1272 | cmd.key_offset = keyconf->hw_key_idx; | 1287 | cmd.key_offset = key_offset; |
| 1273 | cmd.key_flags = key_flags; | 1288 | cmd.key_flags = key_flags; |
| 1274 | cmd.sta_id = sta_id; | 1289 | cmd.sta_id = sta_id; |
| 1275 | 1290 | ||
| @@ -1360,6 +1375,7 @@ static int __iwl_mvm_set_sta_key(struct iwl_mvm *mvm, | |||
| 1360 | struct ieee80211_vif *vif, | 1375 | struct ieee80211_vif *vif, |
| 1361 | struct ieee80211_sta *sta, | 1376 | struct ieee80211_sta *sta, |
| 1362 | struct ieee80211_key_conf *keyconf, | 1377 | struct ieee80211_key_conf *keyconf, |
| 1378 | u8 key_offset, | ||
| 1363 | bool mcast) | 1379 | bool mcast) |
| 1364 | { | 1380 | { |
| 1365 | struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta); | 1381 | struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta); |
| @@ -1375,17 +1391,17 @@ static int __iwl_mvm_set_sta_key(struct iwl_mvm *mvm, | |||
| 1375 | ieee80211_get_key_rx_seq(keyconf, 0, &seq); | 1391 | ieee80211_get_key_rx_seq(keyconf, 0, &seq); |
| 1376 | ieee80211_get_tkip_rx_p1k(keyconf, addr, seq.tkip.iv32, p1k); | 1392 | ieee80211_get_tkip_rx_p1k(keyconf, addr, seq.tkip.iv32, p1k); |
| 1377 | ret = iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, mcast, | 1393 | ret = iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, mcast, |
| 1378 | seq.tkip.iv32, p1k, 0); | 1394 | seq.tkip.iv32, p1k, 0, key_offset); |
| 1379 | break; | 1395 | break; |
| 1380 | case WLAN_CIPHER_SUITE_CCMP: | 1396 | case WLAN_CIPHER_SUITE_CCMP: |
| 1381 | case WLAN_CIPHER_SUITE_WEP40: | 1397 | case WLAN_CIPHER_SUITE_WEP40: |
| 1382 | case WLAN_CIPHER_SUITE_WEP104: | 1398 | case WLAN_CIPHER_SUITE_WEP104: |
| 1383 | ret = iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, mcast, | 1399 | ret = iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, mcast, |
| 1384 | 0, NULL, 0); | 1400 | 0, NULL, 0, key_offset); |
| 1385 | break; | 1401 | break; |
| 1386 | default: | 1402 | default: |
| 1387 | ret = iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, mcast, | 1403 | ret = iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, mcast, |
| 1388 | 0, NULL, 0); | 1404 | 0, NULL, 0, key_offset); |
| 1389 | } | 1405 | } |
| 1390 | 1406 | ||
| 1391 | return ret; | 1407 | return ret; |
| @@ -1433,7 +1449,7 @@ int iwl_mvm_set_sta_key(struct iwl_mvm *mvm, | |||
| 1433 | struct ieee80211_vif *vif, | 1449 | struct ieee80211_vif *vif, |
| 1434 | struct ieee80211_sta *sta, | 1450 | struct ieee80211_sta *sta, |
| 1435 | struct ieee80211_key_conf *keyconf, | 1451 | struct ieee80211_key_conf *keyconf, |
| 1436 | bool have_key_offset) | 1452 | u8 key_offset) |
| 1437 | { | 1453 | { |
| 1438 | bool mcast = !(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE); | 1454 | bool mcast = !(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE); |
| 1439 | u8 sta_id; | 1455 | u8 sta_id; |
| @@ -1443,7 +1459,7 @@ int iwl_mvm_set_sta_key(struct iwl_mvm *mvm, | |||
| 1443 | lockdep_assert_held(&mvm->mutex); | 1459 | lockdep_assert_held(&mvm->mutex); |
| 1444 | 1460 | ||
| 1445 | /* Get the station id from the mvm local station table */ | 1461 | /* Get the station id from the mvm local station table */ |
| 1446 | sta_id = iwl_mvm_get_key_sta_id(vif, sta); | 1462 | sta_id = iwl_mvm_get_key_sta_id(mvm, vif, sta); |
| 1447 | if (sta_id == IWL_MVM_STATION_COUNT) { | 1463 | if (sta_id == IWL_MVM_STATION_COUNT) { |
| 1448 | IWL_ERR(mvm, "Failed to find station id\n"); | 1464 | IWL_ERR(mvm, "Failed to find station id\n"); |
| 1449 | return -EINVAL; | 1465 | return -EINVAL; |
| @@ -1470,18 +1486,25 @@ int iwl_mvm_set_sta_key(struct iwl_mvm *mvm, | |||
| 1470 | if (WARN_ON_ONCE(iwl_mvm_sta_from_mac80211(sta)->vif != vif)) | 1486 | if (WARN_ON_ONCE(iwl_mvm_sta_from_mac80211(sta)->vif != vif)) |
| 1471 | return -EINVAL; | 1487 | return -EINVAL; |
| 1472 | 1488 | ||
| 1473 | if (!have_key_offset) { | 1489 | /* If the key_offset is not pre-assigned, we need to find a |
| 1474 | /* | 1490 | * new offset to use. In normal cases, the offset is not |
| 1475 | * The D3 firmware hardcodes the PTK offset to 0, so we have to | 1491 | * pre-assigned, but during HW_RESTART we want to reuse the |
| 1476 | * configure it there. As a result, this workaround exists to | 1492 | * same indices, so we pass them when this function is called. |
| 1477 | * let the caller set the key offset (hw_key_idx), see d3.c. | 1493 | * |
| 1478 | */ | 1494 | * In D3 entry, we need to hardcoded the indices (because the |
| 1479 | keyconf->hw_key_idx = iwl_mvm_set_fw_key_idx(mvm); | 1495 | * firmware hardcodes the PTK offset to 0). In this case, we |
| 1480 | if (keyconf->hw_key_idx == STA_KEY_IDX_INVALID) | 1496 | * need to make sure we don't overwrite the hw_key_idx in the |
| 1497 | * keyconf structure, because otherwise we cannot configure | ||
| 1498 | * the original ones back when resuming. | ||
| 1499 | */ | ||
| 1500 | if (key_offset == STA_KEY_IDX_INVALID) { | ||
| 1501 | key_offset = iwl_mvm_set_fw_key_idx(mvm); | ||
| 1502 | if (key_offset == STA_KEY_IDX_INVALID) | ||
| 1481 | return -ENOSPC; | 1503 | return -ENOSPC; |
| 1504 | keyconf->hw_key_idx = key_offset; | ||
| 1482 | } | 1505 | } |
| 1483 | 1506 | ||
| 1484 | ret = __iwl_mvm_set_sta_key(mvm, vif, sta, keyconf, mcast); | 1507 | ret = __iwl_mvm_set_sta_key(mvm, vif, sta, keyconf, key_offset, mcast); |
| 1485 | if (ret) { | 1508 | if (ret) { |
| 1486 | __clear_bit(keyconf->hw_key_idx, mvm->fw_key_table); | 1509 | __clear_bit(keyconf->hw_key_idx, mvm->fw_key_table); |
| 1487 | goto end; | 1510 | goto end; |
| @@ -1495,7 +1518,8 @@ int iwl_mvm_set_sta_key(struct iwl_mvm *mvm, | |||
| 1495 | */ | 1518 | */ |
| 1496 | if (keyconf->cipher == WLAN_CIPHER_SUITE_WEP40 || | 1519 | if (keyconf->cipher == WLAN_CIPHER_SUITE_WEP40 || |
| 1497 | keyconf->cipher == WLAN_CIPHER_SUITE_WEP104) { | 1520 | keyconf->cipher == WLAN_CIPHER_SUITE_WEP104) { |
| 1498 | ret = __iwl_mvm_set_sta_key(mvm, vif, sta, keyconf, !mcast); | 1521 | ret = __iwl_mvm_set_sta_key(mvm, vif, sta, keyconf, |
| 1522 | key_offset, !mcast); | ||
| 1499 | if (ret) { | 1523 | if (ret) { |
| 1500 | __clear_bit(keyconf->hw_key_idx, mvm->fw_key_table); | 1524 | __clear_bit(keyconf->hw_key_idx, mvm->fw_key_table); |
| 1501 | __iwl_mvm_remove_sta_key(mvm, sta_id, keyconf, mcast); | 1525 | __iwl_mvm_remove_sta_key(mvm, sta_id, keyconf, mcast); |
| @@ -1521,7 +1545,7 @@ int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm, | |||
| 1521 | lockdep_assert_held(&mvm->mutex); | 1545 | lockdep_assert_held(&mvm->mutex); |
| 1522 | 1546 | ||
| 1523 | /* Get the station id from the mvm local station table */ | 1547 | /* Get the station id from the mvm local station table */ |
| 1524 | sta_id = iwl_mvm_get_key_sta_id(vif, sta); | 1548 | sta_id = iwl_mvm_get_key_sta_id(mvm, vif, sta); |
| 1525 | 1549 | ||
| 1526 | IWL_DEBUG_WEP(mvm, "mvm remove dynamic key: idx=%d sta=%d\n", | 1550 | IWL_DEBUG_WEP(mvm, "mvm remove dynamic key: idx=%d sta=%d\n", |
| 1527 | keyconf->keyidx, sta_id); | 1551 | keyconf->keyidx, sta_id); |
| @@ -1547,24 +1571,6 @@ int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm, | |||
| 1547 | return 0; | 1571 | return 0; |
| 1548 | } | 1572 | } |
| 1549 | 1573 | ||
| 1550 | /* | ||
| 1551 | * It is possible that the 'sta' parameter is NULL, and thus | ||
| 1552 | * there is a need to retrieve the sta from the local station table, | ||
| 1553 | * for example when a GTK is removed (where the sta_id will then be | ||
| 1554 | * the AP ID, and no station was passed by mac80211.) | ||
| 1555 | */ | ||
| 1556 | if (!sta) { | ||
| 1557 | sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id], | ||
| 1558 | lockdep_is_held(&mvm->mutex)); | ||
| 1559 | if (!sta) { | ||
| 1560 | IWL_ERR(mvm, "Invalid station id\n"); | ||
| 1561 | return -EINVAL; | ||
| 1562 | } | ||
| 1563 | } | ||
| 1564 | |||
| 1565 | if (WARN_ON_ONCE(iwl_mvm_sta_from_mac80211(sta)->vif != vif)) | ||
| 1566 | return -EINVAL; | ||
| 1567 | |||
| 1568 | ret = __iwl_mvm_remove_sta_key(mvm, sta_id, keyconf, mcast); | 1574 | ret = __iwl_mvm_remove_sta_key(mvm, sta_id, keyconf, mcast); |
| 1569 | if (ret) | 1575 | if (ret) |
| 1570 | return ret; | 1576 | return ret; |
| @@ -1584,7 +1590,7 @@ void iwl_mvm_update_tkip_key(struct iwl_mvm *mvm, | |||
| 1584 | u16 *phase1key) | 1590 | u16 *phase1key) |
| 1585 | { | 1591 | { |
| 1586 | struct iwl_mvm_sta *mvm_sta; | 1592 | struct iwl_mvm_sta *mvm_sta; |
| 1587 | u8 sta_id = iwl_mvm_get_key_sta_id(vif, sta); | 1593 | u8 sta_id = iwl_mvm_get_key_sta_id(mvm, vif, sta); |
| 1588 | bool mcast = !(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE); | 1594 | bool mcast = !(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE); |
| 1589 | 1595 | ||
| 1590 | if (WARN_ON_ONCE(sta_id == IWL_MVM_STATION_COUNT)) | 1596 | if (WARN_ON_ONCE(sta_id == IWL_MVM_STATION_COUNT)) |
| @@ -1602,7 +1608,7 @@ void iwl_mvm_update_tkip_key(struct iwl_mvm *mvm, | |||
| 1602 | 1608 | ||
| 1603 | mvm_sta = iwl_mvm_sta_from_mac80211(sta); | 1609 | mvm_sta = iwl_mvm_sta_from_mac80211(sta); |
| 1604 | iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, mcast, | 1610 | iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, mcast, |
| 1605 | iv32, phase1key, CMD_ASYNC); | 1611 | iv32, phase1key, CMD_ASYNC, keyconf->hw_key_idx); |
| 1606 | rcu_read_unlock(); | 1612 | rcu_read_unlock(); |
| 1607 | } | 1613 | } |
| 1608 | 1614 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.h b/drivers/net/wireless/iwlwifi/mvm/sta.h index eedb215eba3f..0631cc0a6d3c 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.h +++ b/drivers/net/wireless/iwlwifi/mvm/sta.h | |||
| @@ -365,8 +365,8 @@ int iwl_mvm_rm_sta_id(struct iwl_mvm *mvm, | |||
| 365 | int iwl_mvm_set_sta_key(struct iwl_mvm *mvm, | 365 | int iwl_mvm_set_sta_key(struct iwl_mvm *mvm, |
| 366 | struct ieee80211_vif *vif, | 366 | struct ieee80211_vif *vif, |
| 367 | struct ieee80211_sta *sta, | 367 | struct ieee80211_sta *sta, |
| 368 | struct ieee80211_key_conf *key, | 368 | struct ieee80211_key_conf *keyconf, |
| 369 | bool have_key_offset); | 369 | u8 key_offset); |
| 370 | int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm, | 370 | int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm, |
| 371 | struct ieee80211_vif *vif, | 371 | struct ieee80211_vif *vif, |
| 372 | struct ieee80211_sta *sta, | 372 | struct ieee80211_sta *sta, |
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c index 644b58bc5226..639761fb2bfb 100644 --- a/drivers/net/wireless/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/iwlwifi/pcie/drv.c | |||
| @@ -423,14 +423,21 @@ static const struct pci_device_id iwl_hw_card_ids[] = { | |||
| 423 | /* 8000 Series */ | 423 | /* 8000 Series */ |
| 424 | {IWL_PCI_DEVICE(0x24F3, 0x0010, iwl8260_2ac_cfg)}, | 424 | {IWL_PCI_DEVICE(0x24F3, 0x0010, iwl8260_2ac_cfg)}, |
| 425 | {IWL_PCI_DEVICE(0x24F3, 0x1010, iwl8260_2ac_cfg)}, | 425 | {IWL_PCI_DEVICE(0x24F3, 0x1010, iwl8260_2ac_cfg)}, |
| 426 | {IWL_PCI_DEVICE(0x24F3, 0x0130, iwl8260_2ac_cfg)}, | ||
| 427 | {IWL_PCI_DEVICE(0x24F3, 0x1130, iwl8260_2ac_cfg)}, | ||
| 428 | {IWL_PCI_DEVICE(0x24F3, 0x0132, iwl8260_2ac_cfg)}, | ||
| 429 | {IWL_PCI_DEVICE(0x24F3, 0x1132, iwl8260_2ac_cfg)}, | ||
| 426 | {IWL_PCI_DEVICE(0x24F3, 0x0110, iwl8260_2ac_cfg)}, | 430 | {IWL_PCI_DEVICE(0x24F3, 0x0110, iwl8260_2ac_cfg)}, |
| 431 | {IWL_PCI_DEVICE(0x24F3, 0x01F0, iwl8260_2ac_cfg)}, | ||
| 432 | {IWL_PCI_DEVICE(0x24F3, 0x0012, iwl8260_2ac_cfg)}, | ||
| 433 | {IWL_PCI_DEVICE(0x24F3, 0x1012, iwl8260_2ac_cfg)}, | ||
| 427 | {IWL_PCI_DEVICE(0x24F3, 0x1110, iwl8260_2ac_cfg)}, | 434 | {IWL_PCI_DEVICE(0x24F3, 0x1110, iwl8260_2ac_cfg)}, |
| 428 | {IWL_PCI_DEVICE(0x24F3, 0x0050, iwl8260_2ac_cfg)}, | 435 | {IWL_PCI_DEVICE(0x24F3, 0x0050, iwl8260_2ac_cfg)}, |
| 429 | {IWL_PCI_DEVICE(0x24F3, 0x0250, iwl8260_2ac_cfg)}, | 436 | {IWL_PCI_DEVICE(0x24F3, 0x0250, iwl8260_2ac_cfg)}, |
| 430 | {IWL_PCI_DEVICE(0x24F3, 0x1050, iwl8260_2ac_cfg)}, | 437 | {IWL_PCI_DEVICE(0x24F3, 0x1050, iwl8260_2ac_cfg)}, |
| 431 | {IWL_PCI_DEVICE(0x24F3, 0x0150, iwl8260_2ac_cfg)}, | 438 | {IWL_PCI_DEVICE(0x24F3, 0x0150, iwl8260_2ac_cfg)}, |
| 439 | {IWL_PCI_DEVICE(0x24F3, 0x1150, iwl8260_2ac_cfg)}, | ||
| 432 | {IWL_PCI_DEVICE(0x24F4, 0x0030, iwl8260_2ac_cfg)}, | 440 | {IWL_PCI_DEVICE(0x24F4, 0x0030, iwl8260_2ac_cfg)}, |
| 433 | {IWL_PCI_DEVICE(0x24F4, 0x1130, iwl8260_2ac_cfg)}, | ||
| 434 | {IWL_PCI_DEVICE(0x24F4, 0x1030, iwl8260_2ac_cfg)}, | 441 | {IWL_PCI_DEVICE(0x24F4, 0x1030, iwl8260_2ac_cfg)}, |
| 435 | {IWL_PCI_DEVICE(0x24F3, 0xC010, iwl8260_2ac_cfg)}, | 442 | {IWL_PCI_DEVICE(0x24F3, 0xC010, iwl8260_2ac_cfg)}, |
| 436 | {IWL_PCI_DEVICE(0x24F3, 0xC110, iwl8260_2ac_cfg)}, | 443 | {IWL_PCI_DEVICE(0x24F3, 0xC110, iwl8260_2ac_cfg)}, |
| @@ -438,18 +445,28 @@ static const struct pci_device_id iwl_hw_card_ids[] = { | |||
| 438 | {IWL_PCI_DEVICE(0x24F3, 0xC050, iwl8260_2ac_cfg)}, | 445 | {IWL_PCI_DEVICE(0x24F3, 0xC050, iwl8260_2ac_cfg)}, |
| 439 | {IWL_PCI_DEVICE(0x24F3, 0xD050, iwl8260_2ac_cfg)}, | 446 | {IWL_PCI_DEVICE(0x24F3, 0xD050, iwl8260_2ac_cfg)}, |
| 440 | {IWL_PCI_DEVICE(0x24F3, 0x8010, iwl8260_2ac_cfg)}, | 447 | {IWL_PCI_DEVICE(0x24F3, 0x8010, iwl8260_2ac_cfg)}, |
| 448 | {IWL_PCI_DEVICE(0x24F3, 0x8110, iwl8260_2ac_cfg)}, | ||
| 441 | {IWL_PCI_DEVICE(0x24F3, 0x9010, iwl8260_2ac_cfg)}, | 449 | {IWL_PCI_DEVICE(0x24F3, 0x9010, iwl8260_2ac_cfg)}, |
| 450 | {IWL_PCI_DEVICE(0x24F3, 0x9110, iwl8260_2ac_cfg)}, | ||
| 442 | {IWL_PCI_DEVICE(0x24F4, 0x8030, iwl8260_2ac_cfg)}, | 451 | {IWL_PCI_DEVICE(0x24F4, 0x8030, iwl8260_2ac_cfg)}, |
| 443 | {IWL_PCI_DEVICE(0x24F4, 0x9030, iwl8260_2ac_cfg)}, | 452 | {IWL_PCI_DEVICE(0x24F4, 0x9030, iwl8260_2ac_cfg)}, |
| 453 | {IWL_PCI_DEVICE(0x24F3, 0x8130, iwl8260_2ac_cfg)}, | ||
| 454 | {IWL_PCI_DEVICE(0x24F3, 0x9130, iwl8260_2ac_cfg)}, | ||
| 455 | {IWL_PCI_DEVICE(0x24F3, 0x8132, iwl8260_2ac_cfg)}, | ||
| 456 | {IWL_PCI_DEVICE(0x24F3, 0x9132, iwl8260_2ac_cfg)}, | ||
| 444 | {IWL_PCI_DEVICE(0x24F3, 0x8050, iwl8260_2ac_cfg)}, | 457 | {IWL_PCI_DEVICE(0x24F3, 0x8050, iwl8260_2ac_cfg)}, |
| 458 | {IWL_PCI_DEVICE(0x24F3, 0x8150, iwl8260_2ac_cfg)}, | ||
| 445 | {IWL_PCI_DEVICE(0x24F3, 0x9050, iwl8260_2ac_cfg)}, | 459 | {IWL_PCI_DEVICE(0x24F3, 0x9050, iwl8260_2ac_cfg)}, |
| 460 | {IWL_PCI_DEVICE(0x24F3, 0x9150, iwl8260_2ac_cfg)}, | ||
| 446 | {IWL_PCI_DEVICE(0x24F3, 0x0004, iwl8260_2n_cfg)}, | 461 | {IWL_PCI_DEVICE(0x24F3, 0x0004, iwl8260_2n_cfg)}, |
| 462 | {IWL_PCI_DEVICE(0x24F3, 0x0044, iwl8260_2n_cfg)}, | ||
| 447 | {IWL_PCI_DEVICE(0x24F5, 0x0010, iwl4165_2ac_cfg)}, | 463 | {IWL_PCI_DEVICE(0x24F5, 0x0010, iwl4165_2ac_cfg)}, |
| 448 | {IWL_PCI_DEVICE(0x24F6, 0x0030, iwl4165_2ac_cfg)}, | 464 | {IWL_PCI_DEVICE(0x24F6, 0x0030, iwl4165_2ac_cfg)}, |
| 449 | {IWL_PCI_DEVICE(0x24F3, 0x0810, iwl8260_2ac_cfg)}, | 465 | {IWL_PCI_DEVICE(0x24F3, 0x0810, iwl8260_2ac_cfg)}, |
| 450 | {IWL_PCI_DEVICE(0x24F3, 0x0910, iwl8260_2ac_cfg)}, | 466 | {IWL_PCI_DEVICE(0x24F3, 0x0910, iwl8260_2ac_cfg)}, |
| 451 | {IWL_PCI_DEVICE(0x24F3, 0x0850, iwl8260_2ac_cfg)}, | 467 | {IWL_PCI_DEVICE(0x24F3, 0x0850, iwl8260_2ac_cfg)}, |
| 452 | {IWL_PCI_DEVICE(0x24F3, 0x0950, iwl8260_2ac_cfg)}, | 468 | {IWL_PCI_DEVICE(0x24F3, 0x0950, iwl8260_2ac_cfg)}, |
| 469 | {IWL_PCI_DEVICE(0x24F3, 0x0930, iwl8260_2ac_cfg)}, | ||
| 453 | #endif /* CONFIG_IWLMVM */ | 470 | #endif /* CONFIG_IWLMVM */ |
| 454 | 471 | ||
| 455 | {0} | 472 | {0} |
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c index 6e9418ed90c2..bbb789f8990b 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c | |||
| @@ -2272,7 +2272,7 @@ void rtl8821ae_enable_interrupt(struct ieee80211_hw *hw) | |||
| 2272 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 2272 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
| 2273 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | 2273 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); |
| 2274 | 2274 | ||
| 2275 | if (!rtlpci->int_clear) | 2275 | if (rtlpci->int_clear) |
| 2276 | rtl8821ae_clear_interrupt(hw);/*clear it here first*/ | 2276 | rtl8821ae_clear_interrupt(hw);/*clear it here first*/ |
| 2277 | 2277 | ||
| 2278 | rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF); | 2278 | rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF); |
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c index 8ee141a55bc5..142bdff4ed60 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c | |||
| @@ -448,7 +448,7 @@ MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n"); | |||
| 448 | MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 1)\n"); | 448 | MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 1)\n"); |
| 449 | MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)"); | 449 | MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)"); |
| 450 | MODULE_PARM_DESC(disable_watchdog, "Set to 1 to disable the watchdog (default 0)\n"); | 450 | MODULE_PARM_DESC(disable_watchdog, "Set to 1 to disable the watchdog (default 0)\n"); |
| 451 | MODULE_PARM_DESC(int_clear, "Set to 1 to disable interrupt clear before set (default 0)\n"); | 451 | MODULE_PARM_DESC(int_clear, "Set to 0 to disable interrupt clear before set (default 1)\n"); |
| 452 | 452 | ||
| 453 | static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume); | 453 | static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume); |
| 454 | 454 | ||
diff --git a/drivers/nvme/host/Makefile b/drivers/nvme/host/Makefile index 219dc206fa5f..a5fe23952586 100644 --- a/drivers/nvme/host/Makefile +++ b/drivers/nvme/host/Makefile | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | 1 | ||
| 2 | obj-$(CONFIG_BLK_DEV_NVME) += nvme.o | 2 | obj-$(CONFIG_BLK_DEV_NVME) += nvme.o |
| 3 | 3 | ||
| 4 | nvme-y += pci.o scsi.o lightnvm.o | 4 | lightnvm-$(CONFIG_NVM) := lightnvm.o |
| 5 | nvme-y += pci.o scsi.o $(lightnvm-y) | ||
diff --git a/drivers/nvme/host/lightnvm.c b/drivers/nvme/host/lightnvm.c index 9202d1a468d0..06c336410235 100644 --- a/drivers/nvme/host/lightnvm.c +++ b/drivers/nvme/host/lightnvm.c | |||
| @@ -22,8 +22,6 @@ | |||
| 22 | 22 | ||
| 23 | #include "nvme.h" | 23 | #include "nvme.h" |
| 24 | 24 | ||
| 25 | #ifdef CONFIG_NVM | ||
| 26 | |||
| 27 | #include <linux/nvme.h> | 25 | #include <linux/nvme.h> |
| 28 | #include <linux/bitops.h> | 26 | #include <linux/bitops.h> |
| 29 | #include <linux/lightnvm.h> | 27 | #include <linux/lightnvm.h> |
| @@ -357,10 +355,11 @@ out: | |||
| 357 | return ret; | 355 | return ret; |
| 358 | } | 356 | } |
| 359 | 357 | ||
| 360 | static int nvme_nvm_get_bb_tbl(struct request_queue *q, struct ppa_addr ppa, | 358 | static int nvme_nvm_get_bb_tbl(struct nvm_dev *nvmdev, struct ppa_addr ppa, |
| 361 | int nr_blocks, nvm_bb_update_fn *update_bbtbl, | 359 | int nr_blocks, nvm_bb_update_fn *update_bbtbl, |
| 362 | void *priv) | 360 | void *priv) |
| 363 | { | 361 | { |
| 362 | struct request_queue *q = nvmdev->q; | ||
| 364 | struct nvme_ns *ns = q->queuedata; | 363 | struct nvme_ns *ns = q->queuedata; |
| 365 | struct nvme_dev *dev = ns->dev; | 364 | struct nvme_dev *dev = ns->dev; |
| 366 | struct nvme_nvm_command c = {}; | 365 | struct nvme_nvm_command c = {}; |
| @@ -404,6 +403,7 @@ static int nvme_nvm_get_bb_tbl(struct request_queue *q, struct ppa_addr ppa, | |||
| 404 | goto out; | 403 | goto out; |
| 405 | } | 404 | } |
| 406 | 405 | ||
| 406 | ppa = dev_to_generic_addr(nvmdev, ppa); | ||
| 407 | ret = update_bbtbl(ppa, nr_blocks, bb_tbl->blk, priv); | 407 | ret = update_bbtbl(ppa, nr_blocks, bb_tbl->blk, priv); |
| 408 | if (ret) { | 408 | if (ret) { |
| 409 | ret = -EINTR; | 409 | ret = -EINTR; |
| @@ -571,31 +571,27 @@ void nvme_nvm_unregister(struct request_queue *q, char *disk_name) | |||
| 571 | nvm_unregister(disk_name); | 571 | nvm_unregister(disk_name); |
| 572 | } | 572 | } |
| 573 | 573 | ||
| 574 | /* move to shared place when used in multiple places. */ | ||
| 575 | #define PCI_VENDOR_ID_CNEX 0x1d1d | ||
| 576 | #define PCI_DEVICE_ID_CNEX_WL 0x2807 | ||
| 577 | #define PCI_DEVICE_ID_CNEX_QEMU 0x1f1f | ||
| 578 | |||
| 574 | int nvme_nvm_ns_supported(struct nvme_ns *ns, struct nvme_id_ns *id) | 579 | int nvme_nvm_ns_supported(struct nvme_ns *ns, struct nvme_id_ns *id) |
| 575 | { | 580 | { |
| 576 | struct nvme_dev *dev = ns->dev; | 581 | struct nvme_dev *dev = ns->dev; |
| 577 | struct pci_dev *pdev = to_pci_dev(dev->dev); | 582 | struct pci_dev *pdev = to_pci_dev(dev->dev); |
| 578 | 583 | ||
| 579 | /* QEMU NVMe simulator - PCI ID + Vendor specific bit */ | 584 | /* QEMU NVMe simulator - PCI ID + Vendor specific bit */ |
| 580 | if (pdev->vendor == PCI_VENDOR_ID_INTEL && pdev->device == 0x5845 && | 585 | if (pdev->vendor == PCI_VENDOR_ID_CNEX && |
| 586 | pdev->device == PCI_DEVICE_ID_CNEX_QEMU && | ||
| 581 | id->vs[0] == 0x1) | 587 | id->vs[0] == 0x1) |
| 582 | return 1; | 588 | return 1; |
| 583 | 589 | ||
| 584 | /* CNEX Labs - PCI ID + Vendor specific bit */ | 590 | /* CNEX Labs - PCI ID + Vendor specific bit */ |
| 585 | if (pdev->vendor == 0x1d1d && pdev->device == 0x2807 && | 591 | if (pdev->vendor == PCI_VENDOR_ID_CNEX && |
| 592 | pdev->device == PCI_DEVICE_ID_CNEX_WL && | ||
| 586 | id->vs[0] == 0x1) | 593 | id->vs[0] == 0x1) |
| 587 | return 1; | 594 | return 1; |
| 588 | 595 | ||
| 589 | return 0; | 596 | return 0; |
| 590 | } | 597 | } |
| 591 | #else | ||
| 592 | int nvme_nvm_register(struct request_queue *q, char *disk_name) | ||
| 593 | { | ||
| 594 | return 0; | ||
| 595 | } | ||
| 596 | void nvme_nvm_unregister(struct request_queue *q, char *disk_name) {}; | ||
| 597 | int nvme_nvm_ns_supported(struct nvme_ns *ns, struct nvme_id_ns *id) | ||
| 598 | { | ||
| 599 | return 0; | ||
| 600 | } | ||
| 601 | #endif /* CONFIG_NVM */ | ||
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index fdb4e5bad9ac..044253dca30a 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h | |||
| @@ -136,8 +136,22 @@ int nvme_sg_io(struct nvme_ns *ns, struct sg_io_hdr __user *u_hdr); | |||
| 136 | int nvme_sg_io32(struct nvme_ns *ns, unsigned long arg); | 136 | int nvme_sg_io32(struct nvme_ns *ns, unsigned long arg); |
| 137 | int nvme_sg_get_version_num(int __user *ip); | 137 | int nvme_sg_get_version_num(int __user *ip); |
| 138 | 138 | ||
| 139 | #ifdef CONFIG_NVM | ||
| 139 | int nvme_nvm_ns_supported(struct nvme_ns *ns, struct nvme_id_ns *id); | 140 | int nvme_nvm_ns_supported(struct nvme_ns *ns, struct nvme_id_ns *id); |
| 140 | int nvme_nvm_register(struct request_queue *q, char *disk_name); | 141 | int nvme_nvm_register(struct request_queue *q, char *disk_name); |
| 141 | void nvme_nvm_unregister(struct request_queue *q, char *disk_name); | 142 | void nvme_nvm_unregister(struct request_queue *q, char *disk_name); |
| 143 | #else | ||
| 144 | static inline int nvme_nvm_register(struct request_queue *q, char *disk_name) | ||
| 145 | { | ||
| 146 | return 0; | ||
| 147 | } | ||
| 148 | |||
| 149 | static inline void nvme_nvm_unregister(struct request_queue *q, char *disk_name) {}; | ||
| 150 | |||
| 151 | static inline int nvme_nvm_ns_supported(struct nvme_ns *ns, struct nvme_id_ns *id) | ||
| 152 | { | ||
| 153 | return 0; | ||
| 154 | } | ||
| 155 | #endif /* CONFIG_NVM */ | ||
| 142 | 156 | ||
| 143 | #endif /* _NVME_H */ | 157 | #endif /* _NVME_H */ |
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index f3b53af789ef..9e294ff4e652 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c | |||
| @@ -2708,6 +2708,18 @@ static int nvme_dev_map(struct nvme_dev *dev) | |||
| 2708 | dev->q_depth = min_t(int, NVME_CAP_MQES(cap) + 1, NVME_Q_DEPTH); | 2708 | dev->q_depth = min_t(int, NVME_CAP_MQES(cap) + 1, NVME_Q_DEPTH); |
| 2709 | dev->db_stride = 1 << NVME_CAP_STRIDE(cap); | 2709 | dev->db_stride = 1 << NVME_CAP_STRIDE(cap); |
| 2710 | dev->dbs = ((void __iomem *)dev->bar) + 4096; | 2710 | dev->dbs = ((void __iomem *)dev->bar) + 4096; |
| 2711 | |||
| 2712 | /* | ||
| 2713 | * Temporary fix for the Apple controller found in the MacBook8,1 and | ||
| 2714 | * some MacBook7,1 to avoid controller resets and data loss. | ||
| 2715 | */ | ||
| 2716 | if (pdev->vendor == PCI_VENDOR_ID_APPLE && pdev->device == 0x2001) { | ||
| 2717 | dev->q_depth = 2; | ||
| 2718 | dev_warn(dev->dev, "detected Apple NVMe controller, set " | ||
| 2719 | "queue depth=%u to work around controller resets\n", | ||
| 2720 | dev->q_depth); | ||
| 2721 | } | ||
| 2722 | |||
| 2711 | if (readl(&dev->bar->vs) >= NVME_VS(1, 2)) | 2723 | if (readl(&dev->bar->vs) >= NVME_VS(1, 2)) |
| 2712 | dev->cmb = nvme_map_cmb(dev); | 2724 | dev->cmb = nvme_map_cmb(dev); |
| 2713 | 2725 | ||
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 4446fcb5effd..d7ffd66814bb 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
| @@ -1146,9 +1146,21 @@ static int pci_pm_runtime_suspend(struct device *dev) | |||
| 1146 | pci_dev->state_saved = false; | 1146 | pci_dev->state_saved = false; |
| 1147 | pci_dev->no_d3cold = false; | 1147 | pci_dev->no_d3cold = false; |
| 1148 | error = pm->runtime_suspend(dev); | 1148 | error = pm->runtime_suspend(dev); |
| 1149 | suspend_report_result(pm->runtime_suspend, error); | 1149 | if (error) { |
| 1150 | if (error) | 1150 | /* |
| 1151 | * -EBUSY and -EAGAIN is used to request the runtime PM core | ||
| 1152 | * to schedule a new suspend, so log the event only with debug | ||
| 1153 | * log level. | ||
| 1154 | */ | ||
| 1155 | if (error == -EBUSY || error == -EAGAIN) | ||
| 1156 | dev_dbg(dev, "can't suspend now (%pf returned %d)\n", | ||
| 1157 | pm->runtime_suspend, error); | ||
| 1158 | else | ||
| 1159 | dev_err(dev, "can't suspend (%pf returned %d)\n", | ||
| 1160 | pm->runtime_suspend, error); | ||
| 1161 | |||
| 1151 | return error; | 1162 | return error; |
| 1163 | } | ||
| 1152 | if (!pci_dev->d3cold_allowed) | 1164 | if (!pci_dev->d3cold_allowed) |
| 1153 | pci_dev->no_d3cold = true; | 1165 | pci_dev->no_d3cold = true; |
| 1154 | 1166 | ||
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index b422e4ed73f4..312c78b27a32 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig | |||
| @@ -5,8 +5,6 @@ | |||
| 5 | config PINCTRL | 5 | config PINCTRL |
| 6 | bool | 6 | bool |
| 7 | 7 | ||
| 8 | if PINCTRL | ||
| 9 | |||
| 10 | menu "Pin controllers" | 8 | menu "Pin controllers" |
| 11 | depends on PINCTRL | 9 | depends on PINCTRL |
| 12 | 10 | ||
| @@ -274,5 +272,3 @@ config PINCTRL_TB10X | |||
| 274 | select GPIOLIB | 272 | select GPIOLIB |
| 275 | 273 | ||
| 276 | endmenu | 274 | endmenu |
| 277 | |||
| 278 | endif | ||
diff --git a/drivers/pinctrl/freescale/pinctrl-imx1-core.c b/drivers/pinctrl/freescale/pinctrl-imx1-core.c index 88a7fac11bd4..acaf84cadca3 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx1-core.c +++ b/drivers/pinctrl/freescale/pinctrl-imx1-core.c | |||
| @@ -538,8 +538,10 @@ static int imx1_pinctrl_parse_functions(struct device_node *np, | |||
| 538 | func->groups[i] = child->name; | 538 | func->groups[i] = child->name; |
| 539 | grp = &info->groups[grp_index++]; | 539 | grp = &info->groups[grp_index++]; |
| 540 | ret = imx1_pinctrl_parse_groups(child, grp, info, i++); | 540 | ret = imx1_pinctrl_parse_groups(child, grp, info, i++); |
| 541 | if (ret == -ENOMEM) | 541 | if (ret == -ENOMEM) { |
| 542 | of_node_put(child); | ||
| 542 | return ret; | 543 | return ret; |
| 544 | } | ||
| 543 | } | 545 | } |
| 544 | 546 | ||
| 545 | return 0; | 547 | return 0; |
| @@ -582,8 +584,10 @@ static int imx1_pinctrl_parse_dt(struct platform_device *pdev, | |||
| 582 | 584 | ||
| 583 | for_each_child_of_node(np, child) { | 585 | for_each_child_of_node(np, child) { |
| 584 | ret = imx1_pinctrl_parse_functions(child, info, ifunc++); | 586 | ret = imx1_pinctrl_parse_functions(child, info, ifunc++); |
| 585 | if (ret == -ENOMEM) | 587 | if (ret == -ENOMEM) { |
| 588 | of_node_put(child); | ||
| 586 | return -ENOMEM; | 589 | return -ENOMEM; |
| 590 | } | ||
| 587 | } | 591 | } |
| 588 | 592 | ||
| 589 | return 0; | 593 | return 0; |
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c index f307f1d27d64..5c717275a7fa 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c | |||
| @@ -747,7 +747,7 @@ static int mtk_gpio_get_direction(struct gpio_chip *chip, unsigned offset) | |||
| 747 | reg_addr = mtk_get_port(pctl, offset) + pctl->devdata->dir_offset; | 747 | reg_addr = mtk_get_port(pctl, offset) + pctl->devdata->dir_offset; |
| 748 | bit = BIT(offset & 0xf); | 748 | bit = BIT(offset & 0xf); |
| 749 | regmap_read(pctl->regmap1, reg_addr, &read_val); | 749 | regmap_read(pctl->regmap1, reg_addr, &read_val); |
| 750 | return !!(read_val & bit); | 750 | return !(read_val & bit); |
| 751 | } | 751 | } |
| 752 | 752 | ||
| 753 | static int mtk_gpio_get(struct gpio_chip *chip, unsigned offset) | 753 | static int mtk_gpio_get(struct gpio_chip *chip, unsigned offset) |
| @@ -757,12 +757,8 @@ static int mtk_gpio_get(struct gpio_chip *chip, unsigned offset) | |||
| 757 | unsigned int read_val = 0; | 757 | unsigned int read_val = 0; |
| 758 | struct mtk_pinctrl *pctl = dev_get_drvdata(chip->dev); | 758 | struct mtk_pinctrl *pctl = dev_get_drvdata(chip->dev); |
| 759 | 759 | ||
| 760 | if (mtk_gpio_get_direction(chip, offset)) | 760 | reg_addr = mtk_get_port(pctl, offset) + |
| 761 | reg_addr = mtk_get_port(pctl, offset) + | 761 | pctl->devdata->din_offset; |
| 762 | pctl->devdata->dout_offset; | ||
| 763 | else | ||
| 764 | reg_addr = mtk_get_port(pctl, offset) + | ||
| 765 | pctl->devdata->din_offset; | ||
| 766 | 762 | ||
| 767 | bit = BIT(offset & 0xf); | 763 | bit = BIT(offset & 0xf); |
| 768 | regmap_read(pctl->regmap1, reg_addr, &read_val); | 764 | regmap_read(pctl->regmap1, reg_addr, &read_val); |
| @@ -997,6 +993,7 @@ static struct gpio_chip mtk_gpio_chip = { | |||
| 997 | .owner = THIS_MODULE, | 993 | .owner = THIS_MODULE, |
| 998 | .request = gpiochip_generic_request, | 994 | .request = gpiochip_generic_request, |
| 999 | .free = gpiochip_generic_free, | 995 | .free = gpiochip_generic_free, |
| 996 | .get_direction = mtk_gpio_get_direction, | ||
| 1000 | .direction_input = mtk_gpio_direction_input, | 997 | .direction_input = mtk_gpio_direction_input, |
| 1001 | .direction_output = mtk_gpio_direction_output, | 998 | .direction_output = mtk_gpio_direction_output, |
| 1002 | .get = mtk_gpio_get, | 999 | .get = mtk_gpio_get, |
diff --git a/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c b/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c index d809c9eaa323..19a3c3bc2f1f 100644 --- a/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c +++ b/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c | |||
| @@ -672,7 +672,7 @@ static int pm8xxx_gpio_probe(struct platform_device *pdev) | |||
| 672 | return -ENOMEM; | 672 | return -ENOMEM; |
| 673 | 673 | ||
| 674 | pctrl->dev = &pdev->dev; | 674 | pctrl->dev = &pdev->dev; |
| 675 | pctrl->npins = (unsigned)of_device_get_match_data(&pdev->dev); | 675 | pctrl->npins = (unsigned long)of_device_get_match_data(&pdev->dev); |
| 676 | 676 | ||
| 677 | pctrl->regmap = dev_get_regmap(pdev->dev.parent, NULL); | 677 | pctrl->regmap = dev_get_regmap(pdev->dev.parent, NULL); |
| 678 | if (!pctrl->regmap) { | 678 | if (!pctrl->regmap) { |
diff --git a/drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c b/drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c index 8982027de8e8..b868ef1766a0 100644 --- a/drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c +++ b/drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c | |||
| @@ -763,7 +763,7 @@ static int pm8xxx_mpp_probe(struct platform_device *pdev) | |||
| 763 | return -ENOMEM; | 763 | return -ENOMEM; |
| 764 | 764 | ||
| 765 | pctrl->dev = &pdev->dev; | 765 | pctrl->dev = &pdev->dev; |
| 766 | pctrl->npins = (unsigned)of_device_get_match_data(&pdev->dev); | 766 | pctrl->npins = (unsigned long)of_device_get_match_data(&pdev->dev); |
| 767 | 767 | ||
| 768 | pctrl->regmap = dev_get_regmap(pdev->dev.parent, NULL); | 768 | pctrl->regmap = dev_get_regmap(pdev->dev.parent, NULL); |
| 769 | if (!pctrl->regmap) { | 769 | if (!pctrl->regmap) { |
diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7734.c b/drivers/pinctrl/sh-pfc/pfc-sh7734.c index e7deb51de7dc..9842bb106796 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7734.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7734.c | |||
| @@ -31,11 +31,11 @@ | |||
| 31 | PORT_GP_12(5, fn, sfx) | 31 | PORT_GP_12(5, fn, sfx) |
| 32 | 32 | ||
| 33 | #undef _GP_DATA | 33 | #undef _GP_DATA |
| 34 | #define _GP_DATA(bank, pin, name, sfx) \ | 34 | #define _GP_DATA(bank, pin, name, sfx, cfg) \ |
| 35 | PINMUX_DATA(name##_DATA, name##_FN, name##_IN, name##_OUT) | 35 | PINMUX_DATA(name##_DATA, name##_FN, name##_IN, name##_OUT) |
| 36 | 36 | ||
| 37 | #define _GP_INOUTSEL(bank, pin, name, sfx) name##_IN, name##_OUT | 37 | #define _GP_INOUTSEL(bank, pin, name, sfx, cfg) name##_IN, name##_OUT |
| 38 | #define _GP_INDT(bank, pin, name, sfx) name##_DATA | 38 | #define _GP_INDT(bank, pin, name, sfx, cfg) name##_DATA |
| 39 | #define GP_INOUTSEL(bank) PORT_GP_32_REV(bank, _GP_INOUTSEL, unused) | 39 | #define GP_INOUTSEL(bank) PORT_GP_32_REV(bank, _GP_INOUTSEL, unused) |
| 40 | #define GP_INDT(bank) PORT_GP_32_REV(bank, _GP_INDT, unused) | 40 | #define GP_INDT(bank) PORT_GP_32_REV(bank, _GP_INDT, unused) |
| 41 | 41 | ||
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 8b3130f22b42..9e03d158f411 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c | |||
| @@ -1478,6 +1478,8 @@ module_init(remoteproc_init); | |||
| 1478 | 1478 | ||
| 1479 | static void __exit remoteproc_exit(void) | 1479 | static void __exit remoteproc_exit(void) |
| 1480 | { | 1480 | { |
| 1481 | ida_destroy(&rproc_dev_index); | ||
| 1482 | |||
| 1481 | rproc_exit_debugfs(); | 1483 | rproc_exit_debugfs(); |
| 1482 | } | 1484 | } |
| 1483 | module_exit(remoteproc_exit); | 1485 | module_exit(remoteproc_exit); |
diff --git a/drivers/remoteproc/remoteproc_debugfs.c b/drivers/remoteproc/remoteproc_debugfs.c index 9d30809bb407..916af5096f57 100644 --- a/drivers/remoteproc/remoteproc_debugfs.c +++ b/drivers/remoteproc/remoteproc_debugfs.c | |||
| @@ -156,7 +156,7 @@ rproc_recovery_write(struct file *filp, const char __user *user_buf, | |||
| 156 | char buf[10]; | 156 | char buf[10]; |
| 157 | int ret; | 157 | int ret; |
| 158 | 158 | ||
| 159 | if (count > sizeof(buf)) | 159 | if (count < 1 || count > sizeof(buf)) |
| 160 | return count; | 160 | return count; |
| 161 | 161 | ||
| 162 | ret = copy_from_user(buf, user_buf, count); | 162 | ret = copy_from_user(buf, user_buf, count); |
diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index 06858e04ec59..bf9a610e5b89 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c | |||
| @@ -562,8 +562,8 @@ static int bcm63xx_spi_probe(struct platform_device *pdev) | |||
| 562 | goto out_clk_disable; | 562 | goto out_clk_disable; |
| 563 | } | 563 | } |
| 564 | 564 | ||
| 565 | dev_info(dev, "at 0x%08x (irq %d, FIFOs size %d)\n", | 565 | dev_info(dev, "at %pr (irq %d, FIFOs size %d)\n", |
| 566 | r->start, irq, bs->fifo_size); | 566 | r, irq, bs->fifo_size); |
| 567 | 567 | ||
| 568 | return 0; | 568 | return 0; |
| 569 | 569 | ||
diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c index 563954a61424..7840067062a8 100644 --- a/drivers/spi/spi-mt65xx.c +++ b/drivers/spi/spi-mt65xx.c | |||
| @@ -410,7 +410,7 @@ static int mtk_spi_setup(struct spi_device *spi) | |||
| 410 | if (!spi->controller_data) | 410 | if (!spi->controller_data) |
| 411 | spi->controller_data = (void *)&mtk_default_chip_info; | 411 | spi->controller_data = (void *)&mtk_default_chip_info; |
| 412 | 412 | ||
| 413 | if (mdata->dev_comp->need_pad_sel) | 413 | if (mdata->dev_comp->need_pad_sel && gpio_is_valid(spi->cs_gpio)) |
| 414 | gpio_direction_output(spi->cs_gpio, !(spi->mode & SPI_CS_HIGH)); | 414 | gpio_direction_output(spi->cs_gpio, !(spi->mode & SPI_CS_HIGH)); |
| 415 | 415 | ||
| 416 | return 0; | 416 | return 0; |
| @@ -632,13 +632,23 @@ static int mtk_spi_probe(struct platform_device *pdev) | |||
| 632 | goto err_put_master; | 632 | goto err_put_master; |
| 633 | } | 633 | } |
| 634 | 634 | ||
| 635 | for (i = 0; i < master->num_chipselect; i++) { | 635 | if (!master->cs_gpios && master->num_chipselect > 1) { |
| 636 | ret = devm_gpio_request(&pdev->dev, master->cs_gpios[i], | 636 | dev_err(&pdev->dev, |
| 637 | dev_name(&pdev->dev)); | 637 | "cs_gpios not specified and num_chipselect > 1\n"); |
| 638 | if (ret) { | 638 | ret = -EINVAL; |
| 639 | dev_err(&pdev->dev, | 639 | goto err_put_master; |
| 640 | "can't get CS GPIO %i\n", i); | 640 | } |
| 641 | goto err_put_master; | 641 | |
| 642 | if (master->cs_gpios) { | ||
| 643 | for (i = 0; i < master->num_chipselect; i++) { | ||
| 644 | ret = devm_gpio_request(&pdev->dev, | ||
| 645 | master->cs_gpios[i], | ||
| 646 | dev_name(&pdev->dev)); | ||
| 647 | if (ret) { | ||
| 648 | dev_err(&pdev->dev, | ||
| 649 | "can't get CS GPIO %i\n", i); | ||
| 650 | goto err_put_master; | ||
| 651 | } | ||
| 642 | } | 652 | } |
| 643 | } | 653 | } |
| 644 | } | 654 | } |
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index 94af80676684..5e5fd77e2711 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c | |||
| @@ -1171,19 +1171,31 @@ err_no_rxchan: | |||
| 1171 | static int pl022_dma_autoprobe(struct pl022 *pl022) | 1171 | static int pl022_dma_autoprobe(struct pl022 *pl022) |
| 1172 | { | 1172 | { |
| 1173 | struct device *dev = &pl022->adev->dev; | 1173 | struct device *dev = &pl022->adev->dev; |
| 1174 | struct dma_chan *chan; | ||
| 1175 | int err; | ||
| 1174 | 1176 | ||
| 1175 | /* automatically configure DMA channels from platform, normally using DT */ | 1177 | /* automatically configure DMA channels from platform, normally using DT */ |
| 1176 | pl022->dma_rx_channel = dma_request_slave_channel(dev, "rx"); | 1178 | chan = dma_request_slave_channel_reason(dev, "rx"); |
| 1177 | if (!pl022->dma_rx_channel) | 1179 | if (IS_ERR(chan)) { |
| 1180 | err = PTR_ERR(chan); | ||
| 1178 | goto err_no_rxchan; | 1181 | goto err_no_rxchan; |
| 1182 | } | ||
| 1183 | |||
| 1184 | pl022->dma_rx_channel = chan; | ||
| 1179 | 1185 | ||
| 1180 | pl022->dma_tx_channel = dma_request_slave_channel(dev, "tx"); | 1186 | chan = dma_request_slave_channel_reason(dev, "tx"); |
| 1181 | if (!pl022->dma_tx_channel) | 1187 | if (IS_ERR(chan)) { |
| 1188 | err = PTR_ERR(chan); | ||
| 1182 | goto err_no_txchan; | 1189 | goto err_no_txchan; |
| 1190 | } | ||
| 1191 | |||
| 1192 | pl022->dma_tx_channel = chan; | ||
| 1183 | 1193 | ||
| 1184 | pl022->dummypage = kmalloc(PAGE_SIZE, GFP_KERNEL); | 1194 | pl022->dummypage = kmalloc(PAGE_SIZE, GFP_KERNEL); |
| 1185 | if (!pl022->dummypage) | 1195 | if (!pl022->dummypage) { |
| 1196 | err = -ENOMEM; | ||
| 1186 | goto err_no_dummypage; | 1197 | goto err_no_dummypage; |
| 1198 | } | ||
| 1187 | 1199 | ||
| 1188 | return 0; | 1200 | return 0; |
| 1189 | 1201 | ||
| @@ -1194,7 +1206,7 @@ err_no_txchan: | |||
| 1194 | dma_release_channel(pl022->dma_rx_channel); | 1206 | dma_release_channel(pl022->dma_rx_channel); |
| 1195 | pl022->dma_rx_channel = NULL; | 1207 | pl022->dma_rx_channel = NULL; |
| 1196 | err_no_rxchan: | 1208 | err_no_rxchan: |
| 1197 | return -ENODEV; | 1209 | return err; |
| 1198 | } | 1210 | } |
| 1199 | 1211 | ||
| 1200 | static void terminate_dma(struct pl022 *pl022) | 1212 | static void terminate_dma(struct pl022 *pl022) |
| @@ -2236,6 +2248,10 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
| 2236 | 2248 | ||
| 2237 | /* Get DMA channels, try autoconfiguration first */ | 2249 | /* Get DMA channels, try autoconfiguration first */ |
| 2238 | status = pl022_dma_autoprobe(pl022); | 2250 | status = pl022_dma_autoprobe(pl022); |
| 2251 | if (status == -EPROBE_DEFER) { | ||
| 2252 | dev_dbg(dev, "deferring probe to get DMA channel\n"); | ||
| 2253 | goto err_no_irq; | ||
| 2254 | } | ||
| 2239 | 2255 | ||
| 2240 | /* If that failed, use channels from platform_info */ | 2256 | /* If that failed, use channels from platform_info */ |
| 2241 | if (status == 0) | 2257 | if (status == 0) |
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index e2415be209d5..2b0a8ec3affb 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
| @@ -376,6 +376,7 @@ static void spi_drv_shutdown(struct device *dev) | |||
| 376 | 376 | ||
| 377 | /** | 377 | /** |
| 378 | * __spi_register_driver - register a SPI driver | 378 | * __spi_register_driver - register a SPI driver |
| 379 | * @owner: owner module of the driver to register | ||
| 379 | * @sdrv: the driver to register | 380 | * @sdrv: the driver to register |
| 380 | * Context: can sleep | 381 | * Context: can sleep |
| 381 | * | 382 | * |
| @@ -2130,6 +2131,7 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) | |||
| 2130 | * Set transfer tx_nbits and rx_nbits as single transfer default | 2131 | * Set transfer tx_nbits and rx_nbits as single transfer default |
| 2131 | * (SPI_NBITS_SINGLE) if it is not set for this transfer. | 2132 | * (SPI_NBITS_SINGLE) if it is not set for this transfer. |
| 2132 | */ | 2133 | */ |
| 2134 | message->frame_length = 0; | ||
| 2133 | list_for_each_entry(xfer, &message->transfers, transfer_list) { | 2135 | list_for_each_entry(xfer, &message->transfers, transfer_list) { |
| 2134 | message->frame_length += xfer->len; | 2136 | message->frame_length += xfer->len; |
| 2135 | if (!xfer->bits_per_word) | 2137 | if (!xfer->bits_per_word) |
