aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/base/dma-contiguous.c3
-rw-r--r--drivers/bcma/host_pci.c5
-rw-r--r--drivers/bcma/main.c2
-rw-r--r--drivers/block/null_blk.c14
-rw-r--r--drivers/block/sunvdc.c9
-rw-r--r--drivers/block/zram/zram_drv.c10
-rw-r--r--drivers/clocksource/arm_arch_timer.c6
-rw-r--r--drivers/edac/cpc925_edac.c2
-rw-r--r--drivers/edac/e7xxx_edac.c2
-rw-r--r--drivers/edac/i3200_edac.c4
-rw-r--r--drivers/edac/i82860_edac.c2
-rw-r--r--drivers/hid/hid-debug.c6
-rw-r--r--drivers/hid/hid-ids.h2
-rw-r--r--drivers/hid/hid-input.c12
-rw-r--r--drivers/hid/usbhid/hid-quirks.c2
-rw-r--r--drivers/infiniband/hw/mlx4/main.c10
-rw-r--r--drivers/media/common/saa7146/saa7146_core.c6
-rw-r--r--drivers/media/pci/cx23885/cx23885-dvb.c3
-rw-r--r--drivers/media/pci/tw68/Kconfig1
-rw-r--r--drivers/media/pci/tw68/tw68-core.c2
-rw-r--r--drivers/media/platform/Kconfig6
-rw-r--r--drivers/media/platform/exynos4-is/Kconfig2
-rw-r--r--drivers/media/platform/exynos4-is/fimc-core.c2
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-core.c6
-rw-r--r--drivers/media/platform/s5p-tv/Kconfig2
-rw-r--r--drivers/media/platform/vivid/Kconfig5
-rw-r--r--drivers/media/platform/vivid/vivid-tpg.c2
-rw-r--r--drivers/media/radio/wl128x/fmdrv_common.c2
-rw-r--r--drivers/media/tuners/xc5000.c2
-rw-r--r--drivers/media/usb/dvb-usb-v2/af9035.c6
-rw-r--r--drivers/media/usb/dvb-usb-v2/anysee.c6
-rw-r--r--drivers/media/usb/em28xx/em28xx-core.c2
-rw-r--r--drivers/media/usb/em28xx/em28xx-input.c4
-rw-r--r--drivers/media/usb/hackrf/hackrf.c2
-rw-r--r--drivers/media/usb/usbvision/usbvision-video.c2
-rw-r--r--drivers/media/usb/uvc/uvc_v4l2.c1
-rw-r--r--drivers/media/usb/uvc/uvc_video.c2
-rw-r--r--drivers/media/usb/uvc/uvcvideo.h1
-rw-r--r--drivers/media/v4l2-core/videobuf-dma-contig.c9
-rw-r--r--drivers/misc/cxl/fault.c74
-rw-r--r--drivers/misc/cxl/native.c4
-rw-r--r--drivers/net/Kconfig2
-rw-r--r--drivers/net/dsa/mv88e6171.c2
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-drv.c22
-rw-r--r--drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c16
-rw-r--r--drivers/net/ethernet/broadcom/bcmsysport.c11
-rw-r--r--drivers/net/ethernet/broadcom/cnic.c5
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c55
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c7
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c16
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_clsf.c12
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_main.c4
-rw-r--r--drivers/net/ethernet/freescale/fec_main.c3
-rw-r--r--drivers/net/ethernet/freescale/fs_enet/mac-fec.c3
-rw-r--r--drivers/net/ethernet/freescale/fs_enet/mac-scc.c3
-rw-r--r--drivers/net/ethernet/intel/e1000/e1000_main.c5
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_main.c4
-rw-r--r--drivers/net/ethernet/intel/igb/igb_main.c6
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c4
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_main.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_tx.c7
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/eq.c1
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mcg.c4
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/eq.c1
-rw-r--r--drivers/net/ethernet/sfc/tx.c4
-rw-r--r--drivers/net/ethernet/smsc/smc91x.c58
-rw-r--r--drivers/net/ethernet/smsc/smc91x.h3
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c7
-rw-r--r--drivers/net/ethernet/ti/cpsw.c48
-rw-r--r--drivers/net/ethernet/ti/cpsw_ale.c29
-rw-r--r--drivers/net/ethernet/ti/cpsw_ale.h2
-rw-r--r--drivers/net/hyperv/netvsc_drv.c1
-rw-r--r--drivers/net/macvlan.c10
-rw-r--r--drivers/net/macvtap.c16
-rw-r--r--drivers/net/phy/marvell.c19
-rw-r--r--drivers/net/tun.c25
-rw-r--r--drivers/net/usb/ax88179_178a.c7
-rw-r--r--drivers/net/usb/cdc_ether.c47
-rw-r--r--drivers/net/usb/r8152.c17
-rw-r--r--drivers/net/usb/usbnet.c20
-rw-r--r--drivers/net/virtio_net.c24
-rw-r--r--drivers/net/wireless/ath/ath.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/common.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c55
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c10
-rw-r--r--drivers/net/wireless/ath/regd.c14
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c25
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/mac80211.c24
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-8000.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/coex.c4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/coex_legacy.c4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-power.h35
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h1
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw.c9
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c32
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c1
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c3
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tx.c8
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c22
-rw-r--r--drivers/net/wireless/mwifiex/11n_rxreorder.c52
-rw-r--r--drivers/net/wireless/mwifiex/11n_rxreorder.h2
-rw-r--r--drivers/net/wireless/mwifiex/main.h1
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c1
-rw-r--r--drivers/net/wireless/rtlwifi/base.c2
-rw-r--r--drivers/net/wireless/rtlwifi/core.c6
-rw-r--r--drivers/net/wireless/rtlwifi/core.h1
-rw-r--r--drivers/net/wireless/rtlwifi/pci.c3
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c8
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h4
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/def.h2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/hw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/sw.c1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/trx.c3
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/hw.c17
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/hw.h1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/sw.c7
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/sw.c1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ee/hw.c8
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/def.h2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/sw.c22
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/trx.c3
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8821ae/phy.c15
-rw-r--r--drivers/net/wireless/rtlwifi/usb.c11
-rw-r--r--drivers/net/xen-netback/common.h39
-rw-r--r--drivers/net/xen-netback/interface.c74
-rw-r--r--drivers/net/xen-netback/netback.c319
-rw-r--r--drivers/net/xen-netback/xenbus.c22
-rw-r--r--drivers/of/of_reserved_mem.c14
-rw-r--r--drivers/pci/host/pci-imx6.c13
-rw-r--r--drivers/pci/hotplug/pciehp_core.c7
-rw-r--r--drivers/pci/pci-sysfs.c8
-rw-r--r--drivers/regulator/rk808-regulator.c2
-rw-r--r--drivers/rtc/Kconfig2
-rw-r--r--drivers/rtc/rtc-bq32k.c2
-rw-r--r--drivers/rtc/rtc-pm8xxx.c222
-rw-r--r--drivers/rtc/rtc-s3c.c14
-rw-r--r--drivers/spi/spi-dw.c1
-rw-r--r--drivers/spi/spi-orion.c2
-rw-r--r--drivers/spi/spi-pl022.c2
-rw-r--r--drivers/spi/spi-rockchip.c50
-rw-r--r--drivers/spi/spidev.c79
-rw-r--r--drivers/video/console/fbcon.c19
-rw-r--r--drivers/video/console/vgacon.c24
-rw-r--r--drivers/video/fbdev/atmel_lcdfb.c1
-rw-r--r--drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c3
-rw-r--r--drivers/video/fbdev/omap2/displays-new/connector-dvi.c1
-rw-r--r--drivers/video/fbdev/omap2/displays-new/connector-hdmi.c1
-rw-r--r--drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c1
-rw-r--r--drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c1
-rw-r--r--drivers/video/fbdev/omap2/displays-new/panel-dpi.c1
-rw-r--r--drivers/video/fbdev/omap2/displays-new/panel-dsi-cm.c1
-rw-r--r--drivers/video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c1
-rw-r--r--drivers/video/fbdev/omap2/displays-new/panel-nec-nl8048hl11.c1
-rw-r--r--drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c1
-rw-r--r--drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c1
-rw-r--r--drivers/video/fbdev/omap2/displays-new/panel-tpo-td028ttec1.c1
-rw-r--r--drivers/video/fbdev/omap2/displays-new/panel-tpo-td043mtea1.c1
-rw-r--r--drivers/video/fbdev/omap2/dss/apply.c2
-rw-r--r--drivers/video/fbdev/omap2/dss/dispc.c8
-rw-r--r--drivers/video/fbdev/omap2/dss/dispc.h3
-rw-r--r--drivers/video/fbdev/omap2/dss/dpi.c1
-rw-r--r--drivers/video/fbdev/omap2/dss/dsi.c3
-rw-r--r--drivers/video/fbdev/omap2/dss/dss.c1
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi4.c1
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi5.c1
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi_pll.c13
-rw-r--r--drivers/video/fbdev/omap2/dss/rfbi.c1
-rw-r--r--drivers/video/fbdev/omap2/dss/sdi.c1
-rw-r--r--drivers/video/fbdev/omap2/dss/venc.c1
-rw-r--r--drivers/video/fbdev/omap2/omapfb/omapfb-main.c18
174 files changed, 1435 insertions, 770 deletions
diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c
index 473ff4892401..950fff9ce453 100644
--- a/drivers/base/dma-contiguous.c
+++ b/drivers/base/dma-contiguous.c
@@ -223,9 +223,10 @@ bool dma_release_from_contiguous(struct device *dev, struct page *pages,
#undef pr_fmt
#define pr_fmt(fmt) fmt
-static void rmem_cma_device_init(struct reserved_mem *rmem, struct device *dev)
+static int rmem_cma_device_init(struct reserved_mem *rmem, struct device *dev)
{
dev_set_cma_area(dev, rmem->priv);
+ return 0;
}
static void rmem_cma_device_release(struct reserved_mem *rmem,
diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c
index 1e5ac0a79696..cd9161a8b3a1 100644
--- a/drivers/bcma/host_pci.c
+++ b/drivers/bcma/host_pci.c
@@ -275,7 +275,7 @@ static SIMPLE_DEV_PM_OPS(bcma_pm_ops, bcma_host_pci_suspend,
static const struct pci_device_id bcma_pci_bridge_tbl[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4313) },
- { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43224) },
+ { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43224) }, /* 0xa8d8 */
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) },
@@ -285,7 +285,8 @@ static const struct pci_device_id bcma_pci_bridge_tbl[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a9) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43aa) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) },
- { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43227) }, /* 0xA8DB */
+ { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43227) }, /* 0xa8db, BCM43217 (sic!) */
+ { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43228) }, /* 0xa8dc */
{ 0, },
};
MODULE_DEVICE_TABLE(pci, bcma_pci_bridge_tbl);
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
index d1656c2f70af..1000955ce09d 100644
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -132,7 +132,7 @@ static bool bcma_is_core_needed_early(u16 core_id)
return false;
}
-#ifdef CONFIG_OF
+#if defined(CONFIG_OF) && defined(CONFIG_OF_ADDRESS)
static struct device_node *bcma_of_find_child_device(struct platform_device *parent,
struct bcma_device *core)
{
diff --git a/drivers/block/null_blk.c b/drivers/block/null_blk.c
index 2671a3f02f0c..8001e812018b 100644
--- a/drivers/block/null_blk.c
+++ b/drivers/block/null_blk.c
@@ -450,14 +450,10 @@ static int init_driver_queues(struct nullb *nullb)
ret = setup_commands(nq);
if (ret)
- goto err_queue;
+ return ret;
nullb->nr_queues++;
}
-
return 0;
-err_queue:
- cleanup_queues(nullb);
- return ret;
}
static int null_add_dev(void)
@@ -507,7 +503,9 @@ static int null_add_dev(void)
goto out_cleanup_queues;
}
blk_queue_make_request(nullb->q, null_queue_bio);
- init_driver_queues(nullb);
+ rv = init_driver_queues(nullb);
+ if (rv)
+ goto out_cleanup_blk_queue;
} else {
nullb->q = blk_init_queue_node(null_request_fn, &nullb->lock, home_node);
if (!nullb->q) {
@@ -516,7 +514,9 @@ static int null_add_dev(void)
}
blk_queue_prep_rq(nullb->q, null_rq_prep_fn);
blk_queue_softirq_done(nullb->q, null_softirq_done_fn);
- init_driver_queues(nullb);
+ rv = init_driver_queues(nullb);
+ if (rv)
+ goto out_cleanup_blk_queue;
}
nullb->q->queuedata = nullb;
diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c
index 756b8ec00f16..0ebadf93b6c5 100644
--- a/drivers/block/sunvdc.c
+++ b/drivers/block/sunvdc.c
@@ -69,8 +69,6 @@ struct vdc_port {
u8 vdisk_mtype;
char disk_name[32];
-
- struct vio_disk_vtoc label;
};
static inline struct vdc_port *to_vdc_port(struct vio_driver_state *vio)
@@ -710,13 +708,6 @@ static int probe_disk(struct vdc_port *port)
if (comp.err)
return comp.err;
- err = generic_request(port, VD_OP_GET_VTOC,
- &port->label, sizeof(port->label));
- if (err < 0) {
- printk(KERN_ERR PFX "VD_OP_GET_VTOC returns error %d\n", err);
- return err;
- }
-
if (vdc_version_supported(port, 1, 1)) {
/* vdisk_size should be set during the handshake, if it wasn't
* then the underlying disk is reserved by another system
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index 0e63e8aa8279..2ad0b5bce44b 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -99,11 +99,12 @@ static ssize_t mem_used_total_show(struct device *dev,
{
u64 val = 0;
struct zram *zram = dev_to_zram(dev);
- struct zram_meta *meta = zram->meta;
down_read(&zram->init_lock);
- if (init_done(zram))
+ if (init_done(zram)) {
+ struct zram_meta *meta = zram->meta;
val = zs_get_total_pages(meta->mem_pool);
+ }
up_read(&zram->init_lock);
return scnprintf(buf, PAGE_SIZE, "%llu\n", val << PAGE_SHIFT);
@@ -173,16 +174,17 @@ static ssize_t mem_used_max_store(struct device *dev,
int err;
unsigned long val;
struct zram *zram = dev_to_zram(dev);
- struct zram_meta *meta = zram->meta;
err = kstrtoul(buf, 10, &val);
if (err || val != 0)
return -EINVAL;
down_read(&zram->init_lock);
- if (init_done(zram))
+ if (init_done(zram)) {
+ struct zram_meta *meta = zram->meta;
atomic_long_set(&zram->stats.max_used_pages,
zs_get_total_pages(meta->mem_pool));
+ }
up_read(&zram->init_lock);
return len;
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 2133f9d59d06..43005d4d3348 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -660,11 +660,11 @@ static bool __init
arch_timer_probed(int type, const struct of_device_id *matches)
{
struct device_node *dn;
- bool probed = false;
+ bool probed = true;
dn = of_find_matching_node(NULL, matches);
- if (dn && of_device_is_available(dn) && (arch_timers_present & type))
- probed = true;
+ if (dn && of_device_is_available(dn) && !(arch_timers_present & type))
+ probed = false;
of_node_put(dn);
return probed;
diff --git a/drivers/edac/cpc925_edac.c b/drivers/edac/cpc925_edac.c
index df6575f1430d..682288ced4ac 100644
--- a/drivers/edac/cpc925_edac.c
+++ b/drivers/edac/cpc925_edac.c
@@ -562,7 +562,7 @@ static void cpc925_mc_check(struct mem_ctl_info *mci)
if (apiexcp & UECC_EXCP_DETECTED) {
cpc925_mc_printk(mci, KERN_INFO, "DRAM UECC Fault\n");
- edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1,
+ edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1,
pfn, offset, 0,
csrow, -1, -1,
mci->ctl_name, "");
diff --git a/drivers/edac/e7xxx_edac.c b/drivers/edac/e7xxx_edac.c
index 3cda79bc8b00..ece3aef16bb1 100644
--- a/drivers/edac/e7xxx_edac.c
+++ b/drivers/edac/e7xxx_edac.c
@@ -226,7 +226,7 @@ static void process_ce(struct mem_ctl_info *mci, struct e7xxx_error_info *info)
static void process_ce_no_info(struct mem_ctl_info *mci)
{
edac_dbg(3, "\n");
- edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1, 0, 0, 0, -1, -1, -1,
+ edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1, 0, 0, 0, -1, -1, -1,
"e7xxx CE log register overflow", "");
}
diff --git a/drivers/edac/i3200_edac.c b/drivers/edac/i3200_edac.c
index 022a70273ada..aa98b136f5d0 100644
--- a/drivers/edac/i3200_edac.c
+++ b/drivers/edac/i3200_edac.c
@@ -242,11 +242,11 @@ static void i3200_process_error_info(struct mem_ctl_info *mci,
-1, -1,
"i3000 UE", "");
} else if (log & I3200_ECCERRLOG_CE) {
- edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1,
+ edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1,
0, 0, eccerrlog_syndrome(log),
eccerrlog_row(channel, log),
-1, -1,
- "i3000 UE", "");
+ "i3000 CE", "");
}
}
}
diff --git a/drivers/edac/i82860_edac.c b/drivers/edac/i82860_edac.c
index 3382f6344e42..4382343a7c60 100644
--- a/drivers/edac/i82860_edac.c
+++ b/drivers/edac/i82860_edac.c
@@ -124,7 +124,7 @@ static int i82860_process_error_info(struct mem_ctl_info *mci,
dimm->location[0], dimm->location[1], -1,
"i82860 UE", "");
else
- edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1,
+ edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1,
info->eap, 0, info->derrsyn,
dimm->location[0], dimm->location[1], -1,
"i82860 CE", "");
diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c
index 84c3cb15ccdd..8bf61d295ffd 100644
--- a/drivers/hid/hid-debug.c
+++ b/drivers/hid/hid-debug.c
@@ -946,6 +946,12 @@ static const char *keys[KEY_MAX + 1] = {
[KEY_BRIGHTNESS_MIN] = "BrightnessMin",
[KEY_BRIGHTNESS_MAX] = "BrightnessMax",
[KEY_BRIGHTNESS_AUTO] = "BrightnessAuto",
+ [KEY_KBDINPUTASSIST_PREV] = "KbdInputAssistPrev",
+ [KEY_KBDINPUTASSIST_NEXT] = "KbdInputAssistNext",
+ [KEY_KBDINPUTASSIST_PREVGROUP] = "KbdInputAssistPrevGroup",
+ [KEY_KBDINPUTASSIST_NEXTGROUP] = "KbdInputAssistNextGroup",
+ [KEY_KBDINPUTASSIST_ACCEPT] = "KbdInputAssistAccept",
+ [KEY_KBDINPUTASSIST_CANCEL] = "KbdInputAssistCancel",
};
static const char *relatives[REL_MAX + 1] = {
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index cd9c9e96cf0e..e23ab8b30626 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -298,6 +298,8 @@
#define USB_VENDOR_ID_ELAN 0x04f3
#define USB_DEVICE_ID_ELAN_TOUCHSCREEN 0x0089
+#define USB_DEVICE_ID_ELAN_TOUCHSCREEN_009B 0x009b
+#define USB_DEVICE_ID_ELAN_TOUCHSCREEN_016F 0x016f
#define USB_VENDOR_ID_ELECOM 0x056e
#define USB_DEVICE_ID_ELECOM_BM084 0x0061
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 2df7fddbd119..725f22ca47fc 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -695,7 +695,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
break;
case 0x5b: /* TransducerSerialNumber */
- set_bit(MSC_SERIAL, input->mscbit);
+ usage->type = EV_MSC;
+ usage->code = MSC_SERIAL;
+ bit = input->mscbit;
+ max = MSC_MAX;
break;
default: goto unknown;
@@ -862,6 +865,13 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
case 0x28b: map_key_clear(KEY_FORWARDMAIL); break;
case 0x28c: map_key_clear(KEY_SEND); break;
+ case 0x2c7: map_key_clear(KEY_KBDINPUTASSIST_PREV); break;
+ case 0x2c8: map_key_clear(KEY_KBDINPUTASSIST_NEXT); break;
+ case 0x2c9: map_key_clear(KEY_KBDINPUTASSIST_PREVGROUP); break;
+ case 0x2ca: map_key_clear(KEY_KBDINPUTASSIST_NEXTGROUP); break;
+ case 0x2cb: map_key_clear(KEY_KBDINPUTASSIST_ACCEPT); break;
+ case 0x2cc: map_key_clear(KEY_KBDINPUTASSIST_CANCEL); break;
+
default: goto ignore;
}
break;
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index f3cb5b0a4345..5014bb567b29 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -71,6 +71,8 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN, HID_QUIRK_ALWAYS_POLL },
+ { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN_009B, HID_QUIRK_ALWAYS_POLL },
+ { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN_016F, HID_QUIRK_ALWAYS_POLL },
{ USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET },
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index bda5994ceb68..8b72cf392b34 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -1173,18 +1173,24 @@ static struct ib_flow *mlx4_ib_create_flow(struct ib_qp *qp,
err = __mlx4_ib_create_flow(qp, flow_attr, domain, type[i],
&mflow->reg_id[i]);
if (err)
- goto err_free;
+ goto err_create_flow;
i++;
}
if (i < ARRAY_SIZE(type) && flow_attr->type == IB_FLOW_ATTR_NORMAL) {
err = mlx4_ib_tunnel_steer_add(qp, flow_attr, &mflow->reg_id[i]);
if (err)
- goto err_free;
+ goto err_create_flow;
+ i++;
}
return &mflow->ibflow;
+err_create_flow:
+ while (i) {
+ (void)__mlx4_ib_destroy_flow(to_mdev(qp->device)->dev, mflow->reg_id[i]);
+ i--;
+ }
err_free:
kfree(mflow);
return ERR_PTR(err);
diff --git a/drivers/media/common/saa7146/saa7146_core.c b/drivers/media/common/saa7146/saa7146_core.c
index 97afee672d07..4418119cf707 100644
--- a/drivers/media/common/saa7146/saa7146_core.c
+++ b/drivers/media/common/saa7146/saa7146_core.c
@@ -364,6 +364,9 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent
goto out;
}
+ /* create a nice device name */
+ sprintf(dev->name, "saa7146 (%d)", saa7146_num);
+
DEB_EE("pci:%p\n", pci);
err = pci_enable_device(pci);
@@ -438,9 +441,6 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent
/* the rest + print status message */
- /* create a nice device name */
- sprintf(dev->name, "saa7146 (%d)", saa7146_num);
-
pr_info("found saa7146 @ mem %p (revision %d, irq %d) (0x%04x,0x%04x)\n",
dev->mem, dev->revision, pci->irq,
pci->subsystem_vendor, pci->subsystem_device);
diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c
index 13734b8c7917..4cb90317ff45 100644
--- a/drivers/media/pci/cx23885/cx23885-dvb.c
+++ b/drivers/media/pci/cx23885/cx23885-dvb.c
@@ -1600,6 +1600,7 @@ static int dvb_register(struct cx23885_tsport *port)
break;
/* attach tuner */
+ memset(&m88ts2022_config, 0, sizeof(m88ts2022_config));
m88ts2022_config.fe = fe0->dvb.frontend;
m88ts2022_config.clock = 27000000;
memset(&info, 0, sizeof(struct i2c_board_info));
@@ -1635,6 +1636,7 @@ static int dvb_register(struct cx23885_tsport *port)
/* port c - terrestrial/cable */
case 2:
/* attach frontend */
+ memset(&si2168_config, 0, sizeof(si2168_config));
si2168_config.i2c_adapter = &adapter;
si2168_config.fe = &fe0->dvb.frontend;
si2168_config.ts_mode = SI2168_TS_SERIAL;
@@ -1654,6 +1656,7 @@ static int dvb_register(struct cx23885_tsport *port)
port->i2c_client_demod = client_demod;
/* attach tuner */
+ memset(&si2157_config, 0, sizeof(si2157_config));
si2157_config.fe = fe0->dvb.frontend;
memset(&info, 0, sizeof(struct i2c_board_info));
strlcpy(info.type, "si2157", I2C_NAME_SIZE);
diff --git a/drivers/media/pci/tw68/Kconfig b/drivers/media/pci/tw68/Kconfig
index 5425ba1e320d..95d5d5202048 100644
--- a/drivers/media/pci/tw68/Kconfig
+++ b/drivers/media/pci/tw68/Kconfig
@@ -1,7 +1,6 @@
config VIDEO_TW68
tristate "Techwell tw68x Video For Linux"
depends on VIDEO_DEV && PCI && VIDEO_V4L2
- select I2C_ALGOBIT
select VIDEOBUF2_DMA_SG
---help---
Support for Techwell tw68xx based frame grabber boards.
diff --git a/drivers/media/pci/tw68/tw68-core.c b/drivers/media/pci/tw68/tw68-core.c
index a6fb48cf7aae..63f0b64057cb 100644
--- a/drivers/media/pci/tw68/tw68-core.c
+++ b/drivers/media/pci/tw68/tw68-core.c
@@ -306,7 +306,7 @@ static int tw68_initdev(struct pci_dev *pci_dev,
/* get irq */
err = devm_request_irq(&pci_dev->dev, pci_dev->irq, tw68_irq,
- IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
+ IRQF_SHARED, dev->name, dev);
if (err < 0) {
pr_err("%s: can't get IRQ %d\n",
dev->name, pci_dev->irq);
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index bee9074ebc13..3aac88f1d54a 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -166,7 +166,7 @@ config VIDEO_MEM2MEM_DEINTERLACE
config VIDEO_SAMSUNG_S5P_G2D
tristate "Samsung S5P and EXYNOS4 G2D 2d graphics accelerator driver"
depends on VIDEO_DEV && VIDEO_V4L2
- depends on PLAT_S5P || ARCH_EXYNOS || COMPILE_TEST
+ depends on ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
depends on HAS_DMA
select VIDEOBUF2_DMA_CONTIG
select V4L2_MEM2MEM_DEV
@@ -178,7 +178,7 @@ config VIDEO_SAMSUNG_S5P_G2D
config VIDEO_SAMSUNG_S5P_JPEG
tristate "Samsung S5P/Exynos3250/Exynos4 JPEG codec driver"
depends on VIDEO_DEV && VIDEO_V4L2
- depends on PLAT_S5P || ARCH_EXYNOS || COMPILE_TEST
+ depends on ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
depends on HAS_DMA
select VIDEOBUF2_DMA_CONTIG
select V4L2_MEM2MEM_DEV
@@ -189,7 +189,7 @@ config VIDEO_SAMSUNG_S5P_JPEG
config VIDEO_SAMSUNG_S5P_MFC
tristate "Samsung S5P MFC Video Codec"
depends on VIDEO_DEV && VIDEO_V4L2
- depends on PLAT_S5P || ARCH_EXYNOS || COMPILE_TEST
+ depends on ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
depends on HAS_DMA
select VIDEOBUF2_DMA_CONTIG
default n
diff --git a/drivers/media/platform/exynos4-is/Kconfig b/drivers/media/platform/exynos4-is/Kconfig
index 77c951237744..b7b2e472240a 100644
--- a/drivers/media/platform/exynos4-is/Kconfig
+++ b/drivers/media/platform/exynos4-is/Kconfig
@@ -2,7 +2,7 @@
config VIDEO_SAMSUNG_EXYNOS4_IS
bool "Samsung S5P/EXYNOS4 SoC series Camera Subsystem driver"
depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
- depends on (PLAT_S5P || ARCH_EXYNOS || COMPILE_TEST)
+ depends on ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
depends on OF && COMMON_CLK
help
Say Y here to enable camera host interface devices for
diff --git a/drivers/media/platform/exynos4-is/fimc-core.c b/drivers/media/platform/exynos4-is/fimc-core.c
index b70fd996d794..aee92d908e49 100644
--- a/drivers/media/platform/exynos4-is/fimc-core.c
+++ b/drivers/media/platform/exynos4-is/fimc-core.c
@@ -832,6 +832,7 @@ err:
return -ENXIO;
}
+#if defined(CONFIG_PM_RUNTIME) || defined(CONFIG_PM_SLEEP)
static int fimc_m2m_suspend(struct fimc_dev *fimc)
{
unsigned long flags;
@@ -870,6 +871,7 @@ static int fimc_m2m_resume(struct fimc_dev *fimc)
return 0;
}
+#endif /* CONFIG_PM_RUNTIME || CONFIG_PM_SLEEP */
static const struct of_device_id fimc_of_match[];
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index e525a7c8d885..6fcc7f072ace 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -893,7 +893,7 @@ static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result,
unsigned long buffer, unsigned long size,
struct s5p_jpeg_ctx *ctx)
{
- int c, components, notfound;
+ int c, components = 0, notfound;
unsigned int height, width, word, subsampling = 0;
long length;
struct s5p_jpeg_buffer jpeg_buffer;
@@ -2632,6 +2632,7 @@ static int s5p_jpeg_remove(struct platform_device *pdev)
return 0;
}
+#if defined(CONFIG_PM_RUNTIME) || defined(CONFIG_PM_SLEEP)
static int s5p_jpeg_runtime_suspend(struct device *dev)
{
struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
@@ -2681,7 +2682,9 @@ static int s5p_jpeg_runtime_resume(struct device *dev)
return 0;
}
+#endif /* CONFIG_PM_RUNTIME || CONFIG_PM_SLEEP */
+#ifdef CONFIG_PM_SLEEP
static int s5p_jpeg_suspend(struct device *dev)
{
if (pm_runtime_suspended(dev))
@@ -2697,6 +2700,7 @@ static int s5p_jpeg_resume(struct device *dev)
return s5p_jpeg_runtime_resume(dev);
}
+#endif
static const struct dev_pm_ops s5p_jpeg_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(s5p_jpeg_suspend, s5p_jpeg_resume)
diff --git a/drivers/media/platform/s5p-tv/Kconfig b/drivers/media/platform/s5p-tv/Kconfig
index a9d56f8936b4..beb180e71ba0 100644
--- a/drivers/media/platform/s5p-tv/Kconfig
+++ b/drivers/media/platform/s5p-tv/Kconfig
@@ -9,7 +9,7 @@
config VIDEO_SAMSUNG_S5P_TV
bool "Samsung TV driver for S5P platform"
depends on PM_RUNTIME
- depends on PLAT_S5P || ARCH_EXYNOS || COMPILE_TEST
+ depends on ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
default n
---help---
Say Y here to enable selecting the TV output devices for
diff --git a/drivers/media/platform/vivid/Kconfig b/drivers/media/platform/vivid/Kconfig
index d71139a2ae00..c3090932f06d 100644
--- a/drivers/media/platform/vivid/Kconfig
+++ b/drivers/media/platform/vivid/Kconfig
@@ -1,8 +1,11 @@
config VIDEO_VIVID
tristate "Virtual Video Test Driver"
- depends on VIDEO_DEV && VIDEO_V4L2 && !SPARC32 && !SPARC64
+ depends on VIDEO_DEV && VIDEO_V4L2 && !SPARC32 && !SPARC64 && FB
select FONT_SUPPORT
select FONT_8x16
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
select VIDEOBUF2_VMALLOC
default n
---help---
diff --git a/drivers/media/platform/vivid/vivid-tpg.c b/drivers/media/platform/vivid/vivid-tpg.c
index 0c6fa53fa646..cbcd6250e7b2 100644
--- a/drivers/media/platform/vivid/vivid-tpg.c
+++ b/drivers/media/platform/vivid/vivid-tpg.c
@@ -136,7 +136,7 @@ int tpg_alloc(struct tpg_data *tpg, unsigned max_w)
tpg->black_line[plane] = vzalloc(max_w * pixelsz);
if (!tpg->black_line[plane])
return -ENOMEM;
- tpg->random_line[plane] = vzalloc(max_w * pixelsz);
+ tpg->random_line[plane] = vzalloc(max_w * 2 * pixelsz);
if (!tpg->random_line[plane])
return -ENOMEM;
}
diff --git a/drivers/media/radio/wl128x/fmdrv_common.c b/drivers/media/radio/wl128x/fmdrv_common.c
index 6f28f6e02ea5..704397f3c106 100644
--- a/drivers/media/radio/wl128x/fmdrv_common.c
+++ b/drivers/media/radio/wl128x/fmdrv_common.c
@@ -1256,7 +1256,7 @@ static int fm_download_firmware(struct fmdev *fmdev, const u8 *fw_name)
fmerr("Unable to read firmware(%s) content\n", fw_name);
return ret;
}
- fmdbg("Firmware(%s) length : %d bytes\n", fw_name, fw_entry->size);
+ fmdbg("Firmware(%s) length : %zu bytes\n", fw_name, fw_entry->size);
fw_data = (void *)fw_entry->data;
fw_len = fw_entry->size;
diff --git a/drivers/media/tuners/xc5000.c b/drivers/media/tuners/xc5000.c
index e44c8aba6074..803a0e63d47e 100644
--- a/drivers/media/tuners/xc5000.c
+++ b/drivers/media/tuners/xc5000.c
@@ -1333,9 +1333,9 @@ static int xc5000_release(struct dvb_frontend *fe)
if (priv) {
cancel_delayed_work(&priv->timer_sleep);
- hybrid_tuner_release_state(priv);
if (priv->firmware)
release_firmware(priv->firmware);
+ hybrid_tuner_release_state(priv);
}
mutex_unlock(&xc5000_list_mutex);
diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c
index 00758c83eec7..1896ab218b11 100644
--- a/drivers/media/usb/dvb-usb-v2/af9035.c
+++ b/drivers/media/usb/dvb-usb-v2/af9035.c
@@ -193,8 +193,8 @@ static int af9035_wr_reg_mask(struct dvb_usb_device *d, u32 reg, u8 val,
return af9035_wr_regs(d, reg, &val, 1);
}
-static int af9035_add_i2c_dev(struct dvb_usb_device *d, char *type, u8 addr,
- void *platform_data, struct i2c_adapter *adapter)
+static int af9035_add_i2c_dev(struct dvb_usb_device *d, const char *type,
+ u8 addr, void *platform_data, struct i2c_adapter *adapter)
{
int ret, num;
struct state *state = d_to_priv(d);
@@ -221,7 +221,7 @@ static int af9035_add_i2c_dev(struct dvb_usb_device *d, char *type, u8 addr,
goto err;
}
- request_module(board_info.type);
+ request_module("%s", board_info.type);
/* register I2C device */
client = i2c_new_device(adapter, &board_info);
diff --git a/drivers/media/usb/dvb-usb-v2/anysee.c b/drivers/media/usb/dvb-usb-v2/anysee.c
index d3c5f230e97a..ae917c042a52 100644
--- a/drivers/media/usb/dvb-usb-v2/anysee.c
+++ b/drivers/media/usb/dvb-usb-v2/anysee.c
@@ -630,8 +630,8 @@ error:
return ret;
}
-static int anysee_add_i2c_dev(struct dvb_usb_device *d, char *type, u8 addr,
- void *platform_data)
+static int anysee_add_i2c_dev(struct dvb_usb_device *d, const char *type,
+ u8 addr, void *platform_data)
{
int ret, num;
struct anysee_state *state = d_to_priv(d);
@@ -659,7 +659,7 @@ static int anysee_add_i2c_dev(struct dvb_usb_device *d, char *type, u8 addr,
goto err;
}
- request_module(board_info.type);
+ request_module("%s", board_info.type);
/* register I2C device */
client = i2c_new_device(adapter, &board_info);
diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c
index b5e52fe7957a..901cf2b952d7 100644
--- a/drivers/media/usb/em28xx/em28xx-core.c
+++ b/drivers/media/usb/em28xx/em28xx-core.c
@@ -504,7 +504,7 @@ EXPORT_SYMBOL_GPL(em28xx_audio_analog_set);
int em28xx_audio_setup(struct em28xx *dev)
{
int vid1, vid2, feat, cfg;
- u32 vid;
+ u32 vid = 0;
u8 i2s_samplerates;
if (dev->chip_id == CHIP_ID_EM2870 ||
diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c
index 581f6dad4ca9..23f8f6afa2e0 100644
--- a/drivers/media/usb/em28xx/em28xx-input.c
+++ b/drivers/media/usb/em28xx/em28xx-input.c
@@ -712,8 +712,10 @@ static int em28xx_ir_init(struct em28xx *dev)
em28xx_info("Registering input extension\n");
ir = kzalloc(sizeof(*ir), GFP_KERNEL);
+ if (!ir)
+ return -ENOMEM;
rc = rc_allocate_device();
- if (!ir || !rc)
+ if (!rc)
goto error;
/* record handles to ourself */
diff --git a/drivers/media/usb/hackrf/hackrf.c b/drivers/media/usb/hackrf/hackrf.c
index 328b5ba47a0a..fd1fa412e094 100644
--- a/drivers/media/usb/hackrf/hackrf.c
+++ b/drivers/media/usb/hackrf/hackrf.c
@@ -932,7 +932,7 @@ static int hackrf_set_bandwidth(struct hackrf_dev *dev)
dev->bandwidth->val = bandwidth;
dev->bandwidth->cur.val = bandwidth;
- dev_dbg(dev->dev, "bandwidth selected=%d\n", bandwidth_lut[i].freq);
+ dev_dbg(dev->dev, "bandwidth selected=%d\n", bandwidth);
u16tmp = 0;
u16tmp |= ((bandwidth >> 0) & 0xff) << 0;
diff --git a/drivers/media/usb/usbvision/usbvision-video.c b/drivers/media/usb/usbvision/usbvision-video.c
index 68bc9615660e..9bfa041e3316 100644
--- a/drivers/media/usb/usbvision/usbvision-video.c
+++ b/drivers/media/usb/usbvision/usbvision-video.c
@@ -446,6 +446,7 @@ static int usbvision_v4l2_close(struct file *file)
if (usbvision->remove_pending) {
printk(KERN_INFO "%s: Final disconnect\n", __func__);
usbvision_release(usbvision);
+ return 0;
}
mutex_unlock(&usbvision->v4l2_lock);
@@ -1221,6 +1222,7 @@ static int usbvision_radio_close(struct file *file)
if (usbvision->remove_pending) {
printk(KERN_INFO "%s: Final disconnect\n", __func__);
usbvision_release(usbvision);
+ return err_code;
}
mutex_unlock(&usbvision->v4l2_lock);
diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c
index 60a8e2c3631e..378ae02e593b 100644
--- a/drivers/media/usb/uvc/uvc_v4l2.c
+++ b/drivers/media/usb/uvc/uvc_v4l2.c
@@ -318,7 +318,6 @@ static int uvc_v4l2_set_format(struct uvc_streaming *stream,
stream->ctrl = probe;
stream->cur_format = format;
stream->cur_frame = frame;
- stream->frame_size = fmt->fmt.pix.sizeimage;
done:
mutex_unlock(&stream->mutex);
diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
index 9ace520bb079..df81b9c4faf1 100644
--- a/drivers/media/usb/uvc/uvc_video.c
+++ b/drivers/media/usb/uvc/uvc_video.c
@@ -1143,7 +1143,7 @@ static int uvc_video_encode_data(struct uvc_streaming *stream,
static void uvc_video_validate_buffer(const struct uvc_streaming *stream,
struct uvc_buffer *buf)
{
- if (stream->frame_size != buf->bytesused &&
+ if (stream->ctrl.dwMaxVideoFrameSize != buf->bytesused &&
!(stream->cur_format->flags & UVC_FMT_FLAG_COMPRESSED))
buf->error = 1;
}
diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
index 6f676c29ec09..864ada740360 100644
--- a/drivers/media/usb/uvc/uvcvideo.h
+++ b/drivers/media/usb/uvc/uvcvideo.h
@@ -457,7 +457,6 @@ struct uvc_streaming {
struct uvc_format *def_format;
struct uvc_format *cur_format;
struct uvc_frame *cur_frame;
- size_t frame_size;
/* Protect access to ctrl, cur_format, cur_frame and hardware video
* probe control.
diff --git a/drivers/media/v4l2-core/videobuf-dma-contig.c b/drivers/media/v4l2-core/videobuf-dma-contig.c
index bf80f0f7dfb8..e02353e340dd 100644
--- a/drivers/media/v4l2-core/videobuf-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf-dma-contig.c
@@ -305,6 +305,15 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,
/* Try to remap memory */
size = vma->vm_end - vma->vm_start;
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+ /* the "vm_pgoff" is just used in v4l2 to find the
+ * corresponding buffer data structure which is allocated
+ * earlier and it does not mean the offset from the physical
+ * buffer start address as usual. So set it to 0 to pass
+ * the sanity check in vm_iomap_memory().
+ */
+ vma->vm_pgoff = 0;
+
retval = vm_iomap_memory(vma, mem->dma_handle, size);
if (retval) {
dev_err(q->dev, "mmap: remap failed with error %d. ",
diff --git a/drivers/misc/cxl/fault.c b/drivers/misc/cxl/fault.c
index 69506ebd4d07..c99e896604ee 100644
--- a/drivers/misc/cxl/fault.c
+++ b/drivers/misc/cxl/fault.c
@@ -21,60 +21,64 @@
#include "cxl.h"
-static struct cxl_sste* find_free_sste(struct cxl_sste *primary_group,
- bool sec_hash,
- struct cxl_sste *secondary_group,
- unsigned int *lru)
+static bool sste_matches(struct cxl_sste *sste, struct copro_slb *slb)
{
- unsigned int i, entry;
- struct cxl_sste *sste, *group = primary_group;
-
- for (i = 0; i < 2; i++) {
- for (entry = 0; entry < 8; entry++) {
- sste = group + entry;
- if (!(be64_to_cpu(sste->esid_data) & SLB_ESID_V))
- return sste;
- }
- if (!sec_hash)
- break;
- group = secondary_group;
+ return ((sste->vsid_data == cpu_to_be64(slb->vsid)) &&
+ (sste->esid_data == cpu_to_be64(slb->esid)));
+}
+
+/*
+ * This finds a free SSTE for the given SLB, or returns NULL if it's already in
+ * the segment table.
+ */
+static struct cxl_sste* find_free_sste(struct cxl_context *ctx,
+ struct copro_slb *slb)
+{
+ struct cxl_sste *primary, *sste, *ret = NULL;
+ unsigned int mask = (ctx->sst_size >> 7) - 1; /* SSTP0[SegTableSize] */
+ unsigned int entry;
+ unsigned int hash;
+
+ if (slb->vsid & SLB_VSID_B_1T)
+ hash = (slb->esid >> SID_SHIFT_1T) & mask;
+ else /* 256M */
+ hash = (slb->esid >> SID_SHIFT) & mask;
+
+ primary = ctx->sstp + (hash << 3);
+
+ for (entry = 0, sste = primary; entry < 8; entry++, sste++) {
+ if (!ret && !(be64_to_cpu(sste->esid_data) & SLB_ESID_V))
+ ret = sste;
+ if (sste_matches(sste, slb))
+ return NULL;
}
+ if (ret)
+ return ret;
+
/* Nothing free, select an entry to cast out */
- if (sec_hash && (*lru & 0x8))
- sste = secondary_group + (*lru & 0x7);
- else
- sste = primary_group + (*lru & 0x7);
- *lru = (*lru + 1) & 0xf;
+ ret = primary + ctx->sst_lru;
+ ctx->sst_lru = (ctx->sst_lru + 1) & 0x7;
- return sste;
+ return ret;
}
static void cxl_load_segment(struct cxl_context *ctx, struct copro_slb *slb)
{
/* mask is the group index, we search primary and secondary here. */
- unsigned int mask = (ctx->sst_size >> 7)-1; /* SSTP0[SegTableSize] */
- bool sec_hash = 1;
struct cxl_sste *sste;
- unsigned int hash;
unsigned long flags;
-
- sec_hash = !!(cxl_p1n_read(ctx->afu, CXL_PSL_SR_An) & CXL_PSL_SR_An_SC);
-
- if (slb->vsid & SLB_VSID_B_1T)
- hash = (slb->esid >> SID_SHIFT_1T) & mask;
- else /* 256M */
- hash = (slb->esid >> SID_SHIFT) & mask;
-
spin_lock_irqsave(&ctx->sste_lock, flags);
- sste = find_free_sste(ctx->sstp + (hash << 3), sec_hash,
- ctx->sstp + ((~hash & mask) << 3), &ctx->sst_lru);
+ sste = find_free_sste(ctx, slb);
+ if (!sste)
+ goto out_unlock;
pr_devel("CXL Populating SST[%li]: %#llx %#llx\n",
sste - ctx->sstp, slb->vsid, slb->esid);
sste->vsid_data = cpu_to_be64(slb->vsid);
sste->esid_data = cpu_to_be64(slb->esid);
+out_unlock:
spin_unlock_irqrestore(&ctx->sste_lock, flags);
}
diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c
index 623286a77114..d47532e8f4f1 100644
--- a/drivers/misc/cxl/native.c
+++ b/drivers/misc/cxl/native.c
@@ -417,7 +417,7 @@ static int attach_afu_directed(struct cxl_context *ctx, u64 wed, u64 amr)
ctx->elem->haurp = 0; /* disable */
ctx->elem->sdr = cpu_to_be64(mfspr(SPRN_SDR1));
- sr = CXL_PSL_SR_An_SC;
+ sr = 0;
if (ctx->master)
sr |= CXL_PSL_SR_An_MP;
if (mfspr(SPRN_LPCR) & LPCR_TC)
@@ -508,7 +508,7 @@ static int attach_dedicated(struct cxl_context *ctx, u64 wed, u64 amr)
u64 sr;
int rc;
- sr = CXL_PSL_SR_An_SC;
+ sr = 0;
set_endian(sr);
if (ctx->master)
sr |= CXL_PSL_SR_An_MP;
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 4706386b7d34..f9009be3f307 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -135,6 +135,7 @@ config MACVLAN
config MACVTAP
tristate "MAC-VLAN based tap driver"
depends on MACVLAN
+ depends on INET
help
This adds a specialized tap character device driver that is based
on the MAC-VLAN network interface, called macvtap. A macvtap device
@@ -200,6 +201,7 @@ config RIONET_RX_SIZE
config TUN
tristate "Universal TUN/TAP device driver support"
+ depends on INET
select CRC32
---help---
TUN/TAP provides packet reception and transmission for user space
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index 1020a7af67cf..78d8e876f3aa 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -395,7 +395,7 @@ static int mv88e6171_get_sset_count(struct dsa_switch *ds)
}
struct dsa_switch_driver mv88e6171_switch_driver = {
- .tag_protocol = DSA_TAG_PROTO_DSA,
+ .tag_protocol = DSA_TAG_PROTO_EDSA,
.priv_size = sizeof(struct mv88e6xxx_priv_state),
.probe = mv88e6171_probe,
.setup = mv88e6171_setup,
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
index 29554992215a..2349ea970255 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
@@ -1465,7 +1465,7 @@ static int xgbe_set_features(struct net_device *netdev,
{
struct xgbe_prv_data *pdata = netdev_priv(netdev);
struct xgbe_hw_if *hw_if = &pdata->hw_if;
- unsigned int rxcsum, rxvlan, rxvlan_filter;
+ netdev_features_t rxcsum, rxvlan, rxvlan_filter;
rxcsum = pdata->netdev_features & NETIF_F_RXCSUM;
rxvlan = pdata->netdev_features & NETIF_F_HW_VLAN_CTAG_RX;
@@ -1598,7 +1598,8 @@ static int xgbe_rx_poll(struct xgbe_channel *channel, int budget)
struct skb_shared_hwtstamps *hwtstamps;
unsigned int incomplete, error, context_next, context;
unsigned int len, put_len, max_len;
- int received = 0;
+ unsigned int received = 0;
+ int packet_count = 0;
DBGPR("-->xgbe_rx_poll: budget=%d\n", budget);
@@ -1608,7 +1609,7 @@ static int xgbe_rx_poll(struct xgbe_channel *channel, int budget)
rdata = XGBE_GET_DESC_DATA(ring, ring->cur);
packet = &ring->packet_data;
- while (received < budget) {
+ while (packet_count < budget) {
DBGPR(" cur = %d\n", ring->cur);
/* First time in loop see if we need to restore state */
@@ -1662,7 +1663,7 @@ read_again:
if (packet->errors)
DBGPR("Error in received packet\n");
dev_kfree_skb(skb);
- continue;
+ goto next_packet;
}
if (!context) {
@@ -1677,7 +1678,7 @@ read_again:
}
dev_kfree_skb(skb);
- continue;
+ goto next_packet;
}
memcpy(skb_tail_pointer(skb), rdata->skb->data,
put_len);
@@ -1694,7 +1695,7 @@ read_again:
/* Stray Context Descriptor? */
if (!skb)
- continue;
+ goto next_packet;
/* Be sure we don't exceed the configured MTU */
max_len = netdev->mtu + ETH_HLEN;
@@ -1705,7 +1706,7 @@ read_again:
if (skb->len > max_len) {
DBGPR("packet length exceeds configured MTU\n");
dev_kfree_skb(skb);
- continue;
+ goto next_packet;
}
#ifdef XGMAC_ENABLE_RX_PKT_DUMP
@@ -1739,6 +1740,9 @@ read_again:
netdev->last_rx = jiffies;
napi_gro_receive(&pdata->napi, skb);
+
+next_packet:
+ packet_count++;
}
/* Check if we need to save state before leaving */
@@ -1752,9 +1756,9 @@ read_again:
rdata->state.error = error;
}
- DBGPR("<--xgbe_rx_poll: received = %d\n", received);
+ DBGPR("<--xgbe_rx_poll: packet_count = %d\n", packet_count);
- return received;
+ return packet_count;
}
static int xgbe_poll(struct napi_struct *napi, int budget)
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c b/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c
index e6d24c210198..c22f32622fa9 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c
@@ -124,20 +124,18 @@ static int xgene_enet_ecc_init(struct xgene_enet_pdata *p)
{
struct net_device *ndev = p->ndev;
u32 data;
- int i;
+ int i = 0;
xgene_enet_wr_diag_csr(p, ENET_CFG_MEM_RAM_SHUTDOWN_ADDR, 0);
- for (i = 0; i < 10 && data != ~0U ; i++) {
+ do {
usleep_range(100, 110);
data = xgene_enet_rd_diag_csr(p, ENET_BLOCK_MEM_RDY_ADDR);
- }
+ if (data == ~0U)
+ return 0;
+ } while (++i < 10);
- if (data != ~0U) {
- netdev_err(ndev, "Failed to release memory from shutdown\n");
- return -ENODEV;
- }
-
- return 0;
+ netdev_err(ndev, "Failed to release memory from shutdown\n");
+ return -ENODEV;
}
static void xgene_enet_config_ring_if_assoc(struct xgene_enet_pdata *p)
diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c
index 9ae36979bdee..3a6778a667f4 100644
--- a/drivers/net/ethernet/broadcom/bcmsysport.c
+++ b/drivers/net/ethernet/broadcom/bcmsysport.c
@@ -1397,6 +1397,9 @@ static void bcm_sysport_netif_start(struct net_device *dev)
/* Enable NAPI */
napi_enable(&priv->napi);
+ /* Enable RX interrupt and TX ring full interrupt */
+ intrl2_0_mask_clear(priv, INTRL2_0_RDMA_MBDONE | INTRL2_0_TX_RING_FULL);
+
phy_start(priv->phydev);
/* Enable TX interrupts for the 32 TXQs */
@@ -1499,9 +1502,6 @@ static int bcm_sysport_open(struct net_device *dev)
if (ret)
goto out_free_rx_ring;
- /* Enable RX interrupt and TX ring full interrupt */
- intrl2_0_mask_clear(priv, INTRL2_0_RDMA_MBDONE | INTRL2_0_TX_RING_FULL);
-
/* Turn on TDMA */
ret = tdma_enable_set(priv, 1);
if (ret)
@@ -1858,6 +1858,8 @@ static int bcm_sysport_resume(struct device *d)
if (!netif_running(dev))
return 0;
+ umac_reset(priv);
+
/* We may have been suspended and never received a WOL event that
* would turn off MPD detection, take care of that now
*/
@@ -1885,9 +1887,6 @@ static int bcm_sysport_resume(struct device *d)
netif_device_attach(dev);
- /* Enable RX interrupt and TX ring full interrupt */
- intrl2_0_mask_clear(priv, INTRL2_0_RDMA_MBDONE | INTRL2_0_TX_RING_FULL);
-
/* RX pipe enable */
topctrl_writel(priv, 0, RX_FLUSH_CNTL);
diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c
index 23f23c97c2ad..f05fab65d78a 100644
--- a/drivers/net/ethernet/broadcom/cnic.c
+++ b/drivers/net/ethernet/broadcom/cnic.c
@@ -382,10 +382,8 @@ static int cnic_iscsi_nl_msg_recv(struct cnic_dev *dev, u32 msg_type,
if (l5_cid >= MAX_CM_SK_TBL_SZ)
break;
- rcu_read_lock();
if (!rcu_access_pointer(cp->ulp_ops[CNIC_ULP_L4])) {
rc = -ENODEV;
- rcu_read_unlock();
break;
}
csk = &cp->csk_tbl[l5_cid];
@@ -414,7 +412,6 @@ static int cnic_iscsi_nl_msg_recv(struct cnic_dev *dev, u32 msg_type,
}
}
csk_put(csk);
- rcu_read_unlock();
rc = 0;
}
}
@@ -615,7 +612,7 @@ static int cnic_unregister_device(struct cnic_dev *dev, int ulp_type)
cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL);
mutex_lock(&cnic_lock);
- if (rcu_dereference(cp->ulp_ops[ulp_type])) {
+ if (rcu_access_pointer(cp->ulp_ops[ulp_type])) {
RCU_INIT_POINTER(cp->ulp_ops[ulp_type], NULL);
cnic_put(dev);
} else {
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c
index 8edf0f5bd679..6fe300e316c3 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c
@@ -60,6 +60,42 @@ void cxgb4_dcb_version_init(struct net_device *dev)
dcb->dcb_version = FW_PORT_DCB_VER_AUTO;
}
+static void cxgb4_dcb_cleanup_apps(struct net_device *dev)
+{
+ struct port_info *pi = netdev2pinfo(dev);
+ struct adapter *adap = pi->adapter;
+ struct port_dcb_info *dcb = &pi->dcb;
+ struct dcb_app app;
+ int i, err;
+
+ /* zero priority implies remove */
+ app.priority = 0;
+
+ for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
+ /* Check if app list is exhausted */
+ if (!dcb->app_priority[i].protocolid)
+ break;
+
+ app.protocol = dcb->app_priority[i].protocolid;
+
+ if (dcb->dcb_version == FW_PORT_DCB_VER_IEEE) {
+ app.selector = dcb->app_priority[i].sel_field + 1;
+ err = dcb_ieee_setapp(dev, &app);
+ } else {
+ app.selector = !!(dcb->app_priority[i].sel_field);
+ err = dcb_setapp(dev, &app);
+ }
+
+ if (err) {
+ dev_err(adap->pdev_dev,
+ "Failed DCB Clear %s Application Priority: sel=%d, prot=%d, , err=%d\n",
+ dcb_ver_array[dcb->dcb_version], app.selector,
+ app.protocol, -err);
+ break;
+ }
+ }
+}
+
/* Finite State machine for Data Center Bridging.
*/
void cxgb4_dcb_state_fsm(struct net_device *dev,
@@ -80,7 +116,6 @@ void cxgb4_dcb_state_fsm(struct net_device *dev,
/* we're going to use Host DCB */
dcb->state = CXGB4_DCB_STATE_HOST;
dcb->supported = CXGB4_DCBX_HOST_SUPPORT;
- dcb->enabled = 1;
break;
}
@@ -145,6 +180,7 @@ void cxgb4_dcb_state_fsm(struct net_device *dev,
* state. We need to reset back to a ground state
* of incomplete.
*/
+ cxgb4_dcb_cleanup_apps(dev);
cxgb4_dcb_state_init(dev);
dcb->state = CXGB4_DCB_STATE_FW_INCOMPLETE;
dcb->supported = CXGB4_DCBX_FW_SUPPORT;
@@ -349,6 +385,12 @@ static u8 cxgb4_setstate(struct net_device *dev, u8 enabled)
{
struct port_info *pi = netdev2pinfo(dev);
+ /* If DCBx is host-managed, dcb is enabled by outside lldp agents */
+ if (pi->dcb.state == CXGB4_DCB_STATE_HOST) {
+ pi->dcb.enabled = enabled;
+ return 0;
+ }
+
/* Firmware doesn't provide any mechanism to control the DCB state.
*/
if (enabled != (pi->dcb.state == CXGB4_DCB_STATE_FW_ALLSYNCED))
@@ -833,11 +875,16 @@ static int cxgb4_setapp(struct net_device *dev, u8 app_idtype, u16 app_id,
/* Return whether IEEE Data Center Bridging has been negotiated.
*/
-static inline int cxgb4_ieee_negotiation_complete(struct net_device *dev)
+static inline int
+cxgb4_ieee_negotiation_complete(struct net_device *dev,
+ enum cxgb4_dcb_fw_msgs dcb_subtype)
{
struct port_info *pi = netdev2pinfo(dev);
struct port_dcb_info *dcb = &pi->dcb;
+ if (dcb_subtype && !(dcb->msgs & dcb_subtype))
+ return 0;
+
return (dcb->state == CXGB4_DCB_STATE_FW_ALLSYNCED &&
(dcb->supported & DCB_CAP_DCBX_VER_IEEE));
}
@@ -850,7 +897,7 @@ static int cxgb4_ieee_getapp(struct net_device *dev, struct dcb_app *app)
{
int prio;
- if (!cxgb4_ieee_negotiation_complete(dev))
+ if (!cxgb4_ieee_negotiation_complete(dev, CXGB4_DCB_FW_APP_ID))
return -EINVAL;
if (!(app->selector && app->protocol))
return -EINVAL;
@@ -872,7 +919,7 @@ static int cxgb4_ieee_setapp(struct net_device *dev, struct dcb_app *app)
{
int ret;
- if (!cxgb4_ieee_negotiation_complete(dev))
+ if (!cxgb4_ieee_negotiation_complete(dev, CXGB4_DCB_FW_APP_ID))
return -EINVAL;
if (!(app->selector && app->protocol))
return -EINVAL;
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index 3f60070f2519..8520d5529df8 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -694,7 +694,11 @@ int cxgb4_dcb_enabled(const struct net_device *dev)
#ifdef CONFIG_CHELSIO_T4_DCB
struct port_info *pi = netdev_priv(dev);
- return pi->dcb.state == CXGB4_DCB_STATE_FW_ALLSYNCED;
+ if (!pi->dcb.enabled)
+ return 0;
+
+ return ((pi->dcb.state == CXGB4_DCB_STATE_FW_ALLSYNCED) ||
+ (pi->dcb.state == CXGB4_DCB_STATE_HOST));
#else
return 0;
#endif
@@ -6610,6 +6614,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
spin_lock_init(&adapter->stats_lock);
spin_lock_init(&adapter->tid_release_lock);
+ spin_lock_init(&adapter->win0_lock);
INIT_WORK(&adapter->tid_release_task, process_tid_release_list);
INIT_WORK(&adapter->db_full_task, process_db_full);
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
index bfa398d91826..0b42bddaf284 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
@@ -2929,14 +2929,14 @@ static const struct pci_device_id cxgb4vf_pci_tbl[] = {
CH_DEVICE(0x480d), /* T480-cr */
CH_DEVICE(0x480e), /* T440-lp-cr */
CH_DEVICE(0x4880),
- CH_DEVICE(0x4880),
- CH_DEVICE(0x4880),
- CH_DEVICE(0x4880),
- CH_DEVICE(0x4880),
- CH_DEVICE(0x4880),
- CH_DEVICE(0x4880),
- CH_DEVICE(0x4880),
- CH_DEVICE(0x4880),
+ CH_DEVICE(0x4881),
+ CH_DEVICE(0x4882),
+ CH_DEVICE(0x4883),
+ CH_DEVICE(0x4884),
+ CH_DEVICE(0x4885),
+ CH_DEVICE(0x4886),
+ CH_DEVICE(0x4887),
+ CH_DEVICE(0x4888),
CH_DEVICE(0x5801), /* T520-cr */
CH_DEVICE(0x5802), /* T522-cr */
CH_DEVICE(0x5803), /* T540-cr */
diff --git a/drivers/net/ethernet/cisco/enic/enic_clsf.c b/drivers/net/ethernet/cisco/enic/enic_clsf.c
index 69dfd3c9e529..0be6850be8a2 100644
--- a/drivers/net/ethernet/cisco/enic/enic_clsf.c
+++ b/drivers/net/ethernet/cisco/enic/enic_clsf.c
@@ -86,7 +86,7 @@ void enic_rfs_flw_tbl_free(struct enic *enic)
int i;
enic_rfs_timer_stop(enic);
- spin_lock(&enic->rfs_h.lock);
+ spin_lock_bh(&enic->rfs_h.lock);
enic->rfs_h.free = 0;
for (i = 0; i < (1 << ENIC_RFS_FLW_BITSHIFT); i++) {
struct hlist_head *hhead;
@@ -100,7 +100,7 @@ void enic_rfs_flw_tbl_free(struct enic *enic)
kfree(n);
}
}
- spin_unlock(&enic->rfs_h.lock);
+ spin_unlock_bh(&enic->rfs_h.lock);
}
struct enic_rfs_fltr_node *htbl_fltr_search(struct enic *enic, u16 fltr_id)
@@ -128,7 +128,7 @@ void enic_flow_may_expire(unsigned long data)
bool res;
int j;
- spin_lock(&enic->rfs_h.lock);
+ spin_lock_bh(&enic->rfs_h.lock);
for (j = 0; j < ENIC_CLSF_EXPIRE_COUNT; j++) {
struct hlist_head *hhead;
struct hlist_node *tmp;
@@ -148,7 +148,7 @@ void enic_flow_may_expire(unsigned long data)
}
}
}
- spin_unlock(&enic->rfs_h.lock);
+ spin_unlock_bh(&enic->rfs_h.lock);
mod_timer(&enic->rfs_h.rfs_may_expire, jiffies + HZ/4);
}
@@ -183,7 +183,7 @@ int enic_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
return -EPROTONOSUPPORT;
tbl_idx = skb_get_hash_raw(skb) & ENIC_RFS_FLW_MASK;
- spin_lock(&enic->rfs_h.lock);
+ spin_lock_bh(&enic->rfs_h.lock);
n = htbl_key_search(&enic->rfs_h.ht_head[tbl_idx], &keys);
if (n) { /* entry already present */
@@ -277,7 +277,7 @@ int enic_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
}
ret_unlock:
- spin_unlock(&enic->rfs_h.lock);
+ spin_unlock_bh(&enic->rfs_h.lock);
return res;
}
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
index 929bfe70080a..180e53fa628f 100644
--- a/drivers/net/ethernet/cisco/enic/enic_main.c
+++ b/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -1674,13 +1674,13 @@ static int enic_stop(struct net_device *netdev)
enic_dev_disable(enic);
- local_bh_disable();
for (i = 0; i < enic->rq_count; i++) {
napi_disable(&enic->napi[i]);
+ local_bh_disable();
while (!enic_poll_lock_napi(&enic->rq[i]))
mdelay(1);
+ local_bh_enable();
}
- local_bh_enable();
netif_carrier_off(netdev);
netif_tx_disable(netdev);
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 81b96cf87574..50a851db2852 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1581,7 +1581,8 @@ fec_enet_interrupt(int irq, void *dev_id)
complete(&fep->mdio_done);
}
- fec_ptp_check_pps_event(fep);
+ if (fep->ptp_clock)
+ fec_ptp_check_pps_event(fep);
return ret;
}
diff --git a/drivers/net/ethernet/freescale/fs_enet/mac-fec.c b/drivers/net/ethernet/freescale/fs_enet/mac-fec.c
index 3d4e08be1709..b34214e2df5f 100644
--- a/drivers/net/ethernet/freescale/fs_enet/mac-fec.c
+++ b/drivers/net/ethernet/freescale/fs_enet/mac-fec.c
@@ -341,6 +341,9 @@ static void restart(struct net_device *dev)
FC(fecp, x_cntrl, FEC_TCNTRL_FDEN); /* FD disable */
}
+ /* Restore multicast and promiscuous settings */
+ set_multicast_list(dev);
+
/*
* Enable interrupts we wish to service.
*/
diff --git a/drivers/net/ethernet/freescale/fs_enet/mac-scc.c b/drivers/net/ethernet/freescale/fs_enet/mac-scc.c
index f30411f0701f..7a184e8816a4 100644
--- a/drivers/net/ethernet/freescale/fs_enet/mac-scc.c
+++ b/drivers/net/ethernet/freescale/fs_enet/mac-scc.c
@@ -355,6 +355,9 @@ static void restart(struct net_device *dev)
if (fep->phydev->duplex)
S16(sccp, scc_psmr, SCC_PSMR_LPB | SCC_PSMR_FDE);
+ /* Restore multicast and promiscuous settings */
+ set_multicast_list(dev);
+
S32(sccp, scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
}
diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c
index 5f6aded512f5..24f3986cfae2 100644
--- a/drivers/net/ethernet/intel/e1000/e1000_main.c
+++ b/drivers/net/ethernet/intel/e1000/e1000_main.c
@@ -1075,7 +1075,10 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
NETIF_F_HW_CSUM |
NETIF_F_SG);
- netdev->priv_flags |= IFF_UNICAST_FLT;
+ /* Do not set IFF_UNICAST_FLT for VMWare's 82545EM */
+ if (hw->device_id != E1000_DEV_ID_82545EM_COPPER ||
+ hw->subsystem_vendor_id != PCI_VENDOR_ID_VMWARE)
+ netdev->priv_flags |= IFF_UNICAST_FLT;
adapter->en_mng_pt = e1000_enable_mng_pass_thru(hw);
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index ed5f1c15fb0f..c3a7f4a4b775 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -6151,7 +6151,7 @@ static void i40e_handle_mdd_event(struct i40e_pf *pf)
I40E_GL_MDET_TX_PF_NUM_SHIFT;
u8 vf_num = (reg & I40E_GL_MDET_TX_VF_NUM_MASK) >>
I40E_GL_MDET_TX_VF_NUM_SHIFT;
- u8 event = (reg & I40E_GL_MDET_TX_EVENT_SHIFT) >>
+ u8 event = (reg & I40E_GL_MDET_TX_EVENT_MASK) >>
I40E_GL_MDET_TX_EVENT_SHIFT;
u8 queue = (reg & I40E_GL_MDET_TX_QUEUE_MASK) >>
I40E_GL_MDET_TX_QUEUE_SHIFT;
@@ -6165,7 +6165,7 @@ static void i40e_handle_mdd_event(struct i40e_pf *pf)
if (reg & I40E_GL_MDET_RX_VALID_MASK) {
u8 func = (reg & I40E_GL_MDET_RX_FUNCTION_MASK) >>
I40E_GL_MDET_RX_FUNCTION_SHIFT;
- u8 event = (reg & I40E_GL_MDET_RX_EVENT_SHIFT) >>
+ u8 event = (reg & I40E_GL_MDET_RX_EVENT_MASK) >>
I40E_GL_MDET_RX_EVENT_SHIFT;
u8 queue = (reg & I40E_GL_MDET_RX_QUEUE_MASK) >>
I40E_GL_MDET_RX_QUEUE_SHIFT;
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index a21b14495ebd..a2d72a87cbde 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -6537,6 +6537,9 @@ static bool igb_can_reuse_rx_page(struct igb_rx_buffer *rx_buffer,
if (unlikely(page_to_nid(page) != numa_node_id()))
return false;
+ if (unlikely(page->pfmemalloc))
+ return false;
+
#if (PAGE_SIZE < 8192)
/* if we are only owner of page we can reuse it */
if (unlikely(page_count(page) != 1))
@@ -6603,7 +6606,8 @@ static bool igb_add_rx_frag(struct igb_ring *rx_ring,
memcpy(__skb_put(skb, size), va, ALIGN(size, sizeof(long)));
/* we can reuse buffer as-is, just make sure it is local */
- if (likely(page_to_nid(page) == numa_node_id()))
+ if (likely((page_to_nid(page) == numa_node_id()) &&
+ !page->pfmemalloc))
return true;
/* this page cannot be reused so discard it */
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
index 3ce4a258f945..0ae038b9af90 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
@@ -342,12 +342,16 @@ static int ixgbe_set_settings(struct net_device *netdev,
if (old == advertised)
return err;
/* this sets the link speed and restarts auto-neg */
+ while (test_and_set_bit(__IXGBE_IN_SFP_INIT, &adapter->state))
+ usleep_range(1000, 2000);
+
hw->mac.autotry_restart = true;
err = hw->mac.ops.setup_link(hw, advertised, true);
if (err) {
e_info(probe, "setup link failed with code %d\n", err);
hw->mac.ops.setup_link(hw, old, true);
}
+ clear_bit(__IXGBE_IN_SFP_INIT, &adapter->state);
} else {
/* in this case we currently only support 10Gb/FULL */
u32 speed = ethtool_cmd_speed(ecmd);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index fec5212d4337..d2df4e3d1032 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -4321,8 +4321,8 @@ static void ixgbe_clean_rx_ring(struct ixgbe_ring *rx_ring)
IXGBE_CB(skb)->page_released = false;
}
dev_kfree_skb(skb);
+ rx_buffer->skb = NULL;
}
- rx_buffer->skb = NULL;
if (rx_buffer->dma)
dma_unmap_page(dev, rx_buffer->dma,
ixgbe_rx_pg_size(rx_ring),
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
index 34c137878545..454d9fea640e 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
@@ -836,8 +836,11 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
* whether LSO is used */
tx_desc->ctrl.srcrb_flags = priv->ctrl_flags;
if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
- tx_desc->ctrl.srcrb_flags |= cpu_to_be32(MLX4_WQE_CTRL_IP_CSUM |
- MLX4_WQE_CTRL_TCP_UDP_CSUM);
+ if (!skb->encapsulation)
+ tx_desc->ctrl.srcrb_flags |= cpu_to_be32(MLX4_WQE_CTRL_IP_CSUM |
+ MLX4_WQE_CTRL_TCP_UDP_CSUM);
+ else
+ tx_desc->ctrl.srcrb_flags |= cpu_to_be32(MLX4_WQE_CTRL_IP_CSUM);
ring->tx_csum++;
}
diff --git a/drivers/net/ethernet/mellanox/mlx4/eq.c b/drivers/net/ethernet/mellanox/mlx4/eq.c
index a49c9d11d8a5..49290a405903 100644
--- a/drivers/net/ethernet/mellanox/mlx4/eq.c
+++ b/drivers/net/ethernet/mellanox/mlx4/eq.c
@@ -1026,6 +1026,7 @@ static void mlx4_free_eq(struct mlx4_dev *dev,
pr_cont("\n");
}
}
+ synchronize_irq(eq->irq);
mlx4_mtt_cleanup(dev, &eq->mtt);
for (i = 0; i < npages; ++i)
diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c
index ca0f98c95105..872843179f44 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mcg.c
+++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c
@@ -955,6 +955,10 @@ static void mlx4_err_rule(struct mlx4_dev *dev, char *str,
cur->ib.dst_gid_msk);
break;
+ case MLX4_NET_TRANS_RULE_ID_VXLAN:
+ len += snprintf(buf + len, BUF_SIZE - len,
+ "VNID = %d ", be32_to_cpu(cur->vxlan.vni));
+ break;
case MLX4_NET_TRANS_RULE_ID_IPV6:
break;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eq.c b/drivers/net/ethernet/mellanox/mlx5/core/eq.c
index ed53291468f3..a278238a2db6 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eq.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eq.c
@@ -420,6 +420,7 @@ int mlx5_destroy_unmap_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq)
if (err)
mlx5_core_warn(dev, "failed to destroy a previously created eq: eqn %d\n",
eq->eqn);
+ synchronize_irq(table->msix_arr[eq->irqn].vector);
mlx5_buf_free(dev, &eq->buf);
return err;
diff --git a/drivers/net/ethernet/sfc/tx.c b/drivers/net/ethernet/sfc/tx.c
index ee84a90e371c..aaf2987512b5 100644
--- a/drivers/net/ethernet/sfc/tx.c
+++ b/drivers/net/ethernet/sfc/tx.c
@@ -343,8 +343,6 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
unsigned short dma_flags;
int i = 0;
- EFX_BUG_ON_PARANOID(tx_queue->write_count > tx_queue->insert_count);
-
if (skb_shinfo(skb)->gso_size)
return efx_enqueue_skb_tso(tx_queue, skb);
@@ -1258,8 +1256,6 @@ static int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue,
/* Find the packet protocol and sanity-check it */
state.protocol = efx_tso_check_protocol(skb);
- EFX_BUG_ON_PARANOID(tx_queue->write_count > tx_queue->insert_count);
-
rc = tso_start(&state, efx, skb);
if (rc)
goto mem_err;
diff --git a/drivers/net/ethernet/smsc/smc91x.c b/drivers/net/ethernet/smsc/smc91x.c
index 5e94d00b96b3..2c62208077fe 100644
--- a/drivers/net/ethernet/smsc/smc91x.c
+++ b/drivers/net/ethernet/smsc/smc91x.c
@@ -81,6 +81,7 @@ static const char version[] =
#include <linux/workqueue.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/of_gpio.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
@@ -2188,6 +2189,41 @@ static const struct of_device_id smc91x_match[] = {
{},
};
MODULE_DEVICE_TABLE(of, smc91x_match);
+
+/**
+ * of_try_set_control_gpio - configure a gpio if it exists
+ */
+static int try_toggle_control_gpio(struct device *dev,
+ struct gpio_desc **desc,
+ const char *name, int index,
+ int value, unsigned int nsdelay)
+{
+ struct gpio_desc *gpio = *desc;
+ int res;
+
+ gpio = devm_gpiod_get_index(dev, name, index);
+ if (IS_ERR(gpio)) {
+ if (PTR_ERR(gpio) == -ENOENT) {
+ *desc = NULL;
+ return 0;
+ }
+
+ return PTR_ERR(gpio);
+ }
+ res = gpiod_direction_output(gpio, !value);
+ if (res) {
+ dev_err(dev, "unable to toggle gpio %s: %i\n", name, res);
+ devm_gpiod_put(dev, gpio);
+ gpio = NULL;
+ return res;
+ }
+ if (nsdelay)
+ usleep_range(nsdelay, 2 * nsdelay);
+ gpiod_set_value_cansleep(gpio, value);
+ *desc = gpio;
+
+ return 0;
+}
#endif
/*
@@ -2237,6 +2273,28 @@ static int smc_drv_probe(struct platform_device *pdev)
struct device_node *np = pdev->dev.of_node;
u32 val;
+ /* Optional pwrdwn GPIO configured? */
+ ret = try_toggle_control_gpio(&pdev->dev, &lp->power_gpio,
+ "power", 0, 0, 100);
+ if (ret)
+ return ret;
+
+ /*
+ * Optional reset GPIO configured? Minimum 100 ns reset needed
+ * according to LAN91C96 datasheet page 14.
+ */
+ ret = try_toggle_control_gpio(&pdev->dev, &lp->reset_gpio,
+ "reset", 0, 0, 100);
+ if (ret)
+ return ret;
+
+ /*
+ * Need to wait for optional EEPROM to load, max 750 us according
+ * to LAN91C96 datasheet page 55.
+ */
+ if (lp->reset_gpio)
+ usleep_range(750, 1000);
+
/* Combination of IO widths supported, default to 16-bit */
if (!of_property_read_u32(np, "reg-io-width", &val)) {
if (val & 1)
diff --git a/drivers/net/ethernet/smsc/smc91x.h b/drivers/net/ethernet/smsc/smc91x.h
index 47dce918eb0f..2a38dacbbd27 100644
--- a/drivers/net/ethernet/smsc/smc91x.h
+++ b/drivers/net/ethernet/smsc/smc91x.h
@@ -298,6 +298,9 @@ struct smc_local {
struct sk_buff *pending_tx_skb;
struct tasklet_struct tx_task;
+ struct gpio_desc *power_gpio;
+ struct gpio_desc *reset_gpio;
+
/* version/revision of the SMC91x chip */
int version;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
index 655a23bbc451..e17a970eaf2b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
@@ -33,6 +33,7 @@ static struct stmmac_dma_cfg dma_cfg;
static void stmmac_default_data(void)
{
memset(&plat_dat, 0, sizeof(struct plat_stmmacenet_data));
+
plat_dat.bus_id = 1;
plat_dat.phy_addr = 0;
plat_dat.interface = PHY_INTERFACE_MODE_GMII;
@@ -47,6 +48,12 @@ static void stmmac_default_data(void)
dma_cfg.pbl = 32;
dma_cfg.burst_len = DMA_AXI_BLEN_256;
plat_dat.dma_cfg = &dma_cfg;
+
+ /* Set default value for multicast hash bins */
+ plat_dat.multicast_filter_bins = HASH_TABLE_SIZE;
+
+ /* Set default value for unicast filter entries */
+ plat_dat.unicast_filter_entries = 1;
}
/**
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 952e1e4764b7..d8794488f80a 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -591,8 +591,8 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable)
if (enable) {
unsigned long timeout = jiffies + HZ;
- /* Disable Learn for all ports */
- for (i = 0; i < priv->data.slaves; i++) {
+ /* Disable Learn for all ports (host is port 0 and slaves are port 1 and up */
+ for (i = 0; i <= priv->data.slaves; i++) {
cpsw_ale_control_set(ale, i,
ALE_PORT_NOLEARN, 1);
cpsw_ale_control_set(ale, i,
@@ -616,11 +616,11 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable)
cpsw_ale_control_set(ale, 0, ALE_P0_UNI_FLOOD, 1);
dev_dbg(&ndev->dev, "promiscuity enabled\n");
} else {
- /* Flood All Unicast Packets to Host port */
+ /* Don't Flood All Unicast Packets to Host port */
cpsw_ale_control_set(ale, 0, ALE_P0_UNI_FLOOD, 0);
- /* Enable Learn for all ports */
- for (i = 0; i < priv->data.slaves; i++) {
+ /* Enable Learn for all ports (host is port 0 and slaves are port 1 and up */
+ for (i = 0; i <= priv->data.slaves; i++) {
cpsw_ale_control_set(ale, i,
ALE_PORT_NOLEARN, 0);
cpsw_ale_control_set(ale, i,
@@ -638,12 +638,16 @@ static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
if (ndev->flags & IFF_PROMISC) {
/* Enable promiscuous mode */
cpsw_set_promiscious(ndev, true);
+ cpsw_ale_set_allmulti(priv->ale, IFF_ALLMULTI);
return;
} else {
/* Disable promiscuous mode */
cpsw_set_promiscious(ndev, false);
}
+ /* Restore allmulti on vlans if necessary */
+ cpsw_ale_set_allmulti(priv->ale, priv->ndev->flags & IFF_ALLMULTI);
+
/* Clear all mcast from ALE */
cpsw_ale_flush_multicast(priv->ale, ALE_ALL_PORTS << priv->host_port);
@@ -1149,6 +1153,7 @@ static inline void cpsw_add_default_vlan(struct cpsw_priv *priv)
const int port = priv->host_port;
u32 reg;
int i;
+ int unreg_mcast_mask;
reg = (priv->version == CPSW_VERSION_1) ? CPSW1_PORT_VLAN :
CPSW2_PORT_VLAN;
@@ -1158,9 +1163,14 @@ static inline void cpsw_add_default_vlan(struct cpsw_priv *priv)
for (i = 0; i < priv->data.slaves; i++)
slave_write(priv->slaves + i, vlan, reg);
+ if (priv->ndev->flags & IFF_ALLMULTI)
+ unreg_mcast_mask = ALE_ALL_PORTS;
+ else
+ unreg_mcast_mask = ALE_PORT_1 | ALE_PORT_2;
+
cpsw_ale_add_vlan(priv->ale, vlan, ALE_ALL_PORTS << port,
ALE_ALL_PORTS << port, ALE_ALL_PORTS << port,
- (ALE_PORT_1 | ALE_PORT_2) << port);
+ unreg_mcast_mask << port);
}
static void cpsw_init_host_port(struct cpsw_priv *priv)
@@ -1620,11 +1630,17 @@ static inline int cpsw_add_vlan_ale_entry(struct cpsw_priv *priv,
unsigned short vid)
{
int ret;
+ int unreg_mcast_mask;
+
+ if (priv->ndev->flags & IFF_ALLMULTI)
+ unreg_mcast_mask = ALE_ALL_PORTS;
+ else
+ unreg_mcast_mask = ALE_PORT_1 | ALE_PORT_2;
ret = cpsw_ale_add_vlan(priv->ale, vid,
ALE_ALL_PORTS << priv->host_port,
0, ALE_ALL_PORTS << priv->host_port,
- (ALE_PORT_1 | ALE_PORT_2) << priv->host_port);
+ unreg_mcast_mask << priv->host_port);
if (ret != 0)
return ret;
@@ -2006,7 +2022,7 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data,
parp = of_get_property(slave_node, "phy_id", &lenp);
if ((parp == NULL) || (lenp != (sizeof(void *) * 2))) {
dev_err(&pdev->dev, "Missing slave[%d] phy_id property\n", i);
- return -EINVAL;
+ goto no_phy_slave;
}
mdio_node = of_find_node_by_phandle(be32_to_cpup(parp));
phyid = be32_to_cpup(parp+1);
@@ -2019,6 +2035,14 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data,
snprintf(slave_data->phy_id, sizeof(slave_data->phy_id),
PHY_ID_FMT, mdio->name, phyid);
+ slave_data->phy_if = of_get_phy_mode(slave_node);
+ if (slave_data->phy_if < 0) {
+ dev_err(&pdev->dev, "Missing or malformed slave[%d] phy-mode property\n",
+ i);
+ return slave_data->phy_if;
+ }
+
+no_phy_slave:
mac_addr = of_get_mac_address(slave_node);
if (mac_addr) {
memcpy(slave_data->mac_addr, mac_addr, ETH_ALEN);
@@ -2030,14 +2054,6 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data,
return ret;
}
}
-
- slave_data->phy_if = of_get_phy_mode(slave_node);
- if (slave_data->phy_if < 0) {
- dev_err(&pdev->dev, "Missing or malformed slave[%d] phy-mode property\n",
- i);
- return slave_data->phy_if;
- }
-
if (data->dual_emac) {
if (of_property_read_u32(slave_node, "dual_emac_res_vlan",
&prop)) {
diff --git a/drivers/net/ethernet/ti/cpsw_ale.c b/drivers/net/ethernet/ti/cpsw_ale.c
index 0579b2243bb6..3ae83879a75f 100644
--- a/drivers/net/ethernet/ti/cpsw_ale.c
+++ b/drivers/net/ethernet/ti/cpsw_ale.c
@@ -443,6 +443,35 @@ int cpsw_ale_del_vlan(struct cpsw_ale *ale, u16 vid, int port_mask)
return 0;
}
+void cpsw_ale_set_allmulti(struct cpsw_ale *ale, int allmulti)
+{
+ u32 ale_entry[ALE_ENTRY_WORDS];
+ int type, idx;
+ int unreg_mcast = 0;
+
+ /* Only bother doing the work if the setting is actually changing */
+ if (ale->allmulti == allmulti)
+ return;
+
+ /* Remember the new setting to check against next time */
+ ale->allmulti = allmulti;
+
+ for (idx = 0; idx < ale->params.ale_entries; idx++) {
+ cpsw_ale_read(ale, idx, ale_entry);
+ type = cpsw_ale_get_entry_type(ale_entry);
+ if (type != ALE_TYPE_VLAN)
+ continue;
+
+ unreg_mcast = cpsw_ale_get_vlan_unreg_mcast(ale_entry);
+ if (allmulti)
+ unreg_mcast |= 1;
+ else
+ unreg_mcast &= ~1;
+ cpsw_ale_set_vlan_unreg_mcast(ale_entry, unreg_mcast);
+ cpsw_ale_write(ale, idx, ale_entry);
+ }
+}
+
struct ale_control_info {
const char *name;
int offset, port_offset;
diff --git a/drivers/net/ethernet/ti/cpsw_ale.h b/drivers/net/ethernet/ti/cpsw_ale.h
index 31cf43cab42e..c0d4127aa549 100644
--- a/drivers/net/ethernet/ti/cpsw_ale.h
+++ b/drivers/net/ethernet/ti/cpsw_ale.h
@@ -27,6 +27,7 @@ struct cpsw_ale {
struct cpsw_ale_params params;
struct timer_list timer;
unsigned long ageout;
+ int allmulti;
};
enum cpsw_ale_control {
@@ -103,6 +104,7 @@ int cpsw_ale_del_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask,
int cpsw_ale_add_vlan(struct cpsw_ale *ale, u16 vid, int port, int untag,
int reg_mcast, int unreg_mcast);
int cpsw_ale_del_vlan(struct cpsw_ale *ale, u16 vid, int port);
+void cpsw_ale_set_allmulti(struct cpsw_ale *ale, int allmulti);
int cpsw_ale_control_get(struct cpsw_ale *ale, int port, int control);
int cpsw_ale_control_set(struct cpsw_ale *ale, int port,
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 9e17d1a91e71..78ec33f5100b 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -550,6 +550,7 @@ do_lso:
do_send:
/* Start filling in the page buffers with the rndis hdr */
rndis_msg->msg_len += rndis_msg_size;
+ packet->total_data_buflen = rndis_msg->msg_len;
packet->page_buf_cnt = init_page_array(rndis_msg, rndis_msg_size,
skb, &packet->page_buf[0]);
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 29b3bb410781..bfb0b6ec8c56 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -272,7 +272,7 @@ static void macvlan_process_broadcast(struct work_struct *w)
struct sk_buff *skb;
struct sk_buff_head list;
- skb_queue_head_init(&list);
+ __skb_queue_head_init(&list);
spin_lock_bh(&port->bc_queue.lock);
skb_queue_splice_tail_init(&port->bc_queue, &list);
@@ -1082,9 +1082,15 @@ static void macvlan_port_destroy(struct net_device *dev)
{
struct macvlan_port *port = macvlan_port_get_rtnl(dev);
- cancel_work_sync(&port->bc_work);
dev->priv_flags &= ~IFF_MACVLAN_PORT;
netdev_rx_handler_unregister(dev);
+
+ /* After this point, no packet can schedule bc_work anymore,
+ * but we need to cancel it and purge left skbs if any.
+ */
+ cancel_work_sync(&port->bc_work);
+ __skb_queue_purge(&port->bc_queue);
+
kfree_rcu(port, rcu);
}
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
index 65e2892342bd..6f226de655a4 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -16,6 +16,7 @@
#include <linux/idr.h>
#include <linux/fs.h>
+#include <net/ipv6.h>
#include <net/net_namespace.h>
#include <net/rtnetlink.h>
#include <net/sock.h>
@@ -65,7 +66,7 @@ static struct cdev macvtap_cdev;
static const struct proto_ops macvtap_socket_ops;
#define TUN_OFFLOADS (NETIF_F_HW_CSUM | NETIF_F_TSO_ECN | NETIF_F_TSO | \
- NETIF_F_TSO6 | NETIF_F_UFO)
+ NETIF_F_TSO6)
#define RX_OFFLOADS (NETIF_F_GRO | NETIF_F_LRO)
#define TAP_FEATURES (NETIF_F_GSO | NETIF_F_SG)
@@ -569,7 +570,11 @@ static int macvtap_skb_from_vnet_hdr(struct sk_buff *skb,
gso_type = SKB_GSO_TCPV6;
break;
case VIRTIO_NET_HDR_GSO_UDP:
+ pr_warn_once("macvtap: %s: using disabled UFO feature; please fix this program\n",
+ current->comm);
gso_type = SKB_GSO_UDP;
+ if (skb->protocol == htons(ETH_P_IPV6))
+ ipv6_proxy_select_ident(skb);
break;
default:
return -EINVAL;
@@ -614,8 +619,6 @@ static void macvtap_skb_to_vnet_hdr(const struct sk_buff *skb,
vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
else if (sinfo->gso_type & SKB_GSO_TCPV6)
vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
- else if (sinfo->gso_type & SKB_GSO_UDP)
- vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_UDP;
else
BUG();
if (sinfo->gso_type & SKB_GSO_TCP_ECN)
@@ -950,9 +953,6 @@ static int set_offload(struct macvtap_queue *q, unsigned long arg)
if (arg & TUN_F_TSO6)
feature_mask |= NETIF_F_TSO6;
}
-
- if (arg & TUN_F_UFO)
- feature_mask |= NETIF_F_UFO;
}
/* tun/tap driver inverts the usage for TSO offloads, where
@@ -963,7 +963,7 @@ static int set_offload(struct macvtap_queue *q, unsigned long arg)
* When user space turns off TSO, we turn off GSO/LRO so that
* user-space will not receive TSO frames.
*/
- if (feature_mask & (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_UFO))
+ if (feature_mask & (NETIF_F_TSO | NETIF_F_TSO6))
features |= RX_OFFLOADS;
else
features &= ~RX_OFFLOADS;
@@ -1064,7 +1064,7 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd,
case TUNSETOFFLOAD:
/* let the user check for future flags */
if (arg & ~(TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 |
- TUN_F_TSO_ECN | TUN_F_UFO))
+ TUN_F_TSO_ECN))
return -EINVAL;
rtnl_lock();
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index bd37e45c89c0..225c033b08f3 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -50,10 +50,15 @@
#define MII_M1011_PHY_SCR 0x10
#define MII_M1011_PHY_SCR_AUTO_CROSS 0x0060
+#define MII_M1145_PHY_EXT_SR 0x1b
#define MII_M1145_PHY_EXT_CR 0x14
#define MII_M1145_RGMII_RX_DELAY 0x0080
#define MII_M1145_RGMII_TX_DELAY 0x0002
+#define MII_M1145_HWCFG_MODE_SGMII_NO_CLK 0x4
+#define MII_M1145_HWCFG_MODE_MASK 0xf
+#define MII_M1145_HWCFG_FIBER_COPPER_AUTO 0x8000
+
#define MII_M1111_PHY_LED_CONTROL 0x18
#define MII_M1111_PHY_LED_DIRECT 0x4100
#define MII_M1111_PHY_LED_COMBINE 0x411c
@@ -676,6 +681,20 @@ static int m88e1145_config_init(struct phy_device *phydev)
}
}
+ if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
+ int temp = phy_read(phydev, MII_M1145_PHY_EXT_SR);
+ if (temp < 0)
+ return temp;
+
+ temp &= ~MII_M1145_HWCFG_MODE_MASK;
+ temp |= MII_M1145_HWCFG_MODE_SGMII_NO_CLK;
+ temp |= MII_M1145_HWCFG_FIBER_COPPER_AUTO;
+
+ err = phy_write(phydev, MII_M1145_PHY_EXT_SR, temp);
+ if (err < 0)
+ return err;
+ }
+
err = marvell_of_reg_init(phydev);
if (err < 0)
return err;
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 186ce541c657..7302398f0b1f 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -65,6 +65,7 @@
#include <linux/nsproxy.h>
#include <linux/virtio_net.h>
#include <linux/rcupdate.h>
+#include <net/ipv6.h>
#include <net/net_namespace.h>
#include <net/netns/generic.h>
#include <net/rtnetlink.h>
@@ -174,7 +175,7 @@ struct tun_struct {
struct net_device *dev;
netdev_features_t set_features;
#define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \
- NETIF_F_TSO6|NETIF_F_UFO)
+ NETIF_F_TSO6)
int vnet_hdr_sz;
int sndbuf;
@@ -1139,6 +1140,8 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
break;
}
+ skb_reset_network_header(skb);
+
if (gso.gso_type != VIRTIO_NET_HDR_GSO_NONE) {
pr_debug("GSO!\n");
switch (gso.gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
@@ -1149,8 +1152,20 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
break;
case VIRTIO_NET_HDR_GSO_UDP:
+ {
+ static bool warned;
+
+ if (!warned) {
+ warned = true;
+ netdev_warn(tun->dev,
+ "%s: using disabled UFO feature; please fix this program\n",
+ current->comm);
+ }
skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
+ if (skb->protocol == htons(ETH_P_IPV6))
+ ipv6_proxy_select_ident(skb);
break;
+ }
default:
tun->dev->stats.rx_frame_errors++;
kfree_skb(skb);
@@ -1179,7 +1194,6 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG;
}
- skb_reset_network_header(skb);
skb_probe_transport_header(skb, 0);
rxhash = skb_get_hash(skb);
@@ -1251,8 +1265,6 @@ static ssize_t tun_put_user(struct tun_struct *tun,
gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
else if (sinfo->gso_type & SKB_GSO_TCPV6)
gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
- else if (sinfo->gso_type & SKB_GSO_UDP)
- gso.gso_type = VIRTIO_NET_HDR_GSO_UDP;
else {
pr_err("unexpected GSO type: "
"0x%x, gso_size %d, hdr_len %d\n",
@@ -1762,11 +1774,6 @@ static int set_offload(struct tun_struct *tun, unsigned long arg)
features |= NETIF_F_TSO6;
arg &= ~(TUN_F_TSO4|TUN_F_TSO6);
}
-
- if (arg & TUN_F_UFO) {
- features |= NETIF_F_UFO;
- arg &= ~TUN_F_UFO;
- }
}
/* This gives the user a way to test for new features in future by
diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c
index be4275721039..e6338c16081a 100644
--- a/drivers/net/usb/ax88179_178a.c
+++ b/drivers/net/usb/ax88179_178a.c
@@ -937,6 +937,7 @@ static int ax88179_set_mac_addr(struct net_device *net, void *p)
{
struct usbnet *dev = netdev_priv(net);
struct sockaddr *addr = p;
+ int ret;
if (netif_running(net))
return -EBUSY;
@@ -946,8 +947,12 @@ static int ax88179_set_mac_addr(struct net_device *net, void *p)
memcpy(net->dev_addr, addr->sa_data, ETH_ALEN);
/* Set the MAC address */
- return ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN,
+ ret = ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN,
ETH_ALEN, net->dev_addr);
+ if (ret < 0)
+ return ret;
+
+ return 0;
}
static const struct net_device_ops ax88179_netdev_ops = {
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index 2a32d9167d3b..d3920b54a92c 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -67,6 +67,35 @@ static const u8 mbm_guid[16] = {
0xa6, 0x07, 0xc0, 0xff, 0xcb, 0x7e, 0x39, 0x2a,
};
+static void usbnet_cdc_update_filter(struct usbnet *dev)
+{
+ struct cdc_state *info = (void *) &dev->data;
+ struct usb_interface *intf = info->control;
+
+ u16 cdc_filter =
+ USB_CDC_PACKET_TYPE_ALL_MULTICAST | USB_CDC_PACKET_TYPE_DIRECTED |
+ USB_CDC_PACKET_TYPE_BROADCAST;
+
+ if (dev->net->flags & IFF_PROMISC)
+ cdc_filter |= USB_CDC_PACKET_TYPE_PROMISCUOUS;
+
+ /* FIXME cdc-ether has some multicast code too, though it complains
+ * in routine cases. info->ether describes the multicast support.
+ * Implement that here, manipulating the cdc filter as needed.
+ */
+
+ usb_control_msg(dev->udev,
+ usb_sndctrlpipe(dev->udev, 0),
+ USB_CDC_SET_ETHERNET_PACKET_FILTER,
+ USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+ cdc_filter,
+ intf->cur_altsetting->desc.bInterfaceNumber,
+ NULL,
+ 0,
+ USB_CTRL_SET_TIMEOUT
+ );
+}
+
/* probes control interface, claims data interface, collects the bulk
* endpoints, activates data interface (if needed), maybe sets MTU.
* all pure cdc, except for certain firmware workarounds, and knowing
@@ -347,16 +376,8 @@ next_desc:
* don't do reset all the way. So the packet filter should
* be set to a sane initial value.
*/
- usb_control_msg(dev->udev,
- usb_sndctrlpipe(dev->udev, 0),
- USB_CDC_SET_ETHERNET_PACKET_FILTER,
- USB_TYPE_CLASS | USB_RECIP_INTERFACE,
- USB_CDC_PACKET_TYPE_ALL_MULTICAST | USB_CDC_PACKET_TYPE_DIRECTED | USB_CDC_PACKET_TYPE_BROADCAST,
- intf->cur_altsetting->desc.bInterfaceNumber,
- NULL,
- 0,
- USB_CTRL_SET_TIMEOUT
- );
+ usbnet_cdc_update_filter(dev);
+
return 0;
bad_desc:
@@ -468,10 +489,6 @@ int usbnet_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
return status;
}
- /* FIXME cdc-ether has some multicast code too, though it complains
- * in routine cases. info->ether describes the multicast support.
- * Implement that here, manipulating the cdc filter as needed.
- */
return 0;
}
EXPORT_SYMBOL_GPL(usbnet_cdc_bind);
@@ -482,6 +499,7 @@ static const struct driver_info cdc_info = {
.bind = usbnet_cdc_bind,
.unbind = usbnet_cdc_unbind,
.status = usbnet_cdc_status,
+ .set_rx_mode = usbnet_cdc_update_filter,
.manage_power = usbnet_manage_power,
};
@@ -491,6 +509,7 @@ static const struct driver_info wwan_info = {
.bind = usbnet_cdc_bind,
.unbind = usbnet_cdc_unbind,
.status = usbnet_cdc_status,
+ .set_rx_mode = usbnet_cdc_update_filter,
.manage_power = usbnet_manage_power,
};
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index e3d84c322e4e..c6554c7a8147 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -1162,6 +1162,9 @@ static void intr_callback(struct urb *urb)
case -ESHUTDOWN:
netif_device_detach(tp->netdev);
case -ENOENT:
+ case -EPROTO:
+ netif_info(tp, intr, tp->netdev,
+ "Stop submitting intr, status %d\n", status);
return;
case -EOVERFLOW:
netif_info(tp, intr, tp->netdev, "intr status -EOVERFLOW\n");
@@ -2891,6 +2894,9 @@ static int rtl8152_open(struct net_device *netdev)
if (res)
goto out;
+ /* set speed to 0 to avoid autoresume try to submit rx */
+ tp->speed = 0;
+
res = usb_autopm_get_interface(tp->intf);
if (res < 0) {
free_all_mem(tp);
@@ -2904,6 +2910,8 @@ static int rtl8152_open(struct net_device *netdev)
clear_bit(WORK_ENABLE, &tp->flags);
usb_kill_urb(tp->intr_urb);
cancel_delayed_work_sync(&tp->schedule);
+
+ /* disable the tx/rx, if the workqueue has enabled them. */
if (tp->speed & LINK_STATUS)
tp->rtl_ops.disable(tp);
}
@@ -2955,10 +2963,7 @@ static int rtl8152_close(struct net_device *netdev)
* be disable when autoresume occurs, because the
* netif_running() would be false.
*/
- if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) {
- rtl_runtime_suspend_enable(tp, false);
- clear_bit(SELECTIVE_SUSPEND, &tp->flags);
- }
+ rtl_runtime_suspend_enable(tp, false);
tasklet_disable(&tp->tl);
tp->rtl_ops.down(tp);
@@ -3205,7 +3210,7 @@ static int rtl8152_suspend(struct usb_interface *intf, pm_message_t message)
netif_device_detach(netdev);
}
- if (netif_running(netdev)) {
+ if (netif_running(netdev) && test_bit(WORK_ENABLE, &tp->flags)) {
clear_bit(WORK_ENABLE, &tp->flags);
usb_kill_urb(tp->intr_urb);
tasklet_disable(&tp->tl);
@@ -3253,6 +3258,8 @@ static int rtl8152_resume(struct usb_interface *intf)
set_bit(WORK_ENABLE, &tp->flags);
}
usb_submit_urb(tp->intr_urb, GFP_KERNEL);
+ } else if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) {
+ clear_bit(SELECTIVE_SUSPEND, &tp->flags);
}
mutex_unlock(&tp->control);
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 20615bbd693b..3a6770a65d78 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -1052,6 +1052,21 @@ static void __handle_link_change(struct usbnet *dev)
clear_bit(EVENT_LINK_CHANGE, &dev->flags);
}
+static void usbnet_set_rx_mode(struct net_device *net)
+{
+ struct usbnet *dev = netdev_priv(net);
+
+ usbnet_defer_kevent(dev, EVENT_SET_RX_MODE);
+}
+
+static void __handle_set_rx_mode(struct usbnet *dev)
+{
+ if (dev->driver_info->set_rx_mode)
+ (dev->driver_info->set_rx_mode)(dev);
+
+ clear_bit(EVENT_SET_RX_MODE, &dev->flags);
+}
+
/* work that cannot be done in interrupt context uses keventd.
*
* NOTE: with 2.5 we could do more of this using completion callbacks,
@@ -1157,6 +1172,10 @@ skip_reset:
if (test_bit (EVENT_LINK_CHANGE, &dev->flags))
__handle_link_change(dev);
+ if (test_bit (EVENT_SET_RX_MODE, &dev->flags))
+ __handle_set_rx_mode(dev);
+
+
if (dev->flags)
netdev_dbg(dev->net, "kevent done, flags = 0x%lx\n", dev->flags);
}
@@ -1525,6 +1544,7 @@ static const struct net_device_ops usbnet_netdev_ops = {
.ndo_stop = usbnet_stop,
.ndo_start_xmit = usbnet_start_xmit,
.ndo_tx_timeout = usbnet_tx_timeout,
+ .ndo_set_rx_mode = usbnet_set_rx_mode,
.ndo_change_mtu = usbnet_change_mtu,
.ndo_set_mac_address = eth_mac_addr,
.ndo_validate_addr = eth_validate_addr,
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index d75256bd1a6a..ec2a8b41ed41 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -491,8 +491,17 @@ static void receive_buf(struct receive_queue *rq, void *buf, unsigned int len)
skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
break;
case VIRTIO_NET_HDR_GSO_UDP:
+ {
+ static bool warned;
+
+ if (!warned) {
+ warned = true;
+ netdev_warn(dev,
+ "host using disabled UFO feature; please fix it\n");
+ }
skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
break;
+ }
case VIRTIO_NET_HDR_GSO_TCPV6:
skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
break;
@@ -881,8 +890,6 @@ static int xmit_skb(struct send_queue *sq, struct sk_buff *skb)
hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
- else if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP)
- hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_UDP;
else
BUG();
if (skb_shinfo(skb)->gso_type & SKB_GSO_TCP_ECN)
@@ -1705,7 +1712,7 @@ static int virtnet_probe(struct virtio_device *vdev)
dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST;
if (virtio_has_feature(vdev, VIRTIO_NET_F_GSO)) {
- dev->hw_features |= NETIF_F_TSO | NETIF_F_UFO
+ dev->hw_features |= NETIF_F_TSO
| NETIF_F_TSO_ECN | NETIF_F_TSO6;
}
/* Individual feature bits: what can host handle? */
@@ -1715,11 +1722,9 @@ static int virtnet_probe(struct virtio_device *vdev)
dev->hw_features |= NETIF_F_TSO6;
if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_ECN))
dev->hw_features |= NETIF_F_TSO_ECN;
- if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_UFO))
- dev->hw_features |= NETIF_F_UFO;
if (gso)
- dev->features |= dev->hw_features & (NETIF_F_ALL_TSO|NETIF_F_UFO);
+ dev->features |= dev->hw_features & NETIF_F_ALL_TSO;
/* (!csum && gso) case will be fixed by register_netdev() */
}
if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_CSUM))
@@ -1757,8 +1762,7 @@ static int virtnet_probe(struct virtio_device *vdev)
/* If we can receive ANY GSO packets, we must allocate large ones. */
if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) ||
virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6) ||
- virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN) ||
- virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_UFO))
+ virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN))
vi->big_packets = true;
if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF))
@@ -1952,9 +1956,9 @@ static struct virtio_device_id id_table[] = {
static unsigned int features[] = {
VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GUEST_CSUM,
VIRTIO_NET_F_GSO, VIRTIO_NET_F_MAC,
- VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6,
+ VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_TSO6,
VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6,
- VIRTIO_NET_F_GUEST_ECN, VIRTIO_NET_F_GUEST_UFO,
+ VIRTIO_NET_F_GUEST_ECN,
VIRTIO_NET_F_MRG_RXBUF, VIRTIO_NET_F_STATUS, VIRTIO_NET_F_CTRL_VQ,
VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN,
VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_MQ,
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index e5ba6faf3281..86907e5ba6ca 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -80,6 +80,7 @@ struct reg_dmn_pair_mapping {
struct ath_regulatory {
char alpha2[2];
+ enum nl80211_dfs_regions region;
u16 country_code;
u16 max_power_level;
u16 current_rd;
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c
index c6dd7f1fed65..33b0c7aef2ea 100644
--- a/drivers/net/wireless/ath/ath9k/common.c
+++ b/drivers/net/wireless/ath/ath9k/common.c
@@ -368,11 +368,11 @@ void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow,
{
struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
- if (reg->power_limit != new_txpow) {
+ if (reg->power_limit != new_txpow)
ath9k_hw_set_txpowerlimit(ah, new_txpow, false);
- /* read back in case value is clamped */
- *txpower = reg->max_power_level;
- }
+
+ /* read back in case value is clamped */
+ *txpower = reg->max_power_level;
}
EXPORT_SYMBOL(ath9k_cmn_update_txpow);
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 46f20a309b5f..5c45e787814e 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -455,7 +455,7 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf,
"%2d %2x %1x %2x %2x\n",
i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset,
(*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset + 3),
- val[2] & (0x7 << (i * 3)) >> (i * 3),
+ (val[2] & (0x7 << (i * 3))) >> (i * 3),
(*dcuBase & (0x1f << dcuOffset)) >> dcuOffset);
}
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 156a944134dc..3bd030494986 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -734,6 +734,32 @@ static const struct ieee80211_iface_combination if_comb[] = {
#endif
};
+#ifdef CONFIG_ATH9K_CHANNEL_CONTEXT
+static void ath9k_set_mcc_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
+{
+ struct ath_hw *ah = sc->sc_ah;
+ struct ath_common *common = ath9k_hw_common(ah);
+
+ if (!ath9k_is_chanctx_enabled())
+ return;
+
+ hw->flags |= IEEE80211_HW_QUEUE_CONTROL;
+ hw->queues = ATH9K_NUM_TX_QUEUES;
+ hw->offchannel_tx_hw_queue = hw->queues - 1;
+ hw->wiphy->interface_modes &= ~ BIT(NL80211_IFTYPE_WDS);
+ hw->wiphy->iface_combinations = if_comb_multi;
+ hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb_multi);
+ hw->wiphy->max_scan_ssids = 255;
+ hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
+ hw->wiphy->max_remain_on_channel_duration = 10000;
+ hw->chanctx_data_size = sizeof(void *);
+ hw->extra_beacon_tailroom =
+ sizeof(struct ieee80211_p2p_noa_attr) + 9;
+
+ ath_dbg(common, CHAN_CTX, "Use channel contexts\n");
+}
+#endif /* CONFIG_ATH9K_CHANNEL_CONTEXT */
+
static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
{
struct ath_hw *ah = sc->sc_ah;
@@ -746,7 +772,6 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
IEEE80211_HW_SPECTRUM_MGMT |
IEEE80211_HW_REPORTS_TX_ACK_STATUS |
IEEE80211_HW_SUPPORTS_RC_TABLE |
- IEEE80211_HW_QUEUE_CONTROL |
IEEE80211_HW_SUPPORTS_HT_CCK_RATES;
if (ath9k_ps_enable)
@@ -781,24 +806,6 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
}
-#ifdef CONFIG_ATH9K_CHANNEL_CONTEXT
-
- if (ath9k_is_chanctx_enabled()) {
- hw->wiphy->interface_modes &= ~ BIT(NL80211_IFTYPE_WDS);
- hw->wiphy->iface_combinations = if_comb_multi;
- hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb_multi);
- hw->wiphy->max_scan_ssids = 255;
- hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
- hw->wiphy->max_remain_on_channel_duration = 10000;
- hw->chanctx_data_size = sizeof(void *);
- hw->extra_beacon_tailroom =
- sizeof(struct ieee80211_p2p_noa_attr) + 9;
-
- ath_dbg(common, CHAN_CTX, "Use channel contexts\n");
- }
-
-#endif /* CONFIG_ATH9K_CHANNEL_CONTEXT */
-
hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
@@ -808,12 +815,7 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
- /* allow 4 queues per channel context +
- * 1 cab queue + 1 offchannel tx queue
- */
- hw->queues = ATH9K_NUM_TX_QUEUES;
- /* last queue for offchannel */
- hw->offchannel_tx_hw_queue = hw->queues - 1;
+ hw->queues = 4;
hw->max_rates = 4;
hw->max_listen_interval = 10;
hw->max_rate_tries = 10;
@@ -837,6 +839,9 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
&common->sbands[IEEE80211_BAND_5GHZ];
+#ifdef CONFIG_ATH9K_CHANNEL_CONTEXT
+ ath9k_set_mcc_capab(sc, hw);
+#endif
ath9k_init_wow(hw);
ath9k_cmn_reload_chainmask(ah);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 6f6a974f7fdb..30c66dfcd7a0 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1162,6 +1162,9 @@ static void ath9k_assign_hw_queues(struct ieee80211_hw *hw,
{
int i;
+ if (!ath9k_is_chanctx_enabled())
+ return;
+
for (i = 0; i < IEEE80211_NUM_ACS; i++)
vif->hw_queue[i] = i;
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 493a183d0aaf..d6e54a3c88f6 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -169,7 +169,10 @@ static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
if (txq->stopped &&
txq->pending_frames < sc->tx.txq_max_pending[q]) {
- ieee80211_wake_queue(sc->hw, info->hw_queue);
+ if (ath9k_is_chanctx_enabled())
+ ieee80211_wake_queue(sc->hw, info->hw_queue);
+ else
+ ieee80211_wake_queue(sc->hw, q);
txq->stopped = false;
}
}
@@ -2247,7 +2250,10 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
fi->txq = q;
if (++txq->pending_frames > sc->tx.txq_max_pending[q] &&
!txq->stopped) {
- ieee80211_stop_queue(sc->hw, info->hw_queue);
+ if (ath9k_is_chanctx_enabled())
+ ieee80211_stop_queue(sc->hw, info->hw_queue);
+ else
+ ieee80211_stop_queue(sc->hw, q);
txq->stopped = true;
}
}
diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c
index 415393dfb6fc..06ea6cc9e30a 100644
--- a/drivers/net/wireless/ath/regd.c
+++ b/drivers/net/wireless/ath/regd.c
@@ -515,6 +515,7 @@ void ath_reg_notifier_apply(struct wiphy *wiphy,
if (!request)
return;
+ reg->region = request->dfs_region;
switch (request->initiator) {
case NL80211_REGDOM_SET_BY_CORE:
/*
@@ -779,6 +780,19 @@ u32 ath_regd_get_band_ctl(struct ath_regulatory *reg,
return SD_NO_CTL;
}
+ if (ath_regd_get_eepromRD(reg) == CTRY_DEFAULT) {
+ switch (reg->region) {
+ case NL80211_DFS_FCC:
+ return CTL_FCC;
+ case NL80211_DFS_ETSI:
+ return CTL_ETSI;
+ case NL80211_DFS_JP:
+ return CTL_MKK;
+ default:
+ break;
+ }
+ }
+
switch (band) {
case IEEE80211_BAND_2GHZ:
return reg->regpair->reg_2ghz_ctl;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index f55f625fd06b..d20d4e6f391a 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -670,7 +670,6 @@ static int brcmf_sdio_get_fwnames(struct brcmf_chip *ci,
struct brcmf_sdio_dev *sdiodev)
{
int i;
- uint fw_len, nv_len;
char end;
for (i = 0; i < ARRAY_SIZE(brcmf_fwname_data); i++) {
@@ -684,25 +683,25 @@ static int brcmf_sdio_get_fwnames(struct brcmf_chip *ci,
return -ENODEV;
}
- fw_len = sizeof(sdiodev->fw_name) - 1;
- nv_len = sizeof(sdiodev->nvram_name) - 1;
/* check if firmware path is provided by module parameter */
if (brcmf_firmware_path[0] != '\0') {
- strncpy(sdiodev->fw_name, brcmf_firmware_path, fw_len);
- strncpy(sdiodev->nvram_name, brcmf_firmware_path, nv_len);
- fw_len -= strlen(sdiodev->fw_name);
- nv_len -= strlen(sdiodev->nvram_name);
+ strlcpy(sdiodev->fw_name, brcmf_firmware_path,
+ sizeof(sdiodev->fw_name));
+ strlcpy(sdiodev->nvram_name, brcmf_firmware_path,
+ sizeof(sdiodev->nvram_name));
end = brcmf_firmware_path[strlen(brcmf_firmware_path) - 1];
if (end != '/') {
- strncat(sdiodev->fw_name, "/", fw_len);
- strncat(sdiodev->nvram_name, "/", nv_len);
- fw_len--;
- nv_len--;
+ strlcat(sdiodev->fw_name, "/",
+ sizeof(sdiodev->fw_name));
+ strlcat(sdiodev->nvram_name, "/",
+ sizeof(sdiodev->nvram_name));
}
}
- strncat(sdiodev->fw_name, brcmf_fwname_data[i].bin, fw_len);
- strncat(sdiodev->nvram_name, brcmf_fwname_data[i].nv, nv_len);
+ strlcat(sdiodev->fw_name, brcmf_fwname_data[i].bin,
+ sizeof(sdiodev->fw_name));
+ strlcat(sdiodev->nvram_name, brcmf_fwname_data[i].nv,
+ sizeof(sdiodev->nvram_name));
return 0;
}
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
index 2364a3c09b9e..cae692ff1013 100644
--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
@@ -1095,6 +1095,7 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
u32 queues, bool drop)
{
struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
+ u32 scd_queues;
mutex_lock(&priv->mutex);
IWL_DEBUG_MAC80211(priv, "enter\n");
@@ -1108,18 +1109,19 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
goto done;
}
- /*
- * mac80211 will not push any more frames for transmit
- * until the flush is completed
- */
- if (drop) {
- IWL_DEBUG_MAC80211(priv, "send flush command\n");
- if (iwlagn_txfifo_flush(priv, 0)) {
- IWL_ERR(priv, "flush request fail\n");
- goto done;
- }
+ scd_queues = BIT(priv->cfg->base_params->num_of_queues) - 1;
+ scd_queues &= ~(BIT(IWL_IPAN_CMD_QUEUE_NUM) |
+ BIT(IWL_DEFAULT_CMD_QUEUE_NUM));
+
+ if (vif)
+ scd_queues &= ~BIT(vif->hw_queue[IEEE80211_AC_VO]);
+
+ IWL_DEBUG_TX_QUEUES(priv, "Flushing SCD queues: 0x%x\n", scd_queues);
+ if (iwlagn_txfifo_flush(priv, scd_queues)) {
+ IWL_ERR(priv, "flush request fail\n");
+ goto done;
}
- IWL_DEBUG_MAC80211(priv, "wait transmit/flush all frames\n");
+ IWL_DEBUG_TX_QUEUES(priv, "wait transmit/flush all frames\n");
iwl_trans_wait_tx_queue_empty(priv->trans, 0xffffffff);
done:
mutex_unlock(&priv->mutex);
diff --git a/drivers/net/wireless/iwlwifi/iwl-8000.c b/drivers/net/wireless/iwlwifi/iwl-8000.c
index e4351487ca72..d2b7234b1c73 100644
--- a/drivers/net/wireless/iwlwifi/iwl-8000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-8000.c
@@ -82,7 +82,8 @@
#define IWL8000_TX_POWER_VERSION 0xffff /* meaningless */
#define IWL8000_FW_PRE "iwlwifi-8000"
-#define IWL8000_MODULE_FIRMWARE(api) IWL8000_FW_PRE __stringify(api) ".ucode"
+#define IWL8000_MODULE_FIRMWARE(api) \
+ IWL8000_FW_PRE "-" __stringify(api) ".ucode"
#define NVM_HW_SECTION_NUM_FAMILY_8000 10
#define DEFAULT_NVM_FILE_FAMILY_8000 "iwl_nvm_8000.bin"
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index 9eb85249e89c..d8fc548c0d6c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -563,6 +563,7 @@ enum iwl_trans_state {
* Set during transport allocation.
* @hw_id_str: a string with info about HW ID. Set during transport allocation.
* @pm_support: set to true in start_hw if link pm is supported
+ * @ltr_enabled: set to true if the LTR is enabled
* @dev_cmd_pool: pool for Tx cmd allocation - for internal use only.
* The user should use iwl_trans_{alloc,free}_tx_cmd.
* @dev_cmd_headroom: room needed for the transport's private use before the
@@ -589,6 +590,7 @@ struct iwl_trans {
u8 rx_mpdu_cmd, rx_mpdu_cmd_hdr_size;
bool pm_support;
+ bool ltr_enabled;
/* The following fields are internal only */
struct kmem_cache *dev_cmd_pool;
diff --git a/drivers/net/wireless/iwlwifi/mvm/coex.c b/drivers/net/wireless/iwlwifi/mvm/coex.c
index 8df2021f9856..da2ffb785194 100644
--- a/drivers/net/wireless/iwlwifi/mvm/coex.c
+++ b/drivers/net/wireless/iwlwifi/mvm/coex.c
@@ -303,8 +303,8 @@ static const __le64 iwl_ci_mask[][3] = {
};
static const __le32 iwl_bt_mprio_lut[BT_COEX_MULTI_PRIO_LUT_SIZE] = {
- cpu_to_le32(0x28412201),
- cpu_to_le32(0x11118451),
+ cpu_to_le32(0x2e402280),
+ cpu_to_le32(0x7711a751),
};
struct corunning_block_luts {
diff --git a/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c
index 585c0ab4a3ec..8a1d2f33d5b7 100644
--- a/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c
+++ b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c
@@ -291,8 +291,8 @@ static const __le64 iwl_ci_mask[][3] = {
};
static const __le32 iwl_bt_mprio_lut[BT_COEX_MULTI_PRIO_LUT_SIZE] = {
- cpu_to_le32(0x28412201),
- cpu_to_le32(0x11118451),
+ cpu_to_le32(0x2e402280),
+ cpu_to_le32(0x7711a751),
};
struct corunning_block_luts {
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
index 27dd86395b39..2fd8ad4633e0 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
@@ -68,13 +68,46 @@
/* Power Management Commands, Responses, Notifications */
+/**
+ * enum iwl_ltr_config_flags - masks for LTR config command flags
+ * @LTR_CFG_FLAG_FEATURE_ENABLE: Feature operational status
+ * @LTR_CFG_FLAG_HW_DIS_ON_SHADOW_REG_ACCESS: allow LTR change on shadow
+ * memory access
+ * @LTR_CFG_FLAG_HW_EN_SHRT_WR_THROUGH: allow LTR msg send on ANY LTR
+ * reg change
+ * @LTR_CFG_FLAG_HW_DIS_ON_D0_2_D3: allow LTR msg send on transition from
+ * D0 to D3
+ * @LTR_CFG_FLAG_SW_SET_SHORT: fixed static short LTR register
+ * @LTR_CFG_FLAG_SW_SET_LONG: fixed static short LONG register
+ * @LTR_CFG_FLAG_DENIE_C10_ON_PD: allow going into C10 on PD
+ */
+enum iwl_ltr_config_flags {
+ LTR_CFG_FLAG_FEATURE_ENABLE = BIT(0),
+ LTR_CFG_FLAG_HW_DIS_ON_SHADOW_REG_ACCESS = BIT(1),
+ LTR_CFG_FLAG_HW_EN_SHRT_WR_THROUGH = BIT(2),
+ LTR_CFG_FLAG_HW_DIS_ON_D0_2_D3 = BIT(3),
+ LTR_CFG_FLAG_SW_SET_SHORT = BIT(4),
+ LTR_CFG_FLAG_SW_SET_LONG = BIT(5),
+ LTR_CFG_FLAG_DENIE_C10_ON_PD = BIT(6),
+};
+
+/**
+ * struct iwl_ltr_config_cmd - configures the LTR
+ * @flags: See %enum iwl_ltr_config_flags
+ */
+struct iwl_ltr_config_cmd {
+ __le32 flags;
+ __le32 static_long;
+ __le32 static_short;
+} __packed;
+
/* Radio LP RX Energy Threshold measured in dBm */
#define POWER_LPRX_RSSI_THRESHOLD 75
#define POWER_LPRX_RSSI_THRESHOLD_MAX 94
#define POWER_LPRX_RSSI_THRESHOLD_MIN 30
/**
- * enum iwl_scan_flags - masks for power table command flags
+ * enum iwl_power_flags - masks for power table command flags
* @POWER_FLAGS_POWER_SAVE_ENA_MSK: '1' Allow to save power by turning off
* receiver and transmitter. '0' - does not allow.
* @POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK: '0' Driver disables power management,
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
index 667a92274c87..c62575d86bcd 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -157,6 +157,7 @@ enum {
/* Power - legacy power table command */
POWER_TABLE_CMD = 0x77,
PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION = 0x78,
+ LTR_CONFIG = 0xee,
/* Thermal Throttling*/
REPLY_THERMAL_MNG_BACKOFF = 0x7e,
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c
index 23fd711a67e4..e0d9f19650b0 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/iwlwifi/mvm/fw.c
@@ -480,6 +480,15 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
/* Initialize tx backoffs to the minimal possible */
iwl_mvm_tt_tx_backoff(mvm, 0);
+ if (mvm->trans->ltr_enabled) {
+ struct iwl_ltr_config_cmd cmd = {
+ .flags = cpu_to_le32(LTR_CFG_FLAG_FEATURE_ENABLE),
+ };
+
+ WARN_ON(iwl_mvm_send_cmd_pdu(mvm, LTR_CONFIG, 0,
+ sizeof(cmd), &cmd));
+ }
+
ret = iwl_mvm_power_update_device(mvm);
if (ret)
goto error;
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index c7a73c68bdab..585fe5b7100f 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -526,7 +526,8 @@ static void iwl_mvm_mac_tx(struct ieee80211_hw *hw,
}
if (IEEE80211_SKB_CB(skb)->hw_queue == IWL_MVM_OFFCHANNEL_QUEUE &&
- !test_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status))
+ !test_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status) &&
+ !test_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status))
goto drop;
/* treat non-bufferable MMPDUs as broadcast if sta is sleeping */
@@ -1734,6 +1735,13 @@ iwl_mvm_bss_info_changed_ap_ibss(struct iwl_mvm *mvm,
if (changes & BSS_CHANGED_BEACON &&
iwl_mvm_mac_ctxt_beacon_changed(mvm, vif))
IWL_WARN(mvm, "Failed updating beacon data\n");
+
+ if (changes & BSS_CHANGED_TXPOWER) {
+ IWL_DEBUG_CALIB(mvm, "Changing TX Power to %d\n",
+ bss_conf->txpower);
+ iwl_mvm_set_tx_power(mvm, vif, bss_conf->txpower);
+ }
+
}
static void iwl_mvm_bss_info_changed(struct ieee80211_hw *hw,
@@ -2367,14 +2375,19 @@ static int iwl_mvm_send_aux_roc_cmd(struct iwl_mvm *mvm,
/* Set the node address */
memcpy(aux_roc_req.node_addr, vif->addr, ETH_ALEN);
+ lockdep_assert_held(&mvm->mutex);
+
+ spin_lock_bh(&mvm->time_event_lock);
+
+ if (WARN_ON(te_data->id == HOT_SPOT_CMD)) {
+ spin_unlock_bh(&mvm->time_event_lock);
+ return -EIO;
+ }
+
te_data->vif = vif;
te_data->duration = duration;
te_data->id = HOT_SPOT_CMD;
- lockdep_assert_held(&mvm->mutex);
-
- spin_lock_bh(&mvm->time_event_lock);
- list_add_tail(&te_data->list, &mvm->time_event_list);
spin_unlock_bh(&mvm->time_event_lock);
/*
@@ -2430,22 +2443,23 @@ static int iwl_mvm_roc(struct ieee80211_hw *hw,
IWL_DEBUG_MAC80211(mvm, "enter (%d, %d, %d)\n", channel->hw_value,
duration, type);
+ mutex_lock(&mvm->mutex);
+
switch (vif->type) {
case NL80211_IFTYPE_STATION:
/* Use aux roc framework (HS20) */
ret = iwl_mvm_send_aux_roc_cmd(mvm, channel,
vif, duration);
- return ret;
+ goto out_unlock;
case NL80211_IFTYPE_P2P_DEVICE:
/* handle below */
break;
default:
IWL_ERR(mvm, "vif isn't P2P_DEVICE: %d\n", vif->type);
- return -EINVAL;
+ ret = -EINVAL;
+ goto out_unlock;
}
- mutex_lock(&mvm->mutex);
-
for (i = 0; i < NUM_PHY_CTX; i++) {
phy_ctxt = &mvm->phy_ctxts[i];
if (phy_ctxt->ref == 0 || mvmvif->phy_ctxt == phy_ctxt)
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index 15aa298ee79c..48cb25a93591 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -336,6 +336,7 @@ static const char *const iwl_mvm_cmd_strings[REPLY_MAX] = {
CMD(DTS_MEASUREMENT_NOTIFICATION),
CMD(REPLY_THERMAL_MNG_BACKOFF),
CMD(MAC_PM_POWER_TABLE),
+ CMD(LTR_CONFIG),
CMD(BT_COEX_CI),
CMD(BT_COEX_UPDATE_SW_BOOST),
CMD(BT_COEX_UPDATE_CORUN_LUT),
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index cb85e63c20aa..b280d5d87127 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -459,7 +459,8 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
basic_ssid ? 1 : 0);
cmd->tx_cmd.tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL |
- TX_CMD_FLG_BT_DIS);
+ 3 << TX_CMD_FLG_BT_PRIO_POS);
+
cmd->tx_cmd.sta_id = mvm->aux_sta.sta_id;
cmd->tx_cmd.life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE);
cmd->tx_cmd.rate_n_flags =
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c
index b7f9e61d14e2..6dfad230be5e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/time-event.c
+++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c
@@ -305,8 +305,8 @@ static int iwl_mvm_aux_roc_te_handle_notif(struct iwl_mvm *mvm,
te_data->running = false;
te_data->vif = NULL;
te_data->uid = 0;
+ te_data->id = TE_MAX;
} else if (le32_to_cpu(notif->action) == TE_V2_NOTIF_HOST_EVENT_START) {
- set_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status);
set_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status);
te_data->running = true;
ieee80211_ready_on_channel(mvm->hw); /* Start TE */
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c
index 1cb793a498ac..c6a517c771df 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tx.c
@@ -175,14 +175,10 @@ static void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm,
/*
* for data packets, rate info comes from the table inside the fw. This
- * table is controlled by LINK_QUALITY commands. Exclude ctrl port
- * frames like EAPOLs which should be treated as mgmt frames. This
- * avoids them being sent initially in high rates which increases the
- * chances for completion of the 4-Way handshake.
+ * table is controlled by LINK_QUALITY commands
*/
- if (ieee80211_is_data(fc) && sta &&
- !(info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO)) {
+ if (ieee80211_is_data(fc) && sta) {
tx_cmd->initial_rate_index = 0;
tx_cmd->tx_flags |= cpu_to_le32(TX_CMD_FLG_STA_RATE);
return;
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index 1393bac0025c..3781b029e54a 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -174,6 +174,7 @@ static void iwl_pcie_apm_config(struct iwl_trans *trans)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
u16 lctl;
+ u16 cap;
/*
* HW bug W/A for instability in PCIe bus L0S->L1 transition.
@@ -184,16 +185,17 @@ static void iwl_pcie_apm_config(struct iwl_trans *trans)
* power savings, even without L1.
*/
pcie_capability_read_word(trans_pcie->pci_dev, PCI_EXP_LNKCTL, &lctl);
- if (lctl & PCI_EXP_LNKCTL_ASPM_L1) {
- /* L1-ASPM enabled; disable(!) L0S */
+ if (lctl & PCI_EXP_LNKCTL_ASPM_L1)
iwl_set_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
- dev_info(trans->dev, "L1 Enabled; Disabling L0S\n");
- } else {
- /* L1-ASPM disabled; enable(!) L0S */
+ else
iwl_clear_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
- dev_info(trans->dev, "L1 Disabled; Enabling L0S\n");
- }
trans->pm_support = !(lctl & PCI_EXP_LNKCTL_ASPM_L0S);
+
+ pcie_capability_read_word(trans_pcie->pci_dev, PCI_EXP_DEVCTL2, &cap);
+ trans->ltr_enabled = cap & PCI_EXP_DEVCTL2_LTR_EN;
+ dev_info(trans->dev, "L1 %sabled - LTR %sabled\n",
+ (lctl & PCI_EXP_LNKCTL_ASPM_L1) ? "En" : "Dis",
+ trans->ltr_enabled ? "En" : "Dis");
}
/*
@@ -428,7 +430,7 @@ static int iwl_pcie_apm_stop_master(struct iwl_trans *trans)
ret = iwl_poll_bit(trans, CSR_RESET,
CSR_RESET_REG_FLAG_MASTER_DISABLED,
CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
- if (ret)
+ if (ret < 0)
IWL_WARN(trans, "Master Disable Timed Out, 100 usec\n");
IWL_DEBUG_INFO(trans, "stop master\n");
@@ -544,7 +546,7 @@ static int iwl_pcie_prepare_card_hw(struct iwl_trans *trans)
msleep(25);
}
- IWL_DEBUG_INFO(trans, "got NIC after %d iterations\n", iter);
+ IWL_ERR(trans, "Couldn't prepare the card\n");
return ret;
}
@@ -1043,7 +1045,7 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans,
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
25000);
- if (ret) {
+ if (ret < 0) {
IWL_ERR(trans, "Failed to resume the device (mac ready)\n");
return ret;
}
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c
index 40057079ffb9..5ef5a0eeba50 100644
--- a/drivers/net/wireless/mwifiex/11n_rxreorder.c
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c
@@ -196,6 +196,7 @@ mwifiex_del_rx_reorder_entry(struct mwifiex_private *priv,
mwifiex_11n_dispatch_pkt_until_start_win(priv, tbl, start_win);
del_timer_sync(&tbl->timer_context.timer);
+ tbl->timer_context.timer_is_set = false;
spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
list_del(&tbl->list);
@@ -297,6 +298,7 @@ mwifiex_flush_data(unsigned long context)
(struct reorder_tmr_cnxt *) context;
int start_win, seq_num;
+ ctx->timer_is_set = false;
seq_num = mwifiex_11n_find_last_seq_num(ctx);
if (seq_num < 0)
@@ -385,6 +387,7 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
new_node->timer_context.ptr = new_node;
new_node->timer_context.priv = priv;
+ new_node->timer_context.timer_is_set = false;
init_timer(&new_node->timer_context.timer);
new_node->timer_context.timer.function = mwifiex_flush_data;
@@ -399,6 +402,22 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
}
+static void
+mwifiex_11n_rxreorder_timer_restart(struct mwifiex_rx_reorder_tbl *tbl)
+{
+ u32 min_flush_time;
+
+ if (tbl->win_size >= MWIFIEX_BA_WIN_SIZE_32)
+ min_flush_time = MIN_FLUSH_TIMER_15_MS;
+ else
+ min_flush_time = MIN_FLUSH_TIMER_MS;
+
+ mod_timer(&tbl->timer_context.timer,
+ jiffies + msecs_to_jiffies(min_flush_time * tbl->win_size));
+
+ tbl->timer_context.timer_is_set = true;
+}
+
/*
* This function prepares command for adding a BA request.
*
@@ -523,31 +542,31 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv,
u8 *ta, u8 pkt_type, void *payload)
{
struct mwifiex_rx_reorder_tbl *tbl;
- int start_win, end_win, win_size;
+ int prev_start_win, start_win, end_win, win_size;
u16 pkt_index;
bool init_window_shift = false;
+ int ret = 0;
tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid, ta);
if (!tbl) {
if (pkt_type != PKT_TYPE_BAR)
mwifiex_11n_dispatch_pkt(priv, payload);
- return 0;
+ return ret;
}
if ((pkt_type == PKT_TYPE_AMSDU) && !tbl->amsdu) {
mwifiex_11n_dispatch_pkt(priv, payload);
- return 0;
+ return ret;
}
start_win = tbl->start_win;
+ prev_start_win = start_win;
win_size = tbl->win_size;
end_win = ((start_win + win_size) - 1) & (MAX_TID_VALUE - 1);
if (tbl->flags & RXREOR_INIT_WINDOW_SHIFT) {
init_window_shift = true;
tbl->flags &= ~RXREOR_INIT_WINDOW_SHIFT;
}
- mod_timer(&tbl->timer_context.timer,
- jiffies + msecs_to_jiffies(MIN_FLUSH_TIMER_MS * win_size));
if (tbl->flags & RXREOR_FORCE_NO_DROP) {
dev_dbg(priv->adapter->dev,
@@ -568,11 +587,14 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv,
if ((start_win + TWOPOW11) > (MAX_TID_VALUE - 1)) {
if (seq_num >= ((start_win + TWOPOW11) &
(MAX_TID_VALUE - 1)) &&
- seq_num < start_win)
- return -1;
+ seq_num < start_win) {
+ ret = -1;
+ goto done;
+ }
} else if ((seq_num < start_win) ||
- (seq_num > (start_win + TWOPOW11))) {
- return -1;
+ (seq_num >= (start_win + TWOPOW11))) {
+ ret = -1;
+ goto done;
}
}
@@ -601,8 +623,10 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv,
else
pkt_index = (seq_num+MAX_TID_VALUE) - start_win;
- if (tbl->rx_reorder_ptr[pkt_index])
- return -1;
+ if (tbl->rx_reorder_ptr[pkt_index]) {
+ ret = -1;
+ goto done;
+ }
tbl->rx_reorder_ptr[pkt_index] = payload;
}
@@ -613,7 +637,11 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv,
*/
mwifiex_11n_scan_and_dispatch(priv, tbl);
- return 0;
+done:
+ if (!tbl->timer_context.timer_is_set ||
+ prev_start_win != tbl->start_win)
+ mwifiex_11n_rxreorder_timer_restart(tbl);
+ return ret;
}
/*
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.h b/drivers/net/wireless/mwifiex/11n_rxreorder.h
index 3a87bb0e3a62..63ecea89b4ab 100644
--- a/drivers/net/wireless/mwifiex/11n_rxreorder.h
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.h
@@ -21,6 +21,8 @@
#define _MWIFIEX_11N_RXREORDER_H_
#define MIN_FLUSH_TIMER_MS 50
+#define MIN_FLUSH_TIMER_15_MS 15
+#define MWIFIEX_BA_WIN_SIZE_32 32
#define PKT_TYPE_BAR 0xE7
#define MAX_TID_VALUE (2 << 11)
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index e2635747d966..f55658d15c60 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -592,6 +592,7 @@ struct reorder_tmr_cnxt {
struct timer_list timer;
struct mwifiex_rx_reorder_tbl *ptr;
struct mwifiex_private *priv;
+ u8 timer_is_set;
};
struct mwifiex_rx_reorder_tbl {
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 573897b8e878..8444313eabe2 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -1111,6 +1111,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
/* Ovislink */
{ USB_DEVICE(0x1b75, 0x3071) },
{ USB_DEVICE(0x1b75, 0x3072) },
+ { USB_DEVICE(0x1b75, 0xa200) },
/* Para */
{ USB_DEVICE(0x20b8, 0x8888) },
/* Pegatron */
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c
index 58ba71830886..40b6d1d006d7 100644
--- a/drivers/net/wireless/rtlwifi/base.c
+++ b/drivers/net/wireless/rtlwifi/base.c
@@ -467,7 +467,7 @@ static void _rtl_init_deferred_work(struct ieee80211_hw *hw)
rtl_easy_concurrent_retrytimer_callback, (unsigned long)hw);
/* <2> work queue */
rtlpriv->works.hw = hw;
- rtlpriv->works.rtl_wq = alloc_workqueue(rtlpriv->cfg->name, 0, 0);
+ rtlpriv->works.rtl_wq = alloc_workqueue("%s", 0, 0, rtlpriv->cfg->name);
INIT_DELAYED_WORK(&rtlpriv->works.watchdog_wq,
(void *)rtl_watchdog_wq_callback);
INIT_DELAYED_WORK(&rtlpriv->works.ips_nic_off_wq,
diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c
index f6179bc06086..07dae0d44abc 100644
--- a/drivers/net/wireless/rtlwifi/core.c
+++ b/drivers/net/wireless/rtlwifi/core.c
@@ -1828,3 +1828,9 @@ const struct ieee80211_ops rtl_ops = {
.flush = rtl_op_flush,
};
EXPORT_SYMBOL_GPL(rtl_ops);
+
+bool rtl_btc_status_false(void)
+{
+ return false;
+}
+EXPORT_SYMBOL_GPL(rtl_btc_status_false);
diff --git a/drivers/net/wireless/rtlwifi/core.h b/drivers/net/wireless/rtlwifi/core.h
index 59cd3b9dca25..624e1dc16d31 100644
--- a/drivers/net/wireless/rtlwifi/core.h
+++ b/drivers/net/wireless/rtlwifi/core.h
@@ -42,5 +42,6 @@ void rtl_rfreg_delay(struct ieee80211_hw *hw, enum radio_path rfpath, u32 addr,
u32 mask, u32 data);
void rtl_bb_delay(struct ieee80211_hw *hw, u32 addr, u32 data);
bool rtl_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb);
+bool rtl_btc_status_false(void);
#endif
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
index 667aba81246c..25daa8715219 100644
--- a/drivers/net/wireless/rtlwifi/pci.c
+++ b/drivers/net/wireless/rtlwifi/pci.c
@@ -1796,7 +1796,8 @@ static int rtl_pci_start(struct ieee80211_hw *hw)
rtl_pci_reset_trx_ring(hw);
rtlpci->driver_is_goingto_unload = false;
- if (rtlpriv->cfg->ops->get_btc_status()) {
+ if (rtlpriv->cfg->ops->get_btc_status &&
+ rtlpriv->cfg->ops->get_btc_status()) {
rtlpriv->btcoexist.btc_ops->btc_init_variables(rtlpriv);
rtlpriv->btcoexist.btc_ops->btc_init_hal_vars(rtlpriv);
}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
index a00861b26ece..29983bc96a89 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
@@ -656,7 +656,8 @@ static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
-void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
+void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw,
+ bool (*cmd_send_packet)(struct ieee80211_hw *, struct sk_buff *))
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
@@ -722,7 +723,10 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
memcpy((u8 *)skb_put(skb, totalpacketlen),
&reserved_page_packet, totalpacketlen);
- rtstatus = rtl_cmd_send_packet(hw, skb);
+ if (cmd_send_packet)
+ rtstatus = cmd_send_packet(hw, skb);
+ else
+ rtstatus = rtl_cmd_send_packet(hw, skb);
if (rtstatus)
b_dlok = true;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h
index a815bd6273da..b64ae45dc674 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h
@@ -109,7 +109,9 @@ void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id,
u32 cmd_len, u8 *p_cmdbuffer);
void rtl92c_firmware_selfreset(struct ieee80211_hw *hw);
void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode);
-void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished);
+void rtl92c_set_fw_rsvdpagepkt
+ (struct ieee80211_hw *hw,
+ bool (*cmd_send_packet)(struct ieee80211_hw *, struct sk_buff *));
void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus);
void usb_writeN_async(struct rtl_priv *rtlpriv, u32 addr, void *data, u16 len);
void rtl92c_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h
index 831df101d7b7..9b660df6fd71 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h
@@ -114,6 +114,8 @@
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 16, 4)
#define GET_C2H_CMD_FEEDBACK_CCX_SEQ(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 20, 12)
+#define GET_RX_STATUS_DESC_BUFF_ADDR(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc + 24, 0, 32)
#define CHIP_VER_B BIT(4)
#define CHIP_BONDING_IDENTIFIER(_value) (((_value) >> 22) & 0x3)
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
index 8ec0f031f48a..55357d69397a 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
@@ -459,7 +459,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2,
tmp_reg422 & (~BIT(6)));
- rtl92c_set_fw_rsvdpagepkt(hw, 0);
+ rtl92c_set_fw_rsvdpagepkt(hw, NULL);
_rtl92ce_set_bcn_ctrl_reg(hw, BIT(3), 0);
_rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(4));
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
index d86b5b566444..46ea07605eb4 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
@@ -244,6 +244,7 @@ static struct rtl_hal_ops rtl8192ce_hal_ops = {
.phy_lc_calibrate = _rtl92ce_phy_lc_calibrate,
.phy_set_bw_mode_callback = rtl92ce_phy_set_bw_mode_callback,
.dm_dynamic_txpower = rtl92ce_dm_dynamic_txpower,
+ .get_btc_status = rtl_btc_status_false,
};
static struct rtl_mod_params rtl92ce_mod_params = {
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
index 2fb9c7acb76a..dc3d20b17a26 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
@@ -728,6 +728,9 @@ u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name)
case HW_DESC_RXPKT_LEN:
ret = GET_RX_DESC_PKT_LEN(pdesc);
break;
+ case HW_DESC_RXBUFF_ADDR:
+ ret = GET_RX_STATUS_DESC_BUFF_ADDR(pdesc);
+ break;
default:
RT_ASSERT(false, "ERR rxdesc :%d not process\n",
desc_name);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
index 04aa0b5f5b3d..873363acbacf 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
@@ -1592,6 +1592,20 @@ void rtl92cu_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
}
}
+bool usb_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ /* Currently nothing happens here.
+ * Traffic stops after some seconds in WPA2 802.11n mode.
+ * Maybe because rtl8192cu chip should be set from here?
+ * If I understand correctly, the realtek vendor driver sends some urbs
+ * if its "here".
+ *
+ * This is maybe necessary:
+ * rtlpriv->cfg->ops->fill_tx_cmddesc(hw, buffer, 1, 1, skb);
+ */
+ return true;
+}
+
void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -1939,7 +1953,8 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
recover = true;
rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2,
tmp_reg422 & (~BIT(6)));
- rtl92c_set_fw_rsvdpagepkt(hw, 0);
+ rtl92c_set_fw_rsvdpagepkt(hw,
+ &usb_cmd_send_packet);
_rtl92cu_set_bcn_ctrl_reg(hw, BIT(3), 0);
_rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(4));
if (recover)
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h
index 0f7812e0c8aa..c1e33b0228c0 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h
@@ -104,7 +104,6 @@ bool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid);
void rtl92cu_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid);
int rtl92c_download_fw(struct ieee80211_hw *hw);
void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode);
-void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished);
void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus);
void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw,
u8 element_id, u32 cmd_len, u8 *p_cmdbuffer);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
index 7c5fbaf5fee0..e06bafee37f9 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
@@ -101,6 +101,12 @@ static void rtl92cu_deinit_sw_vars(struct ieee80211_hw *hw)
}
}
+/* get bt coexist status */
+static bool rtl92cu_get_btc_status(void)
+{
+ return false;
+}
+
static struct rtl_hal_ops rtl8192cu_hal_ops = {
.init_sw_vars = rtl92cu_init_sw_vars,
.deinit_sw_vars = rtl92cu_deinit_sw_vars,
@@ -148,6 +154,7 @@ static struct rtl_hal_ops rtl8192cu_hal_ops = {
.phy_set_bw_mode_callback = rtl92cu_phy_set_bw_mode_callback,
.dm_dynamic_txpower = rtl92cu_dm_dynamic_txpower,
.fill_h2c_cmd = rtl92c_fill_h2c_cmd,
+ .get_btc_status = rtl92cu_get_btc_status,
};
static struct rtl_mod_params rtl92cu_mod_params = {
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
index edab5a5351b5..a0aba088259a 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
@@ -251,6 +251,7 @@ static struct rtl_hal_ops rtl8192de_hal_ops = {
.get_rfreg = rtl92d_phy_query_rf_reg,
.set_rfreg = rtl92d_phy_set_rf_reg,
.linked_set_reg = rtl92d_linked_set_reg,
+ .get_btc_status = rtl_btc_status_false,
};
static struct rtl_mod_params rtl92de_mod_params = {
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ee/hw.c
index dfdc9b20e4ad..1a87edca2c3f 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ee/hw.c
@@ -362,7 +362,7 @@ void rtl92ee_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
}
break;
default:
- RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG,
"switch case not process %x\n", variable);
break;
}
@@ -591,7 +591,7 @@ void rtl92ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
acm_ctrl &= (~ACMHW_BEQEN);
break;
default:
- RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG,
"switch case not process\n");
break;
}
@@ -710,7 +710,7 @@ void rtl92ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
}
break;
default:
- RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG,
"switch case not process %x\n", variable);
break;
}
@@ -2424,7 +2424,7 @@ void rtl92ee_set_key(struct ieee80211_hw *hw, u32 key_index,
enc_algo = CAM_AES;
break;
default:
- RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG,
"switch case not process\n");
enc_algo = CAM_TKIP;
break;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/def.h b/drivers/net/wireless/rtlwifi/rtl8192se/def.h
index 83c98674bfd3..6e7a70b43949 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/def.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/def.h
@@ -446,6 +446,8 @@
/* DWORD 6 */
#define SET_RX_STATUS__DESC_BUFF_ADDR(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc + 24, 0, 32, __val)
+#define GET_RX_STATUS_DESC_BUFF_ADDR(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc + 24, 0, 32)
#define SE_RX_HAL_IS_CCK_RATE(_pdesc)\
(GET_RX_STATUS_DESC_RX_MCS(_pdesc) == DESC92_RATE1M || \
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
index 1bff2a0f7600..aadba29c167a 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
@@ -87,11 +87,8 @@ static void rtl92s_init_aspm_vars(struct ieee80211_hw *hw)
static void rtl92se_fw_cb(const struct firmware *firmware, void *context)
{
struct ieee80211_hw *hw = context;
- struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
struct rtl_priv *rtlpriv = rtl_priv(hw);
- struct rtl_pci *rtlpci = rtl_pcidev(pcipriv);
struct rt_firmware *pfirmware = NULL;
- int err;
RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
"Firmware callback routine entered!\n");
@@ -112,20 +109,6 @@ static void rtl92se_fw_cb(const struct firmware *firmware, void *context)
memcpy(pfirmware->sz_fw_tmpbuffer, firmware->data, firmware->size);
pfirmware->sz_fw_tmpbufferlen = firmware->size;
release_firmware(firmware);
-
- err = ieee80211_register_hw(hw);
- if (err) {
- RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
- "Can't register mac80211 hw\n");
- return;
- } else {
- rtlpriv->mac80211.mac80211_registered = 1;
- }
- rtlpci->irq_alloc = 1;
- set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
-
- /*init rfkill */
- rtl_init_rfkill(hw);
}
static int rtl92s_init_sw_vars(struct ieee80211_hw *hw)
@@ -226,8 +209,8 @@ static int rtl92s_init_sw_vars(struct ieee80211_hw *hw)
if (!rtlpriv->rtlhal.pfirmware)
return 1;
- rtlpriv->max_fw_size = RTL8190_MAX_RAW_FIRMWARE_CODE_SIZE;
-
+ rtlpriv->max_fw_size = RTL8190_MAX_FIRMWARE_CODE_SIZE*2 +
+ sizeof(struct fw_hdr);
pr_info("Driver for Realtek RTL8192SE/RTL8191SE\n"
"Loading firmware %s\n", rtlpriv->cfg->fw_name);
/* request fw */
@@ -294,6 +277,7 @@ static struct rtl_hal_ops rtl8192se_hal_ops = {
.set_bbreg = rtl92s_phy_set_bb_reg,
.get_rfreg = rtl92s_phy_query_rf_reg,
.set_rfreg = rtl92s_phy_set_rf_reg,
+ .get_btc_status = rtl_btc_status_false,
};
static struct rtl_mod_params rtl92se_mod_params = {
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
index b358ebce8942..672fd3b02835 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
@@ -640,6 +640,9 @@ u32 rtl92se_get_desc(u8 *desc, bool istx, u8 desc_name)
case HW_DESC_RXPKT_LEN:
ret = GET_RX_STATUS_DESC_PKT_LEN(desc);
break;
+ case HW_DESC_RXBUFF_ADDR:
+ ret = GET_RX_STATUS_DESC_BUFF_ADDR(desc);
+ break;
default:
RT_ASSERT(false, "ERR rxdesc :%d not process\n",
desc_name);
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/phy.c b/drivers/net/wireless/rtlwifi/rtl8821ae/phy.c
index 9786313dc62f..1e9570fa874f 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/phy.c
+++ b/drivers/net/wireless/rtlwifi/rtl8821ae/phy.c
@@ -1889,15 +1889,18 @@ static void _rtl8821ae_store_tx_power_by_rate(struct ieee80211_hw *hw,
struct rtl_phy *rtlphy = &rtlpriv->phy;
u8 rate_section = _rtl8821ae_get_rate_section_index(regaddr);
- if (band != BAND_ON_2_4G && band != BAND_ON_5G)
+ if (band != BAND_ON_2_4G && band != BAND_ON_5G) {
RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid Band %d\n", band);
-
- if (rfpath >= MAX_RF_PATH)
+ band = BAND_ON_2_4G;
+ }
+ if (rfpath >= MAX_RF_PATH) {
RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid RfPath %d\n", rfpath);
-
- if (txnum >= MAX_RF_PATH)
+ rfpath = MAX_RF_PATH - 1;
+ }
+ if (txnum >= MAX_RF_PATH) {
RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid TxNum %d\n", txnum);
-
+ txnum = MAX_RF_PATH - 1;
+ }
rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section] = data;
RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
"TxPwrByRateOffset[Band %d][RfPath %d][TxNum %d][RateSection %d] = 0x%x\n",
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c
index 10cf69c4bc42..46ee956d0235 100644
--- a/drivers/net/wireless/rtlwifi/usb.c
+++ b/drivers/net/wireless/rtlwifi/usb.c
@@ -1117,7 +1117,18 @@ int rtl_usb_probe(struct usb_interface *intf,
}
rtlpriv->cfg->ops->init_sw_leds(hw);
+ err = ieee80211_register_hw(hw);
+ if (err) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ "Can't register mac80211 hw.\n");
+ err = -ENODEV;
+ goto error_out;
+ }
+ rtlpriv->mac80211.mac80211_registered = 1;
+
+ set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
return 0;
+
error_out:
rtl_deinit_core(hw);
_rtl_usb_io_handler_release(hw);
diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h
index d4eb8d2e9cb7..083ecc93fe5e 100644
--- a/drivers/net/xen-netback/common.h
+++ b/drivers/net/xen-netback/common.h
@@ -176,10 +176,11 @@ struct xenvif_queue { /* Per-queue data for xenvif */
char rx_irq_name[IRQ_NAME_SIZE]; /* DEVNAME-qN-rx */
struct xen_netif_rx_back_ring rx;
struct sk_buff_head rx_queue;
- RING_IDX rx_last_skb_slots;
- unsigned long status;
- struct timer_list rx_stalled;
+ unsigned int rx_queue_max;
+ unsigned int rx_queue_len;
+ unsigned long last_rx_time;
+ bool stalled;
struct gnttab_copy grant_copy_op[MAX_GRANT_COPY_OPS];
@@ -199,18 +200,14 @@ struct xenvif_queue { /* Per-queue data for xenvif */
struct xenvif_stats stats;
};
+/* Maximum number of Rx slots a to-guest packet may use, including the
+ * slot needed for GSO meta-data.
+ */
+#define XEN_NETBK_RX_SLOTS_MAX (MAX_SKB_FRAGS + 1)
+
enum state_bit_shift {
/* This bit marks that the vif is connected */
VIF_STATUS_CONNECTED,
- /* This bit signals the RX thread that queuing was stopped (in
- * start_xmit), and either the timer fired or an RX interrupt came
- */
- QUEUE_STATUS_RX_PURGE_EVENT,
- /* This bit tells the interrupt handler that this queue was the reason
- * for the carrier off, so it should kick the thread. Only queues which
- * brought it down can turn on the carrier.
- */
- QUEUE_STATUS_RX_STALLED
};
struct xenvif {
@@ -228,9 +225,6 @@ struct xenvif {
u8 ip_csum:1;
u8 ipv6_csum:1;
- /* Internal feature information. */
- u8 can_queue:1; /* can queue packets for receiver? */
-
/* Is this interface disabled? True when backend discovers
* frontend is rogue.
*/
@@ -240,6 +234,9 @@ struct xenvif {
/* Queues */
struct xenvif_queue *queues;
unsigned int num_queues; /* active queues, resource allocated */
+ unsigned int stalled_queues;
+
+ spinlock_t lock;
#ifdef CONFIG_DEBUG_FS
struct dentry *xenvif_dbg_root;
@@ -249,6 +246,14 @@ struct xenvif {
struct net_device *dev;
};
+struct xenvif_rx_cb {
+ unsigned long expires;
+ int meta_slots_used;
+ bool full_coalesce;
+};
+
+#define XENVIF_RX_CB(skb) ((struct xenvif_rx_cb *)(skb)->cb)
+
static inline struct xenbus_device *xenvif_to_xenbus_device(struct xenvif *vif)
{
return to_xenbus_device(vif->dev->dev.parent);
@@ -272,8 +277,6 @@ void xenvif_xenbus_fini(void);
int xenvif_schedulable(struct xenvif *vif);
-int xenvif_must_stop_queue(struct xenvif_queue *queue);
-
int xenvif_queue_stopped(struct xenvif_queue *queue);
void xenvif_wake_queue(struct xenvif_queue *queue);
@@ -296,6 +299,8 @@ void xenvif_kick_thread(struct xenvif_queue *queue);
int xenvif_dealloc_kthread(void *data);
+void xenvif_rx_queue_tail(struct xenvif_queue *queue, struct sk_buff *skb);
+
/* Determine whether the needed number of slots (req) are available,
* and set req_event if not.
*/
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
index f379689dde30..895fe84011e7 100644
--- a/drivers/net/xen-netback/interface.c
+++ b/drivers/net/xen-netback/interface.c
@@ -43,6 +43,9 @@
#define XENVIF_QUEUE_LENGTH 32
#define XENVIF_NAPI_WEIGHT 64
+/* Number of bytes allowed on the internal guest Rx queue. */
+#define XENVIF_RX_QUEUE_BYTES (XEN_NETIF_RX_RING_SIZE/2 * PAGE_SIZE)
+
/* This function is used to set SKBTX_DEV_ZEROCOPY as well as
* increasing the inflight counter. We need to increase the inflight
* counter because core driver calls into xenvif_zerocopy_callback
@@ -60,20 +63,11 @@ void xenvif_skb_zerocopy_complete(struct xenvif_queue *queue)
atomic_dec(&queue->inflight_packets);
}
-static inline void xenvif_stop_queue(struct xenvif_queue *queue)
-{
- struct net_device *dev = queue->vif->dev;
-
- if (!queue->vif->can_queue)
- return;
-
- netif_tx_stop_queue(netdev_get_tx_queue(dev, queue->id));
-}
-
int xenvif_schedulable(struct xenvif *vif)
{
return netif_running(vif->dev) &&
- test_bit(VIF_STATUS_CONNECTED, &vif->status);
+ test_bit(VIF_STATUS_CONNECTED, &vif->status) &&
+ !vif->disabled;
}
static irqreturn_t xenvif_tx_interrupt(int irq, void *dev_id)
@@ -114,16 +108,7 @@ int xenvif_poll(struct napi_struct *napi, int budget)
static irqreturn_t xenvif_rx_interrupt(int irq, void *dev_id)
{
struct xenvif_queue *queue = dev_id;
- struct netdev_queue *net_queue =
- netdev_get_tx_queue(queue->vif->dev, queue->id);
- /* QUEUE_STATUS_RX_PURGE_EVENT is only set if either QDisc was off OR
- * the carrier went down and this queue was previously blocked
- */
- if (unlikely(netif_tx_queue_stopped(net_queue) ||
- (!netif_carrier_ok(queue->vif->dev) &&
- test_bit(QUEUE_STATUS_RX_STALLED, &queue->status))))
- set_bit(QUEUE_STATUS_RX_PURGE_EVENT, &queue->status);
xenvif_kick_thread(queue);
return IRQ_HANDLED;
@@ -151,24 +136,13 @@ void xenvif_wake_queue(struct xenvif_queue *queue)
netif_tx_wake_queue(netdev_get_tx_queue(dev, id));
}
-/* Callback to wake the queue's thread and turn the carrier off on timeout */
-static void xenvif_rx_stalled(unsigned long data)
-{
- struct xenvif_queue *queue = (struct xenvif_queue *)data;
-
- if (xenvif_queue_stopped(queue)) {
- set_bit(QUEUE_STATUS_RX_PURGE_EVENT, &queue->status);
- xenvif_kick_thread(queue);
- }
-}
-
static int xenvif_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct xenvif *vif = netdev_priv(dev);
struct xenvif_queue *queue = NULL;
unsigned int num_queues = vif->num_queues;
u16 index;
- int min_slots_needed;
+ struct xenvif_rx_cb *cb;
BUG_ON(skb->dev != dev);
@@ -191,30 +165,10 @@ static int xenvif_start_xmit(struct sk_buff *skb, struct net_device *dev)
!xenvif_schedulable(vif))
goto drop;
- /* At best we'll need one slot for the header and one for each
- * frag.
- */
- min_slots_needed = 1 + skb_shinfo(skb)->nr_frags;
-
- /* If the skb is GSO then we'll also need an extra slot for the
- * metadata.
- */
- if (skb_is_gso(skb))
- min_slots_needed++;
+ cb = XENVIF_RX_CB(skb);
+ cb->expires = jiffies + rx_drain_timeout_jiffies;
- /* If the skb can't possibly fit in the remaining slots
- * then turn off the queue to give the ring a chance to
- * drain.
- */
- if (!xenvif_rx_ring_slots_available(queue, min_slots_needed)) {
- queue->rx_stalled.function = xenvif_rx_stalled;
- queue->rx_stalled.data = (unsigned long)queue;
- xenvif_stop_queue(queue);
- mod_timer(&queue->rx_stalled,
- jiffies + rx_drain_timeout_jiffies);
- }
-
- skb_queue_tail(&queue->rx_queue, skb);
+ xenvif_rx_queue_tail(queue, skb);
xenvif_kick_thread(queue);
return NETDEV_TX_OK;
@@ -465,6 +419,8 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid,
vif->queues = NULL;
vif->num_queues = 0;
+ spin_lock_init(&vif->lock);
+
dev->netdev_ops = &xenvif_netdev_ops;
dev->hw_features = NETIF_F_SG |
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
@@ -508,6 +464,8 @@ int xenvif_init_queue(struct xenvif_queue *queue)
init_timer(&queue->credit_timeout);
queue->credit_window_start = get_jiffies_64();
+ queue->rx_queue_max = XENVIF_RX_QUEUE_BYTES;
+
skb_queue_head_init(&queue->rx_queue);
skb_queue_head_init(&queue->tx_queue);
@@ -539,8 +497,6 @@ int xenvif_init_queue(struct xenvif_queue *queue)
queue->grant_tx_handle[i] = NETBACK_INVALID_HANDLE;
}
- init_timer(&queue->rx_stalled);
-
return 0;
}
@@ -551,7 +507,6 @@ void xenvif_carrier_on(struct xenvif *vif)
dev_set_mtu(vif->dev, ETH_DATA_LEN);
netdev_update_features(vif->dev);
set_bit(VIF_STATUS_CONNECTED, &vif->status);
- netif_carrier_on(vif->dev);
if (netif_running(vif->dev))
xenvif_up(vif);
rtnl_unlock();
@@ -611,6 +566,8 @@ int xenvif_connect(struct xenvif_queue *queue, unsigned long tx_ring_ref,
disable_irq(queue->rx_irq);
}
+ queue->stalled = true;
+
task = kthread_create(xenvif_kthread_guest_rx,
(void *)queue, "%s-guest-rx", queue->name);
if (IS_ERR(task)) {
@@ -674,7 +631,6 @@ void xenvif_disconnect(struct xenvif *vif)
netif_napi_del(&queue->napi);
if (queue->task) {
- del_timer_sync(&queue->rx_stalled);
kthread_stop(queue->task);
queue->task = NULL;
}
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
index 08f65996534c..6563f0713fc0 100644
--- a/drivers/net/xen-netback/netback.c
+++ b/drivers/net/xen-netback/netback.c
@@ -55,13 +55,20 @@
bool separate_tx_rx_irq = 1;
module_param(separate_tx_rx_irq, bool, 0644);
-/* When guest ring is filled up, qdisc queues the packets for us, but we have
- * to timeout them, otherwise other guests' packets can get stuck there
+/* The time that packets can stay on the guest Rx internal queue
+ * before they are dropped.
*/
unsigned int rx_drain_timeout_msecs = 10000;
module_param(rx_drain_timeout_msecs, uint, 0444);
unsigned int rx_drain_timeout_jiffies;
+/* The length of time before the frontend is considered unresponsive
+ * because it isn't providing Rx slots.
+ */
+static unsigned int rx_stall_timeout_msecs = 60000;
+module_param(rx_stall_timeout_msecs, uint, 0444);
+static unsigned int rx_stall_timeout_jiffies;
+
unsigned int xenvif_max_queues;
module_param_named(max_queues, xenvif_max_queues, uint, 0644);
MODULE_PARM_DESC(max_queues,
@@ -83,7 +90,6 @@ static void make_tx_response(struct xenvif_queue *queue,
s8 st);
static inline int tx_work_todo(struct xenvif_queue *queue);
-static inline int rx_work_todo(struct xenvif_queue *queue);
static struct xen_netif_rx_response *make_rx_response(struct xenvif_queue *queue,
u16 id,
@@ -163,6 +169,69 @@ bool xenvif_rx_ring_slots_available(struct xenvif_queue *queue, int needed)
return false;
}
+void xenvif_rx_queue_tail(struct xenvif_queue *queue, struct sk_buff *skb)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&queue->rx_queue.lock, flags);
+
+ __skb_queue_tail(&queue->rx_queue, skb);
+
+ queue->rx_queue_len += skb->len;
+ if (queue->rx_queue_len > queue->rx_queue_max)
+ netif_tx_stop_queue(netdev_get_tx_queue(queue->vif->dev, queue->id));
+
+ spin_unlock_irqrestore(&queue->rx_queue.lock, flags);
+}
+
+static struct sk_buff *xenvif_rx_dequeue(struct xenvif_queue *queue)
+{
+ struct sk_buff *skb;
+
+ spin_lock_irq(&queue->rx_queue.lock);
+
+ skb = __skb_dequeue(&queue->rx_queue);
+ if (skb)
+ queue->rx_queue_len -= skb->len;
+
+ spin_unlock_irq(&queue->rx_queue.lock);
+
+ return skb;
+}
+
+static void xenvif_rx_queue_maybe_wake(struct xenvif_queue *queue)
+{
+ spin_lock_irq(&queue->rx_queue.lock);
+
+ if (queue->rx_queue_len < queue->rx_queue_max)
+ netif_tx_wake_queue(netdev_get_tx_queue(queue->vif->dev, queue->id));
+
+ spin_unlock_irq(&queue->rx_queue.lock);
+}
+
+
+static void xenvif_rx_queue_purge(struct xenvif_queue *queue)
+{
+ struct sk_buff *skb;
+ while ((skb = xenvif_rx_dequeue(queue)) != NULL)
+ kfree_skb(skb);
+}
+
+static void xenvif_rx_queue_drop_expired(struct xenvif_queue *queue)
+{
+ struct sk_buff *skb;
+
+ for(;;) {
+ skb = skb_peek(&queue->rx_queue);
+ if (!skb)
+ break;
+ if (time_before(jiffies, XENVIF_RX_CB(skb)->expires))
+ break;
+ xenvif_rx_dequeue(queue);
+ kfree_skb(skb);
+ }
+}
+
/*
* Returns true if we should start a new receive buffer instead of
* adding 'size' bytes to a buffer which currently contains 'offset'
@@ -237,13 +306,6 @@ static struct xenvif_rx_meta *get_next_rx_buffer(struct xenvif_queue *queue,
return meta;
}
-struct xenvif_rx_cb {
- int meta_slots_used;
- bool full_coalesce;
-};
-
-#define XENVIF_RX_CB(skb) ((struct xenvif_rx_cb *)(skb)->cb)
-
/*
* Set up the grant operations for this fragment. If it's a flipping
* interface, we also set up the unmap request from here.
@@ -587,12 +649,15 @@ static void xenvif_rx_action(struct xenvif_queue *queue)
skb_queue_head_init(&rxq);
- while ((skb = skb_dequeue(&queue->rx_queue)) != NULL) {
+ while (xenvif_rx_ring_slots_available(queue, XEN_NETBK_RX_SLOTS_MAX)
+ && (skb = xenvif_rx_dequeue(queue)) != NULL) {
RING_IDX max_slots_needed;
RING_IDX old_req_cons;
RING_IDX ring_slots_used;
int i;
+ queue->last_rx_time = jiffies;
+
/* We need a cheap worse case estimate for the number of
* slots we'll use.
*/
@@ -634,15 +699,6 @@ static void xenvif_rx_action(struct xenvif_queue *queue)
skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6))
max_slots_needed++;
- /* If the skb may not fit then bail out now */
- if (!xenvif_rx_ring_slots_available(queue, max_slots_needed)) {
- skb_queue_head(&queue->rx_queue, skb);
- need_to_notify = true;
- queue->rx_last_skb_slots = max_slots_needed;
- break;
- } else
- queue->rx_last_skb_slots = 0;
-
old_req_cons = queue->rx.req_cons;
XENVIF_RX_CB(skb)->meta_slots_used = xenvif_gop_skb(skb, &npo, queue);
ring_slots_used = queue->rx.req_cons - old_req_cons;
@@ -1869,12 +1925,6 @@ void xenvif_idx_unmap(struct xenvif_queue *queue, u16 pending_idx)
}
}
-static inline int rx_work_todo(struct xenvif_queue *queue)
-{
- return (!skb_queue_empty(&queue->rx_queue) &&
- xenvif_rx_ring_slots_available(queue, queue->rx_last_skb_slots));
-}
-
static inline int tx_work_todo(struct xenvif_queue *queue)
{
if (likely(RING_HAS_UNCONSUMED_REQUESTS(&queue->tx)))
@@ -1931,92 +1981,121 @@ err:
return err;
}
-static void xenvif_start_queue(struct xenvif_queue *queue)
+static void xenvif_queue_carrier_off(struct xenvif_queue *queue)
{
- if (xenvif_schedulable(queue->vif))
- xenvif_wake_queue(queue);
+ struct xenvif *vif = queue->vif;
+
+ queue->stalled = true;
+
+ /* At least one queue has stalled? Disable the carrier. */
+ spin_lock(&vif->lock);
+ if (vif->stalled_queues++ == 0) {
+ netdev_info(vif->dev, "Guest Rx stalled");
+ netif_carrier_off(vif->dev);
+ }
+ spin_unlock(&vif->lock);
}
-/* Only called from the queue's thread, it handles the situation when the guest
- * doesn't post enough requests on the receiving ring.
- * First xenvif_start_xmit disables QDisc and start a timer, and then either the
- * timer fires, or the guest send an interrupt after posting new request. If it
- * is the timer, the carrier is turned off here.
- * */
-static void xenvif_rx_purge_event(struct xenvif_queue *queue)
+static void xenvif_queue_carrier_on(struct xenvif_queue *queue)
{
- /* Either the last unsuccesful skb or at least 1 slot should fit */
- int needed = queue->rx_last_skb_slots ?
- queue->rx_last_skb_slots : 1;
+ struct xenvif *vif = queue->vif;
- /* It is assumed that if the guest post new slots after this, the RX
- * interrupt will set the QUEUE_STATUS_RX_PURGE_EVENT bit and wake up
- * the thread again
- */
- set_bit(QUEUE_STATUS_RX_STALLED, &queue->status);
- if (!xenvif_rx_ring_slots_available(queue, needed)) {
- rtnl_lock();
- if (netif_carrier_ok(queue->vif->dev)) {
- /* Timer fired and there are still no slots. Turn off
- * everything except the interrupts
- */
- netif_carrier_off(queue->vif->dev);
- skb_queue_purge(&queue->rx_queue);
- queue->rx_last_skb_slots = 0;
- if (net_ratelimit())
- netdev_err(queue->vif->dev, "Carrier off due to lack of guest response on queue %d\n", queue->id);
- } else {
- /* Probably an another queue already turned the carrier
- * off, make sure nothing is stucked in the internal
- * queue of this queue
- */
- skb_queue_purge(&queue->rx_queue);
- queue->rx_last_skb_slots = 0;
- }
- rtnl_unlock();
- } else if (!netif_carrier_ok(queue->vif->dev)) {
- unsigned int num_queues = queue->vif->num_queues;
- unsigned int i;
- /* The carrier was down, but an interrupt kicked
- * the thread again after new requests were
- * posted
- */
- clear_bit(QUEUE_STATUS_RX_STALLED,
- &queue->status);
- rtnl_lock();
- netif_carrier_on(queue->vif->dev);
- netif_tx_wake_all_queues(queue->vif->dev);
- rtnl_unlock();
+ queue->last_rx_time = jiffies; /* Reset Rx stall detection. */
+ queue->stalled = false;
- for (i = 0; i < num_queues; i++) {
- struct xenvif_queue *temp = &queue->vif->queues[i];
+ /* All queues are ready? Enable the carrier. */
+ spin_lock(&vif->lock);
+ if (--vif->stalled_queues == 0) {
+ netdev_info(vif->dev, "Guest Rx ready");
+ netif_carrier_on(vif->dev);
+ }
+ spin_unlock(&vif->lock);
+}
- xenvif_napi_schedule_or_enable_events(temp);
- }
- if (net_ratelimit())
- netdev_err(queue->vif->dev, "Carrier on again\n");
- } else {
- /* Queuing were stopped, but the guest posted
- * new requests and sent an interrupt
- */
- clear_bit(QUEUE_STATUS_RX_STALLED,
- &queue->status);
- del_timer_sync(&queue->rx_stalled);
- xenvif_start_queue(queue);
+static bool xenvif_rx_queue_stalled(struct xenvif_queue *queue)
+{
+ RING_IDX prod, cons;
+
+ prod = queue->rx.sring->req_prod;
+ cons = queue->rx.req_cons;
+
+ return !queue->stalled
+ && prod - cons < XEN_NETBK_RX_SLOTS_MAX
+ && time_after(jiffies,
+ queue->last_rx_time + rx_stall_timeout_jiffies);
+}
+
+static bool xenvif_rx_queue_ready(struct xenvif_queue *queue)
+{
+ RING_IDX prod, cons;
+
+ prod = queue->rx.sring->req_prod;
+ cons = queue->rx.req_cons;
+
+ return queue->stalled
+ && prod - cons >= XEN_NETBK_RX_SLOTS_MAX;
+}
+
+static bool xenvif_have_rx_work(struct xenvif_queue *queue)
+{
+ return (!skb_queue_empty(&queue->rx_queue)
+ && xenvif_rx_ring_slots_available(queue, XEN_NETBK_RX_SLOTS_MAX))
+ || xenvif_rx_queue_stalled(queue)
+ || xenvif_rx_queue_ready(queue)
+ || kthread_should_stop()
+ || queue->vif->disabled;
+}
+
+static long xenvif_rx_queue_timeout(struct xenvif_queue *queue)
+{
+ struct sk_buff *skb;
+ long timeout;
+
+ skb = skb_peek(&queue->rx_queue);
+ if (!skb)
+ return MAX_SCHEDULE_TIMEOUT;
+
+ timeout = XENVIF_RX_CB(skb)->expires - jiffies;
+ return timeout < 0 ? 0 : timeout;
+}
+
+/* Wait until the guest Rx thread has work.
+ *
+ * The timeout needs to be adjusted based on the current head of the
+ * queue (and not just the head at the beginning). In particular, if
+ * the queue is initially empty an infinite timeout is used and this
+ * needs to be reduced when a skb is queued.
+ *
+ * This cannot be done with wait_event_timeout() because it only
+ * calculates the timeout once.
+ */
+static void xenvif_wait_for_rx_work(struct xenvif_queue *queue)
+{
+ DEFINE_WAIT(wait);
+
+ if (xenvif_have_rx_work(queue))
+ return;
+
+ for (;;) {
+ long ret;
+
+ prepare_to_wait(&queue->wq, &wait, TASK_INTERRUPTIBLE);
+ if (xenvif_have_rx_work(queue))
+ break;
+ ret = schedule_timeout(xenvif_rx_queue_timeout(queue));
+ if (!ret)
+ break;
}
+ finish_wait(&queue->wq, &wait);
}
int xenvif_kthread_guest_rx(void *data)
{
struct xenvif_queue *queue = data;
- struct sk_buff *skb;
+ struct xenvif *vif = queue->vif;
- while (!kthread_should_stop()) {
- wait_event_interruptible(queue->wq,
- rx_work_todo(queue) ||
- queue->vif->disabled ||
- test_bit(QUEUE_STATUS_RX_PURGE_EVENT, &queue->status) ||
- kthread_should_stop());
+ for (;;) {
+ xenvif_wait_for_rx_work(queue);
if (kthread_should_stop())
break;
@@ -2028,35 +2107,38 @@ int xenvif_kthread_guest_rx(void *data)
* context so we defer it here, if this thread is
* associated with queue 0.
*/
- if (unlikely(queue->vif->disabled && queue->id == 0)) {
- xenvif_carrier_off(queue->vif);
- } else if (unlikely(queue->vif->disabled)) {
- /* kthread_stop() would be called upon this thread soon,
- * be a bit proactive
- */
- skb_queue_purge(&queue->rx_queue);
- queue->rx_last_skb_slots = 0;
- } else if (unlikely(test_and_clear_bit(QUEUE_STATUS_RX_PURGE_EVENT,
- &queue->status))) {
- xenvif_rx_purge_event(queue);
- } else if (!netif_carrier_ok(queue->vif->dev)) {
- /* Another queue stalled and turned the carrier off, so
- * purge the internal queue of queues which were not
- * blocked
- */
- skb_queue_purge(&queue->rx_queue);
- queue->rx_last_skb_slots = 0;
+ if (unlikely(vif->disabled && queue->id == 0)) {
+ xenvif_carrier_off(vif);
+ xenvif_rx_queue_purge(queue);
+ continue;
}
if (!skb_queue_empty(&queue->rx_queue))
xenvif_rx_action(queue);
+ /* If the guest hasn't provided any Rx slots for a
+ * while it's probably not responsive, drop the
+ * carrier so packets are dropped earlier.
+ */
+ if (xenvif_rx_queue_stalled(queue))
+ xenvif_queue_carrier_off(queue);
+ else if (xenvif_rx_queue_ready(queue))
+ xenvif_queue_carrier_on(queue);
+
+ /* Queued packets may have foreign pages from other
+ * domains. These cannot be queued indefinitely as
+ * this would starve guests of grant refs and transmit
+ * slots.
+ */
+ xenvif_rx_queue_drop_expired(queue);
+
+ xenvif_rx_queue_maybe_wake(queue);
+
cond_resched();
}
/* Bin any remaining skbs */
- while ((skb = skb_dequeue(&queue->rx_queue)) != NULL)
- dev_kfree_skb(skb);
+ xenvif_rx_queue_purge(queue);
return 0;
}
@@ -2113,6 +2195,7 @@ static int __init netback_init(void)
goto failed_init;
rx_drain_timeout_jiffies = msecs_to_jiffies(rx_drain_timeout_msecs);
+ rx_stall_timeout_jiffies = msecs_to_jiffies(rx_stall_timeout_msecs);
#ifdef CONFIG_DEBUG_FS
xen_netback_dbg_root = debugfs_create_dir("xen-netback", NULL);
diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c
index 8079c31ac5e6..4e56a27f9689 100644
--- a/drivers/net/xen-netback/xenbus.c
+++ b/drivers/net/xen-netback/xenbus.c
@@ -52,6 +52,7 @@ static int xenvif_read_io_ring(struct seq_file *m, void *v)
struct xenvif_queue *queue = m->private;
struct xen_netif_tx_back_ring *tx_ring = &queue->tx;
struct xen_netif_rx_back_ring *rx_ring = &queue->rx;
+ struct netdev_queue *dev_queue;
if (tx_ring->sring) {
struct xen_netif_tx_sring *sring = tx_ring->sring;
@@ -112,6 +113,13 @@ static int xenvif_read_io_ring(struct seq_file *m, void *v)
queue->credit_timeout.expires,
jiffies);
+ dev_queue = netdev_get_tx_queue(queue->vif->dev, queue->id);
+
+ seq_printf(m, "\nRx internal queue: len %u max %u pkts %u %s\n",
+ queue->rx_queue_len, queue->rx_queue_max,
+ skb_queue_len(&queue->rx_queue),
+ netif_tx_queue_stopped(dev_queue) ? "stopped" : "running");
+
return 0;
}
@@ -703,6 +711,7 @@ static void connect(struct backend_info *be)
be->vif->queues = vzalloc(requested_num_queues *
sizeof(struct xenvif_queue));
be->vif->num_queues = requested_num_queues;
+ be->vif->stalled_queues = requested_num_queues;
for (queue_index = 0; queue_index < requested_num_queues; ++queue_index) {
queue = &be->vif->queues[queue_index];
@@ -873,15 +882,10 @@ static int read_xenbus_vif_flags(struct backend_info *be)
if (!rx_copy)
return -EOPNOTSUPP;
- if (vif->dev->tx_queue_len != 0) {
- if (xenbus_scanf(XBT_NIL, dev->otherend,
- "feature-rx-notify", "%d", &val) < 0)
- val = 0;
- if (val)
- vif->can_queue = 1;
- else
- /* Must be non-zero for pfifo_fast to work. */
- vif->dev->tx_queue_len = 1;
+ if (xenbus_scanf(XBT_NIL, dev->otherend,
+ "feature-rx-notify", "%d", &val) < 0 || val == 0) {
+ xenbus_dev_fatal(dev, -EINVAL, "feature-rx-notify is mandatory");
+ return -EINVAL;
}
if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-sg",
diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 59fb12e84e6b..dc566b38645f 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -243,23 +243,27 @@ static inline struct reserved_mem *__find_rmem(struct device_node *node)
* This function assign memory region pointed by "memory-region" device tree
* property to the given device.
*/
-void of_reserved_mem_device_init(struct device *dev)
+int of_reserved_mem_device_init(struct device *dev)
{
struct reserved_mem *rmem;
struct device_node *np;
+ int ret;
np = of_parse_phandle(dev->of_node, "memory-region", 0);
if (!np)
- return;
+ return -ENODEV;
rmem = __find_rmem(np);
of_node_put(np);
if (!rmem || !rmem->ops || !rmem->ops->device_init)
- return;
+ return -EINVAL;
+
+ ret = rmem->ops->device_init(rmem, dev);
+ if (ret == 0)
+ dev_info(dev, "assigned reserved memory node %s\n", rmem->name);
- rmem->ops->device_init(rmem, dev);
- dev_info(dev, "assigned reserved memory node %s\n", rmem->name);
+ return ret;
}
/**
diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c
index 233fe8a88264..69202d1eb8fb 100644
--- a/drivers/pci/host/pci-imx6.c
+++ b/drivers/pci/host/pci-imx6.c
@@ -275,15 +275,22 @@ static int imx6_pcie_deassert_core_reset(struct pcie_port *pp)
goto err_pcie;
}
- /* allow the clocks to stabilize */
- usleep_range(200, 500);
-
/* power up core phy and enable ref clock */
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
IMX6Q_GPR1_PCIE_TEST_PD, 0 << 18);
+ /*
+ * the async reset input need ref clock to sync internally,
+ * when the ref clock comes after reset, internal synced
+ * reset time is too short, cannot meet the requirement.
+ * add one ~10us delay here.
+ */
+ udelay(10);
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16);
+ /* allow the clocks to stabilize */
+ usleep_range(200, 500);
+
/* Some boards don't have PCIe reset GPIO. */
if (gpio_is_valid(imx6_pcie->reset_gpio)) {
gpio_set_value(imx6_pcie->reset_gpio, 0);
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index 3a5e7e28b874..07aa722bb12c 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -262,13 +262,6 @@ static int pciehp_probe(struct pcie_device *dev)
goto err_out_none;
}
- if (!dev->port->subordinate) {
- /* Can happen if we run out of bus numbers during probe */
- dev_err(&dev->device,
- "Hotplug bridge without secondary bus, ignoring\n");
- goto err_out_none;
- }
-
ctrl = pcie_init(dev);
if (!ctrl) {
dev_err(&dev->device, "Controller initialization failed\n");
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 92b6d9ab00e4..2c6643fdc0cf 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -185,7 +185,7 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
}
static DEVICE_ATTR_RO(modalias);
-static ssize_t enabled_store(struct device *dev, struct device_attribute *attr,
+static ssize_t enable_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct pci_dev *pdev = to_pci_dev(dev);
@@ -210,7 +210,7 @@ static ssize_t enabled_store(struct device *dev, struct device_attribute *attr,
return result < 0 ? result : count;
}
-static ssize_t enabled_show(struct device *dev, struct device_attribute *attr,
+static ssize_t enable_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct pci_dev *pdev;
@@ -218,7 +218,7 @@ static ssize_t enabled_show(struct device *dev, struct device_attribute *attr,
pdev = to_pci_dev(dev);
return sprintf(buf, "%u\n", atomic_read(&pdev->enable_cnt));
}
-static DEVICE_ATTR_RW(enabled);
+static DEVICE_ATTR_RW(enable);
#ifdef CONFIG_NUMA
static ssize_t numa_node_show(struct device *dev, struct device_attribute *attr,
@@ -563,7 +563,7 @@ static struct attribute *pci_dev_attrs[] = {
#endif
&dev_attr_dma_mask_bits.attr,
&dev_attr_consistent_dma_mask_bits.attr,
- &dev_attr_enabled.attr,
+ &dev_attr_enable.attr,
&dev_attr_broken_parity_status.attr,
&dev_attr_msi_bus.attr,
#if defined(CONFIG_PM_RUNTIME) && defined(CONFIG_ACPI)
diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c
index e305416d7697..196a5c8838c4 100644
--- a/drivers/regulator/rk808-regulator.c
+++ b/drivers/regulator/rk808-regulator.c
@@ -44,7 +44,7 @@ static const int rk808_buck_config_regs[] = {
};
static const struct regulator_linear_range rk808_buck_voltage_ranges[] = {
- REGULATOR_LINEAR_RANGE(700000, 0, 63, 12500),
+ REGULATOR_LINEAR_RANGE(712500, 0, 63, 12500),
};
static const struct regulator_linear_range rk808_buck4_voltage_ranges[] = {
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 94ae1798d48a..6dd12ddbabc6 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1320,7 +1320,7 @@ config RTC_DRV_LPC32XX
config RTC_DRV_PM8XXX
tristate "Qualcomm PMIC8XXX RTC"
- depends on MFD_PM8XXX
+ depends on MFD_PM8XXX || MFD_SPMI_PMIC
help
If you say yes here you get support for the
Qualcomm PMIC8XXX RTC.
diff --git a/drivers/rtc/rtc-bq32k.c b/drivers/rtc/rtc-bq32k.c
index 314129e66d6e..92679df6d6e2 100644
--- a/drivers/rtc/rtc-bq32k.c
+++ b/drivers/rtc/rtc-bq32k.c
@@ -160,7 +160,7 @@ static int trickle_charger_of_init(struct device *dev, struct device_node *node)
dev_err(dev, "bq32k: diode and resistor mismatch\n");
return -EINVAL;
}
- reg = 0x25;
+ reg = 0x45;
break;
default:
diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c
index 197699f358c7..5adcf111fc14 100644
--- a/drivers/rtc/rtc-pm8xxx.c
+++ b/drivers/rtc/rtc-pm8xxx.c
@@ -27,21 +27,36 @@
/* RTC_CTRL register bit fields */
#define PM8xxx_RTC_ENABLE BIT(7)
-#define PM8xxx_RTC_ALARM_ENABLE BIT(1)
#define PM8xxx_RTC_ALARM_CLEAR BIT(0)
#define NUM_8_BIT_RTC_REGS 0x4
/**
+ * struct pm8xxx_rtc_regs - describe RTC registers per PMIC versions
+ * @ctrl: base address of control register
+ * @write: base address of write register
+ * @read: base address of read register
+ * @alarm_ctrl: base address of alarm control register
+ * @alarm_ctrl2: base address of alarm control2 register
+ * @alarm_rw: base address of alarm read-write register
+ * @alarm_en: alarm enable mask
+ */
+struct pm8xxx_rtc_regs {
+ unsigned int ctrl;
+ unsigned int write;
+ unsigned int read;
+ unsigned int alarm_ctrl;
+ unsigned int alarm_ctrl2;
+ unsigned int alarm_rw;
+ unsigned int alarm_en;
+};
+
+/**
* struct pm8xxx_rtc - rtc driver internal structure
* @rtc: rtc device for this driver.
* @regmap: regmap used to access RTC registers
* @allow_set_time: indicates whether writing to the RTC is allowed
* @rtc_alarm_irq: rtc alarm irq number.
- * @rtc_base: address of rtc control register.
- * @rtc_read_base: base address of read registers.
- * @rtc_write_base: base address of write registers.
- * @alarm_rw_base: base address of alarm registers.
* @ctrl_reg: rtc control register.
* @rtc_dev: device structure.
* @ctrl_reg_lock: spinlock protecting access to ctrl_reg.
@@ -51,11 +66,7 @@ struct pm8xxx_rtc {
struct regmap *regmap;
bool allow_set_time;
int rtc_alarm_irq;
- int rtc_base;
- int rtc_read_base;
- int rtc_write_base;
- int alarm_rw_base;
- u8 ctrl_reg;
+ const struct pm8xxx_rtc_regs *regs;
struct device *rtc_dev;
spinlock_t ctrl_reg_lock;
};
@@ -71,8 +82,10 @@ static int pm8xxx_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
int rc, i;
unsigned long secs, irq_flags;
- u8 value[NUM_8_BIT_RTC_REGS], alarm_enabled = 0, ctrl_reg;
+ u8 value[NUM_8_BIT_RTC_REGS], alarm_enabled = 0;
+ unsigned int ctrl_reg;
struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev);
+ const struct pm8xxx_rtc_regs *regs = rtc_dd->regs;
if (!rtc_dd->allow_set_time)
return -EACCES;
@@ -87,30 +100,30 @@ static int pm8xxx_rtc_set_time(struct device *dev, struct rtc_time *tm)
dev_dbg(dev, "Seconds value to be written to RTC = %lu\n", secs);
spin_lock_irqsave(&rtc_dd->ctrl_reg_lock, irq_flags);
- ctrl_reg = rtc_dd->ctrl_reg;
- if (ctrl_reg & PM8xxx_RTC_ALARM_ENABLE) {
+ rc = regmap_read(rtc_dd->regmap, regs->ctrl, &ctrl_reg);
+ if (rc)
+ goto rtc_rw_fail;
+
+ if (ctrl_reg & regs->alarm_en) {
alarm_enabled = 1;
- ctrl_reg &= ~PM8xxx_RTC_ALARM_ENABLE;
- rc = regmap_write(rtc_dd->regmap, rtc_dd->rtc_base, ctrl_reg);
+ ctrl_reg &= ~regs->alarm_en;
+ rc = regmap_write(rtc_dd->regmap, regs->ctrl, ctrl_reg);
if (rc) {
dev_err(dev, "Write to RTC control register failed\n");
goto rtc_rw_fail;
}
- rtc_dd->ctrl_reg = ctrl_reg;
- } else {
- spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags);
}
/* Write 0 to Byte[0] */
- rc = regmap_write(rtc_dd->regmap, rtc_dd->rtc_write_base, 0);
+ rc = regmap_write(rtc_dd->regmap, regs->write, 0);
if (rc) {
dev_err(dev, "Write to RTC write data register failed\n");
goto rtc_rw_fail;
}
/* Write Byte[1], Byte[2], Byte[3] */
- rc = regmap_bulk_write(rtc_dd->regmap, rtc_dd->rtc_write_base + 1,
+ rc = regmap_bulk_write(rtc_dd->regmap, regs->write + 1,
&value[1], sizeof(value) - 1);
if (rc) {
dev_err(dev, "Write to RTC write data register failed\n");
@@ -118,25 +131,23 @@ static int pm8xxx_rtc_set_time(struct device *dev, struct rtc_time *tm)
}
/* Write Byte[0] */
- rc = regmap_write(rtc_dd->regmap, rtc_dd->rtc_write_base, value[0]);
+ rc = regmap_write(rtc_dd->regmap, regs->write, value[0]);
if (rc) {
dev_err(dev, "Write to RTC write data register failed\n");
goto rtc_rw_fail;
}
if (alarm_enabled) {
- ctrl_reg |= PM8xxx_RTC_ALARM_ENABLE;
- rc = regmap_write(rtc_dd->regmap, rtc_dd->rtc_base, ctrl_reg);
+ ctrl_reg |= regs->alarm_en;
+ rc = regmap_write(rtc_dd->regmap, regs->ctrl, ctrl_reg);
if (rc) {
dev_err(dev, "Write to RTC control register failed\n");
goto rtc_rw_fail;
}
- rtc_dd->ctrl_reg = ctrl_reg;
}
rtc_rw_fail:
- if (alarm_enabled)
- spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags);
+ spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags);
return rc;
}
@@ -148,9 +159,9 @@ static int pm8xxx_rtc_read_time(struct device *dev, struct rtc_time *tm)
unsigned long secs;
unsigned int reg;
struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev);
+ const struct pm8xxx_rtc_regs *regs = rtc_dd->regs;
- rc = regmap_bulk_read(rtc_dd->regmap, rtc_dd->rtc_read_base,
- value, sizeof(value));
+ rc = regmap_bulk_read(rtc_dd->regmap, regs->read, value, sizeof(value));
if (rc) {
dev_err(dev, "RTC read data register failed\n");
return rc;
@@ -160,14 +171,14 @@ static int pm8xxx_rtc_read_time(struct device *dev, struct rtc_time *tm)
* Read the LSB again and check if there has been a carry over.
* If there is, redo the read operation.
*/
- rc = regmap_read(rtc_dd->regmap, rtc_dd->rtc_read_base, &reg);
+ rc = regmap_read(rtc_dd->regmap, regs->read, &reg);
if (rc < 0) {
dev_err(dev, "RTC read data register failed\n");
return rc;
}
if (unlikely(reg < value[0])) {
- rc = regmap_bulk_read(rtc_dd->regmap, rtc_dd->rtc_read_base,
+ rc = regmap_bulk_read(rtc_dd->regmap, regs->read,
value, sizeof(value));
if (rc) {
dev_err(dev, "RTC read data register failed\n");
@@ -195,9 +206,11 @@ static int pm8xxx_rtc_read_time(struct device *dev, struct rtc_time *tm)
static int pm8xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{
int rc, i;
- u8 value[NUM_8_BIT_RTC_REGS], ctrl_reg;
+ u8 value[NUM_8_BIT_RTC_REGS];
+ unsigned int ctrl_reg;
unsigned long secs, irq_flags;
struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev);
+ const struct pm8xxx_rtc_regs *regs = rtc_dd->regs;
rtc_tm_to_time(&alarm->time, &secs);
@@ -208,28 +221,28 @@ static int pm8xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
spin_lock_irqsave(&rtc_dd->ctrl_reg_lock, irq_flags);
- rc = regmap_bulk_write(rtc_dd->regmap, rtc_dd->alarm_rw_base, value,
+ rc = regmap_bulk_write(rtc_dd->regmap, regs->alarm_rw, value,
sizeof(value));
if (rc) {
dev_err(dev, "Write to RTC ALARM register failed\n");
goto rtc_rw_fail;
}
- ctrl_reg = rtc_dd->ctrl_reg;
+ rc = regmap_read(rtc_dd->regmap, regs->alarm_ctrl, &ctrl_reg);
+ if (rc)
+ goto rtc_rw_fail;
if (alarm->enabled)
- ctrl_reg |= PM8xxx_RTC_ALARM_ENABLE;
+ ctrl_reg |= regs->alarm_en;
else
- ctrl_reg &= ~PM8xxx_RTC_ALARM_ENABLE;
+ ctrl_reg &= ~regs->alarm_en;
- rc = regmap_write(rtc_dd->regmap, rtc_dd->rtc_base, ctrl_reg);
+ rc = regmap_write(rtc_dd->regmap, regs->alarm_ctrl, ctrl_reg);
if (rc) {
- dev_err(dev, "Write to RTC control register failed\n");
+ dev_err(dev, "Write to RTC alarm control register failed\n");
goto rtc_rw_fail;
}
- rtc_dd->ctrl_reg = ctrl_reg;
-
dev_dbg(dev, "Alarm Set for h:r:s=%d:%d:%d, d/m/y=%d/%d/%d\n",
alarm->time.tm_hour, alarm->time.tm_min,
alarm->time.tm_sec, alarm->time.tm_mday,
@@ -245,8 +258,9 @@ static int pm8xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
u8 value[NUM_8_BIT_RTC_REGS];
unsigned long secs;
struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev);
+ const struct pm8xxx_rtc_regs *regs = rtc_dd->regs;
- rc = regmap_bulk_read(rtc_dd->regmap, rtc_dd->alarm_rw_base, value,
+ rc = regmap_bulk_read(rtc_dd->regmap, regs->alarm_rw, value,
sizeof(value));
if (rc) {
dev_err(dev, "RTC alarm time read failed\n");
@@ -276,25 +290,26 @@ static int pm8xxx_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
int rc;
unsigned long irq_flags;
struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev);
- u8 ctrl_reg;
+ const struct pm8xxx_rtc_regs *regs = rtc_dd->regs;
+ unsigned int ctrl_reg;
spin_lock_irqsave(&rtc_dd->ctrl_reg_lock, irq_flags);
- ctrl_reg = rtc_dd->ctrl_reg;
+ rc = regmap_read(rtc_dd->regmap, regs->alarm_ctrl, &ctrl_reg);
+ if (rc)
+ goto rtc_rw_fail;
if (enable)
- ctrl_reg |= PM8xxx_RTC_ALARM_ENABLE;
+ ctrl_reg |= regs->alarm_en;
else
- ctrl_reg &= ~PM8xxx_RTC_ALARM_ENABLE;
+ ctrl_reg &= ~regs->alarm_en;
- rc = regmap_write(rtc_dd->regmap, rtc_dd->rtc_base, ctrl_reg);
+ rc = regmap_write(rtc_dd->regmap, regs->alarm_ctrl, ctrl_reg);
if (rc) {
dev_err(dev, "Write to RTC control register failed\n");
goto rtc_rw_fail;
}
- rtc_dd->ctrl_reg = ctrl_reg;
-
rtc_rw_fail:
spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags);
return rc;
@@ -311,6 +326,7 @@ static const struct rtc_class_ops pm8xxx_rtc_ops = {
static irqreturn_t pm8xxx_alarm_trigger(int irq, void *dev_id)
{
struct pm8xxx_rtc *rtc_dd = dev_id;
+ const struct pm8xxx_rtc_regs *regs = rtc_dd->regs;
unsigned int ctrl_reg;
int rc;
unsigned long irq_flags;
@@ -320,48 +336,100 @@ static irqreturn_t pm8xxx_alarm_trigger(int irq, void *dev_id)
spin_lock_irqsave(&rtc_dd->ctrl_reg_lock, irq_flags);
/* Clear the alarm enable bit */
- ctrl_reg = rtc_dd->ctrl_reg;
- ctrl_reg &= ~PM8xxx_RTC_ALARM_ENABLE;
+ rc = regmap_read(rtc_dd->regmap, regs->alarm_ctrl, &ctrl_reg);
+ if (rc) {
+ spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags);
+ goto rtc_alarm_handled;
+ }
+
+ ctrl_reg &= ~regs->alarm_en;
- rc = regmap_write(rtc_dd->regmap, rtc_dd->rtc_base, ctrl_reg);
+ rc = regmap_write(rtc_dd->regmap, regs->alarm_ctrl, ctrl_reg);
if (rc) {
spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags);
dev_err(rtc_dd->rtc_dev,
- "Write to RTC control register failed\n");
+ "Write to alarm control register failed\n");
goto rtc_alarm_handled;
}
- rtc_dd->ctrl_reg = ctrl_reg;
spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags);
/* Clear RTC alarm register */
- rc = regmap_read(rtc_dd->regmap,
- rtc_dd->rtc_base + PM8XXX_ALARM_CTRL_OFFSET,
- &ctrl_reg);
+ rc = regmap_read(rtc_dd->regmap, regs->alarm_ctrl2, &ctrl_reg);
if (rc) {
dev_err(rtc_dd->rtc_dev,
- "RTC Alarm control register read failed\n");
+ "RTC Alarm control2 register read failed\n");
goto rtc_alarm_handled;
}
- ctrl_reg &= ~PM8xxx_RTC_ALARM_CLEAR;
- rc = regmap_write(rtc_dd->regmap,
- rtc_dd->rtc_base + PM8XXX_ALARM_CTRL_OFFSET,
- ctrl_reg);
+ ctrl_reg |= PM8xxx_RTC_ALARM_CLEAR;
+ rc = regmap_write(rtc_dd->regmap, regs->alarm_ctrl2, ctrl_reg);
if (rc)
dev_err(rtc_dd->rtc_dev,
- "Write to RTC Alarm control register failed\n");
+ "Write to RTC Alarm control2 register failed\n");
rtc_alarm_handled:
return IRQ_HANDLED;
}
+static int pm8xxx_rtc_enable(struct pm8xxx_rtc *rtc_dd)
+{
+ const struct pm8xxx_rtc_regs *regs = rtc_dd->regs;
+ unsigned int ctrl_reg;
+ int rc;
+
+ /* Check if the RTC is on, else turn it on */
+ rc = regmap_read(rtc_dd->regmap, regs->ctrl, &ctrl_reg);
+ if (rc)
+ return rc;
+
+ if (!(ctrl_reg & PM8xxx_RTC_ENABLE)) {
+ ctrl_reg |= PM8xxx_RTC_ENABLE;
+ rc = regmap_write(rtc_dd->regmap, regs->ctrl, ctrl_reg);
+ if (rc)
+ return rc;
+ }
+
+ return 0;
+}
+
+static const struct pm8xxx_rtc_regs pm8921_regs = {
+ .ctrl = 0x11d,
+ .write = 0x11f,
+ .read = 0x123,
+ .alarm_rw = 0x127,
+ .alarm_ctrl = 0x11d,
+ .alarm_ctrl2 = 0x11e,
+ .alarm_en = BIT(1),
+};
+
+static const struct pm8xxx_rtc_regs pm8058_regs = {
+ .ctrl = 0x1e8,
+ .write = 0x1ea,
+ .read = 0x1ee,
+ .alarm_rw = 0x1f2,
+ .alarm_ctrl = 0x1e8,
+ .alarm_ctrl2 = 0x1e9,
+ .alarm_en = BIT(1),
+};
+
+static const struct pm8xxx_rtc_regs pm8941_regs = {
+ .ctrl = 0x6046,
+ .write = 0x6040,
+ .read = 0x6048,
+ .alarm_rw = 0x6140,
+ .alarm_ctrl = 0x6146,
+ .alarm_ctrl2 = 0x6148,
+ .alarm_en = BIT(7),
+};
+
/*
* Hardcoded RTC bases until IORESOURCE_REG mapping is figured out
*/
static const struct of_device_id pm8xxx_id_table[] = {
- { .compatible = "qcom,pm8921-rtc", .data = (void *) 0x11D },
- { .compatible = "qcom,pm8058-rtc", .data = (void *) 0x1E8 },
+ { .compatible = "qcom,pm8921-rtc", .data = &pm8921_regs },
+ { .compatible = "qcom,pm8058-rtc", .data = &pm8058_regs },
+ { .compatible = "qcom,pm8941-rtc", .data = &pm8941_regs },
{ },
};
MODULE_DEVICE_TABLE(of, pm8xxx_id_table);
@@ -369,7 +437,6 @@ MODULE_DEVICE_TABLE(of, pm8xxx_id_table);
static int pm8xxx_rtc_probe(struct platform_device *pdev)
{
int rc;
- unsigned int ctrl_reg;
struct pm8xxx_rtc *rtc_dd;
const struct of_device_id *match;
@@ -399,33 +466,12 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev)
rtc_dd->allow_set_time = of_property_read_bool(pdev->dev.of_node,
"allow-set-time");
- rtc_dd->rtc_base = (long) match->data;
-
- /* Setup RTC register addresses */
- rtc_dd->rtc_write_base = rtc_dd->rtc_base + PM8XXX_RTC_WRITE_OFFSET;
- rtc_dd->rtc_read_base = rtc_dd->rtc_base + PM8XXX_RTC_READ_OFFSET;
- rtc_dd->alarm_rw_base = rtc_dd->rtc_base + PM8XXX_ALARM_RW_OFFSET;
-
+ rtc_dd->regs = match->data;
rtc_dd->rtc_dev = &pdev->dev;
- /* Check if the RTC is on, else turn it on */
- rc = regmap_read(rtc_dd->regmap, rtc_dd->rtc_base, &ctrl_reg);
- if (rc) {
- dev_err(&pdev->dev, "RTC control register read failed!\n");
+ rc = pm8xxx_rtc_enable(rtc_dd);
+ if (rc)
return rc;
- }
-
- if (!(ctrl_reg & PM8xxx_RTC_ENABLE)) {
- ctrl_reg |= PM8xxx_RTC_ENABLE;
- rc = regmap_write(rtc_dd->regmap, rtc_dd->rtc_base, ctrl_reg);
- if (rc) {
- dev_err(&pdev->dev,
- "Write to RTC control register failed\n");
- return rc;
- }
- }
-
- rtc_dd->ctrl_reg = ctrl_reg;
platform_set_drvdata(pdev, rtc_dd);
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c
index a6b1252c9941..806072238c00 100644
--- a/drivers/rtc/rtc-s3c.c
+++ b/drivers/rtc/rtc-s3c.c
@@ -535,13 +535,15 @@ static int s3c_rtc_probe(struct platform_device *pdev)
}
clk_prepare_enable(info->rtc_clk);
- info->rtc_src_clk = devm_clk_get(&pdev->dev, "rtc_src");
- if (IS_ERR(info->rtc_src_clk)) {
- dev_err(&pdev->dev, "failed to find rtc source clock\n");
- return PTR_ERR(info->rtc_src_clk);
+ if (info->data->needs_src_clk) {
+ info->rtc_src_clk = devm_clk_get(&pdev->dev, "rtc_src");
+ if (IS_ERR(info->rtc_src_clk)) {
+ dev_err(&pdev->dev,
+ "failed to find rtc source clock\n");
+ return PTR_ERR(info->rtc_src_clk);
+ }
+ clk_prepare_enable(info->rtc_src_clk);
}
- clk_prepare_enable(info->rtc_src_clk);
-
/* check to see if everything is setup correctly */
if (info->data->enable)
diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c
index 729215885250..72e12bad14b9 100644
--- a/drivers/spi/spi-dw.c
+++ b/drivers/spi/spi-dw.c
@@ -669,6 +669,7 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
master->cleanup = dw_spi_cleanup;
master->transfer_one_message = dw_spi_transfer_one_message;
master->max_speed_hz = dws->max_freq;
+ master->dev.of_node = dev->of_node;
/* Basic HW init */
spi_hw_init(dws);
diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c
index 835cdda6f4f5..c76b7d7879df 100644
--- a/drivers/spi/spi-orion.c
+++ b/drivers/spi/spi-orion.c
@@ -454,7 +454,7 @@ static int orion_spi_probe(struct platform_device *pdev)
spi->master = master;
of_id = of_match_device(orion_spi_of_match_table, &pdev->dev);
- devdata = of_id->data;
+ devdata = (of_id) ? of_id->data : &orion_spi_dev_data;
spi->devdata = devdata;
spi->clk = devm_clk_get(&pdev->dev, NULL);
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c
index f35f723816ea..fc2dd8441608 100644
--- a/drivers/spi/spi-pl022.c
+++ b/drivers/spi/spi-pl022.c
@@ -1106,7 +1106,7 @@ err_rxdesc:
pl022->sgt_tx.nents, DMA_TO_DEVICE);
err_tx_sgmap:
dma_unmap_sg(rxchan->device->dev, pl022->sgt_rx.sgl,
- pl022->sgt_tx.nents, DMA_FROM_DEVICE);
+ pl022->sgt_rx.nents, DMA_FROM_DEVICE);
err_rx_sgmap:
sg_free_table(&pl022->sgt_tx);
err_alloc_tx_sg:
diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c
index f96ea8a38d64..87bc16f491f0 100644
--- a/drivers/spi/spi-rockchip.c
+++ b/drivers/spi/spi-rockchip.c
@@ -145,6 +145,9 @@
#define RXBUSY (1 << 0)
#define TXBUSY (1 << 1)
+/* sclk_out: spi master internal logic in rk3x can support 50Mhz */
+#define MAX_SCLK_OUT 50000000
+
enum rockchip_ssi_type {
SSI_MOTO_SPI = 0,
SSI_TI_SSP,
@@ -325,6 +328,8 @@ static int rockchip_spi_unprepare_message(struct spi_master *master,
spin_unlock_irqrestore(&rs->lock, flags);
+ spi_enable_chip(rs, 0);
+
return 0;
}
@@ -381,6 +386,8 @@ static int rockchip_spi_pio_transfer(struct rockchip_spi *rs)
if (rs->tx)
wait_for_idle(rs);
+ spi_enable_chip(rs, 0);
+
return 0;
}
@@ -392,8 +399,10 @@ static void rockchip_spi_dma_rxcb(void *data)
spin_lock_irqsave(&rs->lock, flags);
rs->state &= ~RXBUSY;
- if (!(rs->state & TXBUSY))
+ if (!(rs->state & TXBUSY)) {
+ spi_enable_chip(rs, 0);
spi_finalize_current_transfer(rs->master);
+ }
spin_unlock_irqrestore(&rs->lock, flags);
}
@@ -409,8 +418,10 @@ static void rockchip_spi_dma_txcb(void *data)
spin_lock_irqsave(&rs->lock, flags);
rs->state &= ~TXBUSY;
- if (!(rs->state & RXBUSY))
+ if (!(rs->state & RXBUSY)) {
+ spi_enable_chip(rs, 0);
spi_finalize_current_transfer(rs->master);
+ }
spin_unlock_irqrestore(&rs->lock, flags);
}
@@ -496,12 +507,19 @@ static void rockchip_spi_config(struct rockchip_spi *rs)
dmacr |= RF_DMA_EN;
}
+ if (WARN_ON(rs->speed > MAX_SCLK_OUT))
+ rs->speed = MAX_SCLK_OUT;
+
+ /* the minimum divsor is 2 */
+ if (rs->max_freq < 2 * rs->speed) {
+ clk_set_rate(rs->spiclk, 2 * rs->speed);
+ rs->max_freq = clk_get_rate(rs->spiclk);
+ }
+
/* div doesn't support odd number */
div = max_t(u32, rs->max_freq / rs->speed, 1);
div = (div + 1) & 0xfffe;
- spi_enable_chip(rs, 0);
-
writel_relaxed(cr0, rs->regs + ROCKCHIP_SPI_CTRLR0);
writel_relaxed(rs->len - 1, rs->regs + ROCKCHIP_SPI_CTRLR1);
@@ -515,8 +533,6 @@ static void rockchip_spi_config(struct rockchip_spi *rs)
spi_set_clk(rs, div);
dev_dbg(rs->dev, "cr0 0x%x, div %d\n", cr0, div);
-
- spi_enable_chip(rs, 1);
}
static int rockchip_spi_transfer_one(
@@ -524,7 +540,7 @@ static int rockchip_spi_transfer_one(
struct spi_device *spi,
struct spi_transfer *xfer)
{
- int ret = 0;
+ int ret = 1;
struct rockchip_spi *rs = spi_master_get_devdata(master);
WARN_ON(readl_relaxed(rs->regs + ROCKCHIP_SPI_SSIENR) &&
@@ -556,17 +572,27 @@ static int rockchip_spi_transfer_one(
rs->tmode = CR0_XFM_RO;
/* we need prepare dma before spi was enabled */
- if (master->can_dma && master->can_dma(master, spi, xfer)) {
+ if (master->can_dma && master->can_dma(master, spi, xfer))
rs->use_dma = 1;
- rockchip_spi_prepare_dma(rs);
- } else {
+ else
rs->use_dma = 0;
- }
rockchip_spi_config(rs);
- if (!rs->use_dma)
+ if (rs->use_dma) {
+ if (rs->tmode == CR0_XFM_RO) {
+ /* rx: dma must be prepared first */
+ rockchip_spi_prepare_dma(rs);
+ spi_enable_chip(rs, 1);
+ } else {
+ /* tx or tr: spi must be enabled first */
+ spi_enable_chip(rs, 1);
+ rockchip_spi_prepare_dma(rs);
+ }
+ } else {
+ spi_enable_chip(rs, 1);
ret = rockchip_spi_pio_transfer(rs);
+ }
return ret;
}
diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c
index e3bc23bb5883..e50039fb1474 100644
--- a/drivers/spi/spidev.c
+++ b/drivers/spi/spidev.c
@@ -82,10 +82,11 @@ struct spidev_data {
struct spi_device *spi;
struct list_head device_entry;
- /* buffer is NULL unless this device is open (users > 0) */
+ /* TX/RX buffers are NULL unless this device is open (users > 0) */
struct mutex buf_lock;
unsigned users;
- u8 *buffer;
+ u8 *tx_buffer;
+ u8 *rx_buffer;
};
static LIST_HEAD(device_list);
@@ -135,7 +136,7 @@ static inline ssize_t
spidev_sync_write(struct spidev_data *spidev, size_t len)
{
struct spi_transfer t = {
- .tx_buf = spidev->buffer,
+ .tx_buf = spidev->tx_buffer,
.len = len,
};
struct spi_message m;
@@ -149,7 +150,7 @@ static inline ssize_t
spidev_sync_read(struct spidev_data *spidev, size_t len)
{
struct spi_transfer t = {
- .rx_buf = spidev->buffer,
+ .rx_buf = spidev->rx_buffer,
.len = len,
};
struct spi_message m;
@@ -179,7 +180,7 @@ spidev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
if (status > 0) {
unsigned long missing;
- missing = copy_to_user(buf, spidev->buffer, status);
+ missing = copy_to_user(buf, spidev->rx_buffer, status);
if (missing == status)
status = -EFAULT;
else
@@ -206,7 +207,7 @@ spidev_write(struct file *filp, const char __user *buf,
spidev = filp->private_data;
mutex_lock(&spidev->buf_lock);
- missing = copy_from_user(spidev->buffer, buf, count);
+ missing = copy_from_user(spidev->tx_buffer, buf, count);
if (missing == 0)
status = spidev_sync_write(spidev, count);
else
@@ -224,7 +225,7 @@ static int spidev_message(struct spidev_data *spidev,
struct spi_transfer *k_tmp;
struct spi_ioc_transfer *u_tmp;
unsigned n, total;
- u8 *buf;
+ u8 *tx_buf, *rx_buf;
int status = -EFAULT;
spi_message_init(&msg);
@@ -236,7 +237,8 @@ static int spidev_message(struct spidev_data *spidev,
* We walk the array of user-provided transfers, using each one
* to initialize a kernel version of the same transfer.
*/
- buf = spidev->buffer;
+ tx_buf = spidev->tx_buffer;
+ rx_buf = spidev->rx_buffer;
total = 0;
for (n = n_xfers, k_tmp = k_xfers, u_tmp = u_xfers;
n;
@@ -250,20 +252,21 @@ static int spidev_message(struct spidev_data *spidev,
}
if (u_tmp->rx_buf) {
- k_tmp->rx_buf = buf;
+ k_tmp->rx_buf = rx_buf;
if (!access_ok(VERIFY_WRITE, (u8 __user *)
(uintptr_t) u_tmp->rx_buf,
u_tmp->len))
goto done;
}
if (u_tmp->tx_buf) {
- k_tmp->tx_buf = buf;
- if (copy_from_user(buf, (const u8 __user *)
+ k_tmp->tx_buf = tx_buf;
+ if (copy_from_user(tx_buf, (const u8 __user *)
(uintptr_t) u_tmp->tx_buf,
u_tmp->len))
goto done;
}
- buf += k_tmp->len;
+ tx_buf += k_tmp->len;
+ rx_buf += k_tmp->len;
k_tmp->cs_change = !!u_tmp->cs_change;
k_tmp->tx_nbits = u_tmp->tx_nbits;
@@ -290,17 +293,17 @@ static int spidev_message(struct spidev_data *spidev,
goto done;
/* copy any rx data out of bounce buffer */
- buf = spidev->buffer;
+ rx_buf = spidev->rx_buffer;
for (n = n_xfers, u_tmp = u_xfers; n; n--, u_tmp++) {
if (u_tmp->rx_buf) {
if (__copy_to_user((u8 __user *)
- (uintptr_t) u_tmp->rx_buf, buf,
+ (uintptr_t) u_tmp->rx_buf, rx_buf,
u_tmp->len)) {
status = -EFAULT;
goto done;
}
}
- buf += u_tmp->len;
+ rx_buf += u_tmp->len;
}
status = total;
@@ -508,22 +511,41 @@ static int spidev_open(struct inode *inode, struct file *filp)
break;
}
}
- if (status == 0) {
- if (!spidev->buffer) {
- spidev->buffer = kmalloc(bufsiz, GFP_KERNEL);
- if (!spidev->buffer) {
+
+ if (status) {
+ pr_debug("spidev: nothing for minor %d\n", iminor(inode));
+ goto err_find_dev;
+ }
+
+ if (!spidev->tx_buffer) {
+ spidev->tx_buffer = kmalloc(bufsiz, GFP_KERNEL);
+ if (!spidev->tx_buffer) {
dev_dbg(&spidev->spi->dev, "open/ENOMEM\n");
status = -ENOMEM;
+ goto err_find_dev;
}
}
- if (status == 0) {
- spidev->users++;
- filp->private_data = spidev;
- nonseekable_open(inode, filp);
+
+ if (!spidev->rx_buffer) {
+ spidev->rx_buffer = kmalloc(bufsiz, GFP_KERNEL);
+ if (!spidev->rx_buffer) {
+ dev_dbg(&spidev->spi->dev, "open/ENOMEM\n");
+ status = -ENOMEM;
+ goto err_alloc_rx_buf;
}
- } else
- pr_debug("spidev: nothing for minor %d\n", iminor(inode));
+ }
+
+ spidev->users++;
+ filp->private_data = spidev;
+ nonseekable_open(inode, filp);
+
+ mutex_unlock(&device_list_lock);
+ return 0;
+err_alloc_rx_buf:
+ kfree(spidev->tx_buffer);
+ spidev->tx_buffer = NULL;
+err_find_dev:
mutex_unlock(&device_list_lock);
return status;
}
@@ -542,8 +564,11 @@ static int spidev_release(struct inode *inode, struct file *filp)
if (!spidev->users) {
int dofree;
- kfree(spidev->buffer);
- spidev->buffer = NULL;
+ kfree(spidev->tx_buffer);
+ spidev->tx_buffer = NULL;
+
+ kfree(spidev->rx_buffer);
+ spidev->rx_buffer = NULL;
/* ... after we unbound from the underlying device? */
spin_lock_irq(&spidev->spi_lock);
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 57b1d44acbfe..eb976ee3a02f 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -448,8 +448,10 @@ static int __init fb_console_setup(char *this_opt)
return 1;
while ((options = strsep(&this_opt, ",")) != NULL) {
- if (!strncmp(options, "font:", 5))
+ if (!strncmp(options, "font:", 5)) {
strlcpy(fontname, options + 5, sizeof(fontname));
+ continue;
+ }
if (!strncmp(options, "scrollback:", 11)) {
options += 11;
@@ -457,13 +459,9 @@ static int __init fb_console_setup(char *this_opt)
fbcon_softback_size = simple_strtoul(options, &options, 0);
if (*options == 'k' || *options == 'K') {
fbcon_softback_size *= 1024;
- options++;
}
- if (*options != ',')
- return 1;
- options++;
- } else
- return 1;
+ }
+ continue;
}
if (!strncmp(options, "map:", 4)) {
@@ -478,8 +476,7 @@ static int __init fb_console_setup(char *this_opt)
fbcon_map_override();
}
-
- return 1;
+ continue;
}
if (!strncmp(options, "vc:", 3)) {
@@ -491,7 +488,8 @@ static int __init fb_console_setup(char *this_opt)
if (*options++ == '-')
last_fb_vc = simple_strtoul(options, &options, 10) - 1;
fbcon_is_default = 0;
- }
+ continue;
+ }
if (!strncmp(options, "rotate:", 7)) {
options += 7;
@@ -499,6 +497,7 @@ static int __init fb_console_setup(char *this_opt)
initial_rotation = simple_strtoul(options, &options, 0);
if (initial_rotation > 3)
initial_rotation = 0;
+ continue;
}
}
return 1;
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 6e6aa704fe84..517f565b65d7 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -56,7 +56,7 @@ static int cursor_size_lastfrom;
static int cursor_size_lastto;
static u32 vgacon_xres;
static u32 vgacon_yres;
-static struct vgastate state;
+static struct vgastate vgastate;
#define BLANK 0x0020
@@ -400,7 +400,7 @@ static const char *vgacon_startup(void)
vga_video_num_lines = screen_info.orig_video_lines;
vga_video_num_columns = screen_info.orig_video_cols;
- state.vgabase = NULL;
+ vgastate.vgabase = NULL;
if (screen_info.orig_video_mode == 7) {
/* Monochrome display */
@@ -851,12 +851,12 @@ static void vga_set_palette(struct vc_data *vc, unsigned char *table)
{
int i, j;
- vga_w(state.vgabase, VGA_PEL_MSK, 0xff);
+ vga_w(vgastate.vgabase, VGA_PEL_MSK, 0xff);
for (i = j = 0; i < 16; i++) {
- vga_w(state.vgabase, VGA_PEL_IW, table[i]);
- vga_w(state.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2);
- vga_w(state.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2);
- vga_w(state.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2);
+ vga_w(vgastate.vgabase, VGA_PEL_IW, table[i]);
+ vga_w(vgastate.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2);
+ vga_w(vgastate.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2);
+ vga_w(vgastate.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2);
}
}
@@ -1008,7 +1008,7 @@ static int vgacon_blank(struct vc_data *c, int blank, int mode_switch)
switch (blank) {
case 0: /* Unblank */
if (vga_vesa_blanked) {
- vga_vesa_unblank(&state);
+ vga_vesa_unblank(&vgastate);
vga_vesa_blanked = 0;
}
if (vga_palette_blanked) {
@@ -1022,7 +1022,7 @@ static int vgacon_blank(struct vc_data *c, int blank, int mode_switch)
case 1: /* Normal blanking */
case -1: /* Obsolete */
if (!mode_switch && vga_video_type == VIDEO_TYPE_VGAC) {
- vga_pal_blank(&state);
+ vga_pal_blank(&vgastate);
vga_palette_blanked = 1;
return 0;
}
@@ -1034,7 +1034,7 @@ static int vgacon_blank(struct vc_data *c, int blank, int mode_switch)
return 1;
default: /* VESA blanking */
if (vga_video_type == VIDEO_TYPE_VGAC) {
- vga_vesa_blank(&state, blank - 1);
+ vga_vesa_blank(&vgastate, blank - 1);
vga_vesa_blanked = blank;
}
return 0;
@@ -1280,7 +1280,7 @@ static int vgacon_font_set(struct vc_data *c, struct console_font *font, unsigne
(charcount != 256 && charcount != 512))
return -EINVAL;
- rc = vgacon_do_font_op(&state, font->data, 1, charcount == 512);
+ rc = vgacon_do_font_op(&vgastate, font->data, 1, charcount == 512);
if (rc)
return rc;
@@ -1299,7 +1299,7 @@ static int vgacon_font_get(struct vc_data *c, struct console_font *font)
font->charcount = vga_512_chars ? 512 : 256;
if (!font->data)
return 0;
- return vgacon_do_font_op(&state, font->data, 0, vga_512_chars);
+ return vgacon_do_font_op(&vgastate, font->data, 0, vga_512_chars);
}
#else
diff --git a/drivers/video/fbdev/atmel_lcdfb.c b/drivers/video/fbdev/atmel_lcdfb.c
index 3bf403150a2d..9ec81d46fc57 100644
--- a/drivers/video/fbdev/atmel_lcdfb.c
+++ b/drivers/video/fbdev/atmel_lcdfb.c
@@ -27,7 +27,6 @@
#include <linux/regulator/consumer.h>
#include <video/videomode.h>
-#include <mach/cpu.h>
#include <asm/gpio.h>
#include <video/atmel_lcdc.h>
diff --git a/drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c b/drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c
index 5ee3b5505f7f..91921665b98b 100644
--- a/drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c
+++ b/drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c
@@ -301,6 +301,8 @@ static const struct of_device_id tvc_of_match[] = {
{},
};
+MODULE_DEVICE_TABLE(of, tvc_of_match);
+
static struct platform_driver tvc_connector_driver = {
.probe = tvc_probe,
.remove = __exit_p(tvc_remove),
@@ -308,6 +310,7 @@ static struct platform_driver tvc_connector_driver = {
.name = "connector-analog-tv",
.owner = THIS_MODULE,
.of_match_table = tvc_of_match,
+ .suppress_bind_attrs = true,
},
};
diff --git a/drivers/video/fbdev/omap2/displays-new/connector-dvi.c b/drivers/video/fbdev/omap2/displays-new/connector-dvi.c
index 74de2bc50c4f..2dfb6e5ff0cc 100644
--- a/drivers/video/fbdev/omap2/displays-new/connector-dvi.c
+++ b/drivers/video/fbdev/omap2/displays-new/connector-dvi.c
@@ -391,6 +391,7 @@ static struct platform_driver dvi_connector_driver = {
.name = "connector-dvi",
.owner = THIS_MODULE,
.of_match_table = dvic_of_match,
+ .suppress_bind_attrs = true,
},
};
diff --git a/drivers/video/fbdev/omap2/displays-new/connector-hdmi.c b/drivers/video/fbdev/omap2/displays-new/connector-hdmi.c
index 131c6e260898..7b25967a91eb 100644
--- a/drivers/video/fbdev/omap2/displays-new/connector-hdmi.c
+++ b/drivers/video/fbdev/omap2/displays-new/connector-hdmi.c
@@ -437,6 +437,7 @@ static struct platform_driver hdmi_connector_driver = {
.name = "connector-hdmi",
.owner = THIS_MODULE,
.of_match_table = hdmic_of_match,
+ .suppress_bind_attrs = true,
},
};
diff --git a/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c b/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c
index b4e9a42a79e6..47ee7cdee1c5 100644
--- a/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c
+++ b/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c
@@ -298,6 +298,7 @@ static struct platform_driver tfp410_driver = {
.name = "tfp410",
.owner = THIS_MODULE,
.of_match_table = tfp410_of_match,
+ .suppress_bind_attrs = true,
},
};
diff --git a/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c b/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c
index c891d8f84cb2..c4abd56dd846 100644
--- a/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c
+++ b/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c
@@ -461,6 +461,7 @@ static struct platform_driver tpd_driver = {
.name = "tpd12s015",
.owner = THIS_MODULE,
.of_match_table = tpd_of_match,
+ .suppress_bind_attrs = true,
},
};
diff --git a/drivers/video/fbdev/omap2/displays-new/panel-dpi.c b/drivers/video/fbdev/omap2/displays-new/panel-dpi.c
index 3636b61dc9b4..a9c3dcf0f6b5 100644
--- a/drivers/video/fbdev/omap2/displays-new/panel-dpi.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-dpi.c
@@ -327,6 +327,7 @@ static struct platform_driver panel_dpi_driver = {
.name = "panel-dpi",
.owner = THIS_MODULE,
.of_match_table = panel_dpi_of_match,
+ .suppress_bind_attrs = true,
},
};
diff --git a/drivers/video/fbdev/omap2/displays-new/panel-dsi-cm.c b/drivers/video/fbdev/omap2/displays-new/panel-dsi-cm.c
index d6f14e8717e8..899cb1ab523d 100644
--- a/drivers/video/fbdev/omap2/displays-new/panel-dsi-cm.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-dsi-cm.c
@@ -1378,6 +1378,7 @@ static struct platform_driver dsicm_driver = {
.name = "panel-dsi-cm",
.owner = THIS_MODULE,
.of_match_table = dsicm_of_match,
+ .suppress_bind_attrs = true,
},
};
diff --git a/drivers/video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c b/drivers/video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c
index cc5b5124e0b4..27d4fcfa1824 100644
--- a/drivers/video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c
@@ -394,6 +394,7 @@ static struct spi_driver lb035q02_spi_driver = {
.name = "panel_lgphilips_lb035q02",
.owner = THIS_MODULE,
.of_match_table = lb035q02_of_match,
+ .suppress_bind_attrs = true,
},
};
diff --git a/drivers/video/fbdev/omap2/displays-new/panel-nec-nl8048hl11.c b/drivers/video/fbdev/omap2/displays-new/panel-nec-nl8048hl11.c
index 3595f111aa35..ccf3f4f3c703 100644
--- a/drivers/video/fbdev/omap2/displays-new/panel-nec-nl8048hl11.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-nec-nl8048hl11.c
@@ -424,6 +424,7 @@ static struct spi_driver nec_8048_driver = {
.owner = THIS_MODULE,
.pm = NEC_8048_PM_OPS,
.of_match_table = nec_8048_of_match,
+ .suppress_bind_attrs = true,
},
.probe = nec_8048_probe,
.remove = nec_8048_remove,
diff --git a/drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c b/drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c
index f1f72ce50a17..234142cc3764 100644
--- a/drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c
@@ -410,6 +410,7 @@ static struct platform_driver sharp_ls_driver = {
.name = "panel-sharp-ls037v7dw01",
.owner = THIS_MODULE,
.of_match_table = sharp_ls_of_match,
+ .suppress_bind_attrs = true,
},
};
diff --git a/drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c b/drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c
index 617f8d2f5127..337ccc5c0f5e 100644
--- a/drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c
@@ -904,6 +904,7 @@ static struct spi_driver acx565akm_driver = {
.name = "acx565akm",
.owner = THIS_MODULE,
.of_match_table = acx565akm_of_match,
+ .suppress_bind_attrs = true,
},
.probe = acx565akm_probe,
.remove = acx565akm_remove,
diff --git a/drivers/video/fbdev/omap2/displays-new/panel-tpo-td028ttec1.c b/drivers/video/fbdev/omap2/displays-new/panel-tpo-td028ttec1.c
index 728808bcceeb..fbba0b8ca871 100644
--- a/drivers/video/fbdev/omap2/displays-new/panel-tpo-td028ttec1.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-tpo-td028ttec1.c
@@ -500,6 +500,7 @@ static struct spi_driver td028ttec1_spi_driver = {
.name = "panel-tpo-td028ttec1",
.owner = THIS_MODULE,
.of_match_table = td028ttec1_of_match,
+ .suppress_bind_attrs = true,
},
};
diff --git a/drivers/video/fbdev/omap2/displays-new/panel-tpo-td043mtea1.c b/drivers/video/fbdev/omap2/displays-new/panel-tpo-td043mtea1.c
index de78ab0caaa8..5aba76bca25a 100644
--- a/drivers/video/fbdev/omap2/displays-new/panel-tpo-td043mtea1.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-tpo-td043mtea1.c
@@ -673,6 +673,7 @@ static struct spi_driver tpo_td043_spi_driver = {
.owner = THIS_MODULE,
.pm = &tpo_td043_spi_pm,
.of_match_table = tpo_td043_of_match,
+ .suppress_bind_attrs = true,
},
.probe = tpo_td043_probe,
.remove = tpo_td043_remove,
diff --git a/drivers/video/fbdev/omap2/dss/apply.c b/drivers/video/fbdev/omap2/dss/apply.c
index 0a0b084ce65d..663ccc3bf4e5 100644
--- a/drivers/video/fbdev/omap2/dss/apply.c
+++ b/drivers/video/fbdev/omap2/dss/apply.c
@@ -1132,6 +1132,8 @@ static void dss_mgr_disable_compat(struct omap_overlay_manager *mgr)
if (!mp->enabled)
goto out;
+ wait_pending_extra_info_updates();
+
if (!mgr_manual_update(mgr))
dispc_mgr_disable_sync(mgr->id);
diff --git a/drivers/video/fbdev/omap2/dss/dispc.c b/drivers/video/fbdev/omap2/dss/dispc.c
index be053aa80880..0e9a74bb9fc2 100644
--- a/drivers/video/fbdev/omap2/dss/dispc.c
+++ b/drivers/video/fbdev/omap2/dss/dispc.c
@@ -3290,8 +3290,11 @@ static void dispc_dump_regs(struct seq_file *s)
DUMPREG(i, DISPC_OVL_FIFO_SIZE_STATUS);
DUMPREG(i, DISPC_OVL_ROW_INC);
DUMPREG(i, DISPC_OVL_PIXEL_INC);
+
if (dss_has_feature(FEAT_PRELOAD))
DUMPREG(i, DISPC_OVL_PRELOAD);
+ if (dss_has_feature(FEAT_MFLAG))
+ DUMPREG(i, DISPC_OVL_MFLAG_THRESHOLD);
if (i == OMAP_DSS_GFX) {
DUMPREG(i, DISPC_OVL_WINDOW_SKIP);
@@ -3312,10 +3315,6 @@ static void dispc_dump_regs(struct seq_file *s)
}
if (dss_has_feature(FEAT_ATTR2))
DUMPREG(i, DISPC_OVL_ATTRIBUTES2);
- if (dss_has_feature(FEAT_PRELOAD))
- DUMPREG(i, DISPC_OVL_PRELOAD);
- if (dss_has_feature(FEAT_MFLAG))
- DUMPREG(i, DISPC_OVL_MFLAG_THRESHOLD);
}
#undef DISPC_REG
@@ -3843,6 +3842,7 @@ static struct platform_driver omap_dispchw_driver = {
.owner = THIS_MODULE,
.pm = &dispc_pm_ops,
.of_match_table = dispc_of_match,
+ .suppress_bind_attrs = true,
},
};
diff --git a/drivers/video/fbdev/omap2/dss/dispc.h b/drivers/video/fbdev/omap2/dss/dispc.h
index 78edb449c763..3043d6e0a5f9 100644
--- a/drivers/video/fbdev/omap2/dss/dispc.h
+++ b/drivers/video/fbdev/omap2/dss/dispc.h
@@ -101,8 +101,7 @@
DISPC_FIR_COEF_V2_OFFSET(n, i))
#define DISPC_OVL_PRELOAD(n) (DISPC_OVL_BASE(n) + \
DISPC_PRELOAD_OFFSET(n))
-#define DISPC_OVL_MFLAG_THRESHOLD(n) (DISPC_OVL_BASE(n) + \
- DISPC_MFLAG_THRESHOLD_OFFSET(n))
+#define DISPC_OVL_MFLAG_THRESHOLD(n) DISPC_MFLAG_THRESHOLD_OFFSET(n)
/* DISPC up/downsampling FIR filter coefficient structure */
struct dispc_coef {
diff --git a/drivers/video/fbdev/omap2/dss/dpi.c b/drivers/video/fbdev/omap2/dss/dpi.c
index 9368972d6962..4a3363dae74a 100644
--- a/drivers/video/fbdev/omap2/dss/dpi.c
+++ b/drivers/video/fbdev/omap2/dss/dpi.c
@@ -720,6 +720,7 @@ static struct platform_driver omap_dpi_driver = {
.driver = {
.name = "omapdss_dpi",
.owner = THIS_MODULE,
+ .suppress_bind_attrs = true,
},
};
diff --git a/drivers/video/fbdev/omap2/dss/dsi.c b/drivers/video/fbdev/omap2/dss/dsi.c
index b6f6ae1d4664..0793bc67a275 100644
--- a/drivers/video/fbdev/omap2/dss/dsi.c
+++ b/drivers/video/fbdev/omap2/dss/dsi.c
@@ -1603,7 +1603,7 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev,
} else if (dss_has_feature(FEAT_DSI_PLL_SELFREQDCO)) {
f = cinfo->clkin4ddr < 1000000000 ? 0x2 : 0x4;
- l = FLD_MOD(l, f, 4, 1); /* PLL_SELFREQDCO */
+ l = FLD_MOD(l, f, 3, 1); /* PLL_SELFREQDCO */
}
l = FLD_MOD(l, 1, 13, 13); /* DSI_PLL_REFEN */
@@ -5754,6 +5754,7 @@ static struct platform_driver omap_dsihw_driver = {
.owner = THIS_MODULE,
.pm = &dsi_pm_ops,
.of_match_table = dsi_of_match,
+ .suppress_bind_attrs = true,
},
};
diff --git a/drivers/video/fbdev/omap2/dss/dss.c b/drivers/video/fbdev/omap2/dss/dss.c
index 6daeb7ed44c6..14bcd6c43f72 100644
--- a/drivers/video/fbdev/omap2/dss/dss.c
+++ b/drivers/video/fbdev/omap2/dss/dss.c
@@ -966,6 +966,7 @@ static struct platform_driver omap_dsshw_driver = {
.owner = THIS_MODULE,
.pm = &dss_pm_ops,
.of_match_table = dss_of_match,
+ .suppress_bind_attrs = true,
},
};
diff --git a/drivers/video/fbdev/omap2/dss/hdmi4.c b/drivers/video/fbdev/omap2/dss/hdmi4.c
index 6a8550cf43e5..9a8713ca090c 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi4.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi4.c
@@ -781,6 +781,7 @@ static struct platform_driver omapdss_hdmihw_driver = {
.owner = THIS_MODULE,
.pm = &hdmi_pm_ops,
.of_match_table = hdmi_of_match,
+ .suppress_bind_attrs = true,
},
};
diff --git a/drivers/video/fbdev/omap2/dss/hdmi5.c b/drivers/video/fbdev/omap2/dss/hdmi5.c
index 32d02ec34d23..169b764bb9d4 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi5.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi5.c
@@ -806,6 +806,7 @@ static struct platform_driver omapdss_hdmihw_driver = {
.owner = THIS_MODULE,
.pm = &hdmi_pm_ops,
.of_match_table = hdmi_of_match,
+ .suppress_bind_attrs = true,
},
};
diff --git a/drivers/video/fbdev/omap2/dss/hdmi_pll.c b/drivers/video/fbdev/omap2/dss/hdmi_pll.c
index 54df12a8d744..6d92bb32fe51 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi_pll.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi_pll.c
@@ -124,16 +124,15 @@ static int hdmi_pll_config(struct hdmi_pll_data *pll)
r = FLD_MOD(r, 0x0, 14, 14); /* PHY_CLKINEN de-assert during locking */
r = FLD_MOD(r, fmt->refsel, 22, 21); /* REFSEL */
- if (fmt->dcofreq) {
- /* divider programming for frequency beyond 1000Mhz */
- REG_FLD_MOD(pll->base, PLLCTRL_CFG3, fmt->regsd, 17, 10);
+ if (fmt->dcofreq)
r = FLD_MOD(r, 0x4, 3, 1); /* 1000MHz and 2000MHz */
- } else {
+ else
r = FLD_MOD(r, 0x2, 3, 1); /* 500MHz and 1000MHz */
- }
hdmi_write_reg(pll->base, PLLCTRL_CFG2, r);
+ REG_FLD_MOD(pll->base, PLLCTRL_CFG3, fmt->regsd, 17, 10);
+
r = hdmi_read_reg(pll->base, PLLCTRL_CFG4);
r = FLD_MOD(r, fmt->regm2, 24, 18);
r = FLD_MOD(r, fmt->regmf, 17, 0);
@@ -144,8 +143,8 @@ static int hdmi_pll_config(struct hdmi_pll_data *pll)
/* wait for bit change */
if (hdmi_wait_for_bit_change(pll->base, PLLCTRL_PLL_GO,
- 0, 0, 1) != 1) {
- DSSERR("PLL GO bit not set\n");
+ 0, 0, 0) != 0) {
+ DSSERR("PLL GO bit not clearing\n");
return -ETIMEDOUT;
}
diff --git a/drivers/video/fbdev/omap2/dss/rfbi.c b/drivers/video/fbdev/omap2/dss/rfbi.c
index c8a81a2b879c..878273f58839 100644
--- a/drivers/video/fbdev/omap2/dss/rfbi.c
+++ b/drivers/video/fbdev/omap2/dss/rfbi.c
@@ -1044,6 +1044,7 @@ static struct platform_driver omap_rfbihw_driver = {
.name = "omapdss_rfbi",
.owner = THIS_MODULE,
.pm = &rfbi_pm_ops,
+ .suppress_bind_attrs = true,
},
};
diff --git a/drivers/video/fbdev/omap2/dss/sdi.c b/drivers/video/fbdev/omap2/dss/sdi.c
index 911dcc9173a6..4c9c46d4ea60 100644
--- a/drivers/video/fbdev/omap2/dss/sdi.c
+++ b/drivers/video/fbdev/omap2/dss/sdi.c
@@ -377,6 +377,7 @@ static struct platform_driver omap_sdi_driver = {
.driver = {
.name = "omapdss_sdi",
.owner = THIS_MODULE,
+ .suppress_bind_attrs = true,
},
};
diff --git a/drivers/video/fbdev/omap2/dss/venc.c b/drivers/video/fbdev/omap2/dss/venc.c
index 21d81113962b..d077d8a75ddc 100644
--- a/drivers/video/fbdev/omap2/dss/venc.c
+++ b/drivers/video/fbdev/omap2/dss/venc.c
@@ -966,6 +966,7 @@ static struct platform_driver omap_venchw_driver = {
.owner = THIS_MODULE,
.pm = &venc_pm_ops,
.of_match_table = venc_of_match,
+ .suppress_bind_attrs = true,
},
};
diff --git a/drivers/video/fbdev/omap2/omapfb/omapfb-main.c b/drivers/video/fbdev/omap2/omapfb/omapfb-main.c
index 15872433e0c6..ce8a70570756 100644
--- a/drivers/video/fbdev/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/fbdev/omap2/omapfb/omapfb-main.c
@@ -1833,14 +1833,13 @@ static void omapfb_free_resources(struct omapfb2_device *fbdev)
if (fbdev == NULL)
return;
- for (i = 0; i < fbdev->num_fbs; i++) {
- struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[i]);
- int j;
+ for (i = 0; i < fbdev->num_overlays; i++) {
+ struct omap_overlay *ovl = fbdev->overlays[i];
- for (j = 0; j < ofbi->num_overlays; j++) {
- struct omap_overlay *ovl = ofbi->overlays[j];
- ovl->disable(ovl);
- }
+ ovl->disable(ovl);
+
+ if (ovl->manager)
+ ovl->unset_manager(ovl);
}
for (i = 0; i < fbdev->num_fbs; i++)
@@ -2619,7 +2618,7 @@ err0:
return r;
}
-static int __exit omapfb_remove(struct platform_device *pdev)
+static int omapfb_remove(struct platform_device *pdev)
{
struct omapfb2_device *fbdev = platform_get_drvdata(pdev);
@@ -2636,7 +2635,7 @@ static int __exit omapfb_remove(struct platform_device *pdev)
static struct platform_driver omapfb_driver = {
.probe = omapfb_probe,
- .remove = __exit_p(omapfb_remove),
+ .remove = omapfb_remove,
.driver = {
.name = "omapfb",
.owner = THIS_MODULE,
@@ -2651,6 +2650,7 @@ module_param_named(mirror, def_mirror, bool, 0);
module_platform_driver(omapfb_driver);
+MODULE_ALIAS("platform:omapfb");
MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>");
MODULE_DESCRIPTION("OMAP2/3 Framebuffer");
MODULE_LICENSE("GPL v2");